| 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 | |
| 3610 | 3594 |
| 3611 // The code below is made a lot easier because the calling code already sets | 3595 // The code below is made a lot easier because the calling code already sets |
| 3612 // up actual and expected registers according to the contract if values are | 3596 // up actual and expected registers according to the contract if values are |
| 3613 // passed in registers. | 3597 // passed in registers. |
| 3614 ASSERT(actual.is_immediate() || actual.reg().is(a0)); | 3598 ASSERT(actual.is_immediate() || actual.reg().is(a0)); |
| 3615 ASSERT(expected.is_immediate() || expected.reg().is(a2)); | 3599 ASSERT(expected.is_immediate() || expected.reg().is(a2)); |
| 3616 ASSERT((!code_constant.is_null() && code_reg.is(no_reg)) || code_reg.is(a3)); | 3600 ASSERT((!code_constant.is_null() && code_reg.is(no_reg)) || code_reg.is(a3)); |
| 3617 | 3601 |
| 3618 if (expected.is_immediate()) { | 3602 if (expected.is_immediate()) { |
| 3619 ASSERT(actual.is_immediate()); | 3603 ASSERT(actual.is_immediate()); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 3643 if (!definitely_matches) { | 3627 if (!definitely_matches) { |
| 3644 if (!code_constant.is_null()) { | 3628 if (!code_constant.is_null()) { |
| 3645 li(a3, Operand(code_constant)); | 3629 li(a3, Operand(code_constant)); |
| 3646 addiu(a3, a3, Code::kHeaderSize - kHeapObjectTag); | 3630 addiu(a3, a3, Code::kHeaderSize - kHeapObjectTag); |
| 3647 } | 3631 } |
| 3648 | 3632 |
| 3649 Handle<Code> adaptor = | 3633 Handle<Code> adaptor = |
| 3650 isolate()->builtins()->ArgumentsAdaptorTrampoline(); | 3634 isolate()->builtins()->ArgumentsAdaptorTrampoline(); |
| 3651 if (flag == CALL_FUNCTION) { | 3635 if (flag == CALL_FUNCTION) { |
| 3652 call_wrapper.BeforeCall(CallSize(adaptor)); | 3636 call_wrapper.BeforeCall(CallSize(adaptor)); |
| 3653 SetCallKind(t1, call_kind); | |
| 3654 Call(adaptor); | 3637 Call(adaptor); |
| 3655 call_wrapper.AfterCall(); | 3638 call_wrapper.AfterCall(); |
| 3656 if (!*definitely_mismatches) { | 3639 if (!*definitely_mismatches) { |
| 3657 Branch(done); | 3640 Branch(done); |
| 3658 } | 3641 } |
| 3659 } else { | 3642 } else { |
| 3660 SetCallKind(t1, call_kind); | |
| 3661 Jump(adaptor, RelocInfo::CODE_TARGET); | 3643 Jump(adaptor, RelocInfo::CODE_TARGET); |
| 3662 } | 3644 } |
| 3663 bind(®ular_invoke); | 3645 bind(®ular_invoke); |
| 3664 } | 3646 } |
| 3665 } | 3647 } |
| 3666 | 3648 |
| 3667 | 3649 |
| 3668 void MacroAssembler::InvokeCode(Register code, | 3650 void MacroAssembler::InvokeCode(Register code, |
| 3669 const ParameterCount& expected, | 3651 const ParameterCount& expected, |
| 3670 const ParameterCount& actual, | 3652 const ParameterCount& actual, |
| 3671 InvokeFlag flag, | 3653 InvokeFlag flag, |
| 3672 const CallWrapper& call_wrapper, | 3654 const CallWrapper& call_wrapper) { |
| 3673 CallKind call_kind) { | |
| 3674 // You can't call a function without a valid frame. | 3655 // You can't call a function without a valid frame. |
| 3675 ASSERT(flag == JUMP_FUNCTION || has_frame()); | 3656 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
| 3676 | 3657 |
| 3677 Label done; | 3658 Label done; |
| 3678 | 3659 |
| 3679 bool definitely_mismatches = false; | 3660 bool definitely_mismatches = false; |
| 3680 InvokePrologue(expected, actual, Handle<Code>::null(), code, | 3661 InvokePrologue(expected, actual, Handle<Code>::null(), code, |
| 3681 &done, &definitely_mismatches, flag, | 3662 &done, &definitely_mismatches, flag, |
| 3682 call_wrapper, call_kind); | 3663 call_wrapper); |
| 3683 if (!definitely_mismatches) { | 3664 if (!definitely_mismatches) { |
| 3684 if (flag == CALL_FUNCTION) { | 3665 if (flag == CALL_FUNCTION) { |
| 3685 call_wrapper.BeforeCall(CallSize(code)); | 3666 call_wrapper.BeforeCall(CallSize(code)); |
| 3686 SetCallKind(t1, call_kind); | |
| 3687 Call(code); | 3667 Call(code); |
| 3688 call_wrapper.AfterCall(); | 3668 call_wrapper.AfterCall(); |
| 3689 } else { | 3669 } else { |
| 3690 ASSERT(flag == JUMP_FUNCTION); | 3670 ASSERT(flag == JUMP_FUNCTION); |
| 3691 SetCallKind(t1, call_kind); | |
| 3692 Jump(code); | 3671 Jump(code); |
| 3693 } | 3672 } |
| 3694 // Continue here if InvokePrologue does handle the invocation due to | 3673 // Continue here if InvokePrologue does handle the invocation due to |
| 3695 // mismatched parameter counts. | 3674 // mismatched parameter counts. |
| 3696 bind(&done); | 3675 bind(&done); |
| 3697 } | 3676 } |
| 3698 } | 3677 } |
| 3699 | 3678 |
| 3700 | 3679 |
| 3701 void MacroAssembler::InvokeCode(Handle<Code> code, | |
| 3702 const ParameterCount& expected, | |
| 3703 const ParameterCount& actual, | |
| 3704 RelocInfo::Mode rmode, | |
| 3705 InvokeFlag flag, | |
| 3706 CallKind call_kind) { | |
| 3707 // You can't call a function without a valid frame. | |
| 3708 ASSERT(flag == JUMP_FUNCTION || has_frame()); | |
| 3709 | |
| 3710 Label done; | |
| 3711 | |
| 3712 bool definitely_mismatches = false; | |
| 3713 InvokePrologue(expected, actual, code, no_reg, | |
| 3714 &done, &definitely_mismatches, flag, | |
| 3715 NullCallWrapper(), call_kind); | |
| 3716 if (!definitely_mismatches) { | |
| 3717 if (flag == CALL_FUNCTION) { | |
| 3718 SetCallKind(t1, call_kind); | |
| 3719 Call(code, rmode); | |
| 3720 } else { | |
| 3721 SetCallKind(t1, call_kind); | |
| 3722 Jump(code, rmode); | |
| 3723 } | |
| 3724 // Continue here if InvokePrologue does handle the invocation due to | |
| 3725 // mismatched parameter counts. | |
| 3726 bind(&done); | |
| 3727 } | |
| 3728 } | |
| 3729 | |
| 3730 | |
| 3731 void MacroAssembler::InvokeFunction(Register function, | 3680 void MacroAssembler::InvokeFunction(Register function, |
| 3732 const ParameterCount& actual, | 3681 const ParameterCount& actual, |
| 3733 InvokeFlag flag, | 3682 InvokeFlag flag, |
| 3734 const CallWrapper& call_wrapper, | 3683 const CallWrapper& call_wrapper) { |
| 3735 CallKind call_kind) { | |
| 3736 // You can't call a function without a valid frame. | 3684 // You can't call a function without a valid frame. |
| 3737 ASSERT(flag == JUMP_FUNCTION || has_frame()); | 3685 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
| 3738 | 3686 |
| 3739 // Contract with called JS functions requires that function is passed in a1. | 3687 // Contract with called JS functions requires that function is passed in a1. |
| 3740 ASSERT(function.is(a1)); | 3688 ASSERT(function.is(a1)); |
| 3741 Register expected_reg = a2; | 3689 Register expected_reg = a2; |
| 3742 Register code_reg = a3; | 3690 Register code_reg = a3; |
| 3743 | 3691 |
| 3744 lw(code_reg, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 3692 lw(code_reg, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
| 3745 lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 3693 lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
| 3746 lw(expected_reg, | 3694 lw(expected_reg, |
| 3747 FieldMemOperand(code_reg, | 3695 FieldMemOperand(code_reg, |
| 3748 SharedFunctionInfo::kFormalParameterCountOffset)); | 3696 SharedFunctionInfo::kFormalParameterCountOffset)); |
| 3749 sra(expected_reg, expected_reg, kSmiTagSize); | 3697 sra(expected_reg, expected_reg, kSmiTagSize); |
| 3750 lw(code_reg, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | 3698 lw(code_reg, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
| 3751 | 3699 |
| 3752 ParameterCount expected(expected_reg); | 3700 ParameterCount expected(expected_reg); |
| 3753 InvokeCode(code_reg, expected, actual, flag, call_wrapper, call_kind); | 3701 InvokeCode(code_reg, expected, actual, flag, call_wrapper); |
| 3754 } | 3702 } |
| 3755 | 3703 |
| 3756 | 3704 |
| 3757 void MacroAssembler::InvokeFunction(Register function, | 3705 void MacroAssembler::InvokeFunction(Register function, |
| 3758 const ParameterCount& expected, | 3706 const ParameterCount& expected, |
| 3759 const ParameterCount& actual, | 3707 const ParameterCount& actual, |
| 3760 InvokeFlag flag, | 3708 InvokeFlag flag, |
| 3761 const CallWrapper& call_wrapper, | 3709 const CallWrapper& call_wrapper) { |
| 3762 CallKind call_kind) { | |
| 3763 // You can't call a function without a valid frame. | 3710 // You can't call a function without a valid frame. |
| 3764 ASSERT(flag == JUMP_FUNCTION || has_frame()); | 3711 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
| 3765 | 3712 |
| 3766 // Contract with called JS functions requires that function is passed in a1. | 3713 // Contract with called JS functions requires that function is passed in a1. |
| 3767 ASSERT(function.is(a1)); | 3714 ASSERT(function.is(a1)); |
| 3768 | 3715 |
| 3769 // Get the function and setup the context. | 3716 // Get the function and setup the context. |
| 3770 lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 3717 lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
| 3771 | 3718 |
| 3772 // We call indirectly through the code field in the function to | 3719 // We call indirectly through the code field in the function to |
| 3773 // allow recompilation to take effect without changing any of the | 3720 // allow recompilation to take effect without changing any of the |
| 3774 // call sites. | 3721 // call sites. |
| 3775 lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | 3722 lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
| 3776 InvokeCode(a3, expected, actual, flag, call_wrapper, call_kind); | 3723 InvokeCode(a3, expected, actual, flag, call_wrapper); |
| 3777 } | 3724 } |
| 3778 | 3725 |
| 3779 | 3726 |
| 3780 void MacroAssembler::InvokeFunction(Handle<JSFunction> function, | 3727 void MacroAssembler::InvokeFunction(Handle<JSFunction> function, |
| 3781 const ParameterCount& expected, | 3728 const ParameterCount& expected, |
| 3782 const ParameterCount& actual, | 3729 const ParameterCount& actual, |
| 3783 InvokeFlag flag, | 3730 InvokeFlag flag, |
| 3784 const CallWrapper& call_wrapper, | 3731 const CallWrapper& call_wrapper) { |
| 3785 CallKind call_kind) { | |
| 3786 li(a1, function); | 3732 li(a1, function); |
| 3787 InvokeFunction(a1, expected, actual, flag, call_wrapper, call_kind); | 3733 InvokeFunction(a1, expected, actual, flag, call_wrapper); |
| 3788 } | 3734 } |
| 3789 | 3735 |
| 3790 | 3736 |
| 3791 void MacroAssembler::IsObjectJSObjectType(Register heap_object, | 3737 void MacroAssembler::IsObjectJSObjectType(Register heap_object, |
| 3792 Register map, | 3738 Register map, |
| 3793 Register scratch, | 3739 Register scratch, |
| 3794 Label* fail) { | 3740 Label* fail) { |
| 3795 lw(map, FieldMemOperand(heap_object, HeapObject::kMapOffset)); | 3741 lw(map, FieldMemOperand(heap_object, HeapObject::kMapOffset)); |
| 3796 IsInstanceJSObjectType(map, scratch, fail); | 3742 IsInstanceJSObjectType(map, scratch, fail); |
| 3797 } | 3743 } |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4284 | 4230 |
| 4285 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, | 4231 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, |
| 4286 InvokeFlag flag, | 4232 InvokeFlag flag, |
| 4287 const CallWrapper& call_wrapper) { | 4233 const CallWrapper& call_wrapper) { |
| 4288 // You can't call a builtin without a valid frame. | 4234 // You can't call a builtin without a valid frame. |
| 4289 ASSERT(flag == JUMP_FUNCTION || has_frame()); | 4235 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
| 4290 | 4236 |
| 4291 GetBuiltinEntry(t9, id); | 4237 GetBuiltinEntry(t9, id); |
| 4292 if (flag == CALL_FUNCTION) { | 4238 if (flag == CALL_FUNCTION) { |
| 4293 call_wrapper.BeforeCall(CallSize(t9)); | 4239 call_wrapper.BeforeCall(CallSize(t9)); |
| 4294 SetCallKind(t1, CALL_AS_METHOD); | |
| 4295 Call(t9); | 4240 Call(t9); |
| 4296 call_wrapper.AfterCall(); | 4241 call_wrapper.AfterCall(); |
| 4297 } else { | 4242 } else { |
| 4298 ASSERT(flag == JUMP_FUNCTION); | 4243 ASSERT(flag == JUMP_FUNCTION); |
| 4299 SetCallKind(t1, CALL_AS_METHOD); | |
| 4300 Jump(t9); | 4244 Jump(t9); |
| 4301 } | 4245 } |
| 4302 } | 4246 } |
| 4303 | 4247 |
| 4304 | 4248 |
| 4305 void MacroAssembler::GetBuiltinFunction(Register target, | 4249 void MacroAssembler::GetBuiltinFunction(Register target, |
| 4306 Builtins::JavaScript id) { | 4250 Builtins::JavaScript id) { |
| 4307 // Load the builtins object into target register. | 4251 // Load the builtins object into target register. |
| 4308 lw(target, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); | 4252 lw(target, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |
| 4309 lw(target, FieldMemOperand(target, GlobalObject::kBuiltinsOffset)); | 4253 lw(target, FieldMemOperand(target, GlobalObject::kBuiltinsOffset)); |
| (...skipping 1485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5795 opcode == BGTZL); | 5739 opcode == BGTZL); |
| 5796 opcode = (cond == eq) ? BEQ : BNE; | 5740 opcode = (cond == eq) ? BEQ : BNE; |
| 5797 instr = (instr & ~kOpcodeMask) | opcode; | 5741 instr = (instr & ~kOpcodeMask) | opcode; |
| 5798 masm_.emit(instr); | 5742 masm_.emit(instr); |
| 5799 } | 5743 } |
| 5800 | 5744 |
| 5801 | 5745 |
| 5802 } } // namespace v8::internal | 5746 } } // namespace v8::internal |
| 5803 | 5747 |
| 5804 #endif // V8_TARGET_ARCH_MIPS | 5748 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |