Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/arm/codegen-arm.cc

Issue 174056: Add support for forceful termination of JavaScript execution. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/api.cc ('k') | src/codegen.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/api.cc ('k') | src/codegen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698