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