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