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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
138 info_->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { | 138 info_->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { |
139 __ stop("stop_at"); | 139 __ stop("stop_at"); |
140 } | 140 } |
141 #endif | 141 #endif |
142 | 142 |
143 // r1: Callee's JS function. | 143 // r1: Callee's JS function. |
144 // cp: Callee's context. | 144 // cp: Callee's context. |
145 // fp: Caller's frame pointer. | 145 // fp: Caller's frame pointer. |
146 // lr: Caller's pc. | 146 // lr: Caller's pc. |
147 | 147 |
148 // Strict mode functions need to replace the receiver with undefined | |
149 // when called as functions (without an explicit receiver | |
150 // object). ecx is zero for method calls and non-zero for function | |
Kevin Millikin (Chromium)
2011/05/24 13:21:36
ecx ==> r5.
Mads Ager (chromium)
2011/05/24 13:57:53
Done.
| |
151 // calls. | |
152 if (info_->is_strict_mode()) { | |
153 Label ok; | |
154 __ cmp(r5, Operand(0)); | |
155 __ b(eq, &ok); | |
156 int receiver_offset = scope()->num_parameters() * kPointerSize; | |
157 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); | |
158 __ str(r2, MemOperand(sp, receiver_offset)); | |
159 __ bind(&ok); | |
160 } | |
161 | |
148 __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit()); | 162 __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit()); |
149 __ add(fp, sp, Operand(2 * kPointerSize)); // Adjust FP to point to saved FP. | 163 __ add(fp, sp, Operand(2 * kPointerSize)); // Adjust FP to point to saved FP. |
150 | 164 |
151 // Reserve space for the stack slots needed by the code. | 165 // Reserve space for the stack slots needed by the code. |
152 int slots = GetStackSlotCount(); | 166 int slots = GetStackSlotCount(); |
153 if (slots > 0) { | 167 if (slots > 0) { |
154 if (FLAG_debug_code) { | 168 if (FLAG_debug_code) { |
155 __ mov(r0, Operand(slots)); | 169 __ mov(r0, Operand(slots)); |
156 __ mov(r2, Operand(kSlotsZapValue)); | 170 __ mov(r2, Operand(kSlotsZapValue)); |
157 Label loop; | 171 Label loop; |
(...skipping 2603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2761 | 2775 |
2762 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { | 2776 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { |
2763 Register global = ToRegister(instr->global()); | 2777 Register global = ToRegister(instr->global()); |
2764 Register result = ToRegister(instr->result()); | 2778 Register result = ToRegister(instr->result()); |
2765 __ ldr(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset)); | 2779 __ ldr(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset)); |
2766 } | 2780 } |
2767 | 2781 |
2768 | 2782 |
2769 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, | 2783 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
2770 int arity, | 2784 int arity, |
2771 LInstruction* instr) { | 2785 LInstruction* instr, |
2786 CallKind call_kind) { | |
2772 // Change context if needed. | 2787 // Change context if needed. |
2773 bool change_context = | 2788 bool change_context = |
2774 (info()->closure()->context() != function->context()) || | 2789 (info()->closure()->context() != function->context()) || |
2775 scope()->contains_with() || | 2790 scope()->contains_with() || |
2776 (scope()->num_heap_slots() > 0); | 2791 (scope()->num_heap_slots() > 0); |
2777 if (change_context) { | 2792 if (change_context) { |
2778 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | 2793 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
2779 } | 2794 } |
2780 | 2795 |
2781 // Set r0 to arguments count if adaption is not needed. Assumes that r0 | 2796 // Set r0 to arguments count if adaption is not needed. Assumes that r0 |
2782 // is available to write to at this point. | 2797 // is available to write to at this point. |
2783 if (!function->NeedsArgumentsAdaption()) { | 2798 if (!function->NeedsArgumentsAdaption()) { |
2784 __ mov(r0, Operand(arity)); | 2799 __ mov(r0, Operand(arity)); |
2785 } | 2800 } |
2786 | 2801 |
2787 LPointerMap* pointers = instr->pointer_map(); | 2802 LPointerMap* pointers = instr->pointer_map(); |
2788 RecordPosition(pointers->position()); | 2803 RecordPosition(pointers->position()); |
2789 | 2804 |
2790 // Invoke function. | 2805 // Invoke function. |
2806 __ SetCallKind(r5, call_kind); | |
2791 __ ldr(ip, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); | 2807 __ ldr(ip, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); |
2792 __ Call(ip); | 2808 __ Call(ip); |
2793 | 2809 |
2794 // Setup deoptimization. | 2810 // Setup deoptimization. |
2795 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT); | 2811 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT); |
2796 | 2812 |
2797 // Restore context. | 2813 // Restore context. |
2798 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2814 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2799 } | 2815 } |
2800 | 2816 |
2801 | 2817 |
2802 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 2818 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
2803 ASSERT(ToRegister(instr->result()).is(r0)); | 2819 ASSERT(ToRegister(instr->result()).is(r0)); |
2804 __ mov(r1, Operand(instr->function())); | 2820 __ mov(r1, Operand(instr->function())); |
2805 CallKnownFunction(instr->function(), instr->arity(), instr); | 2821 CallKnownFunction(instr->function(), |
2822 instr->arity(), | |
2823 instr, | |
2824 CALL_AS_METHOD); | |
2806 } | 2825 } |
2807 | 2826 |
2808 | 2827 |
2809 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 2828 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { |
2810 ASSERT(instr->InputAt(0)->Equals(instr->result())); | 2829 ASSERT(instr->InputAt(0)->Equals(instr->result())); |
2811 Register input = ToRegister(instr->InputAt(0)); | 2830 Register input = ToRegister(instr->InputAt(0)); |
2812 Register scratch = scratch0(); | 2831 Register scratch = scratch0(); |
2813 | 2832 |
2814 // Deoptimize if not a heap number. | 2833 // Deoptimize if not a heap number. |
2815 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); | 2834 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3177 isolate()->stub_cache()->ComputeKeyedCallInitialize(arity, NOT_IN_LOOP); | 3196 isolate()->stub_cache()->ComputeKeyedCallInitialize(arity, NOT_IN_LOOP); |
3178 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3197 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
3179 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3198 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3180 } | 3199 } |
3181 | 3200 |
3182 | 3201 |
3183 void LCodeGen::DoCallNamed(LCallNamed* instr) { | 3202 void LCodeGen::DoCallNamed(LCallNamed* instr) { |
3184 ASSERT(ToRegister(instr->result()).is(r0)); | 3203 ASSERT(ToRegister(instr->result()).is(r0)); |
3185 | 3204 |
3186 int arity = instr->arity(); | 3205 int arity = instr->arity(); |
3187 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize( | 3206 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; |
3188 arity, NOT_IN_LOOP); | 3207 Handle<Code> ic = |
3208 isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); | |
3189 __ mov(r2, Operand(instr->name())); | 3209 __ mov(r2, Operand(instr->name())); |
3190 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3210 CallCode(ic, mode, instr); |
3191 // Restore context register. | 3211 // Restore context register. |
3192 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3212 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3193 } | 3213 } |
3194 | 3214 |
3195 | 3215 |
3196 void LCodeGen::DoCallFunction(LCallFunction* instr) { | 3216 void LCodeGen::DoCallFunction(LCallFunction* instr) { |
3197 ASSERT(ToRegister(instr->result()).is(r0)); | 3217 ASSERT(ToRegister(instr->result()).is(r0)); |
3198 | 3218 |
3199 int arity = instr->arity(); | 3219 int arity = instr->arity(); |
3200 CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_VALUE); | 3220 CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_IMPLICIT); |
3201 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 3221 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
3202 __ Drop(1); | 3222 __ Drop(1); |
3203 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3223 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3204 } | 3224 } |
3205 | 3225 |
3206 | 3226 |
3207 void LCodeGen::DoCallGlobal(LCallGlobal* instr) { | 3227 void LCodeGen::DoCallGlobal(LCallGlobal* instr) { |
3208 ASSERT(ToRegister(instr->result()).is(r0)); | 3228 ASSERT(ToRegister(instr->result()).is(r0)); |
3209 | 3229 |
3210 int arity = instr->arity(); | 3230 int arity = instr->arity(); |
3231 RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT; | |
3211 Handle<Code> ic = | 3232 Handle<Code> ic = |
3212 isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP); | 3233 isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); |
3213 __ mov(r2, Operand(instr->name())); | 3234 __ mov(r2, Operand(instr->name())); |
3214 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); | 3235 CallCode(ic, mode, instr); |
3215 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3236 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3216 } | 3237 } |
3217 | 3238 |
3218 | 3239 |
3219 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { | 3240 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { |
3220 ASSERT(ToRegister(instr->result()).is(r0)); | 3241 ASSERT(ToRegister(instr->result()).is(r0)); |
3221 __ mov(r1, Operand(instr->target())); | 3242 __ mov(r1, Operand(instr->target())); |
3222 CallKnownFunction(instr->target(), instr->arity(), instr); | 3243 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); |
3223 } | 3244 } |
3224 | 3245 |
3225 | 3246 |
3226 void LCodeGen::DoCallNew(LCallNew* instr) { | 3247 void LCodeGen::DoCallNew(LCallNew* instr) { |
3227 ASSERT(ToRegister(instr->InputAt(0)).is(r1)); | 3248 ASSERT(ToRegister(instr->InputAt(0)).is(r1)); |
3228 ASSERT(ToRegister(instr->result()).is(r0)); | 3249 ASSERT(ToRegister(instr->result()).is(r0)); |
3229 | 3250 |
3230 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); | 3251 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); |
3231 __ mov(r0, Operand(instr->arity())); | 3252 __ mov(r0, Operand(instr->arity())); |
3232 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr); | 3253 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr); |
(...skipping 1233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4466 ASSERT(osr_pc_offset_ == -1); | 4487 ASSERT(osr_pc_offset_ == -1); |
4467 osr_pc_offset_ = masm()->pc_offset(); | 4488 osr_pc_offset_ = masm()->pc_offset(); |
4468 } | 4489 } |
4469 | 4490 |
4470 | 4491 |
4471 | 4492 |
4472 | 4493 |
4473 #undef __ | 4494 #undef __ |
4474 | 4495 |
4475 } } // namespace v8::internal | 4496 } } // namespace v8::internal |
OLD | NEW |