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 |