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