| 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/cpu-profiler.h" | 9 #include "src/cpu-profiler.h" |
| 10 #include "src/hydrogen-osr.h" | 10 #include "src/hydrogen-osr.h" |
| (...skipping 2888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2899 __ Jump(ra); | 2899 __ Jump(ra); |
| 2900 | 2900 |
| 2901 if (no_frame_start != -1) { | 2901 if (no_frame_start != -1) { |
| 2902 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); | 2902 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); |
| 2903 } | 2903 } |
| 2904 } | 2904 } |
| 2905 | 2905 |
| 2906 | 2906 |
| 2907 template <class T> | 2907 template <class T> |
| 2908 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { | 2908 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { |
| 2909 DCHECK(FLAG_vector_ics); | |
| 2910 Register vector_register = ToRegister(instr->temp_vector()); | 2909 Register vector_register = ToRegister(instr->temp_vector()); |
| 2911 Register slot_register = VectorLoadICDescriptor::SlotRegister(); | 2910 Register slot_register = VectorLoadICDescriptor::SlotRegister(); |
| 2912 DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister())); | 2911 DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister())); |
| 2913 DCHECK(slot_register.is(a0)); | 2912 DCHECK(slot_register.is(a0)); |
| 2914 | 2913 |
| 2915 AllowDeferredHandleDereference vector_structure_check; | 2914 AllowDeferredHandleDereference vector_structure_check; |
| 2916 Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector(); | 2915 Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector(); |
| 2917 __ li(vector_register, vector); | 2916 __ li(vector_register, vector); |
| 2918 // No need to allocate this register. | 2917 // No need to allocate this register. |
| 2919 FeedbackVectorICSlot slot = instr->hydrogen()->slot(); | 2918 FeedbackVectorICSlot slot = instr->hydrogen()->slot(); |
| 2920 int index = vector->GetIndex(slot); | 2919 int index = vector->GetIndex(slot); |
| 2921 __ li(slot_register, Operand(Smi::FromInt(index))); | 2920 __ li(slot_register, Operand(Smi::FromInt(index))); |
| 2922 } | 2921 } |
| 2923 | 2922 |
| 2924 | 2923 |
| 2925 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { | 2924 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { |
| 2926 DCHECK(ToRegister(instr->context()).is(cp)); | 2925 DCHECK(ToRegister(instr->context()).is(cp)); |
| 2927 DCHECK(ToRegister(instr->global_object()) | 2926 DCHECK(ToRegister(instr->global_object()) |
| 2928 .is(LoadDescriptor::ReceiverRegister())); | 2927 .is(LoadDescriptor::ReceiverRegister())); |
| 2929 DCHECK(ToRegister(instr->result()).is(v0)); | 2928 DCHECK(ToRegister(instr->result()).is(v0)); |
| 2930 | 2929 |
| 2931 __ li(LoadDescriptor::NameRegister(), Operand(instr->name())); | 2930 __ li(LoadDescriptor::NameRegister(), Operand(instr->name())); |
| 2932 if (FLAG_vector_ics) { | 2931 EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr); |
| 2933 EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr); | |
| 2934 } | |
| 2935 ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; | 2932 ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; |
| 2936 Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, | 2933 Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, |
| 2937 PREMONOMORPHIC).code(); | 2934 PREMONOMORPHIC).code(); |
| 2938 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 2935 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 2939 } | 2936 } |
| 2940 | 2937 |
| 2941 | 2938 |
| 2942 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { | 2939 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { |
| 2943 Register context = ToRegister(instr->context()); | 2940 Register context = ToRegister(instr->context()); |
| 2944 Register result = ToRegister(instr->result()); | 2941 Register result = ToRegister(instr->result()); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3040 } | 3037 } |
| 3041 | 3038 |
| 3042 | 3039 |
| 3043 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { | 3040 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { |
| 3044 DCHECK(ToRegister(instr->context()).is(cp)); | 3041 DCHECK(ToRegister(instr->context()).is(cp)); |
| 3045 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister())); | 3042 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister())); |
| 3046 DCHECK(ToRegister(instr->result()).is(v0)); | 3043 DCHECK(ToRegister(instr->result()).is(v0)); |
| 3047 | 3044 |
| 3048 // Name is always in a2. | 3045 // Name is always in a2. |
| 3049 __ li(LoadDescriptor::NameRegister(), Operand(instr->name())); | 3046 __ li(LoadDescriptor::NameRegister(), Operand(instr->name())); |
| 3050 if (FLAG_vector_ics) { | 3047 EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr); |
| 3051 EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr); | |
| 3052 } | |
| 3053 Handle<Code> ic = CodeFactory::LoadICInOptimizedCode( | 3048 Handle<Code> ic = CodeFactory::LoadICInOptimizedCode( |
| 3054 isolate(), NOT_CONTEXTUAL, | 3049 isolate(), NOT_CONTEXTUAL, |
| 3055 instr->hydrogen()->initialization_state()).code(); | 3050 instr->hydrogen()->initialization_state()).code(); |
| 3056 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3051 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 3057 } | 3052 } |
| 3058 | 3053 |
| 3059 | 3054 |
| 3060 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { | 3055 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { |
| 3061 Register scratch = scratch0(); | 3056 Register scratch = scratch0(); |
| 3062 Register function = ToRegister(instr->function()); | 3057 Register function = ToRegister(instr->function()); |
| (...skipping 945 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4008 ParameterCount count(instr->arity()); | 4003 ParameterCount count(instr->arity()); |
| 4009 __ InvokeFunction(a1, count, CALL_FUNCTION, generator); | 4004 __ InvokeFunction(a1, count, CALL_FUNCTION, generator); |
| 4010 } else { | 4005 } else { |
| 4011 CallKnownFunction(known_function, | 4006 CallKnownFunction(known_function, |
| 4012 instr->hydrogen()->formal_parameter_count(), | 4007 instr->hydrogen()->formal_parameter_count(), |
| 4013 instr->arity(), instr); | 4008 instr->arity(), instr); |
| 4014 } | 4009 } |
| 4015 } | 4010 } |
| 4016 | 4011 |
| 4017 | 4012 |
| 4018 void LCodeGen::DoTailCallThroughMegamorphicCache( | |
| 4019 LTailCallThroughMegamorphicCache* instr) { | |
| 4020 Register receiver = ToRegister(instr->receiver()); | |
| 4021 Register name = ToRegister(instr->name()); | |
| 4022 DCHECK(receiver.is(LoadDescriptor::ReceiverRegister())); | |
| 4023 DCHECK(name.is(LoadDescriptor::NameRegister())); | |
| 4024 DCHECK(receiver.is(a1)); | |
| 4025 DCHECK(name.is(a2)); | |
| 4026 | |
| 4027 Register scratch = a4; | |
| 4028 Register extra = a5; | |
| 4029 Register extra2 = a6; | |
| 4030 Register extra3 = t1; | |
| 4031 | |
| 4032 // The probe will tail call to a handler if found. | |
| 4033 isolate()->stub_cache()->GenerateProbe( | |
| 4034 masm(), Code::LOAD_IC, instr->hydrogen()->flags(), false, receiver, name, | |
| 4035 scratch, extra, extra2, extra3); | |
| 4036 | |
| 4037 // Tail call to miss if we ended up here. | |
| 4038 LoadIC::GenerateMiss(masm()); | |
| 4039 } | |
| 4040 | |
| 4041 | |
| 4042 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { | 4013 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { |
| 4043 DCHECK(ToRegister(instr->result()).is(v0)); | 4014 DCHECK(ToRegister(instr->result()).is(v0)); |
| 4044 | 4015 |
| 4045 if (instr->hydrogen()->IsTailCall()) { | 4016 if (instr->hydrogen()->IsTailCall()) { |
| 4046 if (NeedsEagerFrame()) __ LeaveFrame(StackFrame::INTERNAL); | 4017 if (NeedsEagerFrame()) __ LeaveFrame(StackFrame::INTERNAL); |
| 4047 | 4018 |
| 4048 if (instr->target()->IsConstantOperand()) { | 4019 if (instr->target()->IsConstantOperand()) { |
| 4049 LConstantOperand* target = LConstantOperand::cast(instr->target()); | 4020 LConstantOperand* target = LConstantOperand::cast(instr->target()); |
| 4050 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); | 4021 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); |
| 4051 __ Jump(code, RelocInfo::CODE_TARGET); | 4022 __ Jump(code, RelocInfo::CODE_TARGET); |
| (...skipping 2105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6157 __ li(at, scope_info); | 6128 __ li(at, scope_info); |
| 6158 __ Push(at, ToRegister(instr->function())); | 6129 __ Push(at, ToRegister(instr->function())); |
| 6159 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 6130 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
| 6160 RecordSafepoint(Safepoint::kNoLazyDeopt); | 6131 RecordSafepoint(Safepoint::kNoLazyDeopt); |
| 6161 } | 6132 } |
| 6162 | 6133 |
| 6163 | 6134 |
| 6164 #undef __ | 6135 #undef __ |
| 6165 | 6136 |
| 6166 } } // namespace v8::internal | 6137 } } // namespace v8::internal |
| OLD | NEW |