| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 5683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5694 #ifdef DEBUG | 5694 #ifdef DEBUG |
| 5695 if (FLAG_debug_code) { | 5695 if (FLAG_debug_code) { |
| 5696 __ mov(lr, Operand(pc)); | 5696 __ mov(lr, Operand(pc)); |
| 5697 } | 5697 } |
| 5698 #endif | 5698 #endif |
| 5699 ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); | 5699 ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); |
| 5700 __ pop(pc); | 5700 __ pop(pc); |
| 5701 } | 5701 } |
| 5702 | 5702 |
| 5703 | 5703 |
| 5704 void CEntryStub::GenerateThrowOutOfMemory(MacroAssembler* masm) { | 5704 void CEntryStub::GenerateThrowUncatchable(MacroAssembler* masm, |
| 5705 UncatchableExceptionType type) { |
| 5705 // Adjust this code if not the case. | 5706 // Adjust this code if not the case. |
| 5706 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | 5707 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); |
| 5707 | 5708 |
| 5708 // Drop sp to the top stack handler. | 5709 // Drop sp to the top stack handler. |
| 5709 __ mov(r3, Operand(ExternalReference(Top::k_handler_address))); | 5710 __ mov(r3, Operand(ExternalReference(Top::k_handler_address))); |
| 5710 __ ldr(sp, MemOperand(r3)); | 5711 __ ldr(sp, MemOperand(r3)); |
| 5711 | 5712 |
| 5712 // Unwind the handlers until the ENTRY handler is found. | 5713 // Unwind the handlers until the ENTRY handler is found. |
| 5713 Label loop, done; | 5714 Label loop, done; |
| 5714 __ bind(&loop); | 5715 __ bind(&loop); |
| 5715 // Load the type of the current stack handler. | 5716 // Load the type of the current stack handler. |
| 5716 const int kStateOffset = StackHandlerConstants::kStateOffset; | 5717 const int kStateOffset = StackHandlerConstants::kStateOffset; |
| 5717 __ ldr(r2, MemOperand(sp, kStateOffset)); | 5718 __ ldr(r2, MemOperand(sp, kStateOffset)); |
| 5718 __ cmp(r2, Operand(StackHandler::ENTRY)); | 5719 __ cmp(r2, Operand(StackHandler::ENTRY)); |
| 5719 __ b(eq, &done); | 5720 __ b(eq, &done); |
| 5720 // Fetch the next handler in the list. | 5721 // Fetch the next handler in the list. |
| 5721 const int kNextOffset = StackHandlerConstants::kNextOffset; | 5722 const int kNextOffset = StackHandlerConstants::kNextOffset; |
| 5722 __ ldr(sp, MemOperand(sp, kNextOffset)); | 5723 __ ldr(sp, MemOperand(sp, kNextOffset)); |
| 5723 __ jmp(&loop); | 5724 __ jmp(&loop); |
| 5724 __ bind(&done); | 5725 __ bind(&done); |
| 5725 | 5726 |
| 5726 // Set the top handler address to next handler past the current ENTRY handler. | 5727 // Set the top handler address to next handler past the current ENTRY handler. |
| 5727 ASSERT(StackHandlerConstants::kNextOffset == 0); | 5728 ASSERT(StackHandlerConstants::kNextOffset == 0); |
| 5728 __ pop(r0); | 5729 __ pop(r2); |
| 5729 __ str(r0, MemOperand(r3)); | 5730 __ str(r2, MemOperand(r3)); |
| 5730 | 5731 |
| 5731 // Set external caught exception to false. | 5732 if (type == OUT_OF_MEMORY) { |
| 5732 ExternalReference external_caught(Top::k_external_caught_exception_address); | 5733 // Set external caught exception to false. |
| 5733 __ mov(r0, Operand(false)); | 5734 ExternalReference external_caught(Top::k_external_caught_exception_address); |
| 5734 __ mov(r2, Operand(external_caught)); | 5735 __ mov(r0, Operand(false)); |
| 5735 __ str(r0, MemOperand(r2)); | 5736 __ mov(r2, Operand(external_caught)); |
| 5737 __ str(r0, MemOperand(r2)); |
| 5736 | 5738 |
| 5737 // Set pending exception and r0 to out of memory exception. | 5739 // Set pending exception and r0 to out of memory exception. |
| 5738 Failure* out_of_memory = Failure::OutOfMemoryException(); | 5740 Failure* out_of_memory = Failure::OutOfMemoryException(); |
| 5739 __ mov(r0, Operand(reinterpret_cast<int32_t>(out_of_memory))); | 5741 __ mov(r0, Operand(reinterpret_cast<int32_t>(out_of_memory))); |
| 5740 __ mov(r2, Operand(ExternalReference(Top::k_pending_exception_address))); | 5742 __ mov(r2, Operand(ExternalReference(Top::k_pending_exception_address))); |
| 5741 __ str(r0, MemOperand(r2)); | 5743 __ str(r0, MemOperand(r2)); |
| 5744 } |
| 5742 | 5745 |
| 5743 // Stack layout at this point. See also StackHandlerConstants. | 5746 // Stack layout at this point. See also StackHandlerConstants. |
| 5744 // sp -> state (ENTRY) | 5747 // sp -> state (ENTRY) |
| 5745 // fp | 5748 // fp |
| 5746 // lr | 5749 // lr |
| 5747 | 5750 |
| 5748 // Discard handler state (r2 is not used) and restore frame pointer. | 5751 // Discard handler state (r2 is not used) and restore frame pointer. |
| 5749 ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); | 5752 ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); |
| 5750 __ ldm(ia_w, sp, r2.bit() | fp.bit()); // r2: discarded state. | 5753 __ ldm(ia_w, sp, r2.bit() | fp.bit()); // r2: discarded state. |
| 5751 // Before returning we restore the context from the frame pointer if | 5754 // Before returning we restore the context from the frame pointer if |
| 5752 // not NULL. The frame pointer is NULL in the exception handler of a | 5755 // not NULL. The frame pointer is NULL in the exception handler of a |
| 5753 // JS entry frame. | 5756 // JS entry frame. |
| 5754 __ cmp(fp, Operand(0)); | 5757 __ cmp(fp, Operand(0)); |
| 5755 // Set cp to NULL if fp is NULL. | 5758 // Set cp to NULL if fp is NULL. |
| 5756 __ mov(cp, Operand(0), LeaveCC, eq); | 5759 __ mov(cp, Operand(0), LeaveCC, eq); |
| 5757 // Restore cp otherwise. | 5760 // Restore cp otherwise. |
| 5758 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne); | 5761 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne); |
| 5759 #ifdef DEBUG | 5762 #ifdef DEBUG |
| 5760 if (FLAG_debug_code) { | 5763 if (FLAG_debug_code) { |
| 5761 __ mov(lr, Operand(pc)); | 5764 __ mov(lr, Operand(pc)); |
| 5762 } | 5765 } |
| 5763 #endif | 5766 #endif |
| 5764 ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); | 5767 ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); |
| 5765 __ pop(pc); | 5768 __ pop(pc); |
| 5766 } | 5769 } |
| 5767 | 5770 |
| 5768 | 5771 |
| 5769 void CEntryStub::GenerateCore(MacroAssembler* masm, | 5772 void CEntryStub::GenerateCore(MacroAssembler* masm, |
| 5770 Label* throw_normal_exception, | 5773 Label* throw_normal_exception, |
| 5774 Label* throw_termination_exception, |
| 5771 Label* throw_out_of_memory_exception, | 5775 Label* throw_out_of_memory_exception, |
| 5772 StackFrame::Type frame_type, | 5776 StackFrame::Type frame_type, |
| 5773 bool do_gc, | 5777 bool do_gc, |
| 5774 bool always_allocate) { | 5778 bool always_allocate) { |
| 5775 // r0: result parameter for PerformGC, if any | 5779 // r0: result parameter for PerformGC, if any |
| 5776 // r4: number of arguments including receiver (C callee-saved) | 5780 // r4: number of arguments including receiver (C callee-saved) |
| 5777 // r5: pointer to builtin function (C callee-saved) | 5781 // r5: pointer to builtin function (C callee-saved) |
| 5778 // r6: pointer to the first argument (C callee-saved) | 5782 // r6: pointer to the first argument (C callee-saved) |
| 5779 | 5783 |
| 5780 if (do_gc) { | 5784 if (do_gc) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5831 // fp: frame pointer | 5835 // fp: frame pointer |
| 5832 __ LeaveExitFrame(frame_type); | 5836 __ LeaveExitFrame(frame_type); |
| 5833 | 5837 |
| 5834 // check if we should retry or throw exception | 5838 // check if we should retry or throw exception |
| 5835 Label retry; | 5839 Label retry; |
| 5836 __ bind(&failure_returned); | 5840 __ bind(&failure_returned); |
| 5837 ASSERT(Failure::RETRY_AFTER_GC == 0); | 5841 ASSERT(Failure::RETRY_AFTER_GC == 0); |
| 5838 __ tst(r0, Operand(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); | 5842 __ tst(r0, Operand(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); |
| 5839 __ b(eq, &retry); | 5843 __ b(eq, &retry); |
| 5840 | 5844 |
| 5841 Label continue_exception; | 5845 // Special handling of out of memory exceptions. |
| 5842 // If the returned failure is EXCEPTION then promote Top::pending_exception(). | 5846 Failure* out_of_memory = Failure::OutOfMemoryException(); |
| 5843 __ cmp(r0, Operand(reinterpret_cast<int32_t>(Failure::Exception()))); | 5847 __ cmp(r0, Operand(reinterpret_cast<int32_t>(out_of_memory))); |
| 5844 __ b(ne, &continue_exception); | 5848 __ b(eq, throw_out_of_memory_exception); |
| 5845 | 5849 |
| 5846 // Retrieve the pending exception and clear the variable. | 5850 // Retrieve the pending exception and clear the variable. |
| 5847 __ mov(ip, Operand(ExternalReference::the_hole_value_location())); | 5851 __ mov(ip, Operand(ExternalReference::the_hole_value_location())); |
| 5848 __ ldr(r3, MemOperand(ip)); | 5852 __ ldr(r3, MemOperand(ip)); |
| 5849 __ mov(ip, Operand(ExternalReference(Top::k_pending_exception_address))); | 5853 __ mov(ip, Operand(ExternalReference(Top::k_pending_exception_address))); |
| 5850 __ ldr(r0, MemOperand(ip)); | 5854 __ ldr(r0, MemOperand(ip)); |
| 5851 __ str(r3, MemOperand(ip)); | 5855 __ str(r3, MemOperand(ip)); |
| 5852 | 5856 |
| 5853 __ bind(&continue_exception); | 5857 // Special handling of termination exceptions which are uncatchable |
| 5854 // Special handling of out of memory exception. | 5858 // by javascript code. |
| 5855 Failure* out_of_memory = Failure::OutOfMemoryException(); | 5859 __ cmp(r0, Operand(Factory::termination_exception())); |
| 5856 __ cmp(r0, Operand(reinterpret_cast<int32_t>(out_of_memory))); | 5860 __ b(eq, throw_termination_exception); |
| 5857 __ b(eq, throw_out_of_memory_exception); | |
| 5858 | 5861 |
| 5859 // Handle normal exception. | 5862 // Handle normal exception. |
| 5860 __ jmp(throw_normal_exception); | 5863 __ jmp(throw_normal_exception); |
| 5861 | 5864 |
| 5862 __ bind(&retry); // pass last failure (r0) as parameter (r0) when retrying | 5865 __ bind(&retry); // pass last failure (r0) as parameter (r0) when retrying |
| 5863 } | 5866 } |
| 5864 | 5867 |
| 5865 | 5868 |
| 5866 void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) { | 5869 void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) { |
| 5867 // Called from JavaScript; parameters are on stack as if calling JS function | 5870 // Called from JavaScript; parameters are on stack as if calling JS function |
| (...skipping 12 matching lines...) Expand all Loading... |
| 5880 ? StackFrame::EXIT_DEBUG | 5883 ? StackFrame::EXIT_DEBUG |
| 5881 : StackFrame::EXIT; | 5884 : StackFrame::EXIT; |
| 5882 | 5885 |
| 5883 // Enter the exit frame that transitions from JavaScript to C++. | 5886 // Enter the exit frame that transitions from JavaScript to C++. |
| 5884 __ EnterExitFrame(frame_type); | 5887 __ EnterExitFrame(frame_type); |
| 5885 | 5888 |
| 5886 // r4: number of arguments (C callee-saved) | 5889 // r4: number of arguments (C callee-saved) |
| 5887 // r5: pointer to builtin function (C callee-saved) | 5890 // r5: pointer to builtin function (C callee-saved) |
| 5888 // r6: pointer to first argument (C callee-saved) | 5891 // r6: pointer to first argument (C callee-saved) |
| 5889 | 5892 |
| 5893 Label throw_normal_exception; |
| 5894 Label throw_termination_exception; |
| 5890 Label throw_out_of_memory_exception; | 5895 Label throw_out_of_memory_exception; |
| 5891 Label throw_normal_exception; | |
| 5892 | 5896 |
| 5893 // Call into the runtime system. | 5897 // Call into the runtime system. |
| 5894 GenerateCore(masm, &throw_normal_exception, | 5898 GenerateCore(masm, |
| 5899 &throw_normal_exception, |
| 5900 &throw_termination_exception, |
| 5895 &throw_out_of_memory_exception, | 5901 &throw_out_of_memory_exception, |
| 5896 frame_type, | 5902 frame_type, |
| 5897 false, | 5903 false, |
| 5898 false); | 5904 false); |
| 5899 | 5905 |
| 5900 // Do space-specific GC and retry runtime call. | 5906 // Do space-specific GC and retry runtime call. |
| 5901 GenerateCore(masm, | 5907 GenerateCore(masm, |
| 5902 &throw_normal_exception, | 5908 &throw_normal_exception, |
| 5909 &throw_termination_exception, |
| 5903 &throw_out_of_memory_exception, | 5910 &throw_out_of_memory_exception, |
| 5904 frame_type, | 5911 frame_type, |
| 5905 true, | 5912 true, |
| 5906 false); | 5913 false); |
| 5907 | 5914 |
| 5908 // Do full GC and retry runtime call one final time. | 5915 // Do full GC and retry runtime call one final time. |
| 5909 Failure* failure = Failure::InternalError(); | 5916 Failure* failure = Failure::InternalError(); |
| 5910 __ mov(r0, Operand(reinterpret_cast<int32_t>(failure))); | 5917 __ mov(r0, Operand(reinterpret_cast<int32_t>(failure))); |
| 5911 GenerateCore(masm, | 5918 GenerateCore(masm, |
| 5912 &throw_normal_exception, | 5919 &throw_normal_exception, |
| 5920 &throw_termination_exception, |
| 5913 &throw_out_of_memory_exception, | 5921 &throw_out_of_memory_exception, |
| 5914 frame_type, | 5922 frame_type, |
| 5915 true, | 5923 true, |
| 5916 true); | 5924 true); |
| 5917 | 5925 |
| 5918 __ bind(&throw_out_of_memory_exception); | 5926 __ bind(&throw_out_of_memory_exception); |
| 5919 GenerateThrowOutOfMemory(masm); | 5927 GenerateThrowUncatchable(masm, OUT_OF_MEMORY); |
| 5920 // control flow for generated will not return. | 5928 |
| 5929 __ bind(&throw_termination_exception); |
| 5930 GenerateThrowUncatchable(masm, TERMINATION); |
| 5921 | 5931 |
| 5922 __ bind(&throw_normal_exception); | 5932 __ bind(&throw_normal_exception); |
| 5923 GenerateThrowTOS(masm); | 5933 GenerateThrowTOS(masm); |
| 5924 } | 5934 } |
| 5925 | 5935 |
| 5926 | 5936 |
| 5927 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { | 5937 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { |
| 5928 // r0: code entry | 5938 // r0: code entry |
| 5929 // r1: function | 5939 // r1: function |
| 5930 // r2: receiver | 5940 // r2: receiver |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6228 int CompareStub::MinorKey() { | 6238 int CompareStub::MinorKey() { |
| 6229 // Encode the two parameters in a unique 16 bit value. | 6239 // Encode the two parameters in a unique 16 bit value. |
| 6230 ASSERT(static_cast<unsigned>(cc_) >> 28 < (1 << 15)); | 6240 ASSERT(static_cast<unsigned>(cc_) >> 28 < (1 << 15)); |
| 6231 return (static_cast<unsigned>(cc_) >> 27) | (strict_ ? 1 : 0); | 6241 return (static_cast<unsigned>(cc_) >> 27) | (strict_ ? 1 : 0); |
| 6232 } | 6242 } |
| 6233 | 6243 |
| 6234 | 6244 |
| 6235 #undef __ | 6245 #undef __ |
| 6236 | 6246 |
| 6237 } } // namespace v8::internal | 6247 } } // namespace v8::internal |
| OLD | NEW |