OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
8 | 8 |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/ic/ic.h" | 10 #include "src/ic/ic.h" |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 __ Bind(&slow); | 361 __ Bind(&slow); |
362 GenerateRuntimeGetProperty(masm); | 362 GenerateRuntimeGetProperty(masm); |
363 } | 363 } |
364 | 364 |
365 | 365 |
366 void LoadIC::GenerateMiss(MacroAssembler* masm) { | 366 void LoadIC::GenerateMiss(MacroAssembler* masm) { |
367 // The return address is in lr. | 367 // The return address is in lr. |
368 Isolate* isolate = masm->isolate(); | 368 Isolate* isolate = masm->isolate(); |
369 ASM_LOCATION("LoadIC::GenerateMiss"); | 369 ASM_LOCATION("LoadIC::GenerateMiss"); |
370 | 370 |
371 DCHECK(!FLAG_vector_ics || | 371 DCHECK(!AreAliased(x4, x5, VectorLoadICDescriptor::SlotRegister(), |
372 !AreAliased(x4, x5, VectorLoadICDescriptor::SlotRegister(), | |
373 VectorLoadICDescriptor::VectorRegister())); | 372 VectorLoadICDescriptor::VectorRegister())); |
374 __ IncrementCounter(isolate->counters()->load_miss(), 1, x4, x5); | 373 __ IncrementCounter(isolate->counters()->load_miss(), 1, x4, x5); |
375 | 374 |
376 // Perform tail call to the entry. | 375 // Perform tail call to the entry. |
377 if (FLAG_vector_ics) { | 376 __ Push(VectorLoadICDescriptor::ReceiverRegister(), |
378 __ Push(VectorLoadICDescriptor::ReceiverRegister(), | 377 VectorLoadICDescriptor::NameRegister(), |
379 VectorLoadICDescriptor::NameRegister(), | 378 VectorLoadICDescriptor::SlotRegister(), |
380 VectorLoadICDescriptor::SlotRegister(), | 379 VectorLoadICDescriptor::VectorRegister()); |
381 VectorLoadICDescriptor::VectorRegister()); | |
382 } else { | |
383 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister()); | |
384 } | |
385 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate); | 380 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate); |
386 int arg_count = FLAG_vector_ics ? 4 : 2; | 381 int arg_count = 4; |
387 __ TailCallExternalReference(ref, arg_count, 1); | 382 __ TailCallExternalReference(ref, arg_count, 1); |
388 } | 383 } |
389 | 384 |
390 | 385 |
391 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 386 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |
392 // The return address is in lr. | 387 // The return address is in lr. |
393 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister()); | 388 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister()); |
394 __ TailCallRuntime(Runtime::kGetProperty, 2, 1); | 389 __ TailCallRuntime(Runtime::kGetProperty, 2, 1); |
395 } | 390 } |
396 | 391 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 __ Ret(); | 433 __ Ret(); |
439 __ Bind(&slow); | 434 __ Bind(&slow); |
440 GenerateMiss(masm); | 435 GenerateMiss(masm); |
441 } | 436 } |
442 | 437 |
443 | 438 |
444 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { | 439 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { |
445 // The return address is in lr. | 440 // The return address is in lr. |
446 Isolate* isolate = masm->isolate(); | 441 Isolate* isolate = masm->isolate(); |
447 | 442 |
448 DCHECK(!FLAG_vector_ics || | 443 DCHECK(!AreAliased(x10, x11, VectorLoadICDescriptor::SlotRegister(), |
449 !AreAliased(x10, x11, VectorLoadICDescriptor::SlotRegister(), | |
450 VectorLoadICDescriptor::VectorRegister())); | 444 VectorLoadICDescriptor::VectorRegister())); |
451 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, x10, x11); | 445 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, x10, x11); |
452 | 446 |
453 if (FLAG_vector_ics) { | 447 __ Push(VectorLoadICDescriptor::ReceiverRegister(), |
454 __ Push(VectorLoadICDescriptor::ReceiverRegister(), | 448 VectorLoadICDescriptor::NameRegister(), |
455 VectorLoadICDescriptor::NameRegister(), | 449 VectorLoadICDescriptor::SlotRegister(), |
456 VectorLoadICDescriptor::SlotRegister(), | 450 VectorLoadICDescriptor::VectorRegister()); |
457 VectorLoadICDescriptor::VectorRegister()); | |
458 } else { | |
459 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister()); | |
460 } | |
461 | 451 |
462 // Perform tail call to the entry. | 452 // Perform tail call to the entry. |
463 ExternalReference ref = | 453 ExternalReference ref = |
464 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate); | 454 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate); |
465 int arg_count = FLAG_vector_ics ? 4 : 2; | 455 int arg_count = 4; |
466 __ TailCallExternalReference(ref, arg_count, 1); | 456 __ TailCallExternalReference(ref, arg_count, 1); |
467 } | 457 } |
468 | 458 |
469 | 459 |
470 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 460 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |
471 // The return address is in lr. | 461 // The return address is in lr. |
472 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister()); | 462 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister()); |
473 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); | 463 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); |
474 } | 464 } |
475 | 465 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 | 516 |
527 GenerateKeyedLoadReceiverCheck(masm, receiver, scratch1, scratch2, | 517 GenerateKeyedLoadReceiverCheck(masm, receiver, scratch1, scratch2, |
528 Map::kHasNamedInterceptor, slow); | 518 Map::kHasNamedInterceptor, slow); |
529 | 519 |
530 // If the receiver is a fast-case object, check the stub cache. Otherwise | 520 // If the receiver is a fast-case object, check the stub cache. Otherwise |
531 // probe the dictionary. | 521 // probe the dictionary. |
532 __ Ldr(scratch2, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 522 __ Ldr(scratch2, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
533 __ Ldr(scratch3, FieldMemOperand(scratch2, HeapObject::kMapOffset)); | 523 __ Ldr(scratch3, FieldMemOperand(scratch2, HeapObject::kMapOffset)); |
534 __ JumpIfRoot(scratch3, Heap::kHashTableMapRootIndex, &probe_dictionary); | 524 __ JumpIfRoot(scratch3, Heap::kHashTableMapRootIndex, &probe_dictionary); |
535 | 525 |
536 if (FLAG_vector_ics) { | 526 // The handlers in the stub cache expect a vector and slot. Since we won't |
537 // When vector ics are in use, the handlers in the stub cache expect a | 527 // change the IC from any downstream misses, a dummy vector can be used. |
538 // vector and slot. Since we won't change the IC from any downstream | 528 Register vector = VectorLoadICDescriptor::VectorRegister(); |
539 // misses, a dummy vector can be used. | 529 Register slot = VectorLoadICDescriptor::SlotRegister(); |
540 Register vector = VectorLoadICDescriptor::VectorRegister(); | 530 DCHECK(!AreAliased(vector, slot, scratch1, scratch2, scratch3, scratch4)); |
541 Register slot = VectorLoadICDescriptor::SlotRegister(); | 531 Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast( |
542 DCHECK(!AreAliased(vector, slot, scratch1, scratch2, scratch3, scratch4)); | 532 masm->isolate()->factory()->keyed_load_dummy_vector()); |
543 Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast( | 533 int int_slot = dummy_vector->GetIndex(FeedbackVectorICSlot(0)); |
544 masm->isolate()->factory()->keyed_load_dummy_vector()); | 534 __ LoadRoot(vector, Heap::kKeyedLoadDummyVectorRootIndex); |
545 int int_slot = dummy_vector->GetIndex(FeedbackVectorICSlot(0)); | 535 __ Mov(slot, Operand(Smi::FromInt(int_slot))); |
546 __ LoadRoot(vector, Heap::kKeyedLoadDummyVectorRootIndex); | |
547 __ Mov(slot, Operand(Smi::FromInt(int_slot))); | |
548 } | |
549 | 536 |
550 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | 537 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
551 Code::ComputeHandlerFlags(Code::LOAD_IC)); | 538 Code::ComputeHandlerFlags(Code::LOAD_IC)); |
552 masm->isolate()->stub_cache()->GenerateProbe(masm, Code::KEYED_LOAD_IC, flags, | 539 masm->isolate()->stub_cache()->GenerateProbe(masm, Code::KEYED_LOAD_IC, flags, |
553 false, receiver, key, scratch1, | 540 false, receiver, key, scratch1, |
554 scratch2, scratch3, scratch4); | 541 scratch2, scratch3, scratch4); |
555 // Cache miss. | 542 // Cache miss. |
556 KeyedLoadIC::GenerateMiss(masm); | 543 KeyedLoadIC::GenerateMiss(masm); |
557 | 544 |
558 // Do a quick inline probe of the receiver's dictionary, if it exists. | 545 // Do a quick inline probe of the receiver's dictionary, if it exists. |
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
994 } else { | 981 } else { |
995 DCHECK(to_patch->Mask(TestBranchMask) == TBNZ); | 982 DCHECK(to_patch->Mask(TestBranchMask) == TBNZ); |
996 // This is JumpIfSmi(smi_reg, branch_imm). | 983 // This is JumpIfSmi(smi_reg, branch_imm). |
997 patcher.tbz(smi_reg, 0, branch_imm); | 984 patcher.tbz(smi_reg, 0, branch_imm); |
998 } | 985 } |
999 } | 986 } |
1000 } | 987 } |
1001 } // namespace v8::internal | 988 } // namespace v8::internal |
1002 | 989 |
1003 #endif // V8_TARGET_ARCH_ARM64 | 990 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |