| 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_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
| 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 2850 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2861 | 2861 |
| 2862 EmitReturn(instr, false); | 2862 EmitReturn(instr, false); |
| 2863 if (no_frame_start != -1) { | 2863 if (no_frame_start != -1) { |
| 2864 info()->AddNoFrameRange(no_frame_start, masm_->pc_offset()); | 2864 info()->AddNoFrameRange(no_frame_start, masm_->pc_offset()); |
| 2865 } | 2865 } |
| 2866 } | 2866 } |
| 2867 | 2867 |
| 2868 | 2868 |
| 2869 template <class T> | 2869 template <class T> |
| 2870 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { | 2870 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { |
| 2871 DCHECK(FLAG_vector_ics); | |
| 2872 Register vector_register = ToRegister(instr->temp_vector()); | 2871 Register vector_register = ToRegister(instr->temp_vector()); |
| 2873 Register slot_register = VectorLoadICDescriptor::SlotRegister(); | 2872 Register slot_register = VectorLoadICDescriptor::SlotRegister(); |
| 2874 DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister())); | 2873 DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister())); |
| 2875 DCHECK(slot_register.is(eax)); | 2874 DCHECK(slot_register.is(eax)); |
| 2876 | 2875 |
| 2877 AllowDeferredHandleDereference vector_structure_check; | 2876 AllowDeferredHandleDereference vector_structure_check; |
| 2878 Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector(); | 2877 Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector(); |
| 2879 __ mov(vector_register, vector); | 2878 __ mov(vector_register, vector); |
| 2880 // No need to allocate this register. | 2879 // No need to allocate this register. |
| 2881 FeedbackVectorICSlot slot = instr->hydrogen()->slot(); | 2880 FeedbackVectorICSlot slot = instr->hydrogen()->slot(); |
| 2882 int index = vector->GetIndex(slot); | 2881 int index = vector->GetIndex(slot); |
| 2883 __ mov(slot_register, Immediate(Smi::FromInt(index))); | 2882 __ mov(slot_register, Immediate(Smi::FromInt(index))); |
| 2884 } | 2883 } |
| 2885 | 2884 |
| 2886 | 2885 |
| 2887 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { | 2886 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { |
| 2888 DCHECK(ToRegister(instr->context()).is(esi)); | 2887 DCHECK(ToRegister(instr->context()).is(esi)); |
| 2889 DCHECK(ToRegister(instr->global_object()) | 2888 DCHECK(ToRegister(instr->global_object()) |
| 2890 .is(LoadDescriptor::ReceiverRegister())); | 2889 .is(LoadDescriptor::ReceiverRegister())); |
| 2891 DCHECK(ToRegister(instr->result()).is(eax)); | 2890 DCHECK(ToRegister(instr->result()).is(eax)); |
| 2892 | 2891 |
| 2893 __ mov(LoadDescriptor::NameRegister(), instr->name()); | 2892 __ mov(LoadDescriptor::NameRegister(), instr->name()); |
| 2894 if (FLAG_vector_ics) { | 2893 EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr); |
| 2895 EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr); | |
| 2896 } | |
| 2897 ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; | 2894 ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; |
| 2898 Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, | 2895 Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, |
| 2899 PREMONOMORPHIC).code(); | 2896 PREMONOMORPHIC).code(); |
| 2900 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 2897 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 2901 } | 2898 } |
| 2902 | 2899 |
| 2903 | 2900 |
| 2904 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { | 2901 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { |
| 2905 Register context = ToRegister(instr->context()); | 2902 Register context = ToRegister(instr->context()); |
| 2906 Register result = ToRegister(instr->result()); | 2903 Register result = ToRegister(instr->result()); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3003 } | 3000 } |
| 3004 } | 3001 } |
| 3005 | 3002 |
| 3006 | 3003 |
| 3007 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { | 3004 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { |
| 3008 DCHECK(ToRegister(instr->context()).is(esi)); | 3005 DCHECK(ToRegister(instr->context()).is(esi)); |
| 3009 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister())); | 3006 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister())); |
| 3010 DCHECK(ToRegister(instr->result()).is(eax)); | 3007 DCHECK(ToRegister(instr->result()).is(eax)); |
| 3011 | 3008 |
| 3012 __ mov(LoadDescriptor::NameRegister(), instr->name()); | 3009 __ mov(LoadDescriptor::NameRegister(), instr->name()); |
| 3013 if (FLAG_vector_ics) { | 3010 EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr); |
| 3014 EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr); | |
| 3015 } | |
| 3016 Handle<Code> ic = CodeFactory::LoadICInOptimizedCode( | 3011 Handle<Code> ic = CodeFactory::LoadICInOptimizedCode( |
| 3017 isolate(), NOT_CONTEXTUAL, | 3012 isolate(), NOT_CONTEXTUAL, |
| 3018 instr->hydrogen()->initialization_state()).code(); | 3013 instr->hydrogen()->initialization_state()).code(); |
| 3019 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3014 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 3020 } | 3015 } |
| 3021 | 3016 |
| 3022 | 3017 |
| 3023 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { | 3018 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { |
| 3024 Register function = ToRegister(instr->function()); | 3019 Register function = ToRegister(instr->function()); |
| 3025 Register temp = ToRegister(instr->temp()); | 3020 Register temp = ToRegister(instr->temp()); |
| (...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3478 LPointerMap* pointers = instr->pointer_map(); | 3473 LPointerMap* pointers = instr->pointer_map(); |
| 3479 SafepointGenerator generator( | 3474 SafepointGenerator generator( |
| 3480 this, pointers, Safepoint::kLazyDeopt); | 3475 this, pointers, Safepoint::kLazyDeopt); |
| 3481 ParameterCount count(arity); | 3476 ParameterCount count(arity); |
| 3482 ParameterCount expected(formal_parameter_count); | 3477 ParameterCount expected(formal_parameter_count); |
| 3483 __ InvokeFunction(function_reg, expected, count, CALL_FUNCTION, generator); | 3478 __ InvokeFunction(function_reg, expected, count, CALL_FUNCTION, generator); |
| 3484 } | 3479 } |
| 3485 } | 3480 } |
| 3486 | 3481 |
| 3487 | 3482 |
| 3488 void LCodeGen::DoTailCallThroughMegamorphicCache( | |
| 3489 LTailCallThroughMegamorphicCache* instr) { | |
| 3490 Register receiver = ToRegister(instr->receiver()); | |
| 3491 Register name = ToRegister(instr->name()); | |
| 3492 DCHECK(receiver.is(LoadDescriptor::ReceiverRegister())); | |
| 3493 DCHECK(name.is(LoadDescriptor::NameRegister())); | |
| 3494 Register scratch = ebx; | |
| 3495 Register extra = edi; | |
| 3496 DCHECK(!scratch.is(receiver) && !scratch.is(name)); | |
| 3497 DCHECK(!extra.is(receiver) && !extra.is(name)); | |
| 3498 | |
| 3499 // The probe will tail call to a handler if found. | |
| 3500 // If --vector-ics is on, then it knows to pop the two args first. | |
| 3501 isolate()->stub_cache()->GenerateProbe(masm(), Code::LOAD_IC, | |
| 3502 instr->hydrogen()->flags(), false, | |
| 3503 receiver, name, scratch, extra); | |
| 3504 | |
| 3505 LoadIC::GenerateMiss(masm()); | |
| 3506 } | |
| 3507 | |
| 3508 | |
| 3509 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { | 3483 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { |
| 3510 DCHECK(ToRegister(instr->result()).is(eax)); | 3484 DCHECK(ToRegister(instr->result()).is(eax)); |
| 3511 | 3485 |
| 3512 if (instr->hydrogen()->IsTailCall()) { | 3486 if (instr->hydrogen()->IsTailCall()) { |
| 3513 if (NeedsEagerFrame()) __ leave(); | 3487 if (NeedsEagerFrame()) __ leave(); |
| 3514 | 3488 |
| 3515 if (instr->target()->IsConstantOperand()) { | 3489 if (instr->target()->IsConstantOperand()) { |
| 3516 LConstantOperand* target = LConstantOperand::cast(instr->target()); | 3490 LConstantOperand* target = LConstantOperand::cast(instr->target()); |
| 3517 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); | 3491 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); |
| 3518 __ jmp(code, RelocInfo::CODE_TARGET); | 3492 __ jmp(code, RelocInfo::CODE_TARGET); |
| (...skipping 2345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5864 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 5838 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
| 5865 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5839 RecordSafepoint(Safepoint::kNoLazyDeopt); |
| 5866 } | 5840 } |
| 5867 | 5841 |
| 5868 | 5842 |
| 5869 #undef __ | 5843 #undef __ |
| 5870 | 5844 |
| 5871 } } // namespace v8::internal | 5845 } } // namespace v8::internal |
| 5872 | 5846 |
| 5873 #endif // V8_TARGET_ARCH_IA32 | 5847 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |