| 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 |