| 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 |