| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 892 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 903 __ Push(r3, r2); | 903 __ Push(r3, r2); |
| 904 | 904 |
| 905 // Perform tail call to the entry. | 905 // Perform tail call to the entry. |
| 906 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss)); | 906 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss)); |
| 907 __ TailCallExternalReference(ref, 2, 1); | 907 __ TailCallExternalReference(ref, 2, 1); |
| 908 } | 908 } |
| 909 | 909 |
| 910 // Returns the code marker, or the 0 if the code is not marked. | 910 // Returns the code marker, or the 0 if the code is not marked. |
| 911 static inline int InlinedICSiteMarker(Address address, | 911 static inline int InlinedICSiteMarker(Address address, |
| 912 Address* inline_end_address) { | 912 Address* inline_end_address) { |
| 913 if (V8::UseCrankshaft()) return false; |
| 914 |
| 913 // If the instruction after the call site is not the pseudo instruction nop1 | 915 // If the instruction after the call site is not the pseudo instruction nop1 |
| 914 // then this is not related to an inlined in-object property load. The nop1 | 916 // then this is not related to an inlined in-object property load. The nop1 |
| 915 // instruction is located just after the call to the IC in the deferred code | 917 // instruction is located just after the call to the IC in the deferred code |
| 916 // handling the miss in the inlined code. After the nop1 instruction there is | 918 // handling the miss in the inlined code. After the nop1 instruction there is |
| 917 // a branch instruction for jumping back from the deferred code. | 919 // a branch instruction for jumping back from the deferred code. |
| 918 Address address_after_call = address + Assembler::kCallTargetAddressOffset; | 920 Address address_after_call = address + Assembler::kCallTargetAddressOffset; |
| 919 Instr instr_after_call = Assembler::instr_at(address_after_call); | 921 Instr instr_after_call = Assembler::instr_at(address_after_call); |
| 920 int code_marker = MacroAssembler::GetCodeMarker(instr_after_call); | 922 int code_marker = MacroAssembler::GetCodeMarker(instr_after_call); |
| 921 | 923 |
| 922 // A negative result means the code is not marked. | 924 // A negative result means the code is not marked. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 936 int b_offset = | 938 int b_offset = |
| 937 Assembler::GetBranchOffset(instr_after_nop) + Assembler::kPcLoadDelta; | 939 Assembler::GetBranchOffset(instr_after_nop) + Assembler::kPcLoadDelta; |
| 938 ASSERT(b_offset < 0); // Jumping back from deferred code. | 940 ASSERT(b_offset < 0); // Jumping back from deferred code. |
| 939 *inline_end_address = address_after_nop + b_offset; | 941 *inline_end_address = address_after_nop + b_offset; |
| 940 | 942 |
| 941 return code_marker; | 943 return code_marker; |
| 942 } | 944 } |
| 943 | 945 |
| 944 | 946 |
| 945 bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) { | 947 bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) { |
| 948 if (V8::UseCrankshaft()) return false; |
| 949 |
| 946 // Find the end of the inlined code for handling the load if this is an | 950 // Find the end of the inlined code for handling the load if this is an |
| 947 // inlined IC call site. | 951 // inlined IC call site. |
| 948 Address inline_end_address; | 952 Address inline_end_address; |
| 949 if (InlinedICSiteMarker(address, &inline_end_address) | 953 if (InlinedICSiteMarker(address, &inline_end_address) |
| 950 != Assembler::PROPERTY_ACCESS_INLINED) { | 954 != Assembler::PROPERTY_ACCESS_INLINED) { |
| 951 return false; | 955 return false; |
| 952 } | 956 } |
| 953 | 957 |
| 954 // Patch the offset of the property load instruction (ldr r0, [r1, #+XXX]). | 958 // Patch the offset of the property load instruction (ldr r0, [r1, #+XXX]). |
| 955 // The immediate must be representable in 12 bits. | 959 // The immediate must be representable in 12 bits. |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1015 reinterpret_cast<Address>(map)); | 1019 reinterpret_cast<Address>(map)); |
| 1016 // Patch the cell address. | 1020 // Patch the cell address. |
| 1017 Assembler::set_target_address_at(ldr_cell_instr_address, | 1021 Assembler::set_target_address_at(ldr_cell_instr_address, |
| 1018 reinterpret_cast<Address>(cell)); | 1022 reinterpret_cast<Address>(cell)); |
| 1019 | 1023 |
| 1020 return true; | 1024 return true; |
| 1021 } | 1025 } |
| 1022 | 1026 |
| 1023 | 1027 |
| 1024 bool StoreIC::PatchInlinedStore(Address address, Object* map, int offset) { | 1028 bool StoreIC::PatchInlinedStore(Address address, Object* map, int offset) { |
| 1029 if (V8::UseCrankshaft()) return false; |
| 1030 |
| 1025 // Find the end of the inlined code for the store if there is an | 1031 // Find the end of the inlined code for the store if there is an |
| 1026 // inlined version of the store. | 1032 // inlined version of the store. |
| 1027 Address inline_end_address; | 1033 Address inline_end_address; |
| 1028 if (InlinedICSiteMarker(address, &inline_end_address) | 1034 if (InlinedICSiteMarker(address, &inline_end_address) |
| 1029 != Assembler::PROPERTY_ACCESS_INLINED) { | 1035 != Assembler::PROPERTY_ACCESS_INLINED) { |
| 1030 return false; | 1036 return false; |
| 1031 } | 1037 } |
| 1032 | 1038 |
| 1033 // Compute the address of the map load instruction. | 1039 // Compute the address of the map load instruction. |
| 1034 Address ldr_map_instr_address = | 1040 Address ldr_map_instr_address = |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1065 | 1071 |
| 1066 // Patch the map check. | 1072 // Patch the map check. |
| 1067 Assembler::set_target_address_at(ldr_map_instr_address, | 1073 Assembler::set_target_address_at(ldr_map_instr_address, |
| 1068 reinterpret_cast<Address>(map)); | 1074 reinterpret_cast<Address>(map)); |
| 1069 | 1075 |
| 1070 return true; | 1076 return true; |
| 1071 } | 1077 } |
| 1072 | 1078 |
| 1073 | 1079 |
| 1074 bool KeyedLoadIC::PatchInlinedLoad(Address address, Object* map) { | 1080 bool KeyedLoadIC::PatchInlinedLoad(Address address, Object* map) { |
| 1081 if (V8::UseCrankshaft()) return false; |
| 1082 |
| 1075 Address inline_end_address; | 1083 Address inline_end_address; |
| 1076 if (InlinedICSiteMarker(address, &inline_end_address) | 1084 if (InlinedICSiteMarker(address, &inline_end_address) |
| 1077 != Assembler::PROPERTY_ACCESS_INLINED) { | 1085 != Assembler::PROPERTY_ACCESS_INLINED) { |
| 1078 return false; | 1086 return false; |
| 1079 } | 1087 } |
| 1080 | 1088 |
| 1081 // Patch the map check. | 1089 // Patch the map check. |
| 1082 Address ldr_map_instr_address = | 1090 Address ldr_map_instr_address = |
| 1083 inline_end_address - | 1091 inline_end_address - |
| 1084 (CodeGenerator::GetInlinedKeyedLoadInstructionsAfterPatch() * | 1092 (CodeGenerator::GetInlinedKeyedLoadInstructionsAfterPatch() * |
| 1085 Assembler::kInstrSize); | 1093 Assembler::kInstrSize); |
| 1086 Assembler::set_target_address_at(ldr_map_instr_address, | 1094 Assembler::set_target_address_at(ldr_map_instr_address, |
| 1087 reinterpret_cast<Address>(map)); | 1095 reinterpret_cast<Address>(map)); |
| 1088 return true; | 1096 return true; |
| 1089 } | 1097 } |
| 1090 | 1098 |
| 1091 | 1099 |
| 1092 bool KeyedStoreIC::PatchInlinedStore(Address address, Object* map) { | 1100 bool KeyedStoreIC::PatchInlinedStore(Address address, Object* map) { |
| 1101 if (V8::UseCrankshaft()) return false; |
| 1102 |
| 1093 // Find the end of the inlined code for handling the store if this is an | 1103 // Find the end of the inlined code for handling the store if this is an |
| 1094 // inlined IC call site. | 1104 // inlined IC call site. |
| 1095 Address inline_end_address; | 1105 Address inline_end_address; |
| 1096 if (InlinedICSiteMarker(address, &inline_end_address) | 1106 if (InlinedICSiteMarker(address, &inline_end_address) |
| 1097 != Assembler::PROPERTY_ACCESS_INLINED) { | 1107 != Assembler::PROPERTY_ACCESS_INLINED) { |
| 1098 return false; | 1108 return false; |
| 1099 } | 1109 } |
| 1100 | 1110 |
| 1101 // Patch the map check. | 1111 // Patch the map check. |
| 1102 Address ldr_map_instr_address = | 1112 Address ldr_map_instr_address = |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1311 scratch1, | 1321 scratch1, |
| 1312 scratch2, | 1322 scratch2, |
| 1313 result, | 1323 result, |
| 1314 &miss, // When not a string. | 1324 &miss, // When not a string. |
| 1315 &miss, // When not a number. | 1325 &miss, // When not a number. |
| 1316 &miss, // When index out of range. | 1326 &miss, // When index out of range. |
| 1317 STRING_INDEX_IS_ARRAY_INDEX); | 1327 STRING_INDEX_IS_ARRAY_INDEX); |
| 1318 char_at_generator.GenerateFast(masm); | 1328 char_at_generator.GenerateFast(masm); |
| 1319 __ Ret(); | 1329 __ Ret(); |
| 1320 | 1330 |
| 1321 ICRuntimeCallHelper call_helper; | 1331 StubRuntimeCallHelper call_helper; |
| 1322 char_at_generator.GenerateSlow(masm, call_helper); | 1332 char_at_generator.GenerateSlow(masm, call_helper); |
| 1323 | 1333 |
| 1324 __ bind(&miss); | 1334 __ bind(&miss); |
| 1325 GenerateMiss(masm); | 1335 GenerateMiss(masm); |
| 1326 } | 1336 } |
| 1327 | 1337 |
| 1328 | 1338 |
| 1329 // Convert unsigned integer with specified number of leading zeroes in binary | 1339 // Convert unsigned integer with specified number of leading zeroes in binary |
| 1330 // representation to IEEE 754 double. | 1340 // representation to IEEE 754 double. |
| 1331 // Integer to convert is passed in register hiword. | 1341 // Integer to convert is passed in register hiword. |
| (...skipping 973 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2305 GenerateDictionaryStore(masm, &miss, r3, r2, r0, r4, r5); | 2315 GenerateDictionaryStore(masm, &miss, r3, r2, r0, r4, r5); |
| 2306 __ IncrementCounter(COUNTERS->store_normal_hit(), 1, r4, r5); | 2316 __ IncrementCounter(COUNTERS->store_normal_hit(), 1, r4, r5); |
| 2307 __ Ret(); | 2317 __ Ret(); |
| 2308 | 2318 |
| 2309 __ bind(&miss); | 2319 __ bind(&miss); |
| 2310 __ IncrementCounter(COUNTERS->store_normal_miss(), 1, r4, r5); | 2320 __ IncrementCounter(COUNTERS->store_normal_miss(), 1, r4, r5); |
| 2311 GenerateMiss(masm); | 2321 GenerateMiss(masm); |
| 2312 } | 2322 } |
| 2313 | 2323 |
| 2314 | 2324 |
| 2325 void StoreIC::GenerateGlobalProxy(MacroAssembler* masm) { |
| 2326 // ----------- S t a t e ------------- |
| 2327 // -- r0 : value |
| 2328 // -- r1 : receiver |
| 2329 // -- r2 : name |
| 2330 // -- lr : return address |
| 2331 // ----------------------------------- |
| 2332 |
| 2333 __ Push(r1, r2, r0); |
| 2334 |
| 2335 // Do tail-call to runtime routine. |
| 2336 __ TailCallRuntime(Runtime::kSetProperty, 3, 1); |
| 2337 } |
| 2338 |
| 2339 |
| 2315 #undef __ | 2340 #undef __ |
| 2316 | 2341 |
| 2317 | 2342 |
| 2343 Condition CompareIC::ComputeCondition(Token::Value op) { |
| 2344 switch (op) { |
| 2345 case Token::EQ_STRICT: |
| 2346 case Token::EQ: |
| 2347 return eq; |
| 2348 case Token::LT: |
| 2349 return lt; |
| 2350 case Token::GT: |
| 2351 // Reverse left and right operands to obtain ECMA-262 conversion order. |
| 2352 return lt; |
| 2353 case Token::LTE: |
| 2354 // Reverse left and right operands to obtain ECMA-262 conversion order. |
| 2355 return ge; |
| 2356 case Token::GTE: |
| 2357 return ge; |
| 2358 default: |
| 2359 UNREACHABLE(); |
| 2360 return no_condition; |
| 2361 } |
| 2362 } |
| 2363 |
| 2364 |
| 2365 void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) { |
| 2366 HandleScope scope; |
| 2367 Handle<Code> rewritten; |
| 2368 #ifdef DEBUG |
| 2369 State previous_state = GetState(); |
| 2370 #endif |
| 2371 State state = TargetState(x, y); |
| 2372 if (state == GENERIC) { |
| 2373 CompareStub stub(GetCondition(), strict(), NO_COMPARE_FLAGS, r1, r0); |
| 2374 rewritten = stub.GetCode(); |
| 2375 } else { |
| 2376 ICCompareStub stub(op_, state); |
| 2377 rewritten = stub.GetCode(); |
| 2378 } |
| 2379 set_target(*rewritten); |
| 2380 |
| 2381 #ifdef DEBUG |
| 2382 if (FLAG_trace_ic) { |
| 2383 PrintF("[CompareIC (%s->%s)#%s]\n", |
| 2384 GetStateName(previous_state), |
| 2385 GetStateName(state), |
| 2386 Token::Name(op_)); |
| 2387 } |
| 2388 #endif |
| 2389 } |
| 2390 |
| 2318 } } // namespace v8::internal | 2391 } } // namespace v8::internal |
| 2319 | 2392 |
| 2320 #endif // V8_TARGET_ARCH_ARM | 2393 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |