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