| 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 #include "src/v8.h" | 6 #include "src/v8.h" |
| 7 | 7 |
| 8 #if V8_TARGET_ARCH_MIPS | 8 #if V8_TARGET_ARCH_MIPS |
| 9 | 9 |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 } | 289 } |
| 290 | 290 |
| 291 | 291 |
| 292 // A register that isn't one of the parameters to the load ic. | 292 // A register that isn't one of the parameters to the load ic. |
| 293 static const Register LoadIC_TempRegister() { return a3; } | 293 static const Register LoadIC_TempRegister() { return a3; } |
| 294 | 294 |
| 295 | 295 |
| 296 static void LoadIC_PushArgs(MacroAssembler* masm) { | 296 static void LoadIC_PushArgs(MacroAssembler* masm) { |
| 297 Register receiver = LoadDescriptor::ReceiverRegister(); | 297 Register receiver = LoadDescriptor::ReceiverRegister(); |
| 298 Register name = LoadDescriptor::NameRegister(); | 298 Register name = LoadDescriptor::NameRegister(); |
| 299 if (FLAG_vector_ics) { | 299 Register slot = VectorLoadICDescriptor::SlotRegister(); |
| 300 Register slot = VectorLoadICDescriptor::SlotRegister(); | 300 Register vector = VectorLoadICDescriptor::VectorRegister(); |
| 301 Register vector = VectorLoadICDescriptor::VectorRegister(); | |
| 302 | 301 |
| 303 __ Push(receiver, name, slot, vector); | 302 __ Push(receiver, name, slot, vector); |
| 304 } else { | |
| 305 __ Push(receiver, name); | |
| 306 } | |
| 307 } | 303 } |
| 308 | 304 |
| 309 | 305 |
| 310 void LoadIC::GenerateMiss(MacroAssembler* masm) { | 306 void LoadIC::GenerateMiss(MacroAssembler* masm) { |
| 311 // The return address is in ra. | 307 // The return address is in ra. |
| 312 Isolate* isolate = masm->isolate(); | 308 Isolate* isolate = masm->isolate(); |
| 313 | 309 |
| 314 DCHECK(!FLAG_vector_ics || | 310 DCHECK(!AreAliased(t0, t1, VectorLoadICDescriptor::SlotRegister(), |
| 315 !AreAliased(t0, t1, VectorLoadICDescriptor::SlotRegister(), | |
| 316 VectorLoadICDescriptor::VectorRegister())); | 311 VectorLoadICDescriptor::VectorRegister())); |
| 317 __ IncrementCounter(isolate->counters()->load_miss(), 1, t0, t1); | 312 __ IncrementCounter(isolate->counters()->load_miss(), 1, t0, t1); |
| 318 | 313 |
| 319 LoadIC_PushArgs(masm); | 314 LoadIC_PushArgs(masm); |
| 320 | 315 |
| 321 // Perform tail call to the entry. | 316 // Perform tail call to the entry. |
| 322 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate); | 317 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate); |
| 323 int arg_count = FLAG_vector_ics ? 4 : 2; | 318 int arg_count = 4; |
| 324 __ TailCallExternalReference(ref, arg_count, 1); | 319 __ TailCallExternalReference(ref, arg_count, 1); |
| 325 } | 320 } |
| 326 | 321 |
| 327 | 322 |
| 328 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 323 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |
| 329 // The return address is in ra. | 324 // The return address is in ra. |
| 330 | 325 |
| 331 __ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister()); | 326 __ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister()); |
| 332 __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister()); | 327 __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister()); |
| 333 | 328 |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 __ mov(v0, a0); // (In delay slot) return the value stored in v0. | 438 __ mov(v0, a0); // (In delay slot) return the value stored in v0. |
| 444 __ bind(&slow); | 439 __ bind(&slow); |
| 445 GenerateMiss(masm); | 440 GenerateMiss(masm); |
| 446 } | 441 } |
| 447 | 442 |
| 448 | 443 |
| 449 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { | 444 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { |
| 450 // The return address is in ra. | 445 // The return address is in ra. |
| 451 Isolate* isolate = masm->isolate(); | 446 Isolate* isolate = masm->isolate(); |
| 452 | 447 |
| 453 DCHECK(!FLAG_vector_ics || | 448 DCHECK(!AreAliased(t0, t1, VectorLoadICDescriptor::SlotRegister(), |
| 454 !AreAliased(t0, t1, VectorLoadICDescriptor::SlotRegister(), | |
| 455 VectorLoadICDescriptor::VectorRegister())); | 449 VectorLoadICDescriptor::VectorRegister())); |
| 456 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, t0, t1); | 450 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, t0, t1); |
| 457 | 451 |
| 458 LoadIC_PushArgs(masm); | 452 LoadIC_PushArgs(masm); |
| 459 | 453 |
| 460 // Perform tail call to the entry. | 454 // Perform tail call to the entry. |
| 461 ExternalReference ref = | 455 ExternalReference ref = |
| 462 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate); | 456 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate); |
| 463 | 457 |
| 464 int arg_count = FLAG_vector_ics ? 4 : 2; | 458 int arg_count = 4; |
| 465 __ TailCallExternalReference(ref, arg_count, 1); | 459 __ TailCallExternalReference(ref, arg_count, 1); |
| 466 } | 460 } |
| 467 | 461 |
| 468 | 462 |
| 469 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 463 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |
| 470 // The return address is in ra. | 464 // The return address is in ra. |
| 471 | 465 |
| 472 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister()); | 466 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister()); |
| 473 | 467 |
| 474 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); | 468 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 Map::kHasNamedInterceptor, &slow); | 523 Map::kHasNamedInterceptor, &slow); |
| 530 | 524 |
| 531 | 525 |
| 532 // If the receiver is a fast-case object, check the stub cache. Otherwise | 526 // If the receiver is a fast-case object, check the stub cache. Otherwise |
| 533 // probe the dictionary. | 527 // probe the dictionary. |
| 534 __ lw(a3, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 528 __ lw(a3, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
| 535 __ lw(t0, FieldMemOperand(a3, HeapObject::kMapOffset)); | 529 __ lw(t0, FieldMemOperand(a3, HeapObject::kMapOffset)); |
| 536 __ LoadRoot(at, Heap::kHashTableMapRootIndex); | 530 __ LoadRoot(at, Heap::kHashTableMapRootIndex); |
| 537 __ Branch(&probe_dictionary, eq, t0, Operand(at)); | 531 __ Branch(&probe_dictionary, eq, t0, Operand(at)); |
| 538 | 532 |
| 539 if (FLAG_vector_ics) { | 533 // The handlers in the stub cache expect a vector and slot. Since we won't |
| 540 // When vector ics are in use, the handlers in the stub cache expect a | 534 // change the IC from any downstream misses, a dummy vector can be used. |
| 541 // vector and slot. Since we won't change the IC from any downstream | 535 Register vector = VectorLoadICDescriptor::VectorRegister(); |
| 542 // misses, a dummy vector can be used. | 536 Register slot = VectorLoadICDescriptor::SlotRegister(); |
| 543 Register vector = VectorLoadICDescriptor::VectorRegister(); | 537 DCHECK(!AreAliased(vector, slot, t0, t1, t2, t5)); |
| 544 Register slot = VectorLoadICDescriptor::SlotRegister(); | 538 Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast( |
| 545 DCHECK(!AreAliased(vector, slot, t0, t1, t2, t5)); | 539 masm->isolate()->factory()->keyed_load_dummy_vector()); |
| 546 Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast( | 540 int int_slot = dummy_vector->GetIndex(FeedbackVectorICSlot(0)); |
| 547 masm->isolate()->factory()->keyed_load_dummy_vector()); | 541 __ LoadRoot(vector, Heap::kKeyedLoadDummyVectorRootIndex); |
| 548 int int_slot = dummy_vector->GetIndex(FeedbackVectorICSlot(0)); | 542 __ li(slot, Operand(Smi::FromInt(int_slot))); |
| 549 __ LoadRoot(vector, Heap::kKeyedLoadDummyVectorRootIndex); | |
| 550 __ li(slot, Operand(Smi::FromInt(int_slot))); | |
| 551 } | |
| 552 | 543 |
| 553 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | 544 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
| 554 Code::ComputeHandlerFlags(Code::LOAD_IC)); | 545 Code::ComputeHandlerFlags(Code::LOAD_IC)); |
| 555 masm->isolate()->stub_cache()->GenerateProbe( | 546 masm->isolate()->stub_cache()->GenerateProbe( |
| 556 masm, Code::LOAD_IC, flags, false, receiver, key, t0, t1, t2, t5); | 547 masm, Code::LOAD_IC, flags, false, receiver, key, t0, t1, t2, t5); |
| 557 // Cache miss. | 548 // Cache miss. |
| 558 GenerateMiss(masm); | 549 GenerateMiss(masm); |
| 559 | 550 |
| 560 // Do a quick inline probe of the receiver's dictionary, if it | 551 // Do a quick inline probe of the receiver's dictionary, if it |
| 561 // exists. | 552 // exists. |
| (...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 987 patcher.ChangeBranchCondition(ne); | 978 patcher.ChangeBranchCondition(ne); |
| 988 } else { | 979 } else { |
| 989 DCHECK(Assembler::IsBne(branch_instr)); | 980 DCHECK(Assembler::IsBne(branch_instr)); |
| 990 patcher.ChangeBranchCondition(eq); | 981 patcher.ChangeBranchCondition(eq); |
| 991 } | 982 } |
| 992 } | 983 } |
| 993 } | 984 } |
| 994 } // namespace v8::internal | 985 } // namespace v8::internal |
| 995 | 986 |
| 996 #endif // V8_TARGET_ARCH_MIPS | 987 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |