OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { | 139 info_->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { |
140 __ stop("stop_at"); | 140 __ stop("stop_at"); |
141 } | 141 } |
142 #endif | 142 #endif |
143 | 143 |
144 // a1: Callee's JS function. | 144 // a1: 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 and builtins need to replace the receiver | 149 // Classic mode functions and builtins need to replace the receiver with the |
150 // with undefined when called as functions (without an explicit | 150 // global proxy when called as functions (without an explicit receiver |
151 // receiver object). r5 is zero for method calls and non-zero for | 151 // object). |
152 // function calls. | 152 if (info_->this_has_uses() && |
153 if (!info_->is_classic_mode() || info_->is_native()) { | 153 info_->is_classic_mode() && |
| 154 !info_->is_native()) { |
154 Label ok; | 155 Label ok; |
155 __ Branch(&ok, eq, t1, Operand(zero_reg)); | 156 __ Branch(&ok, eq, t1, Operand(zero_reg)); |
156 | 157 |
157 int receiver_offset = scope()->num_parameters() * kPointerSize; | 158 int receiver_offset = info_->scope()->num_parameters() * kPointerSize; |
158 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); | 159 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
| 160 __ lw(a2, MemOperand(sp, receiver_offset)); |
| 161 __ Branch(&ok, ne, a2, Operand(at)); |
| 162 |
| 163 __ lw(a2, GlobalObjectOperand()); |
| 164 __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset)); |
| 165 |
159 __ sw(a2, MemOperand(sp, receiver_offset)); | 166 __ sw(a2, MemOperand(sp, receiver_offset)); |
| 167 |
160 __ bind(&ok); | 168 __ bind(&ok); |
161 } | 169 } |
162 } | 170 } |
163 | 171 |
164 info()->set_prologue_offset(masm_->pc_offset()); | 172 info()->set_prologue_offset(masm_->pc_offset()); |
165 if (NeedsEagerFrame()) { | 173 if (NeedsEagerFrame()) { |
166 __ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME); | 174 __ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME); |
167 frame_is_built_ = true; | 175 frame_is_built_ = true; |
168 info_->AddNoFrameRange(0, masm_->pc_offset()); | 176 info_->AddNoFrameRange(0, masm_->pc_offset()); |
169 } | 177 } |
(...skipping 3193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3363 // Deoptimize if the receiver is not a JS object. | 3371 // Deoptimize if the receiver is not a JS object. |
3364 __ SmiTst(receiver, scratch); | 3372 __ SmiTst(receiver, scratch); |
3365 DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg)); | 3373 DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg)); |
3366 | 3374 |
3367 __ GetObjectType(receiver, scratch, scratch); | 3375 __ GetObjectType(receiver, scratch, scratch); |
3368 DeoptimizeIf(lt, instr->environment(), | 3376 DeoptimizeIf(lt, instr->environment(), |
3369 scratch, Operand(FIRST_SPEC_OBJECT_TYPE)); | 3377 scratch, Operand(FIRST_SPEC_OBJECT_TYPE)); |
3370 __ Branch(&result_in_receiver); | 3378 __ Branch(&result_in_receiver); |
3371 | 3379 |
3372 __ bind(&global_object); | 3380 __ bind(&global_object); |
3373 CallStubCompiler::FetchGlobalProxy(masm(), receiver, function); | 3381 __ lw(receiver, FieldMemOperand(function, JSFunction::kContextOffset)); |
| 3382 __ lw(receiver, |
| 3383 ContextOperand(receiver, |
| 3384 Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |
| 3385 __ lw(receiver, |
| 3386 FieldMemOperand(receiver, GlobalObject::kGlobalReceiverOffset)); |
3374 | 3387 |
3375 if (result.is(receiver)) { | 3388 if (result.is(receiver)) { |
3376 __ bind(&result_in_receiver); | 3389 __ bind(&result_in_receiver); |
3377 } else { | 3390 } else { |
3378 Label result_ok; | 3391 Label result_ok; |
3379 __ Branch(&result_ok); | 3392 __ Branch(&result_ok); |
3380 __ bind(&result_in_receiver); | 3393 __ bind(&result_in_receiver); |
3381 __ mov(result, receiver); | 3394 __ mov(result, receiver); |
3382 __ bind(&result_ok); | 3395 __ bind(&result_ok); |
3383 } | 3396 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3422 | 3435 |
3423 __ bind(&invoke); | 3436 __ bind(&invoke); |
3424 ASSERT(instr->HasPointerMap()); | 3437 ASSERT(instr->HasPointerMap()); |
3425 LPointerMap* pointers = instr->pointer_map(); | 3438 LPointerMap* pointers = instr->pointer_map(); |
3426 SafepointGenerator safepoint_generator( | 3439 SafepointGenerator safepoint_generator( |
3427 this, pointers, Safepoint::kLazyDeopt); | 3440 this, pointers, Safepoint::kLazyDeopt); |
3428 // The number of arguments is stored in receiver which is a0, as expected | 3441 // The number of arguments is stored in receiver which is a0, as expected |
3429 // by InvokeFunction. | 3442 // by InvokeFunction. |
3430 ParameterCount actual(receiver); | 3443 ParameterCount actual(receiver); |
3431 __ InvokeFunction(function, actual, CALL_FUNCTION, | 3444 __ InvokeFunction(function, actual, CALL_FUNCTION, |
3432 safepoint_generator, CALL_AS_METHOD); | 3445 safepoint_generator, CALL_AS_FUNCTION); |
3433 } | 3446 } |
3434 | 3447 |
3435 | 3448 |
3436 void LCodeGen::DoPushArgument(LPushArgument* instr) { | 3449 void LCodeGen::DoPushArgument(LPushArgument* instr) { |
3437 LOperand* argument = instr->value(); | 3450 LOperand* argument = instr->value(); |
3438 if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) { | 3451 if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) { |
3439 Abort(kDoPushArgumentNotImplementedForDoubleType); | 3452 Abort(kDoPushArgumentNotImplementedForDoubleType); |
3440 } else { | 3453 } else { |
3441 Register argument_reg = EmitLoadRegister(argument, at); | 3454 Register argument_reg = EmitLoadRegister(argument, at); |
3442 __ push(argument_reg); | 3455 __ push(argument_reg); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3543 } | 3556 } |
3544 | 3557 |
3545 | 3558 |
3546 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 3559 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
3547 ASSERT(ToRegister(instr->result()).is(v0)); | 3560 ASSERT(ToRegister(instr->result()).is(v0)); |
3548 __ mov(a0, v0); | 3561 __ mov(a0, v0); |
3549 CallKnownFunction(instr->hydrogen()->function(), | 3562 CallKnownFunction(instr->hydrogen()->function(), |
3550 instr->hydrogen()->formal_parameter_count(), | 3563 instr->hydrogen()->formal_parameter_count(), |
3551 instr->arity(), | 3564 instr->arity(), |
3552 instr, | 3565 instr, |
3553 CALL_AS_METHOD, | 3566 CALL_AS_FUNCTION, |
3554 A1_UNINITIALIZED); | 3567 A1_UNINITIALIZED); |
3555 } | 3568 } |
3556 | 3569 |
3557 | 3570 |
3558 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { | 3571 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { |
3559 ASSERT(instr->context() != NULL); | 3572 ASSERT(instr->context() != NULL); |
3560 ASSERT(ToRegister(instr->context()).is(cp)); | 3573 ASSERT(ToRegister(instr->context()).is(cp)); |
3561 Register input = ToRegister(instr->value()); | 3574 Register input = ToRegister(instr->value()); |
3562 Register result = ToRegister(instr->result()); | 3575 Register result = ToRegister(instr->result()); |
3563 Register scratch = scratch0(); | 3576 Register scratch = scratch0(); |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3866 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { | 3879 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { |
3867 ASSERT(ToRegister(instr->context()).is(cp)); | 3880 ASSERT(ToRegister(instr->context()).is(cp)); |
3868 ASSERT(ToRegister(instr->function()).is(a1)); | 3881 ASSERT(ToRegister(instr->function()).is(a1)); |
3869 ASSERT(instr->HasPointerMap()); | 3882 ASSERT(instr->HasPointerMap()); |
3870 | 3883 |
3871 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); | 3884 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); |
3872 if (known_function.is_null()) { | 3885 if (known_function.is_null()) { |
3873 LPointerMap* pointers = instr->pointer_map(); | 3886 LPointerMap* pointers = instr->pointer_map(); |
3874 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 3887 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
3875 ParameterCount count(instr->arity()); | 3888 ParameterCount count(instr->arity()); |
3876 __ InvokeFunction(a1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); | 3889 __ InvokeFunction(a1, count, CALL_FUNCTION, generator, CALL_AS_FUNCTION); |
3877 } else { | 3890 } else { |
3878 CallKnownFunction(known_function, | 3891 CallKnownFunction(known_function, |
3879 instr->hydrogen()->formal_parameter_count(), | 3892 instr->hydrogen()->formal_parameter_count(), |
3880 instr->arity(), | 3893 instr->arity(), |
3881 instr, | 3894 instr, |
3882 CALL_AS_METHOD, | 3895 CALL_AS_FUNCTION, |
3883 A1_CONTAINS_TARGET); | 3896 A1_CONTAINS_TARGET); |
3884 } | 3897 } |
3885 } | 3898 } |
3886 | 3899 |
3887 | 3900 |
3888 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { | 3901 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { |
3889 ASSERT(ToRegister(instr->context()).is(cp)); | 3902 ASSERT(ToRegister(instr->context()).is(cp)); |
3890 ASSERT(ToRegister(instr->result()).is(v0)); | 3903 ASSERT(ToRegister(instr->result()).is(v0)); |
3891 | 3904 |
3892 int arity = instr->arity(); | 3905 int arity = instr->arity(); |
(...skipping 14 matching lines...) Expand all Loading... |
3907 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3920 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
3908 } | 3921 } |
3909 | 3922 |
3910 | 3923 |
3911 void LCodeGen::DoCallFunction(LCallFunction* instr) { | 3924 void LCodeGen::DoCallFunction(LCallFunction* instr) { |
3912 ASSERT(ToRegister(instr->context()).is(cp)); | 3925 ASSERT(ToRegister(instr->context()).is(cp)); |
3913 ASSERT(ToRegister(instr->function()).is(a1)); | 3926 ASSERT(ToRegister(instr->function()).is(a1)); |
3914 ASSERT(ToRegister(instr->result()).is(v0)); | 3927 ASSERT(ToRegister(instr->result()).is(v0)); |
3915 | 3928 |
3916 int arity = instr->arity(); | 3929 int arity = instr->arity(); |
3917 CallFunctionFlags flags = | 3930 CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS); |
3918 instr->hydrogen()->IsContextualCall() ? | |
3919 RECEIVER_IS_IMPLICIT : NO_CALL_FUNCTION_FLAGS; | |
3920 CallFunctionStub stub(arity, flags); | |
3921 if (instr->hydrogen()->IsTailCall()) { | 3931 if (instr->hydrogen()->IsTailCall()) { |
3922 if (NeedsEagerFrame()) __ mov(sp, fp); | 3932 if (NeedsEagerFrame()) __ mov(sp, fp); |
3923 __ Jump(stub.GetCode(isolate()), RelocInfo::CODE_TARGET); | 3933 __ Jump(stub.GetCode(isolate()), RelocInfo::CODE_TARGET); |
3924 } else { | 3934 } else { |
3925 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 3935 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
3926 } | 3936 } |
3927 } | 3937 } |
3928 | 3938 |
3929 | 3939 |
3930 void LCodeGen::DoCallGlobal(LCallGlobal* instr) { | 3940 void LCodeGen::DoCallGlobal(LCallGlobal* instr) { |
(...skipping 1875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5806 __ Subu(scratch, result, scratch); | 5816 __ Subu(scratch, result, scratch); |
5807 __ lw(result, FieldMemOperand(scratch, | 5817 __ lw(result, FieldMemOperand(scratch, |
5808 FixedArray::kHeaderSize - kPointerSize)); | 5818 FixedArray::kHeaderSize - kPointerSize)); |
5809 __ bind(&done); | 5819 __ bind(&done); |
5810 } | 5820 } |
5811 | 5821 |
5812 | 5822 |
5813 #undef __ | 5823 #undef __ |
5814 | 5824 |
5815 } } // namespace v8::internal | 5825 } } // namespace v8::internal |
OLD | NEW |