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