| 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 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_X87 | 7 #if V8_TARGET_ARCH_X87 |
| 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 3108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3119 __ cmp(result, factory()->the_hole_value()); | 3119 __ cmp(result, factory()->the_hole_value()); |
| 3120 DeoptimizeIf(equal, instr, "hole"); | 3120 DeoptimizeIf(equal, instr, "hole"); |
| 3121 } | 3121 } |
| 3122 } | 3122 } |
| 3123 | 3123 |
| 3124 | 3124 |
| 3125 template <class T> | 3125 template <class T> |
| 3126 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { | 3126 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { |
| 3127 DCHECK(FLAG_vector_ics); | 3127 DCHECK(FLAG_vector_ics); |
| 3128 Register vector_register = ToRegister(instr->temp_vector()); | 3128 Register vector_register = ToRegister(instr->temp_vector()); |
| 3129 Register slot_register = VectorLoadICDescriptor::SlotRegister(); |
| 3129 DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister())); | 3130 DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister())); |
| 3131 DCHECK(slot_register.is(eax)); |
| 3132 |
| 3133 AllowDeferredHandleDereference vector_structure_check; |
| 3130 Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector(); | 3134 Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector(); |
| 3131 __ mov(vector_register, vector); | 3135 __ mov(vector_register, vector); |
| 3132 // No need to allocate this register. | 3136 // No need to allocate this register. |
| 3133 DCHECK(VectorLoadICDescriptor::SlotRegister().is(eax)); | 3137 FeedbackVectorICSlot slot = instr->hydrogen()->slot(); |
| 3134 int index = vector->GetIndex(instr->hydrogen()->slot()); | 3138 int index = vector->GetIndex(slot); |
| 3135 __ mov(VectorLoadICDescriptor::SlotRegister(), | 3139 __ mov(slot_register, Immediate(Smi::FromInt(index))); |
| 3136 Immediate(Smi::FromInt(index))); | |
| 3137 } | 3140 } |
| 3138 | 3141 |
| 3139 | 3142 |
| 3140 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { | 3143 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { |
| 3141 DCHECK(ToRegister(instr->context()).is(esi)); | 3144 DCHECK(ToRegister(instr->context()).is(esi)); |
| 3142 DCHECK(ToRegister(instr->global_object()) | 3145 DCHECK(ToRegister(instr->global_object()) |
| 3143 .is(LoadDescriptor::ReceiverRegister())); | 3146 .is(LoadDescriptor::ReceiverRegister())); |
| 3144 DCHECK(ToRegister(instr->result()).is(eax)); | 3147 DCHECK(ToRegister(instr->result()).is(eax)); |
| 3145 | 3148 |
| 3146 __ mov(LoadDescriptor::NameRegister(), instr->name()); | 3149 __ mov(LoadDescriptor::NameRegister(), instr->name()); |
| (...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3731 } | 3734 } |
| 3732 } | 3735 } |
| 3733 | 3736 |
| 3734 | 3737 |
| 3735 void LCodeGen::DoTailCallThroughMegamorphicCache( | 3738 void LCodeGen::DoTailCallThroughMegamorphicCache( |
| 3736 LTailCallThroughMegamorphicCache* instr) { | 3739 LTailCallThroughMegamorphicCache* instr) { |
| 3737 Register receiver = ToRegister(instr->receiver()); | 3740 Register receiver = ToRegister(instr->receiver()); |
| 3738 Register name = ToRegister(instr->name()); | 3741 Register name = ToRegister(instr->name()); |
| 3739 DCHECK(receiver.is(LoadDescriptor::ReceiverRegister())); | 3742 DCHECK(receiver.is(LoadDescriptor::ReceiverRegister())); |
| 3740 DCHECK(name.is(LoadDescriptor::NameRegister())); | 3743 DCHECK(name.is(LoadDescriptor::NameRegister())); |
| 3744 Register slot = FLAG_vector_ics ? ToRegister(instr->slot()) : no_reg; |
| 3745 Register vector = FLAG_vector_ics ? ToRegister(instr->vector()) : no_reg; |
| 3741 | 3746 |
| 3742 Register scratch = ebx; | 3747 Register scratch = ebx; |
| 3743 Register extra = eax; | 3748 Register extra = edi; |
| 3749 DCHECK(!extra.is(slot) && !extra.is(vector)); |
| 3744 DCHECK(!scratch.is(receiver) && !scratch.is(name)); | 3750 DCHECK(!scratch.is(receiver) && !scratch.is(name)); |
| 3745 DCHECK(!extra.is(receiver) && !extra.is(name)); | 3751 DCHECK(!extra.is(receiver) && !extra.is(name)); |
| 3746 | 3752 |
| 3747 // Important for the tail-call. | 3753 // Important for the tail-call. |
| 3748 bool must_teardown_frame = NeedsEagerFrame(); | 3754 bool must_teardown_frame = NeedsEagerFrame(); |
| 3749 | 3755 |
| 3750 // The probe will tail call to a handler if found. | 3756 if (!instr->hydrogen()->is_just_miss()) { |
| 3751 isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(), | 3757 if (FLAG_vector_ics) { |
| 3752 must_teardown_frame, receiver, name, | 3758 __ push(slot); |
| 3753 scratch, extra); | 3759 __ push(vector); |
| 3760 } |
| 3761 |
| 3762 // The probe will tail call to a handler if found. |
| 3763 // If --vector-ics is on, then it knows to pop the two args first. |
| 3764 DCHECK(!instr->hydrogen()->is_keyed_load()); |
| 3765 isolate()->stub_cache()->GenerateProbe( |
| 3766 masm(), Code::LOAD_IC, instr->hydrogen()->flags(), must_teardown_frame, |
| 3767 receiver, name, scratch, extra); |
| 3768 |
| 3769 if (FLAG_vector_ics) { |
| 3770 __ pop(vector); |
| 3771 __ pop(slot); |
| 3772 } |
| 3773 } |
| 3754 | 3774 |
| 3755 // Tail call to miss if we ended up here. | 3775 // Tail call to miss if we ended up here. |
| 3756 if (must_teardown_frame) __ leave(); | 3776 if (must_teardown_frame) __ leave(); |
| 3757 LoadIC::GenerateMiss(masm()); | 3777 if (instr->hydrogen()->is_keyed_load()) { |
| 3778 KeyedLoadIC::GenerateMiss(masm()); |
| 3779 } else { |
| 3780 LoadIC::GenerateMiss(masm()); |
| 3781 } |
| 3758 } | 3782 } |
| 3759 | 3783 |
| 3760 | 3784 |
| 3761 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { | 3785 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { |
| 3762 DCHECK(ToRegister(instr->result()).is(eax)); | 3786 DCHECK(ToRegister(instr->result()).is(eax)); |
| 3763 | 3787 |
| 3764 LPointerMap* pointers = instr->pointer_map(); | 3788 if (instr->hydrogen()->IsTailCall()) { |
| 3765 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 3789 if (NeedsEagerFrame()) __ leave(); |
| 3766 | 3790 |
| 3767 if (instr->target()->IsConstantOperand()) { | 3791 if (instr->target()->IsConstantOperand()) { |
| 3768 LConstantOperand* target = LConstantOperand::cast(instr->target()); | 3792 LConstantOperand* target = LConstantOperand::cast(instr->target()); |
| 3769 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); | 3793 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); |
| 3770 generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET)); | 3794 __ jmp(code, RelocInfo::CODE_TARGET); |
| 3771 __ call(code, RelocInfo::CODE_TARGET); | 3795 } else { |
| 3796 DCHECK(instr->target()->IsRegister()); |
| 3797 Register target = ToRegister(instr->target()); |
| 3798 __ add(target, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
| 3799 __ jmp(target); |
| 3800 } |
| 3772 } else { | 3801 } else { |
| 3773 DCHECK(instr->target()->IsRegister()); | 3802 LPointerMap* pointers = instr->pointer_map(); |
| 3774 Register target = ToRegister(instr->target()); | 3803 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
| 3775 generator.BeforeCall(__ CallSize(Operand(target))); | 3804 |
| 3776 __ add(target, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 3805 if (instr->target()->IsConstantOperand()) { |
| 3777 __ call(target); | 3806 LConstantOperand* target = LConstantOperand::cast(instr->target()); |
| 3807 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); |
| 3808 generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET)); |
| 3809 __ call(code, RelocInfo::CODE_TARGET); |
| 3810 } else { |
| 3811 DCHECK(instr->target()->IsRegister()); |
| 3812 Register target = ToRegister(instr->target()); |
| 3813 generator.BeforeCall(__ CallSize(Operand(target))); |
| 3814 __ add(target, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
| 3815 __ call(target); |
| 3816 } |
| 3817 generator.AfterCall(); |
| 3778 } | 3818 } |
| 3779 generator.AfterCall(); | |
| 3780 } | 3819 } |
| 3781 | 3820 |
| 3782 | 3821 |
| 3783 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) { | 3822 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) { |
| 3784 DCHECK(ToRegister(instr->function()).is(edi)); | 3823 DCHECK(ToRegister(instr->function()).is(edi)); |
| 3785 DCHECK(ToRegister(instr->result()).is(eax)); | 3824 DCHECK(ToRegister(instr->result()).is(eax)); |
| 3786 | 3825 |
| 3787 if (instr->hydrogen()->pass_argument_count()) { | 3826 if (instr->hydrogen()->pass_argument_count()) { |
| 3788 __ mov(eax, instr->arity()); | 3827 __ mov(eax, instr->arity()); |
| 3789 } | 3828 } |
| (...skipping 2509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6299 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 6338 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
| 6300 RecordSafepoint(Safepoint::kNoLazyDeopt); | 6339 RecordSafepoint(Safepoint::kNoLazyDeopt); |
| 6301 } | 6340 } |
| 6302 | 6341 |
| 6303 | 6342 |
| 6304 #undef __ | 6343 #undef __ |
| 6305 | 6344 |
| 6306 } } // namespace v8::internal | 6345 } } // namespace v8::internal |
| 6307 | 6346 |
| 6308 #endif // V8_TARGET_ARCH_X87 | 6347 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |