| 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 |