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 960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3976 | 3980 |
3977 | 3981 |
3978 void LCodeGen::DoTailCallThroughMegamorphicCache( | 3982 void LCodeGen::DoTailCallThroughMegamorphicCache( |
3979 LTailCallThroughMegamorphicCache* instr) { | 3983 LTailCallThroughMegamorphicCache* instr) { |
3980 Register receiver = ToRegister(instr->receiver()); | 3984 Register receiver = ToRegister(instr->receiver()); |
3981 Register name = ToRegister(instr->name()); | 3985 Register name = ToRegister(instr->name()); |
3982 DCHECK(receiver.is(LoadDescriptor::ReceiverRegister())); | 3986 DCHECK(receiver.is(LoadDescriptor::ReceiverRegister())); |
3983 DCHECK(name.is(LoadDescriptor::NameRegister())); | 3987 DCHECK(name.is(LoadDescriptor::NameRegister())); |
3984 DCHECK(receiver.is(r1)); | 3988 DCHECK(receiver.is(r1)); |
3985 DCHECK(name.is(r2)); | 3989 DCHECK(name.is(r2)); |
3986 | 3990 Register slot = FLAG_vector_ics ? ToRegister(instr->slot()) : no_reg; |
3987 Register scratch = r3; | 3991 Register vector = FLAG_vector_ics ? ToRegister(instr->vector()) : no_reg; |
3988 Register extra = r4; | 3992 Register scratch = r4; |
3989 Register extra2 = r5; | 3993 Register extra = r5; |
3990 Register extra3 = r6; | 3994 Register extra2 = r6; |
3995 Register extra3 = r9; | |
3996 DCHECK(!FLAG_vector_ics || | |
3997 !AreAliased(slot, vector, scratch, extra, extra2, extra3)); | |
3991 | 3998 |
3992 // Important for the tail-call. | 3999 // Important for the tail-call. |
3993 bool must_teardown_frame = NeedsEagerFrame(); | 4000 bool must_teardown_frame = NeedsEagerFrame(); |
3994 | 4001 |
3995 // The probe will tail call to a handler if found. | 4002 if (!instr->hydrogen()->is_just_miss()) { |
3996 isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(), | 4003 DCHECK(!instr->hydrogen()->is_keyed_load()); |
3997 must_teardown_frame, receiver, name, | 4004 |
3998 scratch, extra, extra2, extra3); | 4005 // The probe will tail call to a handler if found. |
4006 isolate()->stub_cache()->GenerateProbe( | |
4007 masm(), Code::LOAD_IC, instr->hydrogen()->flags(), must_teardown_frame, | |
4008 receiver, name, scratch, extra, extra2, extra3); | |
4009 } | |
3999 | 4010 |
4000 // Tail call to miss if we ended up here. | 4011 // Tail call to miss if we ended up here. |
4001 if (must_teardown_frame) __ LeaveFrame(StackFrame::INTERNAL); | 4012 if (must_teardown_frame) __ LeaveFrame(StackFrame::INTERNAL); |
4002 LoadIC::GenerateMiss(masm()); | 4013 if (instr->hydrogen()->is_keyed_load()) { |
4014 KeyedLoadIC::GenerateMiss(masm()); | |
4015 } else { | |
4016 LoadIC::GenerateMiss(masm()); | |
4017 } | |
4003 } | 4018 } |
4004 | 4019 |
4005 | 4020 |
4006 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { | 4021 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { |
4007 DCHECK(ToRegister(instr->result()).is(r0)); | 4022 DCHECK(ToRegister(instr->result()).is(r0)); |
4008 | 4023 |
4009 LPointerMap* pointers = instr->pointer_map(); | 4024 if (instr->hydrogen()->IsTailCall()) { |
4010 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 4025 if (NeedsEagerFrame()) __ LeaveFrame(StackFrame::INTERNAL); |
4011 | 4026 |
4012 if (instr->target()->IsConstantOperand()) { | 4027 if (instr->target()->IsConstantOperand()) { |
4013 LConstantOperand* target = LConstantOperand::cast(instr->target()); | 4028 LConstantOperand* target = LConstantOperand::cast(instr->target()); |
4014 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); | 4029 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); |
4015 generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET)); | 4030 __ Jump(code, RelocInfo::CODE_TARGET); |
4016 PlatformInterfaceDescriptor* call_descriptor = | 4031 } else { |
4017 instr->descriptor().platform_specific_descriptor(); | 4032 DCHECK(instr->target()->IsRegister()); |
4018 __ Call(code, RelocInfo::CODE_TARGET, TypeFeedbackId::None(), al, | 4033 Register target = ToRegister(instr->target()); |
4019 call_descriptor->storage_mode()); | 4034 // Make sure we don't emit any additional entries in the constant pool |
4035 // before the call to ensure that the CallCodeSize() calculated the | |
4036 // correct | |
4037 // number of instructions for the constant pool load. | |
Jakob Kummerow
2014/12/09 16:59:27
nit: join this into the previous line (again below
| |
4038 { | |
4039 ConstantPoolUnavailableScope constant_pool_unavailable(masm_); | |
4040 __ add(target, target, Operand(Code::kHeaderSize - kHeapObjectTag)); | |
4041 } | |
4042 __ Jump(target); | |
4043 } | |
4020 } else { | 4044 } else { |
4021 DCHECK(instr->target()->IsRegister()); | 4045 LPointerMap* pointers = instr->pointer_map(); |
4022 Register target = ToRegister(instr->target()); | 4046 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
4023 generator.BeforeCall(__ CallSize(target)); | 4047 |
4024 // Make sure we don't emit any additional entries in the constant pool | 4048 if (instr->target()->IsConstantOperand()) { |
4025 // before the call to ensure that the CallCodeSize() calculated the correct | 4049 LConstantOperand* target = LConstantOperand::cast(instr->target()); |
4026 // number of instructions for the constant pool load. | 4050 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); |
4027 { | 4051 generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET)); |
4028 ConstantPoolUnavailableScope constant_pool_unavailable(masm_); | 4052 PlatformInterfaceDescriptor* call_descriptor = |
4029 __ add(target, target, Operand(Code::kHeaderSize - kHeapObjectTag)); | 4053 instr->descriptor().platform_specific_descriptor(); |
4054 __ Call(code, RelocInfo::CODE_TARGET, TypeFeedbackId::None(), al, | |
4055 call_descriptor->storage_mode()); | |
4056 } else { | |
4057 DCHECK(instr->target()->IsRegister()); | |
4058 Register target = ToRegister(instr->target()); | |
4059 generator.BeforeCall(__ CallSize(target)); | |
4060 // Make sure we don't emit any additional entries in the constant pool | |
4061 // before the call to ensure that the CallCodeSize() calculated the | |
4062 // correct | |
4063 // number of instructions for the constant pool load. | |
4064 { | |
4065 ConstantPoolUnavailableScope constant_pool_unavailable(masm_); | |
4066 __ add(target, target, Operand(Code::kHeaderSize - kHeapObjectTag)); | |
4067 } | |
4068 __ Call(target); | |
4030 } | 4069 } |
4031 __ Call(target); | 4070 generator.AfterCall(); |
4032 } | 4071 } |
4033 generator.AfterCall(); | |
4034 } | 4072 } |
4035 | 4073 |
4036 | 4074 |
4037 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) { | 4075 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) { |
4038 DCHECK(ToRegister(instr->function()).is(r1)); | 4076 DCHECK(ToRegister(instr->function()).is(r1)); |
4039 DCHECK(ToRegister(instr->result()).is(r0)); | 4077 DCHECK(ToRegister(instr->result()).is(r0)); |
4040 | 4078 |
4041 if (instr->hydrogen()->pass_argument_count()) { | 4079 if (instr->hydrogen()->pass_argument_count()) { |
4042 __ mov(r0, Operand(instr->arity())); | 4080 __ mov(r0, Operand(instr->arity())); |
4043 } | 4081 } |
(...skipping 1862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5906 __ Push(scope_info); | 5944 __ Push(scope_info); |
5907 __ push(ToRegister(instr->function())); | 5945 __ push(ToRegister(instr->function())); |
5908 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 5946 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
5909 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5947 RecordSafepoint(Safepoint::kNoLazyDeopt); |
5910 } | 5948 } |
5911 | 5949 |
5912 | 5950 |
5913 #undef __ | 5951 #undef __ |
5914 | 5952 |
5915 } } // namespace v8::internal | 5953 } } // namespace v8::internal |
OLD | NEW |