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 | 5 |
6 | 6 |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #if V8_TARGET_ARCH_MIPS64 | 9 #if V8_TARGET_ARCH_MIPS64 |
10 | 10 |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
500 __ LoadRoot(a3, Heap::kTheHoleValueRootIndex); | 500 __ LoadRoot(a3, Heap::kTheHoleValueRootIndex); |
501 __ Branch(&slow, eq, a0, Operand(a3)); | 501 __ Branch(&slow, eq, a0, Operand(a3)); |
502 __ Ret(USE_DELAY_SLOT); | 502 __ Ret(USE_DELAY_SLOT); |
503 __ mov(v0, a0); | 503 __ mov(v0, a0); |
504 __ bind(&slow); | 504 __ bind(&slow); |
505 GenerateMiss(masm); | 505 GenerateMiss(masm); |
506 } | 506 } |
507 | 507 |
508 | 508 |
509 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { | 509 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { |
510 // ---------- S t a t e -------------- | 510 Register receiver = ReceiverRegister(); |
511 // -- a0 : value | 511 Register key = NameRegister(); |
512 // -- a1 : key | 512 Register value = ValueRegister(); |
513 // -- a2 : receiver | 513 ASSERT(receiver.is(a2)); |
514 // -- lr : return address | 514 ASSERT(key.is(a1)); |
515 // ----------------------------------- | 515 ASSERT(value.is(a0)); |
| 516 |
516 Label slow, notin; | 517 Label slow, notin; |
517 // Store address is returned in register (of MemOperand) mapped_location. | 518 // Store address is returned in register (of MemOperand) mapped_location. |
518 MemOperand mapped_location = | 519 MemOperand mapped_location = GenerateMappedArgumentsLookup( |
519 GenerateMappedArgumentsLookup(masm, a2, a1, a3, a4, a5, ¬in, &slow); | 520 masm, receiver, key, a3, a4, a5, ¬in, &slow); |
520 __ sd(a0, mapped_location); | 521 __ sd(value, mapped_location); |
521 __ mov(t1, a0); | 522 __ mov(t1, value); |
522 ASSERT_EQ(mapped_location.offset(), 0); | 523 ASSERT_EQ(mapped_location.offset(), 0); |
523 __ RecordWrite(a3, mapped_location.rm(), t1, | 524 __ RecordWrite(a3, mapped_location.rm(), t1, |
524 kRAHasNotBeenSaved, kDontSaveFPRegs); | 525 kRAHasNotBeenSaved, kDontSaveFPRegs); |
525 __ Ret(USE_DELAY_SLOT); | 526 __ Ret(USE_DELAY_SLOT); |
526 __ mov(v0, a0); // (In delay slot) return the value stored in v0. | 527 __ mov(v0, value); // (In delay slot) return the value stored in v0. |
527 __ bind(¬in); | 528 __ bind(¬in); |
528 // The unmapped lookup expects that the parameter map is in a3. | 529 // The unmapped lookup expects that the parameter map is in a3. |
529 // Store address is returned in register (of MemOperand) unmapped_location. | 530 // Store address is returned in register (of MemOperand) unmapped_location. |
530 MemOperand unmapped_location = | 531 MemOperand unmapped_location = |
531 GenerateUnmappedArgumentsLookup(masm, a1, a3, a4, &slow); | 532 GenerateUnmappedArgumentsLookup(masm, key, a3, a4, &slow); |
532 __ sd(a0, unmapped_location); | 533 __ sd(value, unmapped_location); |
533 __ mov(t1, a0); | 534 __ mov(t1, value); |
534 ASSERT_EQ(unmapped_location.offset(), 0); | 535 ASSERT_EQ(unmapped_location.offset(), 0); |
535 __ RecordWrite(a3, unmapped_location.rm(), t1, | 536 __ RecordWrite(a3, unmapped_location.rm(), t1, |
536 kRAHasNotBeenSaved, kDontSaveFPRegs); | 537 kRAHasNotBeenSaved, kDontSaveFPRegs); |
537 __ Ret(USE_DELAY_SLOT); | 538 __ Ret(USE_DELAY_SLOT); |
538 __ mov(v0, a0); // (In delay slot) return the value stored in v0. | 539 __ mov(v0, a0); // (In delay slot) return the value stored in v0. |
539 __ bind(&slow); | 540 __ bind(&slow); |
540 GenerateMiss(masm); | 541 GenerateMiss(masm); |
541 } | 542 } |
542 | 543 |
543 | 544 |
(...skipping 11 matching lines...) Expand all Loading... |
555 | 556 |
556 __ TailCallExternalReference(ref, 2, 1); | 557 __ TailCallExternalReference(ref, 2, 1); |
557 } | 558 } |
558 | 559 |
559 | 560 |
560 // IC register specifications | 561 // IC register specifications |
561 const Register LoadIC::ReceiverRegister() { return a1; } | 562 const Register LoadIC::ReceiverRegister() { return a1; } |
562 const Register LoadIC::NameRegister() { return a2; } | 563 const Register LoadIC::NameRegister() { return a2; } |
563 | 564 |
564 | 565 |
| 566 const Register StoreIC::ReceiverRegister() { return a1; } |
| 567 const Register StoreIC::NameRegister() { return a2; } |
| 568 const Register StoreIC::ValueRegister() { return a0; } |
| 569 |
| 570 |
| 571 const Register KeyedStoreIC::ReceiverRegister() { return a2; } |
| 572 const Register KeyedStoreIC::NameRegister() { return a1; } |
| 573 const Register KeyedStoreIC::ValueRegister() { return a0; } |
| 574 |
| 575 |
565 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 576 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |
566 // The return address is in ra. | 577 // The return address is in ra. |
567 | 578 |
568 __ Push(ReceiverRegister(), NameRegister()); | 579 __ Push(ReceiverRegister(), NameRegister()); |
569 | 580 |
570 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); | 581 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); |
571 } | 582 } |
572 | 583 |
573 | 584 |
574 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { | 585 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
772 StubRuntimeCallHelper call_helper; | 783 StubRuntimeCallHelper call_helper; |
773 char_at_generator.GenerateSlow(masm, call_helper); | 784 char_at_generator.GenerateSlow(masm, call_helper); |
774 | 785 |
775 __ bind(&miss); | 786 __ bind(&miss); |
776 GenerateMiss(masm); | 787 GenerateMiss(masm); |
777 } | 788 } |
778 | 789 |
779 | 790 |
780 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, | 791 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, |
781 StrictMode strict_mode) { | 792 StrictMode strict_mode) { |
782 // ---------- S t a t e -------------- | 793 // Push receiver, key and value for runtime call. |
783 // -- a0 : value | 794 __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); |
784 // -- a1 : key | |
785 // -- a2 : receiver | |
786 // -- ra : return address | |
787 // ----------------------------------- | |
788 | 795 |
789 // Push receiver, key and value for runtime call. | |
790 __ Push(a2, a1, a0); | |
791 __ li(a0, Operand(Smi::FromInt(strict_mode))); // Strict mode. | 796 __ li(a0, Operand(Smi::FromInt(strict_mode))); // Strict mode. |
792 __ Push(a0); | 797 __ Push(a0); |
793 | 798 |
794 __ TailCallRuntime(Runtime::kSetProperty, 4, 1); | 799 __ TailCallRuntime(Runtime::kSetProperty, 4, 1); |
795 } | 800 } |
796 | 801 |
797 | 802 |
798 static void KeyedStoreGenerateGenericHelper( | 803 static void KeyedStoreGenerateGenericHelper( |
799 MacroAssembler* masm, | 804 MacroAssembler* masm, |
800 Label* fast_object, | 805 Label* fast_object, |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
977 // -- a0 : value | 982 // -- a0 : value |
978 // -- a1 : key | 983 // -- a1 : key |
979 // -- a2 : receiver | 984 // -- a2 : receiver |
980 // -- ra : return address | 985 // -- ra : return address |
981 // ----------------------------------- | 986 // ----------------------------------- |
982 Label slow, fast_object, fast_object_grow; | 987 Label slow, fast_object, fast_object_grow; |
983 Label fast_double, fast_double_grow; | 988 Label fast_double, fast_double_grow; |
984 Label array, extra, check_if_double_array; | 989 Label array, extra, check_if_double_array; |
985 | 990 |
986 // Register usage. | 991 // Register usage. |
987 Register value = a0; | 992 Register value = ValueRegister(); |
988 Register key = a1; | 993 Register key = NameRegister(); |
989 Register receiver = a2; | 994 Register receiver = ReceiverRegister(); |
| 995 ASSERT(receiver.is(a2)); |
| 996 ASSERT(key.is(a1)); |
| 997 ASSERT(value.is(a0)); |
990 Register receiver_map = a3; | 998 Register receiver_map = a3; |
991 Register elements_map = a6; | 999 Register elements_map = a6; |
992 Register elements = a7; // Elements array of the receiver. | 1000 Register elements = a7; // Elements array of the receiver. |
993 // a4 and a5 are used as general scratch registers. | 1001 // a4 and a5 are used as general scratch registers. |
994 | 1002 |
995 // Check that the key is a smi. | 1003 // Check that the key is a smi. |
996 __ JumpIfNotSmi(key, &slow); | 1004 __ JumpIfNotSmi(key, &slow); |
997 // Check that the object isn't a smi. | 1005 // Check that the object isn't a smi. |
998 __ JumpIfSmi(receiver, &slow); | 1006 __ JumpIfSmi(receiver, &slow); |
999 // Get the map of the object. | 1007 // Get the map of the object. |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1098 // Perform tail call to the entry. | 1106 // Perform tail call to the entry. |
1099 __ TailCallExternalReference(ExternalReference( | 1107 __ TailCallExternalReference(ExternalReference( |
1100 IC_Utility(kKeyedLoadPropertyWithInterceptor), masm->isolate()), 2, 1); | 1108 IC_Utility(kKeyedLoadPropertyWithInterceptor), masm->isolate()), 2, 1); |
1101 | 1109 |
1102 __ bind(&slow); | 1110 __ bind(&slow); |
1103 GenerateMiss(masm); | 1111 GenerateMiss(masm); |
1104 } | 1112 } |
1105 | 1113 |
1106 | 1114 |
1107 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { | 1115 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { |
1108 // ---------- S t a t e -------------- | |
1109 // -- a0 : value | |
1110 // -- a1 : key | |
1111 // -- a2 : receiver | |
1112 // -- ra : return address | |
1113 // ----------------------------------- | |
1114 | |
1115 // Push receiver, key and value for runtime call. | 1116 // Push receiver, key and value for runtime call. |
1116 __ Push(a2, a1, a0); | 1117 __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); |
1117 | 1118 |
1118 ExternalReference ref = | 1119 ExternalReference ref = |
1119 ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate()); | 1120 ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate()); |
1120 __ TailCallExternalReference(ref, 3, 1); | 1121 __ TailCallExternalReference(ref, 3, 1); |
1121 } | 1122 } |
1122 | 1123 |
1123 | 1124 |
1124 void StoreIC::GenerateSlow(MacroAssembler* masm) { | 1125 void StoreIC::GenerateSlow(MacroAssembler* masm) { |
1125 // ---------- S t a t e -------------- | |
1126 // -- a0 : value | |
1127 // -- a2 : key | |
1128 // -- a1 : receiver | |
1129 // -- ra : return address | |
1130 // ----------------------------------- | |
1131 | |
1132 // Push receiver, key and value for runtime call. | 1126 // Push receiver, key and value for runtime call. |
1133 __ Push(a1, a2, a0); | 1127 __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); |
1134 | 1128 |
1135 // The slow case calls into the runtime to complete the store without causing | 1129 // The slow case calls into the runtime to complete the store without causing |
1136 // an IC miss that would otherwise cause a transition to the generic stub. | 1130 // an IC miss that would otherwise cause a transition to the generic stub. |
1137 ExternalReference ref = | 1131 ExternalReference ref = |
1138 ExternalReference(IC_Utility(kStoreIC_Slow), masm->isolate()); | 1132 ExternalReference(IC_Utility(kStoreIC_Slow), masm->isolate()); |
1139 __ TailCallExternalReference(ref, 3, 1); | 1133 __ TailCallExternalReference(ref, 3, 1); |
1140 } | 1134 } |
1141 | 1135 |
1142 | 1136 |
1143 void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) { | 1137 void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) { |
1144 // ---------- S t a t e -------------- | |
1145 // -- a0 : value | |
1146 // -- a1 : key | |
1147 // -- a2 : receiver | |
1148 // -- ra : return address | |
1149 // ----------------------------------- | |
1150 | |
1151 // Push receiver, key and value for runtime call. | 1138 // Push receiver, key and value for runtime call. |
1152 // We can't use MultiPush as the order of the registers is important. | 1139 // We can't use MultiPush as the order of the registers is important. |
1153 __ Push(a2, a1, a0); | 1140 __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); |
1154 // The slow case calls into the runtime to complete the store without causing | 1141 // The slow case calls into the runtime to complete the store without causing |
1155 // an IC miss that would otherwise cause a transition to the generic stub. | 1142 // an IC miss that would otherwise cause a transition to the generic stub. |
1156 ExternalReference ref = | 1143 ExternalReference ref = |
1157 ExternalReference(IC_Utility(kKeyedStoreIC_Slow), masm->isolate()); | 1144 ExternalReference(IC_Utility(kKeyedStoreIC_Slow), masm->isolate()); |
1158 | 1145 |
1159 __ TailCallExternalReference(ref, 3, 1); | 1146 __ TailCallExternalReference(ref, 3, 1); |
1160 } | 1147 } |
1161 | 1148 |
1162 | 1149 |
1163 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { | 1150 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { |
1164 // ----------- S t a t e ------------- | 1151 Register receiver = ReceiverRegister(); |
1165 // -- a0 : value | 1152 Register name = NameRegister(); |
1166 // -- a1 : receiver | 1153 ASSERT(receiver.is(a1)); |
1167 // -- a2 : name | 1154 ASSERT(name.is(a2)); |
1168 // -- ra : return address | 1155 ASSERT(ValueRegister().is(a0)); |
1169 // ----------------------------------- | |
1170 | 1156 |
1171 // Get the receiver from the stack and probe the stub cache. | 1157 // Get the receiver from the stack and probe the stub cache. |
1172 Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC); | 1158 Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC); |
1173 masm->isolate()->stub_cache()->GenerateProbe( | 1159 masm->isolate()->stub_cache()->GenerateProbe( |
1174 masm, flags, a1, a2, a3, a4, a5, a6); | 1160 masm, flags, receiver, name, a3, a4, a5, a6); |
1175 | 1161 |
1176 // Cache miss: Jump to runtime. | 1162 // Cache miss: Jump to runtime. |
1177 GenerateMiss(masm); | 1163 GenerateMiss(masm); |
1178 } | 1164 } |
1179 | 1165 |
1180 | 1166 |
1181 void StoreIC::GenerateMiss(MacroAssembler* masm) { | 1167 void StoreIC::GenerateMiss(MacroAssembler* masm) { |
1182 // ----------- S t a t e ------------- | 1168 __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); |
1183 // -- a0 : value | |
1184 // -- a1 : receiver | |
1185 // -- a2 : name | |
1186 // -- ra : return address | |
1187 // ----------------------------------- | |
1188 | |
1189 __ Push(a1, a2, a0); | |
1190 // Perform tail call to the entry. | 1169 // Perform tail call to the entry. |
1191 ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss), | 1170 ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss), |
1192 masm->isolate()); | 1171 masm->isolate()); |
1193 __ TailCallExternalReference(ref, 3, 1); | 1172 __ TailCallExternalReference(ref, 3, 1); |
1194 } | 1173 } |
1195 | 1174 |
1196 | 1175 |
1197 void StoreIC::GenerateNormal(MacroAssembler* masm) { | 1176 void StoreIC::GenerateNormal(MacroAssembler* masm) { |
1198 // ----------- S t a t e ------------- | |
1199 // -- a0 : value | |
1200 // -- a1 : receiver | |
1201 // -- a2 : name | |
1202 // -- ra : return address | |
1203 // ----------------------------------- | |
1204 Label miss; | 1177 Label miss; |
| 1178 Register receiver = ReceiverRegister(); |
| 1179 Register name = NameRegister(); |
| 1180 Register value = ValueRegister(); |
| 1181 ASSERT(receiver.is(a1)); |
| 1182 ASSERT(name.is(a2)); |
| 1183 ASSERT(value.is(a0)); |
1205 | 1184 |
1206 GenerateNameDictionaryReceiverCheck(masm, a1, a3, a4, a5, &miss); | 1185 GenerateNameDictionaryReceiverCheck(masm, receiver, a3, a4, a5, &miss); |
1207 | 1186 |
1208 GenerateDictionaryStore(masm, &miss, a3, a2, a0, a4, a5); | 1187 GenerateDictionaryStore(masm, &miss, a3, name, value, a4, a5); |
1209 Counters* counters = masm->isolate()->counters(); | 1188 Counters* counters = masm->isolate()->counters(); |
1210 __ IncrementCounter(counters->store_normal_hit(), 1, a4, a5); | 1189 __ IncrementCounter(counters->store_normal_hit(), 1, a4, a5); |
1211 __ Ret(); | 1190 __ Ret(); |
1212 | 1191 |
1213 __ bind(&miss); | 1192 __ bind(&miss); |
1214 __ IncrementCounter(counters->store_normal_miss(), 1, a4, a5); | 1193 __ IncrementCounter(counters->store_normal_miss(), 1, a4, a5); |
1215 GenerateMiss(masm); | 1194 GenerateMiss(masm); |
1216 } | 1195 } |
1217 | 1196 |
1218 | 1197 |
1219 void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, | 1198 void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, |
1220 StrictMode strict_mode) { | 1199 StrictMode strict_mode) { |
1221 // ----------- S t a t e ------------- | 1200 __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); |
1222 // -- a0 : value | |
1223 // -- a1 : receiver | |
1224 // -- a2 : name | |
1225 // -- ra : return address | |
1226 // ----------------------------------- | |
1227 | |
1228 __ Push(a1, a2, a0); | |
1229 | 1201 |
1230 __ li(a0, Operand(Smi::FromInt(strict_mode))); | 1202 __ li(a0, Operand(Smi::FromInt(strict_mode))); |
1231 __ Push(a0); | 1203 __ Push(a0); |
1232 | 1204 |
1233 // Do tail-call to runtime routine. | 1205 // Do tail-call to runtime routine. |
1234 __ TailCallRuntime(Runtime::kSetProperty, 4, 1); | 1206 __ TailCallRuntime(Runtime::kSetProperty, 4, 1); |
1235 } | 1207 } |
1236 | 1208 |
1237 | 1209 |
1238 #undef __ | 1210 #undef __ |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1328 } else { | 1300 } else { |
1329 ASSERT(Assembler::IsBne(branch_instr)); | 1301 ASSERT(Assembler::IsBne(branch_instr)); |
1330 patcher.ChangeBranchCondition(eq); | 1302 patcher.ChangeBranchCondition(eq); |
1331 } | 1303 } |
1332 } | 1304 } |
1333 | 1305 |
1334 | 1306 |
1335 } } // namespace v8::internal | 1307 } } // namespace v8::internal |
1336 | 1308 |
1337 #endif // V8_TARGET_ARCH_MIPS64 | 1309 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |