| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_ARM | 7 #if V8_TARGET_ARCH_ARM |
| 8 | 8 |
| 9 #include "src/arm/assembler-arm.h" | 9 #include "src/arm/assembler-arm.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 __ LoadRoot(r3, Heap::kTheHoleValueRootIndex); | 490 __ LoadRoot(r3, Heap::kTheHoleValueRootIndex); |
| 491 __ cmp(r0, r3); | 491 __ cmp(r0, r3); |
| 492 __ b(eq, &slow); | 492 __ b(eq, &slow); |
| 493 __ Ret(); | 493 __ Ret(); |
| 494 __ bind(&slow); | 494 __ bind(&slow); |
| 495 GenerateMiss(masm); | 495 GenerateMiss(masm); |
| 496 } | 496 } |
| 497 | 497 |
| 498 | 498 |
| 499 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { | 499 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { |
| 500 // ---------- S t a t e -------------- | 500 Register receiver = ReceiverRegister(); |
| 501 // -- r0 : value | 501 Register key = NameRegister(); |
| 502 // -- r1 : key | 502 Register value = ValueRegister(); |
| 503 // -- r2 : receiver | 503 ASSERT(receiver.is(r2)); |
| 504 // -- lr : return address | 504 ASSERT(key.is(r1)); |
| 505 // ----------------------------------- | 505 ASSERT(value.is(r0)); |
| 506 |
| 506 Label slow, notin; | 507 Label slow, notin; |
| 507 MemOperand mapped_location = | 508 MemOperand mapped_location = GenerateMappedArgumentsLookup( |
| 508 GenerateMappedArgumentsLookup(masm, r2, r1, r3, r4, r5, ¬in, &slow); | 509 masm, receiver, key, r3, r4, r5, ¬in, &slow); |
| 509 __ str(r0, mapped_location); | 510 __ str(value, mapped_location); |
| 510 __ add(r6, r3, r5); | 511 __ add(r6, r3, r5); |
| 511 __ mov(r9, r0); | 512 __ mov(r9, value); |
| 512 __ RecordWrite(r3, r6, r9, kLRHasNotBeenSaved, kDontSaveFPRegs); | 513 __ RecordWrite(r3, r6, r9, kLRHasNotBeenSaved, kDontSaveFPRegs); |
| 513 __ Ret(); | 514 __ Ret(); |
| 514 __ bind(¬in); | 515 __ bind(¬in); |
| 515 // The unmapped lookup expects that the parameter map is in r3. | 516 // The unmapped lookup expects that the parameter map is in r3. |
| 516 MemOperand unmapped_location = | 517 MemOperand unmapped_location = |
| 517 GenerateUnmappedArgumentsLookup(masm, r1, r3, r4, &slow); | 518 GenerateUnmappedArgumentsLookup(masm, key, r3, r4, &slow); |
| 518 __ str(r0, unmapped_location); | 519 __ str(value, unmapped_location); |
| 519 __ add(r6, r3, r4); | 520 __ add(r6, r3, r4); |
| 520 __ mov(r9, r0); | 521 __ mov(r9, value); |
| 521 __ RecordWrite(r3, r6, r9, kLRHasNotBeenSaved, kDontSaveFPRegs); | 522 __ RecordWrite(r3, r6, r9, kLRHasNotBeenSaved, kDontSaveFPRegs); |
| 522 __ Ret(); | 523 __ Ret(); |
| 523 __ bind(&slow); | 524 __ bind(&slow); |
| 524 GenerateMiss(masm); | 525 GenerateMiss(masm); |
| 525 } | 526 } |
| 526 | 527 |
| 527 | 528 |
| 528 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { | 529 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { |
| 529 // The return address is in lr. | 530 // The return address is in lr. |
| 530 Isolate* isolate = masm->isolate(); | 531 Isolate* isolate = masm->isolate(); |
| 531 | 532 |
| 532 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r3, r4); | 533 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r3, r4); |
| 533 | 534 |
| 534 __ Push(ReceiverRegister(), NameRegister()); | 535 __ Push(ReceiverRegister(), NameRegister()); |
| 535 | 536 |
| 536 // Perform tail call to the entry. | 537 // Perform tail call to the entry. |
| 537 ExternalReference ref = | 538 ExternalReference ref = |
| 538 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate); | 539 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate); |
| 539 | 540 |
| 540 __ TailCallExternalReference(ref, 2, 1); | 541 __ TailCallExternalReference(ref, 2, 1); |
| 541 } | 542 } |
| 542 | 543 |
| 543 | 544 |
| 544 // IC register specifications | 545 // IC register specifications |
| 545 const Register LoadIC::ReceiverRegister() { return r1; } | 546 const Register LoadIC::ReceiverRegister() { return r1; } |
| 546 const Register LoadIC::NameRegister() { return r2; } | 547 const Register LoadIC::NameRegister() { return r2; } |
| 547 | 548 |
| 548 | 549 |
| 550 const Register StoreIC::ReceiverRegister() { return r1; } |
| 551 const Register StoreIC::NameRegister() { return r2; } |
| 552 const Register StoreIC::ValueRegister() { return r0; } |
| 553 |
| 554 |
| 555 const Register KeyedStoreIC::ReceiverRegister() { return r2; } |
| 556 const Register KeyedStoreIC::NameRegister() { return r1; } |
| 557 const Register KeyedStoreIC::ValueRegister() { return r0; } |
| 558 |
| 559 |
| 549 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 560 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |
| 550 // The return address is in lr. | 561 // The return address is in lr. |
| 551 | 562 |
| 552 __ Push(ReceiverRegister(), NameRegister()); | 563 __ Push(ReceiverRegister(), NameRegister()); |
| 553 | 564 |
| 554 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); | 565 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); |
| 555 } | 566 } |
| 556 | 567 |
| 557 | 568 |
| 558 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { | 569 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 785 masm->isolate()), | 796 masm->isolate()), |
| 786 2, | 797 2, |
| 787 1); | 798 1); |
| 788 | 799 |
| 789 __ bind(&slow); | 800 __ bind(&slow); |
| 790 GenerateMiss(masm); | 801 GenerateMiss(masm); |
| 791 } | 802 } |
| 792 | 803 |
| 793 | 804 |
| 794 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { | 805 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { |
| 795 // ---------- S t a t e -------------- | |
| 796 // -- r0 : value | |
| 797 // -- r1 : key | |
| 798 // -- r2 : receiver | |
| 799 // -- lr : return address | |
| 800 // ----------------------------------- | |
| 801 | |
| 802 // Push receiver, key and value for runtime call. | 806 // Push receiver, key and value for runtime call. |
| 803 __ Push(r2, r1, r0); | 807 __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); |
| 804 | 808 |
| 805 ExternalReference ref = | 809 ExternalReference ref = |
| 806 ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate()); | 810 ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate()); |
| 807 __ TailCallExternalReference(ref, 3, 1); | 811 __ TailCallExternalReference(ref, 3, 1); |
| 808 } | 812 } |
| 809 | 813 |
| 810 | 814 |
| 811 void StoreIC::GenerateSlow(MacroAssembler* masm) { | 815 void StoreIC::GenerateSlow(MacroAssembler* masm) { |
| 812 // ---------- S t a t e -------------- | |
| 813 // -- r0 : value | |
| 814 // -- r2 : key | |
| 815 // -- r1 : receiver | |
| 816 // -- lr : return address | |
| 817 // ----------------------------------- | |
| 818 | |
| 819 // Push receiver, key and value for runtime call. | 816 // Push receiver, key and value for runtime call. |
| 820 __ Push(r1, r2, r0); | 817 __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); |
| 821 | 818 |
| 822 // The slow case calls into the runtime to complete the store without causing | 819 // The slow case calls into the runtime to complete the store without causing |
| 823 // an IC miss that would otherwise cause a transition to the generic stub. | 820 // an IC miss that would otherwise cause a transition to the generic stub. |
| 824 ExternalReference ref = | 821 ExternalReference ref = |
| 825 ExternalReference(IC_Utility(kStoreIC_Slow), masm->isolate()); | 822 ExternalReference(IC_Utility(kStoreIC_Slow), masm->isolate()); |
| 826 __ TailCallExternalReference(ref, 3, 1); | 823 __ TailCallExternalReference(ref, 3, 1); |
| 827 } | 824 } |
| 828 | 825 |
| 829 | 826 |
| 830 void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) { | 827 void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) { |
| 831 // ---------- S t a t e -------------- | |
| 832 // -- r0 : value | |
| 833 // -- r1 : key | |
| 834 // -- r2 : receiver | |
| 835 // -- lr : return address | |
| 836 // ----------------------------------- | |
| 837 | |
| 838 // Push receiver, key and value for runtime call. | 828 // Push receiver, key and value for runtime call. |
| 839 __ Push(r2, r1, r0); | 829 __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); |
| 840 | 830 |
| 841 // The slow case calls into the runtime to complete the store without causing | 831 // The slow case calls into the runtime to complete the store without causing |
| 842 // an IC miss that would otherwise cause a transition to the generic stub. | 832 // an IC miss that would otherwise cause a transition to the generic stub. |
| 843 ExternalReference ref = | 833 ExternalReference ref = |
| 844 ExternalReference(IC_Utility(kKeyedStoreIC_Slow), masm->isolate()); | 834 ExternalReference(IC_Utility(kKeyedStoreIC_Slow), masm->isolate()); |
| 845 __ TailCallExternalReference(ref, 3, 1); | 835 __ TailCallExternalReference(ref, 3, 1); |
| 846 } | 836 } |
| 847 | 837 |
| 848 | 838 |
| 849 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, | 839 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, |
| 850 StrictMode strict_mode) { | 840 StrictMode strict_mode) { |
| 851 // ---------- S t a t e -------------- | |
| 852 // -- r0 : value | |
| 853 // -- r1 : key | |
| 854 // -- r2 : receiver | |
| 855 // -- lr : return address | |
| 856 // ----------------------------------- | |
| 857 | |
| 858 // Push receiver, key and value for runtime call. | 841 // Push receiver, key and value for runtime call. |
| 859 __ Push(r2, r1, r0); | 842 __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); |
| 860 | 843 |
| 861 __ mov(r0, Operand(Smi::FromInt(strict_mode))); // Strict mode. | 844 __ mov(r0, Operand(Smi::FromInt(strict_mode))); // Strict mode. |
| 862 __ Push(r0); | 845 __ Push(r0); |
| 863 | 846 |
| 864 __ TailCallRuntime(Runtime::kSetProperty, 4, 1); | 847 __ TailCallRuntime(Runtime::kSetProperty, 4, 1); |
| 865 } | 848 } |
| 866 | 849 |
| 867 | 850 |
| 868 static void KeyedStoreGenerateGenericHelper( | 851 static void KeyedStoreGenerateGenericHelper( |
| 869 MacroAssembler* masm, | 852 MacroAssembler* masm, |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1035 // -- r0 : value | 1018 // -- r0 : value |
| 1036 // -- r1 : key | 1019 // -- r1 : key |
| 1037 // -- r2 : receiver | 1020 // -- r2 : receiver |
| 1038 // -- lr : return address | 1021 // -- lr : return address |
| 1039 // ----------------------------------- | 1022 // ----------------------------------- |
| 1040 Label slow, fast_object, fast_object_grow; | 1023 Label slow, fast_object, fast_object_grow; |
| 1041 Label fast_double, fast_double_grow; | 1024 Label fast_double, fast_double_grow; |
| 1042 Label array, extra, check_if_double_array; | 1025 Label array, extra, check_if_double_array; |
| 1043 | 1026 |
| 1044 // Register usage. | 1027 // Register usage. |
| 1045 Register value = r0; | 1028 Register value = ValueRegister(); |
| 1046 Register key = r1; | 1029 Register key = NameRegister(); |
| 1047 Register receiver = r2; | 1030 Register receiver = ReceiverRegister(); |
| 1031 ASSERT(receiver.is(r2)); |
| 1032 ASSERT(key.is(r1)); |
| 1033 ASSERT(value.is(r0)); |
| 1048 Register receiver_map = r3; | 1034 Register receiver_map = r3; |
| 1049 Register elements_map = r6; | 1035 Register elements_map = r6; |
| 1050 Register elements = r9; // Elements array of the receiver. | 1036 Register elements = r9; // Elements array of the receiver. |
| 1051 // r4 and r5 are used as general scratch registers. | 1037 // r4 and r5 are used as general scratch registers. |
| 1052 | 1038 |
| 1053 // Check that the key is a smi. | 1039 // Check that the key is a smi. |
| 1054 __ JumpIfNotSmi(key, &slow); | 1040 __ JumpIfNotSmi(key, &slow); |
| 1055 // Check that the object isn't a smi. | 1041 // Check that the object isn't a smi. |
| 1056 __ JumpIfSmi(receiver, &slow); | 1042 __ JumpIfSmi(receiver, &slow); |
| 1057 // Get the map of the object. | 1043 // Get the map of the object. |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1123 value, key, receiver, receiver_map, | 1109 value, key, receiver, receiver_map, |
| 1124 elements_map, elements); | 1110 elements_map, elements); |
| 1125 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, | 1111 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, |
| 1126 &slow, kDontCheckMap, kIncrementLength, | 1112 &slow, kDontCheckMap, kIncrementLength, |
| 1127 value, key, receiver, receiver_map, | 1113 value, key, receiver, receiver_map, |
| 1128 elements_map, elements); | 1114 elements_map, elements); |
| 1129 } | 1115 } |
| 1130 | 1116 |
| 1131 | 1117 |
| 1132 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { | 1118 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { |
| 1133 // ----------- S t a t e ------------- | 1119 Register receiver = ReceiverRegister(); |
| 1134 // -- r0 : value | 1120 Register name = NameRegister(); |
| 1135 // -- r1 : receiver | 1121 ASSERT(receiver.is(r1)); |
| 1136 // -- r2 : name | 1122 ASSERT(name.is(r2)); |
| 1137 // -- lr : return address | 1123 ASSERT(ValueRegister().is(r0)); |
| 1138 // ----------------------------------- | |
| 1139 | 1124 |
| 1140 // Get the receiver from the stack and probe the stub cache. | 1125 // Get the receiver from the stack and probe the stub cache. |
| 1141 Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC); | 1126 Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC); |
| 1142 | 1127 |
| 1143 masm->isolate()->stub_cache()->GenerateProbe( | 1128 masm->isolate()->stub_cache()->GenerateProbe( |
| 1144 masm, flags, r1, r2, r3, r4, r5, r6); | 1129 masm, flags, receiver, name, r3, r4, r5, r6); |
| 1145 | 1130 |
| 1146 // Cache miss: Jump to runtime. | 1131 // Cache miss: Jump to runtime. |
| 1147 GenerateMiss(masm); | 1132 GenerateMiss(masm); |
| 1148 } | 1133 } |
| 1149 | 1134 |
| 1150 | 1135 |
| 1151 void StoreIC::GenerateMiss(MacroAssembler* masm) { | 1136 void StoreIC::GenerateMiss(MacroAssembler* masm) { |
| 1152 // ----------- S t a t e ------------- | 1137 __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); |
| 1153 // -- r0 : value | |
| 1154 // -- r1 : receiver | |
| 1155 // -- r2 : name | |
| 1156 // -- lr : return address | |
| 1157 // ----------------------------------- | |
| 1158 | |
| 1159 __ Push(r1, r2, r0); | |
| 1160 | 1138 |
| 1161 // Perform tail call to the entry. | 1139 // Perform tail call to the entry. |
| 1162 ExternalReference ref = | 1140 ExternalReference ref = |
| 1163 ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate()); | 1141 ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate()); |
| 1164 __ TailCallExternalReference(ref, 3, 1); | 1142 __ TailCallExternalReference(ref, 3, 1); |
| 1165 } | 1143 } |
| 1166 | 1144 |
| 1167 | 1145 |
| 1168 void StoreIC::GenerateNormal(MacroAssembler* masm) { | 1146 void StoreIC::GenerateNormal(MacroAssembler* masm) { |
| 1169 // ----------- S t a t e ------------- | |
| 1170 // -- r0 : value | |
| 1171 // -- r1 : receiver | |
| 1172 // -- r2 : name | |
| 1173 // -- lr : return address | |
| 1174 // ----------------------------------- | |
| 1175 Label miss; | 1147 Label miss; |
| 1148 Register receiver = ReceiverRegister(); |
| 1149 Register name = NameRegister(); |
| 1150 Register value = ValueRegister(); |
| 1151 ASSERT(receiver.is(r1)); |
| 1152 ASSERT(name.is(r2)); |
| 1153 ASSERT(value.is(r0)); |
| 1176 | 1154 |
| 1177 GenerateNameDictionaryReceiverCheck(masm, r1, r3, r4, r5, &miss); | 1155 GenerateNameDictionaryReceiverCheck(masm, receiver, r3, r4, r5, &miss); |
| 1178 | 1156 |
| 1179 GenerateDictionaryStore(masm, &miss, r3, r2, r0, r4, r5); | 1157 GenerateDictionaryStore(masm, &miss, r3, name, value, r4, r5); |
| 1180 Counters* counters = masm->isolate()->counters(); | 1158 Counters* counters = masm->isolate()->counters(); |
| 1181 __ IncrementCounter(counters->store_normal_hit(), | 1159 __ IncrementCounter(counters->store_normal_hit(), |
| 1182 1, r4, r5); | 1160 1, r4, r5); |
| 1183 __ Ret(); | 1161 __ Ret(); |
| 1184 | 1162 |
| 1185 __ bind(&miss); | 1163 __ bind(&miss); |
| 1186 __ IncrementCounter(counters->store_normal_miss(), 1, r4, r5); | 1164 __ IncrementCounter(counters->store_normal_miss(), 1, r4, r5); |
| 1187 GenerateMiss(masm); | 1165 GenerateMiss(masm); |
| 1188 } | 1166 } |
| 1189 | 1167 |
| 1190 | 1168 |
| 1191 void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, | 1169 void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, |
| 1192 StrictMode strict_mode) { | 1170 StrictMode strict_mode) { |
| 1193 // ----------- S t a t e ------------- | 1171 __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); |
| 1194 // -- r0 : value | |
| 1195 // -- r1 : receiver | |
| 1196 // -- r2 : name | |
| 1197 // -- lr : return address | |
| 1198 // ----------------------------------- | |
| 1199 | |
| 1200 __ Push(r1, r2, r0); | |
| 1201 | 1172 |
| 1202 __ mov(r0, Operand(Smi::FromInt(strict_mode))); | 1173 __ mov(r0, Operand(Smi::FromInt(strict_mode))); |
| 1203 __ Push(r0); | 1174 __ Push(r0); |
| 1204 | 1175 |
| 1205 // Do tail-call to runtime routine. | 1176 // Do tail-call to runtime routine. |
| 1206 __ TailCallRuntime(Runtime::kSetProperty, 4, 1); | 1177 __ TailCallRuntime(Runtime::kSetProperty, 4, 1); |
| 1207 } | 1178 } |
| 1208 | 1179 |
| 1209 | 1180 |
| 1210 #undef __ | 1181 #undef __ |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1300 } else { | 1271 } else { |
| 1301 ASSERT(Assembler::GetCondition(branch_instr) == ne); | 1272 ASSERT(Assembler::GetCondition(branch_instr) == ne); |
| 1302 patcher.EmitCondition(eq); | 1273 patcher.EmitCondition(eq); |
| 1303 } | 1274 } |
| 1304 } | 1275 } |
| 1305 | 1276 |
| 1306 | 1277 |
| 1307 } } // namespace v8::internal | 1278 } } // namespace v8::internal |
| 1308 | 1279 |
| 1309 #endif // V8_TARGET_ARCH_ARM | 1280 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |