| 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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 // pp: Callee's constant pool pointer (if FLAG_enable_ool_constant_pool) | 146 // pp: Callee's constant pool pointer (if FLAG_enable_ool_constant_pool) |
| 147 // fp: Caller's frame pointer. | 147 // fp: Caller's frame pointer. |
| 148 // lr: Caller's pc. | 148 // lr: Caller's pc. |
| 149 | 149 |
| 150 // Strict mode functions and builtins need to replace the receiver | 150 // Classic mode functions and builtins need to replace the receiver with the |
| 151 // with undefined when called as functions (without an explicit | 151 // global proxy when called as functions (without an explicit receiver |
| 152 // receiver object). r5 is zero for method calls and non-zero for | 152 // object). |
| 153 // function calls. | 153 if (info_->this_has_uses() && |
| 154 if (!info_->is_classic_mode() || info_->is_native()) { | 154 info_->is_classic_mode() && |
| 155 !info_->is_native()) { |
| 156 Label ok; |
| 155 __ cmp(r5, Operand::Zero()); | 157 __ cmp(r5, Operand::Zero()); |
| 156 int receiver_offset = scope()->num_parameters() * kPointerSize; | 158 __ b(eq, &ok); |
| 157 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); | 159 |
| 158 __ str(r2, MemOperand(sp, receiver_offset), ne); | 160 int receiver_offset = info_->scope()->num_parameters() * kPointerSize; |
| 161 __ ldr(r2, MemOperand(sp, receiver_offset)); |
| 162 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); |
| 163 __ b(ne, &ok); |
| 164 |
| 165 __ ldr(r2, GlobalObjectOperand()); |
| 166 __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset)); |
| 167 |
| 168 __ str(r2, MemOperand(sp, receiver_offset)); |
| 169 |
| 170 __ bind(&ok); |
| 159 } | 171 } |
| 160 } | 172 } |
| 161 | 173 |
| 162 info()->set_prologue_offset(masm_->pc_offset()); | 174 info()->set_prologue_offset(masm_->pc_offset()); |
| 163 if (NeedsEagerFrame()) { | 175 if (NeedsEagerFrame()) { |
| 164 __ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME); | 176 __ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME); |
| 165 frame_is_built_ = true; | 177 frame_is_built_ = true; |
| 166 info_->AddNoFrameRange(0, masm_->pc_offset()); | 178 info_->AddNoFrameRange(0, masm_->pc_offset()); |
| 167 __ LoadConstantPoolPointerRegister(); | 179 __ LoadConstantPoolPointerRegister(); |
| 168 } | 180 } |
| (...skipping 3318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3487 __ b(eq, &global_object); | 3499 __ b(eq, &global_object); |
| 3488 | 3500 |
| 3489 // Deoptimize if the receiver is not a JS object. | 3501 // Deoptimize if the receiver is not a JS object. |
| 3490 __ SmiTst(receiver); | 3502 __ SmiTst(receiver); |
| 3491 DeoptimizeIf(eq, instr->environment()); | 3503 DeoptimizeIf(eq, instr->environment()); |
| 3492 __ CompareObjectType(receiver, scratch, scratch, FIRST_SPEC_OBJECT_TYPE); | 3504 __ CompareObjectType(receiver, scratch, scratch, FIRST_SPEC_OBJECT_TYPE); |
| 3493 DeoptimizeIf(lt, instr->environment()); | 3505 DeoptimizeIf(lt, instr->environment()); |
| 3494 __ b(&result_in_receiver); | 3506 __ b(&result_in_receiver); |
| 3495 | 3507 |
| 3496 __ bind(&global_object); | 3508 __ bind(&global_object); |
| 3497 CallStubCompiler::FetchGlobalProxy(masm(), receiver, function); | 3509 __ ldr(receiver, FieldMemOperand(function, JSFunction::kContextOffset)); |
| 3510 __ ldr(receiver, |
| 3511 ContextOperand(receiver, |
| 3512 Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |
| 3513 __ ldr(receiver, |
| 3514 FieldMemOperand(receiver, GlobalObject::kGlobalReceiverOffset)); |
| 3498 | 3515 |
| 3499 if (result.is(receiver)) { | 3516 if (result.is(receiver)) { |
| 3500 __ bind(&result_in_receiver); | 3517 __ bind(&result_in_receiver); |
| 3501 } else { | 3518 } else { |
| 3502 Label result_ok; | 3519 Label result_ok; |
| 3503 __ b(&result_ok); | 3520 __ b(&result_ok); |
| 3504 __ bind(&result_in_receiver); | 3521 __ bind(&result_in_receiver); |
| 3505 __ mov(result, receiver); | 3522 __ mov(result, receiver); |
| 3506 __ bind(&result_ok); | 3523 __ bind(&result_ok); |
| 3507 } | 3524 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3545 | 3562 |
| 3546 __ bind(&invoke); | 3563 __ bind(&invoke); |
| 3547 ASSERT(instr->HasPointerMap()); | 3564 ASSERT(instr->HasPointerMap()); |
| 3548 LPointerMap* pointers = instr->pointer_map(); | 3565 LPointerMap* pointers = instr->pointer_map(); |
| 3549 SafepointGenerator safepoint_generator( | 3566 SafepointGenerator safepoint_generator( |
| 3550 this, pointers, Safepoint::kLazyDeopt); | 3567 this, pointers, Safepoint::kLazyDeopt); |
| 3551 // The number of arguments is stored in receiver which is r0, as expected | 3568 // The number of arguments is stored in receiver which is r0, as expected |
| 3552 // by InvokeFunction. | 3569 // by InvokeFunction. |
| 3553 ParameterCount actual(receiver); | 3570 ParameterCount actual(receiver); |
| 3554 __ InvokeFunction(function, actual, CALL_FUNCTION, | 3571 __ InvokeFunction(function, actual, CALL_FUNCTION, |
| 3555 safepoint_generator, CALL_AS_METHOD); | 3572 safepoint_generator, CALL_AS_FUNCTION); |
| 3556 } | 3573 } |
| 3557 | 3574 |
| 3558 | 3575 |
| 3559 void LCodeGen::DoPushArgument(LPushArgument* instr) { | 3576 void LCodeGen::DoPushArgument(LPushArgument* instr) { |
| 3560 LOperand* argument = instr->value(); | 3577 LOperand* argument = instr->value(); |
| 3561 if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) { | 3578 if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) { |
| 3562 Abort(kDoPushArgumentNotImplementedForDoubleType); | 3579 Abort(kDoPushArgumentNotImplementedForDoubleType); |
| 3563 } else { | 3580 } else { |
| 3564 Register argument_reg = EmitLoadRegister(argument, ip); | 3581 Register argument_reg = EmitLoadRegister(argument, ip); |
| 3565 __ push(argument_reg); | 3582 __ push(argument_reg); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3666 } | 3683 } |
| 3667 } | 3684 } |
| 3668 | 3685 |
| 3669 | 3686 |
| 3670 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 3687 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
| 3671 ASSERT(ToRegister(instr->result()).is(r0)); | 3688 ASSERT(ToRegister(instr->result()).is(r0)); |
| 3672 CallKnownFunction(instr->hydrogen()->function(), | 3689 CallKnownFunction(instr->hydrogen()->function(), |
| 3673 instr->hydrogen()->formal_parameter_count(), | 3690 instr->hydrogen()->formal_parameter_count(), |
| 3674 instr->arity(), | 3691 instr->arity(), |
| 3675 instr, | 3692 instr, |
| 3676 CALL_AS_METHOD, | 3693 CALL_AS_FUNCTION, |
| 3677 R1_UNINITIALIZED); | 3694 R1_UNINITIALIZED); |
| 3678 } | 3695 } |
| 3679 | 3696 |
| 3680 | 3697 |
| 3681 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { | 3698 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { |
| 3682 ASSERT(instr->context() != NULL); | 3699 ASSERT(instr->context() != NULL); |
| 3683 ASSERT(ToRegister(instr->context()).is(cp)); | 3700 ASSERT(ToRegister(instr->context()).is(cp)); |
| 3684 Register input = ToRegister(instr->value()); | 3701 Register input = ToRegister(instr->value()); |
| 3685 Register result = ToRegister(instr->result()); | 3702 Register result = ToRegister(instr->result()); |
| 3686 Register scratch = scratch0(); | 3703 Register scratch = scratch0(); |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3944 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { | 3961 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { |
| 3945 ASSERT(ToRegister(instr->context()).is(cp)); | 3962 ASSERT(ToRegister(instr->context()).is(cp)); |
| 3946 ASSERT(ToRegister(instr->function()).is(r1)); | 3963 ASSERT(ToRegister(instr->function()).is(r1)); |
| 3947 ASSERT(instr->HasPointerMap()); | 3964 ASSERT(instr->HasPointerMap()); |
| 3948 | 3965 |
| 3949 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); | 3966 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); |
| 3950 if (known_function.is_null()) { | 3967 if (known_function.is_null()) { |
| 3951 LPointerMap* pointers = instr->pointer_map(); | 3968 LPointerMap* pointers = instr->pointer_map(); |
| 3952 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 3969 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
| 3953 ParameterCount count(instr->arity()); | 3970 ParameterCount count(instr->arity()); |
| 3954 __ InvokeFunction(r1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); | 3971 __ InvokeFunction(r1, count, CALL_FUNCTION, generator, CALL_AS_FUNCTION); |
| 3955 } else { | 3972 } else { |
| 3956 CallKnownFunction(known_function, | 3973 CallKnownFunction(known_function, |
| 3957 instr->hydrogen()->formal_parameter_count(), | 3974 instr->hydrogen()->formal_parameter_count(), |
| 3958 instr->arity(), | 3975 instr->arity(), |
| 3959 instr, | 3976 instr, |
| 3960 CALL_AS_METHOD, | 3977 CALL_AS_FUNCTION, |
| 3961 R1_CONTAINS_TARGET); | 3978 R1_CONTAINS_TARGET); |
| 3962 } | 3979 } |
| 3963 } | 3980 } |
| 3964 | 3981 |
| 3965 | 3982 |
| 3966 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { | 3983 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { |
| 3967 ASSERT(ToRegister(instr->context()).is(cp)); | 3984 ASSERT(ToRegister(instr->context()).is(cp)); |
| 3968 ASSERT(ToRegister(instr->result()).is(r0)); | 3985 ASSERT(ToRegister(instr->result()).is(r0)); |
| 3969 | 3986 |
| 3970 int arity = instr->arity(); | 3987 int arity = instr->arity(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3985 CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); | 4002 CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); |
| 3986 } | 4003 } |
| 3987 | 4004 |
| 3988 | 4005 |
| 3989 void LCodeGen::DoCallFunction(LCallFunction* instr) { | 4006 void LCodeGen::DoCallFunction(LCallFunction* instr) { |
| 3990 ASSERT(ToRegister(instr->context()).is(cp)); | 4007 ASSERT(ToRegister(instr->context()).is(cp)); |
| 3991 ASSERT(ToRegister(instr->function()).is(r1)); | 4008 ASSERT(ToRegister(instr->function()).is(r1)); |
| 3992 ASSERT(ToRegister(instr->result()).is(r0)); | 4009 ASSERT(ToRegister(instr->result()).is(r0)); |
| 3993 | 4010 |
| 3994 int arity = instr->arity(); | 4011 int arity = instr->arity(); |
| 3995 CallFunctionFlags flags = | 4012 CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS); |
| 3996 instr->hydrogen()->IsContextualCall() ? | |
| 3997 RECEIVER_IS_IMPLICIT : NO_CALL_FUNCTION_FLAGS; | |
| 3998 CallFunctionStub stub(arity, flags); | |
| 3999 if (instr->hydrogen()->IsTailCall()) { | 4013 if (instr->hydrogen()->IsTailCall()) { |
| 4000 if (NeedsEagerFrame()) __ mov(sp, fp); | 4014 if (NeedsEagerFrame()) __ mov(sp, fp); |
| 4001 __ Jump(stub.GetCode(isolate()), RelocInfo::CODE_TARGET); | 4015 __ Jump(stub.GetCode(isolate()), RelocInfo::CODE_TARGET); |
| 4002 } else { | 4016 } else { |
| 4003 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 4017 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 4004 } | 4018 } |
| 4005 } | 4019 } |
| 4006 | 4020 |
| 4007 | 4021 |
| 4008 void LCodeGen::DoCallGlobal(LCallGlobal* instr) { | 4022 void LCodeGen::DoCallGlobal(LCallGlobal* instr) { |
| (...skipping 1801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5810 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); | 5824 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); |
| 5811 __ ldr(result, FieldMemOperand(scratch, | 5825 __ ldr(result, FieldMemOperand(scratch, |
| 5812 FixedArray::kHeaderSize - kPointerSize)); | 5826 FixedArray::kHeaderSize - kPointerSize)); |
| 5813 __ bind(&done); | 5827 __ bind(&done); |
| 5814 } | 5828 } |
| 5815 | 5829 |
| 5816 | 5830 |
| 5817 #undef __ | 5831 #undef __ |
| 5818 | 5832 |
| 5819 } } // namespace v8::internal | 5833 } } // namespace v8::internal |
| OLD | NEW |