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 3553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3564 Move(f12, src1); | 3564 Move(f12, src1); |
3565 Move(f14, src2); | 3565 Move(f14, src2); |
3566 } | 3566 } |
3567 } else { | 3567 } else { |
3568 Move(a0, a1, src1); | 3568 Move(a0, a1, src1); |
3569 Move(a2, a3, src2); | 3569 Move(a2, a3, src2); |
3570 } | 3570 } |
3571 } | 3571 } |
3572 | 3572 |
3573 | 3573 |
3574 void MacroAssembler::SetCallKind(Register dst, CallKind call_kind) { | |
3575 // This macro takes the dst register to make the code more readable | |
3576 // at the call sites. However, the dst register has to be t1 to | |
3577 // follow the calling convention which requires the call type to be | |
3578 // in t1. | |
3579 ASSERT(dst.is(t1)); | |
3580 if (call_kind == CALL_AS_FUNCTION) { | |
3581 li(dst, Operand(Smi::FromInt(1))); | |
3582 } else { | |
3583 li(dst, Operand(Smi::FromInt(0))); | |
3584 } | |
3585 } | |
3586 | |
3587 | |
3588 // ----------------------------------------------------------------------------- | 3574 // ----------------------------------------------------------------------------- |
3589 // JavaScript invokes. | 3575 // JavaScript invokes. |
3590 | 3576 |
3591 void MacroAssembler::InvokePrologue(const ParameterCount& expected, | 3577 void MacroAssembler::InvokePrologue(const ParameterCount& expected, |
3592 const ParameterCount& actual, | 3578 const ParameterCount& actual, |
3593 Handle<Code> code_constant, | 3579 Handle<Code> code_constant, |
3594 Register code_reg, | 3580 Register code_reg, |
3595 Label* done, | 3581 Label* done, |
3596 bool* definitely_mismatches, | 3582 bool* definitely_mismatches, |
3597 InvokeFlag flag, | 3583 InvokeFlag flag, |
3598 const CallWrapper& call_wrapper, | 3584 const CallWrapper& call_wrapper) { |
3599 CallKind call_kind) { | |
3600 bool definitely_matches = false; | 3585 bool definitely_matches = false; |
3601 *definitely_mismatches = false; | 3586 *definitely_mismatches = false; |
3602 Label regular_invoke; | 3587 Label regular_invoke; |
3603 | 3588 |
3604 // Check whether the expected and actual arguments count match. If not, | 3589 // Check whether the expected and actual arguments count match. If not, |
3605 // setup registers according to contract with ArgumentsAdaptorTrampoline: | 3590 // setup registers according to contract with ArgumentsAdaptorTrampoline: |
3606 // a0: actual arguments count | 3591 // a0: actual arguments count |
3607 // a1: function (passed through to callee) | 3592 // a1: function (passed through to callee) |
3608 // a2: expected arguments count | 3593 // a2: expected arguments count |
3609 // a3: callee code entry | 3594 // a3: callee code entry |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3643 if (!definitely_matches) { | 3628 if (!definitely_matches) { |
3644 if (!code_constant.is_null()) { | 3629 if (!code_constant.is_null()) { |
3645 li(a3, Operand(code_constant)); | 3630 li(a3, Operand(code_constant)); |
3646 addiu(a3, a3, Code::kHeaderSize - kHeapObjectTag); | 3631 addiu(a3, a3, Code::kHeaderSize - kHeapObjectTag); |
3647 } | 3632 } |
3648 | 3633 |
3649 Handle<Code> adaptor = | 3634 Handle<Code> adaptor = |
3650 isolate()->builtins()->ArgumentsAdaptorTrampoline(); | 3635 isolate()->builtins()->ArgumentsAdaptorTrampoline(); |
3651 if (flag == CALL_FUNCTION) { | 3636 if (flag == CALL_FUNCTION) { |
3652 call_wrapper.BeforeCall(CallSize(adaptor)); | 3637 call_wrapper.BeforeCall(CallSize(adaptor)); |
3653 SetCallKind(t1, call_kind); | |
3654 Call(adaptor); | 3638 Call(adaptor); |
3655 call_wrapper.AfterCall(); | 3639 call_wrapper.AfterCall(); |
3656 if (!*definitely_mismatches) { | 3640 if (!*definitely_mismatches) { |
3657 Branch(done); | 3641 Branch(done); |
3658 } | 3642 } |
3659 } else { | 3643 } else { |
3660 SetCallKind(t1, call_kind); | |
3661 Jump(adaptor, RelocInfo::CODE_TARGET); | 3644 Jump(adaptor, RelocInfo::CODE_TARGET); |
3662 } | 3645 } |
3663 bind(®ular_invoke); | 3646 bind(®ular_invoke); |
3664 } | 3647 } |
3665 } | 3648 } |
3666 | 3649 |
3667 | 3650 |
3668 void MacroAssembler::InvokeCode(Register code, | 3651 void MacroAssembler::InvokeCode(Register code, |
3669 const ParameterCount& expected, | 3652 const ParameterCount& expected, |
3670 const ParameterCount& actual, | 3653 const ParameterCount& actual, |
3671 InvokeFlag flag, | 3654 InvokeFlag flag, |
3672 const CallWrapper& call_wrapper, | 3655 const CallWrapper& call_wrapper) { |
3673 CallKind call_kind) { | |
3674 // You can't call a function without a valid frame. | 3656 // You can't call a function without a valid frame. |
3675 ASSERT(flag == JUMP_FUNCTION || has_frame()); | 3657 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
3676 | 3658 |
3677 Label done; | 3659 Label done; |
3678 | 3660 |
3679 bool definitely_mismatches = false; | 3661 bool definitely_mismatches = false; |
3680 InvokePrologue(expected, actual, Handle<Code>::null(), code, | 3662 InvokePrologue(expected, actual, Handle<Code>::null(), code, |
3681 &done, &definitely_mismatches, flag, | 3663 &done, &definitely_mismatches, flag, |
3682 call_wrapper, call_kind); | 3664 call_wrapper); |
3683 if (!definitely_mismatches) { | 3665 if (!definitely_mismatches) { |
3684 if (flag == CALL_FUNCTION) { | 3666 if (flag == CALL_FUNCTION) { |
3685 call_wrapper.BeforeCall(CallSize(code)); | 3667 call_wrapper.BeforeCall(CallSize(code)); |
3686 SetCallKind(t1, call_kind); | |
3687 Call(code); | 3668 Call(code); |
3688 call_wrapper.AfterCall(); | 3669 call_wrapper.AfterCall(); |
3689 } else { | 3670 } else { |
3690 ASSERT(flag == JUMP_FUNCTION); | 3671 ASSERT(flag == JUMP_FUNCTION); |
3691 SetCallKind(t1, call_kind); | |
3692 Jump(code); | 3672 Jump(code); |
3693 } | 3673 } |
3694 // Continue here if InvokePrologue does handle the invocation due to | 3674 // Continue here if InvokePrologue does handle the invocation due to |
3695 // mismatched parameter counts. | 3675 // mismatched parameter counts. |
3696 bind(&done); | 3676 bind(&done); |
3697 } | 3677 } |
3698 } | 3678 } |
3699 | 3679 |
3700 | 3680 |
3701 void MacroAssembler::InvokeCode(Handle<Code> code, | 3681 void MacroAssembler::InvokeCode(Handle<Code> code, |
3702 const ParameterCount& expected, | 3682 const ParameterCount& expected, |
3703 const ParameterCount& actual, | 3683 const ParameterCount& actual, |
3704 RelocInfo::Mode rmode, | 3684 RelocInfo::Mode rmode, |
3705 InvokeFlag flag, | 3685 InvokeFlag flag) { |
3706 CallKind call_kind) { | |
3707 // You can't call a function without a valid frame. | 3686 // You can't call a function without a valid frame. |
3708 ASSERT(flag == JUMP_FUNCTION || has_frame()); | 3687 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
3709 | 3688 |
3710 Label done; | 3689 Label done; |
3711 | 3690 |
3712 bool definitely_mismatches = false; | 3691 bool definitely_mismatches = false; |
3713 InvokePrologue(expected, actual, code, no_reg, | 3692 InvokePrologue(expected, actual, code, no_reg, |
3714 &done, &definitely_mismatches, flag, | 3693 &done, &definitely_mismatches, flag, |
3715 NullCallWrapper(), call_kind); | 3694 NullCallWrapper()); |
3716 if (!definitely_mismatches) { | 3695 if (!definitely_mismatches) { |
3717 if (flag == CALL_FUNCTION) { | 3696 if (flag == CALL_FUNCTION) { |
3718 SetCallKind(t1, call_kind); | |
3719 Call(code, rmode); | 3697 Call(code, rmode); |
3720 } else { | 3698 } else { |
3721 SetCallKind(t1, call_kind); | |
3722 Jump(code, rmode); | 3699 Jump(code, rmode); |
3723 } | 3700 } |
3724 // Continue here if InvokePrologue does handle the invocation due to | 3701 // Continue here if InvokePrologue does handle the invocation due to |
3725 // mismatched parameter counts. | 3702 // mismatched parameter counts. |
3726 bind(&done); | 3703 bind(&done); |
3727 } | 3704 } |
3728 } | 3705 } |
3729 | 3706 |
3730 | 3707 |
3731 void MacroAssembler::InvokeFunction(Register function, | 3708 void MacroAssembler::InvokeFunction(Register function, |
3732 const ParameterCount& actual, | 3709 const ParameterCount& actual, |
3733 InvokeFlag flag, | 3710 InvokeFlag flag, |
3734 const CallWrapper& call_wrapper, | 3711 const CallWrapper& call_wrapper) { |
3735 CallKind call_kind) { | |
3736 // You can't call a function without a valid frame. | 3712 // You can't call a function without a valid frame. |
3737 ASSERT(flag == JUMP_FUNCTION || has_frame()); | 3713 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
3738 | 3714 |
3739 // Contract with called JS functions requires that function is passed in a1. | 3715 // Contract with called JS functions requires that function is passed in a1. |
3740 ASSERT(function.is(a1)); | 3716 ASSERT(function.is(a1)); |
3741 Register expected_reg = a2; | 3717 Register expected_reg = a2; |
3742 Register code_reg = a3; | 3718 Register code_reg = a3; |
3743 | 3719 |
3744 lw(code_reg, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 3720 lw(code_reg, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
3745 lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 3721 lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
3746 lw(expected_reg, | 3722 lw(expected_reg, |
3747 FieldMemOperand(code_reg, | 3723 FieldMemOperand(code_reg, |
3748 SharedFunctionInfo::kFormalParameterCountOffset)); | 3724 SharedFunctionInfo::kFormalParameterCountOffset)); |
3749 sra(expected_reg, expected_reg, kSmiTagSize); | 3725 sra(expected_reg, expected_reg, kSmiTagSize); |
3750 lw(code_reg, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | 3726 lw(code_reg, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
3751 | 3727 |
3752 ParameterCount expected(expected_reg); | 3728 ParameterCount expected(expected_reg); |
3753 InvokeCode(code_reg, expected, actual, flag, call_wrapper, call_kind); | 3729 InvokeCode(code_reg, expected, actual, flag, call_wrapper); |
3754 } | 3730 } |
3755 | 3731 |
3756 | 3732 |
3757 void MacroAssembler::InvokeFunction(Register function, | 3733 void MacroAssembler::InvokeFunction(Register function, |
3758 const ParameterCount& expected, | 3734 const ParameterCount& expected, |
3759 const ParameterCount& actual, | 3735 const ParameterCount& actual, |
3760 InvokeFlag flag, | 3736 InvokeFlag flag, |
3761 const CallWrapper& call_wrapper, | 3737 const CallWrapper& call_wrapper) { |
3762 CallKind call_kind) { | |
3763 // You can't call a function without a valid frame. | 3738 // You can't call a function without a valid frame. |
3764 ASSERT(flag == JUMP_FUNCTION || has_frame()); | 3739 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
3765 | 3740 |
3766 // Contract with called JS functions requires that function is passed in a1. | 3741 // Contract with called JS functions requires that function is passed in a1. |
3767 ASSERT(function.is(a1)); | 3742 ASSERT(function.is(a1)); |
3768 | 3743 |
3769 // Get the function and setup the context. | 3744 // Get the function and setup the context. |
3770 lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 3745 lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
3771 | 3746 |
3772 // We call indirectly through the code field in the function to | 3747 // We call indirectly through the code field in the function to |
3773 // allow recompilation to take effect without changing any of the | 3748 // allow recompilation to take effect without changing any of the |
3774 // call sites. | 3749 // call sites. |
3775 lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | 3750 lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
3776 InvokeCode(a3, expected, actual, flag, call_wrapper, call_kind); | 3751 InvokeCode(a3, expected, actual, flag, call_wrapper); |
3777 } | 3752 } |
3778 | 3753 |
3779 | 3754 |
3780 void MacroAssembler::InvokeFunction(Handle<JSFunction> function, | 3755 void MacroAssembler::InvokeFunction(Handle<JSFunction> function, |
3781 const ParameterCount& expected, | 3756 const ParameterCount& expected, |
3782 const ParameterCount& actual, | 3757 const ParameterCount& actual, |
3783 InvokeFlag flag, | 3758 InvokeFlag flag, |
3784 const CallWrapper& call_wrapper, | 3759 const CallWrapper& call_wrapper) { |
3785 CallKind call_kind) { | |
3786 li(a1, function); | 3760 li(a1, function); |
3787 InvokeFunction(a1, expected, actual, flag, call_wrapper, call_kind); | 3761 InvokeFunction(a1, expected, actual, flag, call_wrapper); |
3788 } | 3762 } |
3789 | 3763 |
3790 | 3764 |
3791 void MacroAssembler::IsObjectJSObjectType(Register heap_object, | 3765 void MacroAssembler::IsObjectJSObjectType(Register heap_object, |
3792 Register map, | 3766 Register map, |
3793 Register scratch, | 3767 Register scratch, |
3794 Label* fail) { | 3768 Label* fail) { |
3795 lw(map, FieldMemOperand(heap_object, HeapObject::kMapOffset)); | 3769 lw(map, FieldMemOperand(heap_object, HeapObject::kMapOffset)); |
3796 IsInstanceJSObjectType(map, scratch, fail); | 3770 IsInstanceJSObjectType(map, scratch, fail); |
3797 } | 3771 } |
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4284 | 4258 |
4285 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, | 4259 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, |
4286 InvokeFlag flag, | 4260 InvokeFlag flag, |
4287 const CallWrapper& call_wrapper) { | 4261 const CallWrapper& call_wrapper) { |
4288 // You can't call a builtin without a valid frame. | 4262 // You can't call a builtin without a valid frame. |
4289 ASSERT(flag == JUMP_FUNCTION || has_frame()); | 4263 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
4290 | 4264 |
4291 GetBuiltinEntry(t9, id); | 4265 GetBuiltinEntry(t9, id); |
4292 if (flag == CALL_FUNCTION) { | 4266 if (flag == CALL_FUNCTION) { |
4293 call_wrapper.BeforeCall(CallSize(t9)); | 4267 call_wrapper.BeforeCall(CallSize(t9)); |
4294 SetCallKind(t1, CALL_AS_METHOD); | |
4295 Call(t9); | 4268 Call(t9); |
4296 call_wrapper.AfterCall(); | 4269 call_wrapper.AfterCall(); |
4297 } else { | 4270 } else { |
4298 ASSERT(flag == JUMP_FUNCTION); | 4271 ASSERT(flag == JUMP_FUNCTION); |
4299 SetCallKind(t1, CALL_AS_METHOD); | |
4300 Jump(t9); | 4272 Jump(t9); |
4301 } | 4273 } |
4302 } | 4274 } |
4303 | 4275 |
4304 | 4276 |
4305 void MacroAssembler::GetBuiltinFunction(Register target, | 4277 void MacroAssembler::GetBuiltinFunction(Register target, |
4306 Builtins::JavaScript id) { | 4278 Builtins::JavaScript id) { |
4307 // Load the builtins object into target register. | 4279 // Load the builtins object into target register. |
4308 lw(target, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); | 4280 lw(target, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |
4309 lw(target, FieldMemOperand(target, GlobalObject::kBuiltinsOffset)); | 4281 lw(target, FieldMemOperand(target, GlobalObject::kBuiltinsOffset)); |
(...skipping 1485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5795 opcode == BGTZL); | 5767 opcode == BGTZL); |
5796 opcode = (cond == eq) ? BEQ : BNE; | 5768 opcode = (cond == eq) ? BEQ : BNE; |
5797 instr = (instr & ~kOpcodeMask) | opcode; | 5769 instr = (instr & ~kOpcodeMask) | opcode; |
5798 masm_.emit(instr); | 5770 masm_.emit(instr); |
5799 } | 5771 } |
5800 | 5772 |
5801 | 5773 |
5802 } } // namespace v8::internal | 5774 } } // namespace v8::internal |
5803 | 5775 |
5804 #endif // V8_TARGET_ARCH_MIPS | 5776 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |