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

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

Issue 119414: Cleanup of ARM exception handlers. Remove the unused code and... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 6 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 | « no previous file | src/arm/frames-arm.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 2089 matching lines...) Expand 10 before | Expand all | Expand 10 after
2100 bool has_unlinks = false; 2100 bool has_unlinks = false;
2101 for (int i = 0; i < shadows.length(); i++) { 2101 for (int i = 0; i < shadows.length(); i++) {
2102 shadows[i]->StopShadowing(); 2102 shadows[i]->StopShadowing();
2103 has_unlinks = has_unlinks || shadows[i]->is_linked(); 2103 has_unlinks = has_unlinks || shadows[i]->is_linked();
2104 } 2104 }
2105 function_return_is_shadowed_ = function_return_was_shadowed; 2105 function_return_is_shadowed_ = function_return_was_shadowed;
2106 2106
2107 // Get an external reference to the handler address. 2107 // Get an external reference to the handler address.
2108 ExternalReference handler_address(Top::k_handler_address); 2108 ExternalReference handler_address(Top::k_handler_address);
2109 2109
2110 // The next handler address is at kNextIndex in the stack.
2111 const int kNextIndex = StackHandlerConstants::kNextOffset / kPointerSize;
2112 // If we can fall off the end of the try block, unlink from try chain. 2110 // If we can fall off the end of the try block, unlink from try chain.
2113 if (has_valid_frame()) { 2111 if (has_valid_frame()) {
2114 __ ldr(r1, frame_->ElementAt(kNextIndex)); 2112 // The next handler address is on top of the frame. Unlink from
2113 // the handler list and drop the rest of this handler from the
2114 // frame.
2115 ASSERT(StackHandlerConstants::kNextOffset == 0);
2116 frame_->EmitPop(r1);
2115 __ mov(r3, Operand(handler_address)); 2117 __ mov(r3, Operand(handler_address));
2116 __ str(r1, MemOperand(r3)); 2118 __ str(r1, MemOperand(r3));
2117 frame_->Drop(StackHandlerConstants::kSize / kPointerSize); 2119 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
2118 if (has_unlinks) { 2120 if (has_unlinks) {
2119 exit.Jump(); 2121 exit.Jump();
2120 } 2122 }
2121 } 2123 }
2122 2124
2123 // Generate unlink code for the (formerly) shadowing labels that have been 2125 // Generate unlink code for the (formerly) shadowing labels that have been
2124 // jumped to. Deallocate each shadow target. 2126 // jumped to. Deallocate each shadow target.
2125 for (int i = 0; i < shadows.length(); i++) { 2127 for (int i = 0; i < shadows.length(); i++) {
2126 if (shadows[i]->is_linked()) { 2128 if (shadows[i]->is_linked()) {
2127 // Unlink from try chain; 2129 // Unlink from try chain;
2128 shadows[i]->Bind(); 2130 shadows[i]->Bind();
2129 // Because we can be jumping here (to spilled code) from unspilled 2131 // Because we can be jumping here (to spilled code) from unspilled
2130 // code, we need to reestablish a spilled frame at this block. 2132 // code, we need to reestablish a spilled frame at this block.
2131 frame_->SpillAll(); 2133 frame_->SpillAll();
2132 2134
2133 // Reload sp from the top handler, because some statements that we 2135 // Reload sp from the top handler, because some statements that we
2134 // break from (eg, for...in) may have left stuff on the stack. 2136 // break from (eg, for...in) may have left stuff on the stack.
2135 __ mov(r3, Operand(handler_address)); 2137 __ mov(r3, Operand(handler_address));
2136 __ ldr(sp, MemOperand(r3)); 2138 __ ldr(sp, MemOperand(r3));
2137 // The stack pointer was restored to just below the code slot 2139 frame_->Forget(frame_->height() - handler_height);
2138 // (the topmost slot) in the handler.
2139 frame_->Forget(frame_->height() - handler_height + 1);
2140 2140
2141 // kNextIndex is off by one because the code slot has already 2141 ASSERT(StackHandlerConstants::kNextOffset == 0);
2142 // been dropped. 2142 frame_->EmitPop(r1);
2143 __ ldr(r1, frame_->ElementAt(kNextIndex - 1));
2144 __ str(r1, MemOperand(r3)); 2143 __ str(r1, MemOperand(r3));
2145 // The code slot has already been dropped from the handler.
2146 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); 2144 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
2147 2145
2148 if (!function_return_is_shadowed_ && i == kReturnShadowIndex) { 2146 if (!function_return_is_shadowed_ && i == kReturnShadowIndex) {
2149 frame_->PrepareForReturn(); 2147 frame_->PrepareForReturn();
2150 } 2148 }
2151 shadows[i]->other_target()->Jump(); 2149 shadows[i]->other_target()->Jump();
2152 } 2150 }
2153 } 2151 }
2154 2152
2155 exit.Bind(); 2153 exit.Bind();
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2216 int nof_unlinks = 0; 2214 int nof_unlinks = 0;
2217 for (int i = 0; i < shadows.length(); i++) { 2215 for (int i = 0; i < shadows.length(); i++) {
2218 shadows[i]->StopShadowing(); 2216 shadows[i]->StopShadowing();
2219 if (shadows[i]->is_linked()) nof_unlinks++; 2217 if (shadows[i]->is_linked()) nof_unlinks++;
2220 } 2218 }
2221 function_return_is_shadowed_ = function_return_was_shadowed; 2219 function_return_is_shadowed_ = function_return_was_shadowed;
2222 2220
2223 // Get an external reference to the handler address. 2221 // Get an external reference to the handler address.
2224 ExternalReference handler_address(Top::k_handler_address); 2222 ExternalReference handler_address(Top::k_handler_address);
2225 2223
2226 // The next handler address is at kNextIndex in the stack.
2227 const int kNextIndex = StackHandlerConstants::kNextOffset / kPointerSize;
2228 // If we can fall off the end of the try block, unlink from the try 2224 // If we can fall off the end of the try block, unlink from the try
2229 // chain and set the state on the frame to FALLING. 2225 // chain and set the state on the frame to FALLING.
2230 if (has_valid_frame()) { 2226 if (has_valid_frame()) {
2231 __ ldr(r1, frame_->ElementAt(kNextIndex)); 2227 // The next handler address is on top of the frame.
2228 ASSERT(StackHandlerConstants::kNextOffset == 0);
2229 frame_->EmitPop(r1);
2232 __ mov(r3, Operand(handler_address)); 2230 __ mov(r3, Operand(handler_address));
2233 __ str(r1, MemOperand(r3)); 2231 __ str(r1, MemOperand(r3));
2234 frame_->Drop(StackHandlerConstants::kSize / kPointerSize); 2232 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
2235 2233
2236 // Fake a top of stack value (unneeded when FALLING) and set the 2234 // Fake a top of stack value (unneeded when FALLING) and set the
2237 // state in r2, then jump around the unlink blocks if any. 2235 // state in r2, then jump around the unlink blocks if any.
2238 __ mov(r0, Operand(Factory::undefined_value())); 2236 __ mov(r0, Operand(Factory::undefined_value()));
2239 frame_->EmitPush(r0); 2237 frame_->EmitPush(r0);
2240 __ mov(r2, Operand(Smi::FromInt(FALLING))); 2238 __ mov(r2, Operand(Smi::FromInt(FALLING)));
2241 if (nof_unlinks > 0) { 2239 if (nof_unlinks > 0) {
2242 finally_block.Jump(); 2240 finally_block.Jump();
2243 } 2241 }
2244 } 2242 }
(...skipping 10 matching lines...) Expand all
2255 // unspilled code, we need to reestablish a spilled frame at 2253 // unspilled code, we need to reestablish a spilled frame at
2256 // this block. 2254 // this block.
2257 shadows[i]->Bind(); 2255 shadows[i]->Bind();
2258 frame_->SpillAll(); 2256 frame_->SpillAll();
2259 2257
2260 // Reload sp from the top handler, because some statements that 2258 // Reload sp from the top handler, because some statements that
2261 // we break from (eg, for...in) may have left stuff on the 2259 // we break from (eg, for...in) may have left stuff on the
2262 // stack. 2260 // stack.
2263 __ mov(r3, Operand(handler_address)); 2261 __ mov(r3, Operand(handler_address));
2264 __ ldr(sp, MemOperand(r3)); 2262 __ ldr(sp, MemOperand(r3));
2265 // The stack pointer was restored to the address slot in the handler. 2263 frame_->Forget(frame_->height() - handler_height);
2266 ASSERT(StackHandlerConstants::kNextOffset == 1 * kPointerSize);
2267 frame_->Forget(frame_->height() - handler_height + 1);
2268 2264
2269 // Unlink this handler and drop it from the frame. The next 2265 // Unlink this handler and drop it from the frame. The next
2270 // handler address is now on top of the frame. 2266 // handler address is currently on top of the frame.
2267 ASSERT(StackHandlerConstants::kNextOffset == 0);
2271 frame_->EmitPop(r1); 2268 frame_->EmitPop(r1);
2272 __ str(r1, MemOperand(r3)); 2269 __ str(r1, MemOperand(r3));
2273 // The top (code) and the second (handler) slot have both been 2270 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
2274 // dropped already.
2275 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 2);
2276 2271
2277 if (i == kReturnShadowIndex) { 2272 if (i == kReturnShadowIndex) {
2278 // If this label shadowed the function return, materialize the 2273 // If this label shadowed the function return, materialize the
2279 // return value on the stack. 2274 // return value on the stack.
2280 frame_->EmitPush(r0); 2275 frame_->EmitPush(r0);
2281 } else { 2276 } else {
2282 // Fake TOS for targets that shadowed breaks and continues. 2277 // Fake TOS for targets that shadowed breaks and continues.
2283 __ mov(r0, Operand(Factory::undefined_value())); 2278 __ mov(r0, Operand(Factory::undefined_value()));
2284 frame_->EmitPush(r0); 2279 frame_->EmitPush(r0);
2285 } 2280 }
(...skipping 2386 matching lines...) Expand 10 before | Expand all | Expand 10 after
4672 __ push(r0); 4667 __ push(r0);
4673 __ mov(r0, Operand(0)); // set number of arguments 4668 __ mov(r0, Operand(0)); // set number of arguments
4674 __ InvokeBuiltin(Builtins::UNARY_MINUS, JUMP_JS); 4669 __ InvokeBuiltin(Builtins::UNARY_MINUS, JUMP_JS);
4675 4670
4676 __ bind(&done); 4671 __ bind(&done);
4677 __ StubReturn(1); 4672 __ StubReturn(1);
4678 } 4673 }
4679 4674
4680 4675
4681 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { 4676 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
4682 // r0 holds exception 4677 // r0 holds the exception.
4683 ASSERT(StackHandlerConstants::kSize == 6 * kPointerSize); // adjust this code 4678
4679 // Adjust this code if not the case.
4680 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize);
4681
4682 // Drop the sp to the top of the handler.
4684 __ mov(r3, Operand(ExternalReference(Top::k_handler_address))); 4683 __ mov(r3, Operand(ExternalReference(Top::k_handler_address)));
4685 __ ldr(sp, MemOperand(r3)); 4684 __ ldr(sp, MemOperand(r3));
4686 __ pop(r2); // pop next in chain 4685
4686 // Restore the next handler and frame pointer, discard handler state.
4687 ASSERT(StackHandlerConstants::kNextOffset == 0);
4688 __ pop(r2);
4687 __ str(r2, MemOperand(r3)); 4689 __ str(r2, MemOperand(r3));
4688 // restore parameter- and frame-pointer and pop state. 4690 ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize);
4689 __ ldm(ia_w, sp, r3.bit() | pp.bit() | fp.bit()); 4691 __ ldm(ia_w, sp, r3.bit() | fp.bit()); // r3: discarded state.
4690 // Before returning we restore the context from the frame pointer if not NULL. 4692
4691 // The frame pointer is NULL in the exception handler of a JS entry frame. 4693 // Before returning we restore the context from the frame pointer if
4694 // not NULL. The frame pointer is NULL in the exception handler of a
4695 // JS entry frame.
4692 __ cmp(fp, Operand(0)); 4696 __ cmp(fp, Operand(0));
4693 // Set cp to NULL if fp is NULL. 4697 // Set cp to NULL if fp is NULL.
4694 __ mov(cp, Operand(0), LeaveCC, eq); 4698 __ mov(cp, Operand(0), LeaveCC, eq);
4695 // Restore cp otherwise. 4699 // Restore cp otherwise.
4696 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne); 4700 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne);
4697 #ifdef DEBUG 4701 #ifdef DEBUG
4698 if (FLAG_debug_code) { 4702 if (FLAG_debug_code) {
4699 __ mov(lr, Operand(pc)); 4703 __ mov(lr, Operand(pc));
4700 } 4704 }
4701 #endif 4705 #endif
4706 ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize);
4702 __ pop(pc); 4707 __ pop(pc);
4703 } 4708 }
4704 4709
4705 4710
4706 void CEntryStub::GenerateThrowOutOfMemory(MacroAssembler* masm) { 4711 void CEntryStub::GenerateThrowOutOfMemory(MacroAssembler* masm) {
4707 // Fetch top stack handler. 4712 // Adjust this code if not the case.
4713 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize);
4714
4715 // Drop sp to the top stack handler.
4708 __ mov(r3, Operand(ExternalReference(Top::k_handler_address))); 4716 __ mov(r3, Operand(ExternalReference(Top::k_handler_address)));
4709 __ ldr(r3, MemOperand(r3)); 4717 __ ldr(sp, MemOperand(r3));
4710 4718
4711 // Unwind the handlers until the ENTRY handler is found. 4719 // Unwind the handlers until the ENTRY handler is found.
4712 Label loop, done; 4720 Label loop, done;
4713 __ bind(&loop); 4721 __ bind(&loop);
4714 // Load the type of the current stack handler. 4722 // Load the type of the current stack handler.
4715 const int kStateOffset = StackHandlerConstants::kAddressDisplacement + 4723 const int kStateOffset = StackHandlerConstants::kStateOffset;
4716 StackHandlerConstants::kStateOffset; 4724 __ ldr(r2, MemOperand(sp, kStateOffset));
4717 __ ldr(r2, MemOperand(r3, kStateOffset));
4718 __ cmp(r2, Operand(StackHandler::ENTRY)); 4725 __ cmp(r2, Operand(StackHandler::ENTRY));
4719 __ b(eq, &done); 4726 __ b(eq, &done);
4720 // Fetch the next handler in the list. 4727 // Fetch the next handler in the list.
4721 const int kNextOffset = StackHandlerConstants::kAddressDisplacement + 4728 const int kNextOffset = StackHandlerConstants::kNextOffset;
4722 StackHandlerConstants::kNextOffset; 4729 __ ldr(sp, MemOperand(sp, kNextOffset));
4723 __ ldr(r3, MemOperand(r3, kNextOffset));
4724 __ jmp(&loop); 4730 __ jmp(&loop);
4725 __ bind(&done); 4731 __ bind(&done);
4726 4732
4727 // Set the top handler address to next handler past the current ENTRY handler. 4733 // Set the top handler address to next handler past the current ENTRY handler.
4728 __ ldr(r0, MemOperand(r3, kNextOffset)); 4734 ASSERT(StackHandlerConstants::kNextOffset == 0);
4729 __ mov(r2, Operand(ExternalReference(Top::k_handler_address))); 4735 __ pop(r0);
4730 __ str(r0, MemOperand(r2)); 4736 __ str(r0, MemOperand(r3));
4731 4737
4732 // Set external caught exception to false. 4738 // Set external caught exception to false.
4739 ExternalReference external_caught(Top::k_external_caught_exception_address);
4733 __ mov(r0, Operand(false)); 4740 __ mov(r0, Operand(false));
4734 ExternalReference external_caught(Top::k_external_caught_exception_address);
4735 __ mov(r2, Operand(external_caught)); 4741 __ mov(r2, Operand(external_caught));
4736 __ str(r0, MemOperand(r2)); 4742 __ str(r0, MemOperand(r2));
4737 4743
4738 // Set pending exception and r0 to out of memory exception. 4744 // Set pending exception and r0 to out of memory exception.
4739 Failure* out_of_memory = Failure::OutOfMemoryException(); 4745 Failure* out_of_memory = Failure::OutOfMemoryException();
4740 __ mov(r0, Operand(reinterpret_cast<int32_t>(out_of_memory))); 4746 __ mov(r0, Operand(reinterpret_cast<int32_t>(out_of_memory)));
4741 __ mov(r2, Operand(ExternalReference(Top::k_pending_exception_address))); 4747 __ mov(r2, Operand(ExternalReference(Top::k_pending_exception_address)));
4742 __ str(r0, MemOperand(r2)); 4748 __ str(r0, MemOperand(r2));
4743 4749
4744 // Restore the stack to the address of the ENTRY handler 4750 // Stack layout at this point. See also StackHandlerConstants.
4745 __ mov(sp, Operand(r3)); 4751 // sp -> state (ENTRY)
4752 // fp
4753 // lr
4746 4754
4747 // Stack layout at this point. See also PushTryHandler 4755 // Discard handler state (r2 is not used) and restore frame pointer.
4748 // r3, sp -> next handler 4756 ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize);
4749 // state (ENTRY) 4757 __ ldm(ia_w, sp, r2.bit() | fp.bit()); // r2: discarded state.
4750 // pp 4758 // Before returning we restore the context from the frame pointer if
4751 // fp 4759 // not NULL. The frame pointer is NULL in the exception handler of a
4752 // lr 4760 // JS entry frame.
4753
4754 // Discard ENTRY state (r2 is not used), and restore parameter-
4755 // and frame-pointer and pop state.
4756 __ ldm(ia_w, sp, r2.bit() | r3.bit() | pp.bit() | fp.bit());
4757 // Before returning we restore the context from the frame pointer if not NULL.
4758 // The frame pointer is NULL in the exception handler of a JS entry frame.
4759 __ cmp(fp, Operand(0)); 4761 __ cmp(fp, Operand(0));
4760 // Set cp to NULL if fp is NULL. 4762 // Set cp to NULL if fp is NULL.
4761 __ mov(cp, Operand(0), LeaveCC, eq); 4763 __ mov(cp, Operand(0), LeaveCC, eq);
4762 // Restore cp otherwise. 4764 // Restore cp otherwise.
4763 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne); 4765 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne);
4764 #ifdef DEBUG 4766 #ifdef DEBUG
4765 if (FLAG_debug_code) { 4767 if (FLAG_debug_code) {
4766 __ mov(lr, Operand(pc)); 4768 __ mov(lr, Operand(pc));
4767 } 4769 }
4768 #endif 4770 #endif
4771 ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize);
4769 __ pop(pc); 4772 __ pop(pc);
4770 } 4773 }
4771 4774
4772 4775
4773 void CEntryStub::GenerateCore(MacroAssembler* masm, 4776 void CEntryStub::GenerateCore(MacroAssembler* masm,
4774 Label* throw_normal_exception, 4777 Label* throw_normal_exception,
4775 Label* throw_out_of_memory_exception, 4778 Label* throw_out_of_memory_exception,
4776 StackFrame::Type frame_type, 4779 StackFrame::Type frame_type,
4777 bool do_gc, 4780 bool do_gc,
4778 bool always_allocate) { 4781 bool always_allocate) {
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
5176 __ mov(r2, Operand(0)); 5179 __ mov(r2, Operand(0));
5177 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); 5180 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
5178 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), 5181 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)),
5179 RelocInfo::CODE_TARGET); 5182 RelocInfo::CODE_TARGET);
5180 } 5183 }
5181 5184
5182 5185
5183 #undef __ 5186 #undef __
5184 5187
5185 } } // namespace v8::internal 5188 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/arm/frames-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698