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_MIPS | 9 #if V8_TARGET_ARCH_MIPS |
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, t0, t1, ¬in, &slow); | 520 masm, receiver, key, a3, t0, t1, ¬in, &slow); |
520 __ sw(a0, mapped_location); | 521 __ sw(value, mapped_location); |
521 __ mov(t5, a0); | 522 __ mov(t5, value); |
522 ASSERT_EQ(mapped_location.offset(), 0); | 523 ASSERT_EQ(mapped_location.offset(), 0); |
523 __ RecordWrite(a3, mapped_location.rm(), t5, | 524 __ RecordWrite(a3, mapped_location.rm(), t5, |
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, t0, &slow); | 532 GenerateUnmappedArgumentsLookup(masm, key, a3, t0, &slow); |
532 __ sw(a0, unmapped_location); | 533 __ sw(value, unmapped_location); |
533 __ mov(t5, a0); | 534 __ mov(t5, value); |
534 ASSERT_EQ(unmapped_location.offset(), 0); | 535 ASSERT_EQ(unmapped_location.offset(), 0); |
535 __ RecordWrite(a3, unmapped_location.rm(), t5, | 536 __ RecordWrite(a3, unmapped_location.rm(), t5, |
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 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 StubRuntimeCallHelper call_helper; | 776 StubRuntimeCallHelper call_helper; |
766 char_at_generator.GenerateSlow(masm, call_helper); | 777 char_at_generator.GenerateSlow(masm, call_helper); |
767 | 778 |
768 __ bind(&miss); | 779 __ bind(&miss); |
769 GenerateMiss(masm); | 780 GenerateMiss(masm); |
770 } | 781 } |
771 | 782 |
772 | 783 |
773 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, | 784 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, |
774 StrictMode strict_mode) { | 785 StrictMode strict_mode) { |
775 // ---------- S t a t e -------------- | |
776 // -- a0 : value | |
777 // -- a1 : key | |
778 // -- a2 : receiver | |
779 // -- ra : return address | |
780 // ----------------------------------- | |
781 | |
782 // Push receiver, key and value for runtime call. | 786 // Push receiver, key and value for runtime call. |
783 __ Push(a2, a1, a0); | 787 __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); |
784 __ li(a0, Operand(Smi::FromInt(strict_mode))); // Strict mode. | 788 __ li(a0, Operand(Smi::FromInt(strict_mode))); // Strict mode. |
785 __ Push(a0); | 789 __ Push(a0); |
786 | 790 |
787 __ TailCallRuntime(Runtime::kSetProperty, 4, 1); | 791 __ TailCallRuntime(Runtime::kSetProperty, 4, 1); |
788 } | 792 } |
789 | 793 |
790 | 794 |
791 static void KeyedStoreGenerateGenericHelper( | 795 static void KeyedStoreGenerateGenericHelper( |
792 MacroAssembler* masm, | 796 MacroAssembler* masm, |
793 Label* fast_object, | 797 Label* fast_object, |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
967 // -- a0 : value | 971 // -- a0 : value |
968 // -- a1 : key | 972 // -- a1 : key |
969 // -- a2 : receiver | 973 // -- a2 : receiver |
970 // -- ra : return address | 974 // -- ra : return address |
971 // ----------------------------------- | 975 // ----------------------------------- |
972 Label slow, fast_object, fast_object_grow; | 976 Label slow, fast_object, fast_object_grow; |
973 Label fast_double, fast_double_grow; | 977 Label fast_double, fast_double_grow; |
974 Label array, extra, check_if_double_array; | 978 Label array, extra, check_if_double_array; |
975 | 979 |
976 // Register usage. | 980 // Register usage. |
977 Register value = a0; | 981 Register value = ValueRegister(); |
978 Register key = a1; | 982 Register key = NameRegister(); |
979 Register receiver = a2; | 983 Register receiver = ReceiverRegister(); |
| 984 ASSERT(receiver.is(a2)); |
| 985 ASSERT(key.is(a1)); |
| 986 ASSERT(value.is(a0)); |
980 Register receiver_map = a3; | 987 Register receiver_map = a3; |
981 Register elements_map = t2; | 988 Register elements_map = t2; |
982 Register elements = t3; // Elements array of the receiver. | 989 Register elements = t3; // Elements array of the receiver. |
983 // t0 and t1 are used as general scratch registers. | 990 // t0 and t1 are used as general scratch registers. |
984 | 991 |
985 // Check that the key is a smi. | 992 // Check that the key is a smi. |
986 __ JumpIfNotSmi(key, &slow); | 993 __ JumpIfNotSmi(key, &slow); |
987 // Check that the object isn't a smi. | 994 // Check that the object isn't a smi. |
988 __ JumpIfSmi(receiver, &slow); | 995 __ JumpIfSmi(receiver, &slow); |
989 // Get the map of the object. | 996 // Get the map of the object. |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1088 // Perform tail call to the entry. | 1095 // Perform tail call to the entry. |
1089 __ TailCallExternalReference(ExternalReference( | 1096 __ TailCallExternalReference(ExternalReference( |
1090 IC_Utility(kKeyedLoadPropertyWithInterceptor), masm->isolate()), 2, 1); | 1097 IC_Utility(kKeyedLoadPropertyWithInterceptor), masm->isolate()), 2, 1); |
1091 | 1098 |
1092 __ bind(&slow); | 1099 __ bind(&slow); |
1093 GenerateMiss(masm); | 1100 GenerateMiss(masm); |
1094 } | 1101 } |
1095 | 1102 |
1096 | 1103 |
1097 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { | 1104 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { |
1098 // ---------- S t a t e -------------- | |
1099 // -- a0 : value | |
1100 // -- a1 : key | |
1101 // -- a2 : receiver | |
1102 // -- ra : return address | |
1103 // ----------------------------------- | |
1104 | |
1105 // Push receiver, key and value for runtime call. | 1105 // Push receiver, key and value for runtime call. |
1106 __ Push(a2, a1, a0); | 1106 __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); |
1107 | 1107 |
1108 ExternalReference ref = | 1108 ExternalReference ref = |
1109 ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate()); | 1109 ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate()); |
1110 __ TailCallExternalReference(ref, 3, 1); | 1110 __ TailCallExternalReference(ref, 3, 1); |
1111 } | 1111 } |
1112 | 1112 |
1113 | 1113 |
1114 void StoreIC::GenerateSlow(MacroAssembler* masm) { | 1114 void StoreIC::GenerateSlow(MacroAssembler* masm) { |
1115 // ---------- S t a t e -------------- | |
1116 // -- a0 : value | |
1117 // -- a2 : key | |
1118 // -- a1 : receiver | |
1119 // -- ra : return address | |
1120 // ----------------------------------- | |
1121 | |
1122 // Push receiver, key and value for runtime call. | 1115 // Push receiver, key and value for runtime call. |
1123 __ Push(a1, a2, a0); | 1116 __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); |
1124 | 1117 |
1125 // The slow case calls into the runtime to complete the store without causing | 1118 // The slow case calls into the runtime to complete the store without causing |
1126 // an IC miss that would otherwise cause a transition to the generic stub. | 1119 // an IC miss that would otherwise cause a transition to the generic stub. |
1127 ExternalReference ref = | 1120 ExternalReference ref = |
1128 ExternalReference(IC_Utility(kStoreIC_Slow), masm->isolate()); | 1121 ExternalReference(IC_Utility(kStoreIC_Slow), masm->isolate()); |
1129 __ TailCallExternalReference(ref, 3, 1); | 1122 __ TailCallExternalReference(ref, 3, 1); |
1130 } | 1123 } |
1131 | 1124 |
1132 | 1125 |
1133 void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) { | 1126 void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) { |
1134 // ---------- S t a t e -------------- | |
1135 // -- a0 : value | |
1136 // -- a1 : key | |
1137 // -- a2 : receiver | |
1138 // -- ra : return address | |
1139 // ----------------------------------- | |
1140 | |
1141 // Push receiver, key and value for runtime call. | 1127 // Push receiver, key and value for runtime call. |
1142 // We can't use MultiPush as the order of the registers is important. | 1128 // We can't use MultiPush as the order of the registers is important. |
1143 __ Push(a2, a1, a0); | 1129 __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); |
1144 | 1130 |
1145 // The slow case calls into the runtime to complete the store without causing | 1131 // The slow case calls into the runtime to complete the store without causing |
1146 // an IC miss that would otherwise cause a transition to the generic stub. | 1132 // an IC miss that would otherwise cause a transition to the generic stub. |
1147 ExternalReference ref = | 1133 ExternalReference ref = |
1148 ExternalReference(IC_Utility(kKeyedStoreIC_Slow), masm->isolate()); | 1134 ExternalReference(IC_Utility(kKeyedStoreIC_Slow), masm->isolate()); |
1149 | 1135 |
1150 __ TailCallExternalReference(ref, 3, 1); | 1136 __ TailCallExternalReference(ref, 3, 1); |
1151 } | 1137 } |
1152 | 1138 |
1153 | 1139 |
1154 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { | 1140 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { |
1155 // ----------- S t a t e ------------- | 1141 Register receiver = ReceiverRegister(); |
1156 // -- a0 : value | 1142 Register name = NameRegister(); |
1157 // -- a1 : receiver | 1143 ASSERT(receiver.is(a1)); |
1158 // -- a2 : name | 1144 ASSERT(name.is(a2)); |
1159 // -- ra : return address | 1145 ASSERT(ValueRegister().is(a0)); |
1160 // ----------------------------------- | |
1161 | 1146 |
1162 // Get the receiver from the stack and probe the stub cache. | 1147 // Get the receiver from the stack and probe the stub cache. |
1163 Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC); | 1148 Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC); |
1164 masm->isolate()->stub_cache()->GenerateProbe( | 1149 masm->isolate()->stub_cache()->GenerateProbe( |
1165 masm, flags, a1, a2, a3, t0, t1, t2); | 1150 masm, flags, receiver, name, a3, t0, t1, t2); |
1166 | 1151 |
1167 // Cache miss: Jump to runtime. | 1152 // Cache miss: Jump to runtime. |
1168 GenerateMiss(masm); | 1153 GenerateMiss(masm); |
1169 } | 1154 } |
1170 | 1155 |
1171 | 1156 |
1172 void StoreIC::GenerateMiss(MacroAssembler* masm) { | 1157 void StoreIC::GenerateMiss(MacroAssembler* masm) { |
1173 // ----------- S t a t e ------------- | 1158 __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); |
1174 // -- a0 : value | |
1175 // -- a1 : receiver | |
1176 // -- a2 : name | |
1177 // -- ra : return address | |
1178 // ----------------------------------- | |
1179 | |
1180 __ Push(a1, a2, a0); | |
1181 // Perform tail call to the entry. | 1159 // Perform tail call to the entry. |
1182 ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss), | 1160 ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss), |
1183 masm->isolate()); | 1161 masm->isolate()); |
1184 __ TailCallExternalReference(ref, 3, 1); | 1162 __ TailCallExternalReference(ref, 3, 1); |
1185 } | 1163 } |
1186 | 1164 |
1187 | 1165 |
1188 void StoreIC::GenerateNormal(MacroAssembler* masm) { | 1166 void StoreIC::GenerateNormal(MacroAssembler* masm) { |
1189 // ----------- S t a t e ------------- | |
1190 // -- a0 : value | |
1191 // -- a1 : receiver | |
1192 // -- a2 : name | |
1193 // -- ra : return address | |
1194 // ----------------------------------- | |
1195 Label miss; | 1167 Label miss; |
| 1168 Register receiver = ReceiverRegister(); |
| 1169 Register name = NameRegister(); |
| 1170 Register value = ValueRegister(); |
| 1171 ASSERT(receiver.is(a1)); |
| 1172 ASSERT(name.is(a2)); |
| 1173 ASSERT(value.is(a0)); |
1196 | 1174 |
1197 GenerateNameDictionaryReceiverCheck(masm, a1, a3, t0, t1, &miss); | 1175 GenerateNameDictionaryReceiverCheck(masm, receiver, a3, t0, t1, &miss); |
1198 | 1176 |
1199 GenerateDictionaryStore(masm, &miss, a3, a2, a0, t0, t1); | 1177 GenerateDictionaryStore(masm, &miss, a3, name, value, t0, t1); |
1200 Counters* counters = masm->isolate()->counters(); | 1178 Counters* counters = masm->isolate()->counters(); |
1201 __ IncrementCounter(counters->store_normal_hit(), 1, t0, t1); | 1179 __ IncrementCounter(counters->store_normal_hit(), 1, t0, t1); |
1202 __ Ret(); | 1180 __ Ret(); |
1203 | 1181 |
1204 __ bind(&miss); | 1182 __ bind(&miss); |
1205 __ IncrementCounter(counters->store_normal_miss(), 1, t0, t1); | 1183 __ IncrementCounter(counters->store_normal_miss(), 1, t0, t1); |
1206 GenerateMiss(masm); | 1184 GenerateMiss(masm); |
1207 } | 1185 } |
1208 | 1186 |
1209 | 1187 |
1210 void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, | 1188 void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, |
1211 StrictMode strict_mode) { | 1189 StrictMode strict_mode) { |
1212 // ----------- S t a t e ------------- | 1190 __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); |
1213 // -- a0 : value | |
1214 // -- a1 : receiver | |
1215 // -- a2 : name | |
1216 // -- ra : return address | |
1217 // ----------------------------------- | |
1218 | |
1219 __ Push(a1, a2, a0); | |
1220 | 1191 |
1221 __ li(a0, Operand(Smi::FromInt(strict_mode))); | 1192 __ li(a0, Operand(Smi::FromInt(strict_mode))); |
1222 __ Push(a0); | 1193 __ Push(a0); |
1223 | 1194 |
1224 // Do tail-call to runtime routine. | 1195 // Do tail-call to runtime routine. |
1225 __ TailCallRuntime(Runtime::kSetProperty, 4, 1); | 1196 __ TailCallRuntime(Runtime::kSetProperty, 4, 1); |
1226 } | 1197 } |
1227 | 1198 |
1228 | 1199 |
1229 #undef __ | 1200 #undef __ |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1319 } else { | 1290 } else { |
1320 ASSERT(Assembler::IsBne(branch_instr)); | 1291 ASSERT(Assembler::IsBne(branch_instr)); |
1321 patcher.ChangeBranchCondition(eq); | 1292 patcher.ChangeBranchCondition(eq); |
1322 } | 1293 } |
1323 } | 1294 } |
1324 | 1295 |
1325 | 1296 |
1326 } } // namespace v8::internal | 1297 } } // namespace v8::internal |
1327 | 1298 |
1328 #endif // V8_TARGET_ARCH_MIPS | 1299 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |