Chromium Code Reviews| 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 |