OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 bool LCodeGen::GeneratePrologue() { | 121 bool LCodeGen::GeneratePrologue() { |
122 ASSERT(is_generating()); | 122 ASSERT(is_generating()); |
123 | 123 |
124 #ifdef DEBUG | 124 #ifdef DEBUG |
125 if (strlen(FLAG_stop_at) > 0 && | 125 if (strlen(FLAG_stop_at) > 0 && |
126 info_->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { | 126 info_->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { |
127 __ int3(); | 127 __ int3(); |
128 } | 128 } |
129 #endif | 129 #endif |
130 | 130 |
| 131 // Strict mode functions need to replace the receiver with undefined |
| 132 // when called as functions (without an explicit receiver |
| 133 // object). ecx is zero for method calls and non-zero for function |
| 134 // calls. |
| 135 if (info_->is_strict_mode()) { |
| 136 Label ok; |
| 137 __ test(ecx, Operand(ecx)); |
| 138 __ j(zero, &ok, Label::kNear); |
| 139 // +1 for return address. |
| 140 int receiver_offset = (scope()->num_parameters() + 1) * kPointerSize; |
| 141 __ mov(Operand(esp, receiver_offset), |
| 142 Immediate(isolate()->factory()->undefined_value())); |
| 143 __ bind(&ok); |
| 144 } |
| 145 |
131 __ push(ebp); // Caller's frame pointer. | 146 __ push(ebp); // Caller's frame pointer. |
132 __ mov(ebp, esp); | 147 __ mov(ebp, esp); |
133 __ push(esi); // Callee's context. | 148 __ push(esi); // Callee's context. |
134 __ push(edi); // Callee's JS function. | 149 __ push(edi); // Callee's JS function. |
135 | 150 |
136 // Reserve space for the stack slots needed by the code. | 151 // Reserve space for the stack slots needed by the code. |
137 int slots = GetStackSlotCount(); | 152 int slots = GetStackSlotCount(); |
138 if (slots > 0) { | 153 if (slots > 0) { |
139 if (FLAG_debug_code) { | 154 if (FLAG_debug_code) { |
140 __ mov(Operand(eax), Immediate(slots)); | 155 __ mov(Operand(eax), Immediate(slots)); |
(...skipping 2537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2678 | 2693 |
2679 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { | 2694 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { |
2680 Register global = ToRegister(instr->global()); | 2695 Register global = ToRegister(instr->global()); |
2681 Register result = ToRegister(instr->result()); | 2696 Register result = ToRegister(instr->result()); |
2682 __ mov(result, FieldOperand(global, GlobalObject::kGlobalReceiverOffset)); | 2697 __ mov(result, FieldOperand(global, GlobalObject::kGlobalReceiverOffset)); |
2683 } | 2698 } |
2684 | 2699 |
2685 | 2700 |
2686 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, | 2701 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
2687 int arity, | 2702 int arity, |
2688 LInstruction* instr) { | 2703 LInstruction* instr, |
| 2704 CallKind call_kind) { |
2689 // Change context if needed. | 2705 // Change context if needed. |
2690 bool change_context = | 2706 bool change_context = |
2691 (info()->closure()->context() != function->context()) || | 2707 (info()->closure()->context() != function->context()) || |
2692 scope()->contains_with() || | 2708 scope()->contains_with() || |
2693 (scope()->num_heap_slots() > 0); | 2709 (scope()->num_heap_slots() > 0); |
2694 if (change_context) { | 2710 if (change_context) { |
2695 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 2711 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
2696 } else { | 2712 } else { |
2697 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2713 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
2698 } | 2714 } |
2699 | 2715 |
2700 // Set eax to arguments count if adaption is not needed. Assumes that eax | 2716 // Set eax to arguments count if adaption is not needed. Assumes that eax |
2701 // is available to write to at this point. | 2717 // is available to write to at this point. |
2702 if (!function->NeedsArgumentsAdaption()) { | 2718 if (!function->NeedsArgumentsAdaption()) { |
2703 __ mov(eax, arity); | 2719 __ mov(eax, arity); |
2704 } | 2720 } |
2705 | 2721 |
2706 LPointerMap* pointers = instr->pointer_map(); | 2722 LPointerMap* pointers = instr->pointer_map(); |
2707 RecordPosition(pointers->position()); | 2723 RecordPosition(pointers->position()); |
2708 | 2724 |
2709 // Invoke function. | 2725 // Invoke function. |
| 2726 __ SetCallKind(ecx, call_kind); |
2710 if (*function == *info()->closure()) { | 2727 if (*function == *info()->closure()) { |
2711 __ CallSelf(); | 2728 __ CallSelf(); |
2712 } else { | 2729 } else { |
2713 __ call(FieldOperand(edi, JSFunction::kCodeEntryOffset)); | 2730 __ call(FieldOperand(edi, JSFunction::kCodeEntryOffset)); |
2714 } | 2731 } |
2715 | 2732 |
2716 // Setup deoptimization. | 2733 // Setup deoptimization. |
2717 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT); | 2734 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT); |
2718 } | 2735 } |
2719 | 2736 |
2720 | 2737 |
2721 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 2738 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
2722 ASSERT(ToRegister(instr->result()).is(eax)); | 2739 ASSERT(ToRegister(instr->result()).is(eax)); |
2723 __ mov(edi, instr->function()); | 2740 __ mov(edi, instr->function()); |
2724 CallKnownFunction(instr->function(), instr->arity(), instr); | 2741 CallKnownFunction(instr->function(), |
| 2742 instr->arity(), |
| 2743 instr, |
| 2744 CALL_AS_METHOD); |
2725 } | 2745 } |
2726 | 2746 |
2727 | 2747 |
2728 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 2748 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { |
2729 Register input_reg = ToRegister(instr->InputAt(0)); | 2749 Register input_reg = ToRegister(instr->InputAt(0)); |
2730 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), | 2750 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), |
2731 factory()->heap_number_map()); | 2751 factory()->heap_number_map()); |
2732 DeoptimizeIf(not_equal, instr->environment()); | 2752 DeoptimizeIf(not_equal, instr->environment()); |
2733 | 2753 |
2734 Label done; | 2754 Label done; |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3077 ComputeKeyedCallInitialize(arity, NOT_IN_LOOP); | 3097 ComputeKeyedCallInitialize(arity, NOT_IN_LOOP); |
3078 CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 3098 CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); |
3079 } | 3099 } |
3080 | 3100 |
3081 | 3101 |
3082 void LCodeGen::DoCallNamed(LCallNamed* instr) { | 3102 void LCodeGen::DoCallNamed(LCallNamed* instr) { |
3083 ASSERT(ToRegister(instr->context()).is(esi)); | 3103 ASSERT(ToRegister(instr->context()).is(esi)); |
3084 ASSERT(ToRegister(instr->result()).is(eax)); | 3104 ASSERT(ToRegister(instr->result()).is(eax)); |
3085 | 3105 |
3086 int arity = instr->arity(); | 3106 int arity = instr->arity(); |
3087 Handle<Code> ic = isolate()->stub_cache()-> | 3107 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; |
3088 ComputeCallInitialize(arity, NOT_IN_LOOP); | 3108 Handle<Code> ic = |
| 3109 isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); |
3089 __ mov(ecx, instr->name()); | 3110 __ mov(ecx, instr->name()); |
3090 CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 3111 CallCode(ic, mode, instr, CONTEXT_ADJUSTED); |
3091 } | 3112 } |
3092 | 3113 |
3093 | 3114 |
3094 void LCodeGen::DoCallFunction(LCallFunction* instr) { | 3115 void LCodeGen::DoCallFunction(LCallFunction* instr) { |
3095 ASSERT(ToRegister(instr->context()).is(esi)); | 3116 ASSERT(ToRegister(instr->context()).is(esi)); |
3096 ASSERT(ToRegister(instr->result()).is(eax)); | 3117 ASSERT(ToRegister(instr->result()).is(eax)); |
3097 | 3118 |
3098 int arity = instr->arity(); | 3119 int arity = instr->arity(); |
3099 CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_VALUE); | 3120 CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_IMPLICIT); |
3100 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 3121 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); |
3101 __ Drop(1); | 3122 __ Drop(1); |
3102 } | 3123 } |
3103 | 3124 |
3104 | 3125 |
3105 void LCodeGen::DoCallGlobal(LCallGlobal* instr) { | 3126 void LCodeGen::DoCallGlobal(LCallGlobal* instr) { |
3106 ASSERT(ToRegister(instr->context()).is(esi)); | 3127 ASSERT(ToRegister(instr->context()).is(esi)); |
3107 ASSERT(ToRegister(instr->result()).is(eax)); | 3128 ASSERT(ToRegister(instr->result()).is(eax)); |
3108 | 3129 |
3109 int arity = instr->arity(); | 3130 int arity = instr->arity(); |
3110 Handle<Code> ic = isolate()->stub_cache()-> | 3131 RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT; |
3111 ComputeCallInitialize(arity, NOT_IN_LOOP); | 3132 Handle<Code> ic = |
| 3133 isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); |
3112 __ mov(ecx, instr->name()); | 3134 __ mov(ecx, instr->name()); |
3113 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr, CONTEXT_ADJUSTED); | 3135 CallCode(ic, mode, instr, CONTEXT_ADJUSTED); |
3114 } | 3136 } |
3115 | 3137 |
3116 | 3138 |
3117 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { | 3139 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { |
3118 ASSERT(ToRegister(instr->result()).is(eax)); | 3140 ASSERT(ToRegister(instr->result()).is(eax)); |
3119 __ mov(edi, instr->target()); | 3141 __ mov(edi, instr->target()); |
3120 CallKnownFunction(instr->target(), instr->arity(), instr); | 3142 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); |
3121 } | 3143 } |
3122 | 3144 |
3123 | 3145 |
3124 void LCodeGen::DoCallNew(LCallNew* instr) { | 3146 void LCodeGen::DoCallNew(LCallNew* instr) { |
3125 ASSERT(ToRegister(instr->context()).is(esi)); | 3147 ASSERT(ToRegister(instr->context()).is(esi)); |
3126 ASSERT(ToRegister(instr->constructor()).is(edi)); | 3148 ASSERT(ToRegister(instr->constructor()).is(edi)); |
3127 ASSERT(ToRegister(instr->result()).is(eax)); | 3149 ASSERT(ToRegister(instr->result()).is(eax)); |
3128 | 3150 |
3129 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); | 3151 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); |
3130 __ Set(eax, Immediate(instr->arity())); | 3152 __ Set(eax, Immediate(instr->arity())); |
(...skipping 1299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4430 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 4452 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
4431 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); | 4453 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); |
4432 } | 4454 } |
4433 | 4455 |
4434 | 4456 |
4435 #undef __ | 4457 #undef __ |
4436 | 4458 |
4437 } } // namespace v8::internal | 4459 } } // namespace v8::internal |
4438 | 4460 |
4439 #endif // V8_TARGET_ARCH_IA32 | 4461 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |