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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 info_->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { | 139 info_->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { |
140 __ stop("stop_at"); | 140 __ stop("stop_at"); |
141 } | 141 } |
142 #endif | 142 #endif |
143 | 143 |
144 // r1: Callee's JS function. | 144 // r1: Callee's JS function. |
145 // cp: Callee's context. | 145 // cp: Callee's context. |
146 // fp: Caller's frame pointer. | 146 // fp: Caller's frame pointer. |
147 // lr: Caller's pc. | 147 // lr: Caller's pc. |
148 | 148 |
| 149 // Strict mode functions need to replace the receiver with undefined |
| 150 // when called as functions (without an explicit receiver |
| 151 // object). r5 is zero for method calls and non-zero for function |
| 152 // calls. |
| 153 if (info_->is_strict_mode()) { |
| 154 Label ok; |
| 155 __ cmp(r5, Operand(0)); |
| 156 __ b(eq, &ok); |
| 157 int receiver_offset = scope()->num_parameters() * kPointerSize; |
| 158 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
| 159 __ str(r2, MemOperand(sp, receiver_offset)); |
| 160 __ bind(&ok); |
| 161 } |
| 162 |
149 __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit()); | 163 __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit()); |
150 __ add(fp, sp, Operand(2 * kPointerSize)); // Adjust FP to point to saved FP. | 164 __ add(fp, sp, Operand(2 * kPointerSize)); // Adjust FP to point to saved FP. |
151 | 165 |
152 // Reserve space for the stack slots needed by the code. | 166 // Reserve space for the stack slots needed by the code. |
153 int slots = GetStackSlotCount(); | 167 int slots = GetStackSlotCount(); |
154 if (slots > 0) { | 168 if (slots > 0) { |
155 if (FLAG_debug_code) { | 169 if (FLAG_debug_code) { |
156 __ mov(r0, Operand(slots)); | 170 __ mov(r0, Operand(slots)); |
157 __ mov(r2, Operand(kSlotsZapValue)); | 171 __ mov(r2, Operand(kSlotsZapValue)); |
158 Label loop; | 172 Label loop; |
(...skipping 2632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2791 | 2805 |
2792 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { | 2806 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { |
2793 Register global = ToRegister(instr->global()); | 2807 Register global = ToRegister(instr->global()); |
2794 Register result = ToRegister(instr->result()); | 2808 Register result = ToRegister(instr->result()); |
2795 __ ldr(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset)); | 2809 __ ldr(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset)); |
2796 } | 2810 } |
2797 | 2811 |
2798 | 2812 |
2799 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, | 2813 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
2800 int arity, | 2814 int arity, |
2801 LInstruction* instr) { | 2815 LInstruction* instr, |
| 2816 CallKind call_kind) { |
2802 // Change context if needed. | 2817 // Change context if needed. |
2803 bool change_context = | 2818 bool change_context = |
2804 (info()->closure()->context() != function->context()) || | 2819 (info()->closure()->context() != function->context()) || |
2805 scope()->contains_with() || | 2820 scope()->contains_with() || |
2806 (scope()->num_heap_slots() > 0); | 2821 (scope()->num_heap_slots() > 0); |
2807 if (change_context) { | 2822 if (change_context) { |
2808 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | 2823 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
2809 } | 2824 } |
2810 | 2825 |
2811 // Set r0 to arguments count if adaption is not needed. Assumes that r0 | 2826 // Set r0 to arguments count if adaption is not needed. Assumes that r0 |
2812 // is available to write to at this point. | 2827 // is available to write to at this point. |
2813 if (!function->NeedsArgumentsAdaption()) { | 2828 if (!function->NeedsArgumentsAdaption()) { |
2814 __ mov(r0, Operand(arity)); | 2829 __ mov(r0, Operand(arity)); |
2815 } | 2830 } |
2816 | 2831 |
2817 LPointerMap* pointers = instr->pointer_map(); | 2832 LPointerMap* pointers = instr->pointer_map(); |
2818 RecordPosition(pointers->position()); | 2833 RecordPosition(pointers->position()); |
2819 | 2834 |
2820 // Invoke function. | 2835 // Invoke function. |
| 2836 __ SetCallKind(r5, call_kind); |
2821 __ ldr(ip, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); | 2837 __ ldr(ip, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); |
2822 __ Call(ip); | 2838 __ Call(ip); |
2823 | 2839 |
2824 // Setup deoptimization. | 2840 // Setup deoptimization. |
2825 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT); | 2841 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT); |
2826 | 2842 |
2827 // Restore context. | 2843 // Restore context. |
2828 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2844 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2829 } | 2845 } |
2830 | 2846 |
2831 | 2847 |
2832 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 2848 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
2833 ASSERT(ToRegister(instr->result()).is(r0)); | 2849 ASSERT(ToRegister(instr->result()).is(r0)); |
2834 __ mov(r1, Operand(instr->function())); | 2850 __ mov(r1, Operand(instr->function())); |
2835 CallKnownFunction(instr->function(), instr->arity(), instr); | 2851 CallKnownFunction(instr->function(), |
| 2852 instr->arity(), |
| 2853 instr, |
| 2854 CALL_AS_METHOD); |
2836 } | 2855 } |
2837 | 2856 |
2838 | 2857 |
2839 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 2858 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { |
2840 ASSERT(instr->InputAt(0)->Equals(instr->result())); | 2859 ASSERT(instr->InputAt(0)->Equals(instr->result())); |
2841 Register input = ToRegister(instr->InputAt(0)); | 2860 Register input = ToRegister(instr->InputAt(0)); |
2842 Register scratch = scratch0(); | 2861 Register scratch = scratch0(); |
2843 | 2862 |
2844 // Deoptimize if not a heap number. | 2863 // Deoptimize if not a heap number. |
2845 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); | 2864 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3207 isolate()->stub_cache()->ComputeKeyedCallInitialize(arity, NOT_IN_LOOP); | 3226 isolate()->stub_cache()->ComputeKeyedCallInitialize(arity, NOT_IN_LOOP); |
3208 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3227 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
3209 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3228 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3210 } | 3229 } |
3211 | 3230 |
3212 | 3231 |
3213 void LCodeGen::DoCallNamed(LCallNamed* instr) { | 3232 void LCodeGen::DoCallNamed(LCallNamed* instr) { |
3214 ASSERT(ToRegister(instr->result()).is(r0)); | 3233 ASSERT(ToRegister(instr->result()).is(r0)); |
3215 | 3234 |
3216 int arity = instr->arity(); | 3235 int arity = instr->arity(); |
3217 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize( | 3236 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; |
3218 arity, NOT_IN_LOOP); | 3237 Handle<Code> ic = |
| 3238 isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); |
3219 __ mov(r2, Operand(instr->name())); | 3239 __ mov(r2, Operand(instr->name())); |
3220 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3240 CallCode(ic, mode, instr); |
3221 // Restore context register. | 3241 // Restore context register. |
3222 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3242 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3223 } | 3243 } |
3224 | 3244 |
3225 | 3245 |
3226 void LCodeGen::DoCallFunction(LCallFunction* instr) { | 3246 void LCodeGen::DoCallFunction(LCallFunction* instr) { |
3227 ASSERT(ToRegister(instr->result()).is(r0)); | 3247 ASSERT(ToRegister(instr->result()).is(r0)); |
3228 | 3248 |
3229 int arity = instr->arity(); | 3249 int arity = instr->arity(); |
3230 CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_VALUE); | 3250 CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_IMPLICIT); |
3231 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 3251 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
3232 __ Drop(1); | 3252 __ Drop(1); |
3233 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3253 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3234 } | 3254 } |
3235 | 3255 |
3236 | 3256 |
3237 void LCodeGen::DoCallGlobal(LCallGlobal* instr) { | 3257 void LCodeGen::DoCallGlobal(LCallGlobal* instr) { |
3238 ASSERT(ToRegister(instr->result()).is(r0)); | 3258 ASSERT(ToRegister(instr->result()).is(r0)); |
3239 | 3259 |
3240 int arity = instr->arity(); | 3260 int arity = instr->arity(); |
| 3261 RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT; |
3241 Handle<Code> ic = | 3262 Handle<Code> ic = |
3242 isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP); | 3263 isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); |
3243 __ mov(r2, Operand(instr->name())); | 3264 __ mov(r2, Operand(instr->name())); |
3244 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); | 3265 CallCode(ic, mode, instr); |
3245 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3266 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3246 } | 3267 } |
3247 | 3268 |
3248 | 3269 |
3249 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { | 3270 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { |
3250 ASSERT(ToRegister(instr->result()).is(r0)); | 3271 ASSERT(ToRegister(instr->result()).is(r0)); |
3251 __ mov(r1, Operand(instr->target())); | 3272 __ mov(r1, Operand(instr->target())); |
3252 CallKnownFunction(instr->target(), instr->arity(), instr); | 3273 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); |
3253 } | 3274 } |
3254 | 3275 |
3255 | 3276 |
3256 void LCodeGen::DoCallNew(LCallNew* instr) { | 3277 void LCodeGen::DoCallNew(LCallNew* instr) { |
3257 ASSERT(ToRegister(instr->InputAt(0)).is(r1)); | 3278 ASSERT(ToRegister(instr->InputAt(0)).is(r1)); |
3258 ASSERT(ToRegister(instr->result()).is(r0)); | 3279 ASSERT(ToRegister(instr->result()).is(r0)); |
3259 | 3280 |
3260 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); | 3281 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); |
3261 __ mov(r0, Operand(instr->arity())); | 3282 __ mov(r0, Operand(instr->arity())); |
3262 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr); | 3283 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr); |
(...skipping 1233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4496 ASSERT(osr_pc_offset_ == -1); | 4517 ASSERT(osr_pc_offset_ == -1); |
4497 osr_pc_offset_ = masm()->pc_offset(); | 4518 osr_pc_offset_ = masm()->pc_offset(); |
4498 } | 4519 } |
4499 | 4520 |
4500 | 4521 |
4501 | 4522 |
4502 | 4523 |
4503 #undef __ | 4524 #undef __ |
4504 | 4525 |
4505 } } // namespace v8::internal | 4526 } } // namespace v8::internal |
OLD | NEW |