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 |