OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 3573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3584 | 3584 |
3585 // Special handling of out of memory exceptions. | 3585 // Special handling of out of memory exceptions. |
3586 Failure* out_of_memory = Failure::OutOfMemoryException(); | 3586 Failure* out_of_memory = Failure::OutOfMemoryException(); |
3587 __ Branch(throw_out_of_memory_exception, eq, | 3587 __ Branch(throw_out_of_memory_exception, eq, |
3588 v0, Operand(reinterpret_cast<int32_t>(out_of_memory))); | 3588 v0, Operand(reinterpret_cast<int32_t>(out_of_memory))); |
3589 | 3589 |
3590 // Retrieve the pending exception and clear the variable. | 3590 // Retrieve the pending exception and clear the variable. |
3591 __ li(t0, | 3591 __ li(t0, |
3592 Operand(ExternalReference::the_hole_value_location(masm->isolate()))); | 3592 Operand(ExternalReference::the_hole_value_location(masm->isolate()))); |
3593 __ lw(a3, MemOperand(t0)); | 3593 __ lw(a3, MemOperand(t0)); |
3594 __ li(t0, Operand(ExternalReference(Isolate::k_pending_exception_address, | 3594 __ li(t0, Operand(ExternalReference(Isolate::kPendingExceptionAddress, |
3595 masm->isolate()))); | 3595 masm->isolate()))); |
3596 __ lw(v0, MemOperand(t0)); | 3596 __ lw(v0, MemOperand(t0)); |
3597 __ sw(a3, MemOperand(t0)); | 3597 __ sw(a3, MemOperand(t0)); |
3598 | 3598 |
3599 // Special handling of termination exceptions which are uncatchable | 3599 // Special handling of termination exceptions which are uncatchable |
3600 // by javascript code. | 3600 // by javascript code. |
3601 __ Branch(throw_termination_exception, eq, | 3601 __ Branch(throw_termination_exception, eq, |
3602 v0, Operand(masm->isolate()->factory()->termination_exception())); | 3602 v0, Operand(masm->isolate()->factory()->termination_exception())); |
3603 | 3603 |
3604 // Handle normal exception. | 3604 // Handle normal exception. |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3707 offset_to_argv += kNumCalleeSavedFPU * kDoubleSize; | 3707 offset_to_argv += kNumCalleeSavedFPU * kDoubleSize; |
3708 } | 3708 } |
3709 | 3709 |
3710 __ lw(s0, MemOperand(sp, offset_to_argv + kCArgsSlotsSize)); | 3710 __ lw(s0, MemOperand(sp, offset_to_argv + kCArgsSlotsSize)); |
3711 | 3711 |
3712 // We build an EntryFrame. | 3712 // We build an EntryFrame. |
3713 __ li(t3, Operand(-1)); // Push a bad frame pointer to fail if it is used. | 3713 __ li(t3, Operand(-1)); // Push a bad frame pointer to fail if it is used. |
3714 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; | 3714 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; |
3715 __ li(t2, Operand(Smi::FromInt(marker))); | 3715 __ li(t2, Operand(Smi::FromInt(marker))); |
3716 __ li(t1, Operand(Smi::FromInt(marker))); | 3716 __ li(t1, Operand(Smi::FromInt(marker))); |
3717 __ li(t0, Operand(ExternalReference(Isolate::k_c_entry_fp_address, | 3717 __ li(t0, Operand(ExternalReference(Isolate::kCEntryFPAddress, |
3718 masm->isolate()))); | 3718 masm->isolate()))); |
3719 __ lw(t0, MemOperand(t0)); | 3719 __ lw(t0, MemOperand(t0)); |
3720 __ Push(t3, t2, t1, t0); | 3720 __ Push(t3, t2, t1, t0); |
3721 // Setup frame pointer for the frame to be pushed. | 3721 // Setup frame pointer for the frame to be pushed. |
3722 __ addiu(fp, sp, -EntryFrameConstants::kCallerFPOffset); | 3722 __ addiu(fp, sp, -EntryFrameConstants::kCallerFPOffset); |
3723 | 3723 |
3724 // Registers: | 3724 // Registers: |
3725 // a0: entry_address | 3725 // a0: entry_address |
3726 // a1: function | 3726 // a1: function |
3727 // a2: reveiver_pointer | 3727 // a2: reveiver_pointer |
3728 // a3: argc | 3728 // a3: argc |
3729 // s0: argv | 3729 // s0: argv |
3730 // | 3730 // |
3731 // Stack: | 3731 // Stack: |
3732 // caller fp | | 3732 // caller fp | |
3733 // function slot | entry frame | 3733 // function slot | entry frame |
3734 // context slot | | 3734 // context slot | |
3735 // bad fp (0xff...f) | | 3735 // bad fp (0xff...f) | |
3736 // callee saved registers + ra | 3736 // callee saved registers + ra |
3737 // 4 args slots | 3737 // 4 args slots |
3738 // args | 3738 // args |
3739 | 3739 |
3740 // If this is the outermost JS call, set js_entry_sp value. | 3740 // If this is the outermost JS call, set js_entry_sp value. |
3741 Label non_outermost_js; | 3741 Label non_outermost_js; |
3742 ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, | 3742 ExternalReference js_entry_sp(Isolate::kJSEntrySPAddress, |
3743 masm->isolate()); | 3743 masm->isolate()); |
3744 __ li(t1, Operand(ExternalReference(js_entry_sp))); | 3744 __ li(t1, Operand(ExternalReference(js_entry_sp))); |
3745 __ lw(t2, MemOperand(t1)); | 3745 __ lw(t2, MemOperand(t1)); |
3746 __ Branch(&non_outermost_js, ne, t2, Operand(zero_reg)); | 3746 __ Branch(&non_outermost_js, ne, t2, Operand(zero_reg)); |
3747 __ sw(fp, MemOperand(t1)); | 3747 __ sw(fp, MemOperand(t1)); |
3748 __ li(t0, Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); | 3748 __ li(t0, Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); |
3749 Label cont; | 3749 Label cont; |
3750 __ b(&cont); | 3750 __ b(&cont); |
3751 __ nop(); // Branch delay slot nop. | 3751 __ nop(); // Branch delay slot nop. |
3752 __ bind(&non_outermost_js); | 3752 __ bind(&non_outermost_js); |
3753 __ li(t0, Operand(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME))); | 3753 __ li(t0, Operand(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME))); |
3754 __ bind(&cont); | 3754 __ bind(&cont); |
3755 __ push(t0); | 3755 __ push(t0); |
3756 | 3756 |
3757 // Call a faked try-block that does the invoke. | 3757 // Call a faked try-block that does the invoke. |
3758 __ bal(&invoke); // bal exposes branch delay slot. | 3758 __ bal(&invoke); // bal exposes branch delay slot. |
3759 __ nop(); // Branch delay slot nop. | 3759 __ nop(); // Branch delay slot nop. |
3760 | 3760 |
3761 // Caught exception: Store result (exception) in the pending | 3761 // Caught exception: Store result (exception) in the pending |
3762 // exception field in the JSEnv and return a failure sentinel. | 3762 // exception field in the JSEnv and return a failure sentinel. |
3763 // Coming in here the fp will be invalid because the PushTryHandler below | 3763 // Coming in here the fp will be invalid because the PushTryHandler below |
3764 // sets it to 0 to signal the existence of the JSEntry frame. | 3764 // sets it to 0 to signal the existence of the JSEntry frame. |
3765 __ li(t0, Operand(ExternalReference(Isolate::k_pending_exception_address, | 3765 __ li(t0, Operand(ExternalReference(Isolate::kPendingExceptionAddress, |
3766 masm->isolate()))); | 3766 masm->isolate()))); |
3767 __ sw(v0, MemOperand(t0)); // We come back from 'invoke'. result is in v0. | 3767 __ sw(v0, MemOperand(t0)); // We come back from 'invoke'. result is in v0. |
3768 __ li(v0, Operand(reinterpret_cast<int32_t>(Failure::Exception()))); | 3768 __ li(v0, Operand(reinterpret_cast<int32_t>(Failure::Exception()))); |
3769 __ b(&exit); // b exposes branch delay slot. | 3769 __ b(&exit); // b exposes branch delay slot. |
3770 __ nop(); // Branch delay slot nop. | 3770 __ nop(); // Branch delay slot nop. |
3771 | 3771 |
3772 // Invoke: Link this frame into the handler chain. | 3772 // Invoke: Link this frame into the handler chain. |
3773 __ bind(&invoke); | 3773 __ bind(&invoke); |
3774 __ PushTryHandler(IN_JS_ENTRY, JS_ENTRY_HANDLER); | 3774 __ PushTryHandler(IN_JS_ENTRY, JS_ENTRY_HANDLER); |
3775 // If an exception not caught by another handler occurs, this handler | 3775 // If an exception not caught by another handler occurs, this handler |
3776 // returns control to the code after the bal(&invoke) above, which | 3776 // returns control to the code after the bal(&invoke) above, which |
3777 // restores all kCalleeSaved registers (including cp and fp) to their | 3777 // restores all kCalleeSaved registers (including cp and fp) to their |
3778 // saved values before returning a failure to C. | 3778 // saved values before returning a failure to C. |
3779 | 3779 |
3780 // Clear any pending exceptions. | 3780 // Clear any pending exceptions. |
3781 __ li(t0, | 3781 __ li(t0, |
3782 Operand(ExternalReference::the_hole_value_location(masm->isolate()))); | 3782 Operand(ExternalReference::the_hole_value_location(masm->isolate()))); |
3783 __ lw(t1, MemOperand(t0)); | 3783 __ lw(t1, MemOperand(t0)); |
3784 __ li(t0, Operand(ExternalReference(Isolate::k_pending_exception_address, | 3784 __ li(t0, Operand(ExternalReference(Isolate::kPendingExceptionAddress, |
3785 masm->isolate()))); | 3785 masm->isolate()))); |
3786 __ sw(t1, MemOperand(t0)); | 3786 __ sw(t1, MemOperand(t0)); |
3787 | 3787 |
3788 // Invoke the function by calling through JS entry trampoline builtin. | 3788 // Invoke the function by calling through JS entry trampoline builtin. |
3789 // Notice that we cannot store a reference to the trampoline code directly in | 3789 // Notice that we cannot store a reference to the trampoline code directly in |
3790 // this stub, because runtime stubs are not traversed when doing GC. | 3790 // this stub, because runtime stubs are not traversed when doing GC. |
3791 | 3791 |
3792 // Registers: | 3792 // Registers: |
3793 // a0: entry_address | 3793 // a0: entry_address |
3794 // a1: function | 3794 // a1: function |
(...skipping 30 matching lines...) Expand all Loading... |
3825 Label non_outermost_js_2; | 3825 Label non_outermost_js_2; |
3826 __ pop(t1); | 3826 __ pop(t1); |
3827 __ Branch(&non_outermost_js_2, ne, t1, | 3827 __ Branch(&non_outermost_js_2, ne, t1, |
3828 Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); | 3828 Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); |
3829 __ li(t1, Operand(ExternalReference(js_entry_sp))); | 3829 __ li(t1, Operand(ExternalReference(js_entry_sp))); |
3830 __ sw(zero_reg, MemOperand(t1)); | 3830 __ sw(zero_reg, MemOperand(t1)); |
3831 __ bind(&non_outermost_js_2); | 3831 __ bind(&non_outermost_js_2); |
3832 | 3832 |
3833 // Restore the top frame descriptors from the stack. | 3833 // Restore the top frame descriptors from the stack. |
3834 __ pop(t1); | 3834 __ pop(t1); |
3835 __ li(t0, Operand(ExternalReference(Isolate::k_c_entry_fp_address, | 3835 __ li(t0, Operand(ExternalReference(Isolate::kCEntryFPAddress, |
3836 masm->isolate()))); | 3836 masm->isolate()))); |
3837 __ sw(t1, MemOperand(t0)); | 3837 __ sw(t1, MemOperand(t0)); |
3838 | 3838 |
3839 // Reset the stack to the callee saved registers. | 3839 // Reset the stack to the callee saved registers. |
3840 __ addiu(sp, sp, -EntryFrameConstants::kCallerFPOffset); | 3840 __ addiu(sp, sp, -EntryFrameConstants::kCallerFPOffset); |
3841 | 3841 |
3842 if (CpuFeatures::IsSupported(FPU)) { | 3842 if (CpuFeatures::IsSupported(FPU)) { |
3843 CpuFeatures::Scope scope(FPU); | 3843 CpuFeatures::Scope scope(FPU); |
3844 // Restore callee-saved fpu registers. | 3844 // Restore callee-saved fpu registers. |
3845 __ MultiPopFPU(kCalleeSavedFPU); | 3845 __ MultiPopFPU(kCalleeSavedFPU); |
(...skipping 865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4711 // If not exception it can only be retry. Handle that in the runtime system. | 4711 // If not exception it can only be retry. Handle that in the runtime system. |
4712 __ Branch(&runtime, ne, | 4712 __ Branch(&runtime, ne, |
4713 v0, Operand(NativeRegExpMacroAssembler::EXCEPTION)); | 4713 v0, Operand(NativeRegExpMacroAssembler::EXCEPTION)); |
4714 // Result must now be exception. If there is no pending exception already a | 4714 // Result must now be exception. If there is no pending exception already a |
4715 // stack overflow (on the backtrack stack) was detected in RegExp code but | 4715 // stack overflow (on the backtrack stack) was detected in RegExp code but |
4716 // haven't created the exception yet. Handle that in the runtime system. | 4716 // haven't created the exception yet. Handle that in the runtime system. |
4717 // TODO(592): Rerunning the RegExp to get the stack overflow exception. | 4717 // TODO(592): Rerunning the RegExp to get the stack overflow exception. |
4718 __ li(a1, Operand( | 4718 __ li(a1, Operand( |
4719 ExternalReference::the_hole_value_location(masm->isolate()))); | 4719 ExternalReference::the_hole_value_location(masm->isolate()))); |
4720 __ lw(a1, MemOperand(a1, 0)); | 4720 __ lw(a1, MemOperand(a1, 0)); |
4721 __ li(a2, Operand(ExternalReference(Isolate::k_pending_exception_address, | 4721 __ li(a2, Operand(ExternalReference(Isolate::kPendingExceptionAddress, |
4722 masm->isolate()))); | 4722 masm->isolate()))); |
4723 __ lw(v0, MemOperand(a2, 0)); | 4723 __ lw(v0, MemOperand(a2, 0)); |
4724 __ Branch(&runtime, eq, v0, Operand(a1)); | 4724 __ Branch(&runtime, eq, v0, Operand(a1)); |
4725 | 4725 |
4726 __ sw(a1, MemOperand(a2, 0)); // Clear pending exception. | 4726 __ sw(a1, MemOperand(a2, 0)); // Clear pending exception. |
4727 | 4727 |
4728 // Check if the exception is a termination. If so, throw as uncatchable. | 4728 // Check if the exception is a termination. If so, throw as uncatchable. |
4729 __ LoadRoot(a0, Heap::kTerminationExceptionRootIndex); | 4729 __ LoadRoot(a0, Heap::kTerminationExceptionRootIndex); |
4730 Label termination_exception; | 4730 Label termination_exception; |
4731 __ Branch(&termination_exception, eq, v0, Operand(a0)); | 4731 __ Branch(&termination_exception, eq, v0, Operand(a0)); |
(...skipping 2226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6958 __ mov(result, zero_reg); | 6958 __ mov(result, zero_reg); |
6959 __ Ret(); | 6959 __ Ret(); |
6960 } | 6960 } |
6961 | 6961 |
6962 | 6962 |
6963 #undef __ | 6963 #undef __ |
6964 | 6964 |
6965 } } // namespace v8::internal | 6965 } } // namespace v8::internal |
6966 | 6966 |
6967 #endif // V8_TARGET_ARCH_MIPS | 6967 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |