| 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/arm/lithium-codegen-arm.h" | 7 #include "src/arm/lithium-codegen-arm.h" |
| 8 #include "src/arm/lithium-gap-resolver-arm.h" | 8 #include "src/arm/lithium-gap-resolver-arm.h" |
| 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 2978 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2989 __ cmp(result, ip); | 2989 __ cmp(result, ip); |
| 2990 DeoptimizeIf(eq, instr, "hole"); | 2990 DeoptimizeIf(eq, instr, "hole"); |
| 2991 } | 2991 } |
| 2992 } | 2992 } |
| 2993 | 2993 |
| 2994 | 2994 |
| 2995 template <class T> | 2995 template <class T> |
| 2996 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { | 2996 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { |
| 2997 DCHECK(FLAG_vector_ics); | 2997 DCHECK(FLAG_vector_ics); |
| 2998 Register vector_register = ToRegister(instr->temp_vector()); | 2998 Register vector_register = ToRegister(instr->temp_vector()); |
| 2999 Register slot_register = VectorLoadICDescriptor::SlotRegister(); |
| 2999 DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister())); | 3000 DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister())); |
| 3001 DCHECK(slot_register.is(r0)); |
| 3002 |
| 3003 AllowDeferredHandleDereference vector_structure_check; |
| 3000 Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector(); | 3004 Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector(); |
| 3001 __ Move(vector_register, vector); | 3005 __ Move(vector_register, vector); |
| 3002 // No need to allocate this register. | 3006 // No need to allocate this register. |
| 3003 DCHECK(VectorLoadICDescriptor::SlotRegister().is(r0)); | 3007 FeedbackVectorICSlot slot = instr->hydrogen()->slot(); |
| 3004 int index = vector->GetIndex(instr->hydrogen()->slot()); | 3008 int index = vector->GetIndex(slot); |
| 3005 __ mov(VectorLoadICDescriptor::SlotRegister(), Operand(Smi::FromInt(index))); | 3009 __ mov(slot_register, Operand(Smi::FromInt(index))); |
| 3006 } | 3010 } |
| 3007 | 3011 |
| 3008 | 3012 |
| 3009 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { | 3013 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { |
| 3010 DCHECK(ToRegister(instr->context()).is(cp)); | 3014 DCHECK(ToRegister(instr->context()).is(cp)); |
| 3011 DCHECK(ToRegister(instr->global_object()) | 3015 DCHECK(ToRegister(instr->global_object()) |
| 3012 .is(LoadDescriptor::ReceiverRegister())); | 3016 .is(LoadDescriptor::ReceiverRegister())); |
| 3013 DCHECK(ToRegister(instr->result()).is(r0)); | 3017 DCHECK(ToRegister(instr->result()).is(r0)); |
| 3014 | 3018 |
| 3015 __ mov(LoadDescriptor::NameRegister(), Operand(instr->name())); | 3019 __ mov(LoadDescriptor::NameRegister(), Operand(instr->name())); |
| (...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3977 | 3981 |
| 3978 | 3982 |
| 3979 void LCodeGen::DoTailCallThroughMegamorphicCache( | 3983 void LCodeGen::DoTailCallThroughMegamorphicCache( |
| 3980 LTailCallThroughMegamorphicCache* instr) { | 3984 LTailCallThroughMegamorphicCache* instr) { |
| 3981 Register receiver = ToRegister(instr->receiver()); | 3985 Register receiver = ToRegister(instr->receiver()); |
| 3982 Register name = ToRegister(instr->name()); | 3986 Register name = ToRegister(instr->name()); |
| 3983 DCHECK(receiver.is(LoadDescriptor::ReceiverRegister())); | 3987 DCHECK(receiver.is(LoadDescriptor::ReceiverRegister())); |
| 3984 DCHECK(name.is(LoadDescriptor::NameRegister())); | 3988 DCHECK(name.is(LoadDescriptor::NameRegister())); |
| 3985 DCHECK(receiver.is(r1)); | 3989 DCHECK(receiver.is(r1)); |
| 3986 DCHECK(name.is(r2)); | 3990 DCHECK(name.is(r2)); |
| 3991 Register scratch = r4; |
| 3992 Register extra = r5; |
| 3993 Register extra2 = r6; |
| 3994 Register extra3 = r9; |
| 3987 | 3995 |
| 3988 Register scratch = r3; | 3996 #ifdef DEBUG |
| 3989 Register extra = r4; | 3997 Register slot = FLAG_vector_ics ? ToRegister(instr->slot()) : no_reg; |
| 3990 Register extra2 = r5; | 3998 Register vector = FLAG_vector_ics ? ToRegister(instr->vector()) : no_reg; |
| 3991 Register extra3 = r6; | 3999 DCHECK(!FLAG_vector_ics || |
| 4000 !AreAliased(slot, vector, scratch, extra, extra2, extra3)); |
| 4001 #endif |
| 3992 | 4002 |
| 3993 // Important for the tail-call. | 4003 // Important for the tail-call. |
| 3994 bool must_teardown_frame = NeedsEagerFrame(); | 4004 bool must_teardown_frame = NeedsEagerFrame(); |
| 3995 | 4005 |
| 3996 // The probe will tail call to a handler if found. | 4006 if (!instr->hydrogen()->is_just_miss()) { |
| 3997 isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(), | 4007 DCHECK(!instr->hydrogen()->is_keyed_load()); |
| 3998 must_teardown_frame, receiver, name, | 4008 |
| 3999 scratch, extra, extra2, extra3); | 4009 // The probe will tail call to a handler if found. |
| 4010 isolate()->stub_cache()->GenerateProbe( |
| 4011 masm(), Code::LOAD_IC, instr->hydrogen()->flags(), must_teardown_frame, |
| 4012 receiver, name, scratch, extra, extra2, extra3); |
| 4013 } |
| 4000 | 4014 |
| 4001 // Tail call to miss if we ended up here. | 4015 // Tail call to miss if we ended up here. |
| 4002 if (must_teardown_frame) __ LeaveFrame(StackFrame::INTERNAL); | 4016 if (must_teardown_frame) __ LeaveFrame(StackFrame::INTERNAL); |
| 4003 LoadIC::GenerateMiss(masm()); | 4017 if (instr->hydrogen()->is_keyed_load()) { |
| 4018 KeyedLoadIC::GenerateMiss(masm()); |
| 4019 } else { |
| 4020 LoadIC::GenerateMiss(masm()); |
| 4021 } |
| 4004 } | 4022 } |
| 4005 | 4023 |
| 4006 | 4024 |
| 4007 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { | 4025 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { |
| 4008 DCHECK(ToRegister(instr->result()).is(r0)); | 4026 DCHECK(ToRegister(instr->result()).is(r0)); |
| 4009 | 4027 |
| 4010 LPointerMap* pointers = instr->pointer_map(); | 4028 if (instr->hydrogen()->IsTailCall()) { |
| 4011 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 4029 if (NeedsEagerFrame()) __ LeaveFrame(StackFrame::INTERNAL); |
| 4012 | 4030 |
| 4013 if (instr->target()->IsConstantOperand()) { | 4031 if (instr->target()->IsConstantOperand()) { |
| 4014 LConstantOperand* target = LConstantOperand::cast(instr->target()); | 4032 LConstantOperand* target = LConstantOperand::cast(instr->target()); |
| 4015 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); | 4033 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); |
| 4016 generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET)); | 4034 __ Jump(code, RelocInfo::CODE_TARGET); |
| 4017 PlatformInterfaceDescriptor* call_descriptor = | 4035 } else { |
| 4018 instr->descriptor().platform_specific_descriptor(); | 4036 DCHECK(instr->target()->IsRegister()); |
| 4019 __ Call(code, RelocInfo::CODE_TARGET, TypeFeedbackId::None(), al, | 4037 Register target = ToRegister(instr->target()); |
| 4020 call_descriptor->storage_mode()); | 4038 // Make sure we don't emit any additional entries in the constant pool |
| 4039 // before the call to ensure that the CallCodeSize() calculated the |
| 4040 // correct |
| 4041 // number of instructions for the constant pool load. |
| 4042 { |
| 4043 ConstantPoolUnavailableScope constant_pool_unavailable(masm_); |
| 4044 __ add(target, target, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 4045 } |
| 4046 __ Jump(target); |
| 4047 } |
| 4021 } else { | 4048 } else { |
| 4022 DCHECK(instr->target()->IsRegister()); | 4049 LPointerMap* pointers = instr->pointer_map(); |
| 4023 Register target = ToRegister(instr->target()); | 4050 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
| 4024 generator.BeforeCall(__ CallSize(target)); | 4051 |
| 4025 // Make sure we don't emit any additional entries in the constant pool | 4052 if (instr->target()->IsConstantOperand()) { |
| 4026 // before the call to ensure that the CallCodeSize() calculated the correct | 4053 LConstantOperand* target = LConstantOperand::cast(instr->target()); |
| 4027 // number of instructions for the constant pool load. | 4054 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); |
| 4028 { | 4055 generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET)); |
| 4029 ConstantPoolUnavailableScope constant_pool_unavailable(masm_); | 4056 PlatformInterfaceDescriptor* call_descriptor = |
| 4030 __ add(target, target, Operand(Code::kHeaderSize - kHeapObjectTag)); | 4057 instr->descriptor().platform_specific_descriptor(); |
| 4058 __ Call(code, RelocInfo::CODE_TARGET, TypeFeedbackId::None(), al, |
| 4059 call_descriptor->storage_mode()); |
| 4060 } else { |
| 4061 DCHECK(instr->target()->IsRegister()); |
| 4062 Register target = ToRegister(instr->target()); |
| 4063 generator.BeforeCall(__ CallSize(target)); |
| 4064 // Make sure we don't emit any additional entries in the constant pool |
| 4065 // before the call to ensure that the CallCodeSize() calculated the |
| 4066 // correct |
| 4067 // number of instructions for the constant pool load. |
| 4068 { |
| 4069 ConstantPoolUnavailableScope constant_pool_unavailable(masm_); |
| 4070 __ add(target, target, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 4071 } |
| 4072 __ Call(target); |
| 4031 } | 4073 } |
| 4032 __ Call(target); | 4074 generator.AfterCall(); |
| 4033 } | 4075 } |
| 4034 generator.AfterCall(); | |
| 4035 } | 4076 } |
| 4036 | 4077 |
| 4037 | 4078 |
| 4038 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) { | 4079 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) { |
| 4039 DCHECK(ToRegister(instr->function()).is(r1)); | 4080 DCHECK(ToRegister(instr->function()).is(r1)); |
| 4040 DCHECK(ToRegister(instr->result()).is(r0)); | 4081 DCHECK(ToRegister(instr->result()).is(r0)); |
| 4041 | 4082 |
| 4042 if (instr->hydrogen()->pass_argument_count()) { | 4083 if (instr->hydrogen()->pass_argument_count()) { |
| 4043 __ mov(r0, Operand(instr->arity())); | 4084 __ mov(r0, Operand(instr->arity())); |
| 4044 } | 4085 } |
| (...skipping 1862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5907 __ Push(scope_info); | 5948 __ Push(scope_info); |
| 5908 __ push(ToRegister(instr->function())); | 5949 __ push(ToRegister(instr->function())); |
| 5909 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 5950 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
| 5910 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5951 RecordSafepoint(Safepoint::kNoLazyDeopt); |
| 5911 } | 5952 } |
| 5912 | 5953 |
| 5913 | 5954 |
| 5914 #undef __ | 5955 #undef __ |
| 5915 | 5956 |
| 5916 } } // namespace v8::internal | 5957 } } // namespace v8::internal |
| OLD | NEW |