| 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 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 #include "src/hydrogen-osr.h" | 9 #include "src/hydrogen-osr.h" |
| 10 #include "src/ic/ic.h" | 10 #include "src/ic/ic.h" |
| (...skipping 2841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2852 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 2852 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
| 2853 DeoptimizeIf(eq, instr, "hole", result, Operand(at)); | 2853 DeoptimizeIf(eq, instr, "hole", result, Operand(at)); |
| 2854 } | 2854 } |
| 2855 } | 2855 } |
| 2856 | 2856 |
| 2857 | 2857 |
| 2858 template <class T> | 2858 template <class T> |
| 2859 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { | 2859 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { |
| 2860 DCHECK(FLAG_vector_ics); | 2860 DCHECK(FLAG_vector_ics); |
| 2861 Register vector_register = ToRegister(instr->temp_vector()); | 2861 Register vector_register = ToRegister(instr->temp_vector()); |
| 2862 Register slot_register = VectorLoadICDescriptor::SlotRegister(); |
| 2862 DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister())); | 2863 DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister())); |
| 2864 DCHECK(slot_register.is(a0)); |
| 2865 |
| 2866 AllowDeferredHandleDereference vector_structure_check; |
| 2863 Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector(); | 2867 Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector(); |
| 2864 __ li(vector_register, vector); | 2868 __ li(vector_register, vector); |
| 2865 // No need to allocate this register. | 2869 // No need to allocate this register. |
| 2866 DCHECK(VectorLoadICDescriptor::SlotRegister().is(a0)); | 2870 FeedbackVectorICSlot slot = instr->hydrogen()->slot(); |
| 2867 int index = vector->GetIndex(instr->hydrogen()->slot()); | 2871 int index = vector->GetIndex(slot); |
| 2868 __ li(VectorLoadICDescriptor::SlotRegister(), Operand(Smi::FromInt(index))); | 2872 __ li(slot_register, Operand(Smi::FromInt(index))); |
| 2869 } | 2873 } |
| 2870 | 2874 |
| 2871 | 2875 |
| 2872 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { | 2876 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { |
| 2873 DCHECK(ToRegister(instr->context()).is(cp)); | 2877 DCHECK(ToRegister(instr->context()).is(cp)); |
| 2874 DCHECK(ToRegister(instr->global_object()) | 2878 DCHECK(ToRegister(instr->global_object()) |
| 2875 .is(LoadDescriptor::ReceiverRegister())); | 2879 .is(LoadDescriptor::ReceiverRegister())); |
| 2876 DCHECK(ToRegister(instr->result()).is(v0)); | 2880 DCHECK(ToRegister(instr->result()).is(v0)); |
| 2877 | 2881 |
| 2878 __ li(LoadDescriptor::NameRegister(), Operand(instr->name())); | 2882 __ li(LoadDescriptor::NameRegister(), Operand(instr->name())); |
| (...skipping 1093 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3972 | 3976 |
| 3973 void LCodeGen::DoTailCallThroughMegamorphicCache( | 3977 void LCodeGen::DoTailCallThroughMegamorphicCache( |
| 3974 LTailCallThroughMegamorphicCache* instr) { | 3978 LTailCallThroughMegamorphicCache* instr) { |
| 3975 Register receiver = ToRegister(instr->receiver()); | 3979 Register receiver = ToRegister(instr->receiver()); |
| 3976 Register name = ToRegister(instr->name()); | 3980 Register name = ToRegister(instr->name()); |
| 3977 DCHECK(receiver.is(LoadDescriptor::ReceiverRegister())); | 3981 DCHECK(receiver.is(LoadDescriptor::ReceiverRegister())); |
| 3978 DCHECK(name.is(LoadDescriptor::NameRegister())); | 3982 DCHECK(name.is(LoadDescriptor::NameRegister())); |
| 3979 DCHECK(receiver.is(a1)); | 3983 DCHECK(receiver.is(a1)); |
| 3980 DCHECK(name.is(a2)); | 3984 DCHECK(name.is(a2)); |
| 3981 | 3985 |
| 3982 Register scratch = a3; | 3986 Register scratch = a4; |
| 3983 Register extra = a4; | 3987 Register extra = a5; |
| 3984 Register extra2 = a5; | 3988 Register extra2 = a6; |
| 3985 Register extra3 = a6; | 3989 Register extra3 = t1; |
| 3990 #ifdef DEBUG |
| 3991 Register slot = FLAG_vector_ics ? ToRegister(instr->slot()) : no_reg; |
| 3992 Register vector = FLAG_vector_ics ? ToRegister(instr->vector()) : no_reg; |
| 3993 DCHECK(!FLAG_vector_ics || |
| 3994 !AreAliased(slot, vector, scratch, extra, extra2, extra3)); |
| 3995 #endif |
| 3986 | 3996 |
| 3987 // Important for the tail-call. | 3997 // Important for the tail-call. |
| 3988 bool must_teardown_frame = NeedsEagerFrame(); | 3998 bool must_teardown_frame = NeedsEagerFrame(); |
| 3989 | 3999 |
| 3990 // The probe will tail call to a handler if found. | 4000 if (!instr->hydrogen()->is_just_miss()) { |
| 3991 isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(), | 4001 DCHECK(!instr->hydrogen()->is_keyed_load()); |
| 3992 must_teardown_frame, receiver, name, | 4002 |
| 3993 scratch, extra, extra2, extra3); | 4003 // The probe will tail call to a handler if found. |
| 4004 isolate()->stub_cache()->GenerateProbe( |
| 4005 masm(), Code::LOAD_IC, instr->hydrogen()->flags(), must_teardown_frame, |
| 4006 receiver, name, scratch, extra, extra2, extra3); |
| 4007 } |
| 3994 | 4008 |
| 3995 // Tail call to miss if we ended up here. | 4009 // Tail call to miss if we ended up here. |
| 3996 if (must_teardown_frame) __ LeaveFrame(StackFrame::INTERNAL); | 4010 if (must_teardown_frame) __ LeaveFrame(StackFrame::INTERNAL); |
| 3997 LoadIC::GenerateMiss(masm()); | 4011 if (instr->hydrogen()->is_keyed_load()) { |
| 4012 KeyedLoadIC::GenerateMiss(masm()); |
| 4013 } else { |
| 4014 LoadIC::GenerateMiss(masm()); |
| 4015 } |
| 3998 } | 4016 } |
| 3999 | 4017 |
| 4000 | 4018 |
| 4001 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { | 4019 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { |
| 4002 DCHECK(ToRegister(instr->result()).is(v0)); | 4020 DCHECK(ToRegister(instr->result()).is(v0)); |
| 4003 | 4021 |
| 4004 LPointerMap* pointers = instr->pointer_map(); | 4022 if (instr->hydrogen()->IsTailCall()) { |
| 4005 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 4023 if (NeedsEagerFrame()) __ LeaveFrame(StackFrame::INTERNAL); |
| 4006 | 4024 |
| 4007 if (instr->target()->IsConstantOperand()) { | 4025 if (instr->target()->IsConstantOperand()) { |
| 4008 LConstantOperand* target = LConstantOperand::cast(instr->target()); | 4026 LConstantOperand* target = LConstantOperand::cast(instr->target()); |
| 4009 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); | 4027 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); |
| 4010 generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET)); | 4028 __ Jump(code, RelocInfo::CODE_TARGET); |
| 4011 __ Call(code, RelocInfo::CODE_TARGET); | 4029 } else { |
| 4030 DCHECK(instr->target()->IsRegister()); |
| 4031 Register target = ToRegister(instr->target()); |
| 4032 __ Daddu(target, target, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 4033 __ Jump(target); |
| 4034 } |
| 4012 } else { | 4035 } else { |
| 4013 DCHECK(instr->target()->IsRegister()); | 4036 LPointerMap* pointers = instr->pointer_map(); |
| 4014 Register target = ToRegister(instr->target()); | 4037 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
| 4015 generator.BeforeCall(__ CallSize(target)); | 4038 |
| 4016 __ Daddu(target, target, Operand(Code::kHeaderSize - kHeapObjectTag)); | 4039 if (instr->target()->IsConstantOperand()) { |
| 4017 __ Call(target); | 4040 LConstantOperand* target = LConstantOperand::cast(instr->target()); |
| 4041 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); |
| 4042 generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET)); |
| 4043 __ Call(code, RelocInfo::CODE_TARGET); |
| 4044 } else { |
| 4045 DCHECK(instr->target()->IsRegister()); |
| 4046 Register target = ToRegister(instr->target()); |
| 4047 generator.BeforeCall(__ CallSize(target)); |
| 4048 __ Daddu(target, target, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 4049 __ Call(target); |
| 4050 } |
| 4051 generator.AfterCall(); |
| 4018 } | 4052 } |
| 4019 generator.AfterCall(); | |
| 4020 } | 4053 } |
| 4021 | 4054 |
| 4022 | 4055 |
| 4023 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) { | 4056 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) { |
| 4024 DCHECK(ToRegister(instr->function()).is(a1)); | 4057 DCHECK(ToRegister(instr->function()).is(a1)); |
| 4025 DCHECK(ToRegister(instr->result()).is(v0)); | 4058 DCHECK(ToRegister(instr->result()).is(v0)); |
| 4026 | 4059 |
| 4027 if (instr->hydrogen()->pass_argument_count()) { | 4060 if (instr->hydrogen()->pass_argument_count()) { |
| 4028 __ li(a0, Operand(instr->arity())); | 4061 __ li(a0, Operand(instr->arity())); |
| 4029 } | 4062 } |
| (...skipping 1928 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5958 __ li(at, scope_info); | 5991 __ li(at, scope_info); |
| 5959 __ Push(at, ToRegister(instr->function())); | 5992 __ Push(at, ToRegister(instr->function())); |
| 5960 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 5993 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
| 5961 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5994 RecordSafepoint(Safepoint::kNoLazyDeopt); |
| 5962 } | 5995 } |
| 5963 | 5996 |
| 5964 | 5997 |
| 5965 #undef __ | 5998 #undef __ |
| 5966 | 5999 |
| 5967 } } // namespace v8::internal | 6000 } } // namespace v8::internal |
| OLD | NEW |