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_X64 | 7 #if V8_TARGET_ARCH_X64 |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 2834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2845 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); | 2845 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); |
2846 DeoptimizeIf(equal, instr, "hole"); | 2846 DeoptimizeIf(equal, instr, "hole"); |
2847 } | 2847 } |
2848 } | 2848 } |
2849 | 2849 |
2850 | 2850 |
2851 template <class T> | 2851 template <class T> |
2852 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { | 2852 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { |
2853 DCHECK(FLAG_vector_ics); | 2853 DCHECK(FLAG_vector_ics); |
2854 Register vector_register = ToRegister(instr->temp_vector()); | 2854 Register vector_register = ToRegister(instr->temp_vector()); |
| 2855 Register slot_register = VectorLoadICDescriptor::SlotRegister(); |
2855 DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister())); | 2856 DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister())); |
| 2857 DCHECK(slot_register.is(rax)); |
| 2858 |
| 2859 AllowDeferredHandleDereference vector_structure_check; |
2856 Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector(); | 2860 Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector(); |
2857 __ Move(vector_register, vector); | 2861 __ Move(vector_register, vector); |
2858 // No need to allocate this register. | 2862 // No need to allocate this register. |
2859 DCHECK(VectorLoadICDescriptor::SlotRegister().is(rax)); | 2863 FeedbackVectorICSlot slot = instr->hydrogen()->slot(); |
2860 int index = vector->GetIndex(instr->hydrogen()->slot()); | 2864 int index = vector->GetIndex(slot); |
2861 __ Move(VectorLoadICDescriptor::SlotRegister(), Smi::FromInt(index)); | 2865 __ Move(slot_register, Smi::FromInt(index)); |
2862 } | 2866 } |
2863 | 2867 |
2864 | 2868 |
2865 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { | 2869 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { |
2866 DCHECK(ToRegister(instr->context()).is(rsi)); | 2870 DCHECK(ToRegister(instr->context()).is(rsi)); |
2867 DCHECK(ToRegister(instr->global_object()) | 2871 DCHECK(ToRegister(instr->global_object()) |
2868 .is(LoadDescriptor::ReceiverRegister())); | 2872 .is(LoadDescriptor::ReceiverRegister())); |
2869 DCHECK(ToRegister(instr->result()).is(rax)); | 2873 DCHECK(ToRegister(instr->result()).is(rax)); |
2870 | 2874 |
2871 __ Move(LoadDescriptor::NameRegister(), instr->name()); | 2875 __ Move(LoadDescriptor::NameRegister(), instr->name()); |
(...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3532 } | 3536 } |
3533 } | 3537 } |
3534 | 3538 |
3535 | 3539 |
3536 void LCodeGen::DoTailCallThroughMegamorphicCache( | 3540 void LCodeGen::DoTailCallThroughMegamorphicCache( |
3537 LTailCallThroughMegamorphicCache* instr) { | 3541 LTailCallThroughMegamorphicCache* instr) { |
3538 Register receiver = ToRegister(instr->receiver()); | 3542 Register receiver = ToRegister(instr->receiver()); |
3539 Register name = ToRegister(instr->name()); | 3543 Register name = ToRegister(instr->name()); |
3540 DCHECK(receiver.is(LoadDescriptor::ReceiverRegister())); | 3544 DCHECK(receiver.is(LoadDescriptor::ReceiverRegister())); |
3541 DCHECK(name.is(LoadDescriptor::NameRegister())); | 3545 DCHECK(name.is(LoadDescriptor::NameRegister())); |
3542 | 3546 Register scratch = rdi; |
3543 Register scratch = rbx; | |
3544 DCHECK(!scratch.is(receiver) && !scratch.is(name)); | 3547 DCHECK(!scratch.is(receiver) && !scratch.is(name)); |
| 3548 DCHECK(!FLAG_vector_ics || |
| 3549 !AreAliased(ToRegister(instr->slot()), ToRegister(instr->vector()), |
| 3550 scratch)); |
3545 | 3551 |
3546 // Important for the tail-call. | 3552 // Important for the tail-call. |
3547 bool must_teardown_frame = NeedsEagerFrame(); | 3553 bool must_teardown_frame = NeedsEagerFrame(); |
3548 | 3554 |
3549 // The probe will tail call to a handler if found. | 3555 if (!instr->hydrogen()->is_just_miss()) { |
3550 isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(), | 3556 // The probe will tail call to a handler if found. |
3551 must_teardown_frame, receiver, name, | 3557 DCHECK(!instr->hydrogen()->is_keyed_load()); |
3552 scratch, no_reg); | 3558 isolate()->stub_cache()->GenerateProbe( |
| 3559 masm(), Code::LOAD_IC, instr->hydrogen()->flags(), must_teardown_frame, |
| 3560 receiver, name, scratch, no_reg); |
| 3561 } |
3553 | 3562 |
3554 // Tail call to miss if we ended up here. | 3563 // Tail call to miss if we ended up here. |
3555 if (must_teardown_frame) __ leave(); | 3564 if (must_teardown_frame) __ leave(); |
3556 LoadIC::GenerateMiss(masm()); | 3565 if (instr->hydrogen()->is_keyed_load()) { |
| 3566 KeyedLoadIC::GenerateMiss(masm()); |
| 3567 } else { |
| 3568 LoadIC::GenerateMiss(masm()); |
| 3569 } |
3557 } | 3570 } |
3558 | 3571 |
3559 | 3572 |
3560 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { | 3573 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { |
3561 DCHECK(ToRegister(instr->result()).is(rax)); | 3574 DCHECK(ToRegister(instr->result()).is(rax)); |
3562 | 3575 |
3563 LPointerMap* pointers = instr->pointer_map(); | 3576 if (instr->hydrogen()->IsTailCall()) { |
3564 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 3577 if (NeedsEagerFrame()) __ leave(); |
3565 | 3578 |
3566 if (instr->target()->IsConstantOperand()) { | 3579 if (instr->target()->IsConstantOperand()) { |
3567 LConstantOperand* target = LConstantOperand::cast(instr->target()); | 3580 LConstantOperand* target = LConstantOperand::cast(instr->target()); |
3568 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); | 3581 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); |
3569 generator.BeforeCall(__ CallSize(code)); | 3582 __ jmp(code, RelocInfo::CODE_TARGET); |
3570 __ call(code, RelocInfo::CODE_TARGET); | 3583 } else { |
| 3584 DCHECK(instr->target()->IsRegister()); |
| 3585 Register target = ToRegister(instr->target()); |
| 3586 __ addp(target, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
| 3587 __ jmp(target); |
| 3588 } |
3571 } else { | 3589 } else { |
3572 DCHECK(instr->target()->IsRegister()); | 3590 LPointerMap* pointers = instr->pointer_map(); |
3573 Register target = ToRegister(instr->target()); | 3591 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
3574 generator.BeforeCall(__ CallSize(target)); | 3592 |
3575 __ addp(target, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 3593 if (instr->target()->IsConstantOperand()) { |
3576 __ call(target); | 3594 LConstantOperand* target = LConstantOperand::cast(instr->target()); |
| 3595 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); |
| 3596 generator.BeforeCall(__ CallSize(code)); |
| 3597 __ call(code, RelocInfo::CODE_TARGET); |
| 3598 } else { |
| 3599 DCHECK(instr->target()->IsRegister()); |
| 3600 Register target = ToRegister(instr->target()); |
| 3601 generator.BeforeCall(__ CallSize(target)); |
| 3602 __ addp(target, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
| 3603 __ call(target); |
| 3604 } |
| 3605 generator.AfterCall(); |
3577 } | 3606 } |
3578 generator.AfterCall(); | |
3579 } | 3607 } |
3580 | 3608 |
3581 | 3609 |
3582 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) { | 3610 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) { |
3583 DCHECK(ToRegister(instr->function()).is(rdi)); | 3611 DCHECK(ToRegister(instr->function()).is(rdi)); |
3584 DCHECK(ToRegister(instr->result()).is(rax)); | 3612 DCHECK(ToRegister(instr->result()).is(rax)); |
3585 | 3613 |
3586 if (instr->hydrogen()->pass_argument_count()) { | 3614 if (instr->hydrogen()->pass_argument_count()) { |
3587 __ Set(rax, instr->arity()); | 3615 __ Set(rax, instr->arity()); |
3588 } | 3616 } |
(...skipping 2301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5890 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 5918 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
5891 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5919 RecordSafepoint(Safepoint::kNoLazyDeopt); |
5892 } | 5920 } |
5893 | 5921 |
5894 | 5922 |
5895 #undef __ | 5923 #undef __ |
5896 | 5924 |
5897 } } // namespace v8::internal | 5925 } } // namespace v8::internal |
5898 | 5926 |
5899 #endif // V8_TARGET_ARCH_X64 | 5927 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |