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