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 |