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

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

Issue 39331: Fix issue 263:... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 9 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/codegen-ia32.cc » ('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-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 2040 matching lines...) Expand 10 before | Expand all | Expand 10 after
2051 for (int i = 0; i < nof_escapes; i++) { 2051 for (int i = 0; i < nof_escapes; i++) {
2052 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); 2052 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i)));
2053 } 2053 }
2054 2054
2055 // Generate code for the statements in the try block. 2055 // Generate code for the statements in the try block.
2056 VisitStatementsAndSpill(node->try_block()->statements()); 2056 VisitStatementsAndSpill(node->try_block()->statements());
2057 2057
2058 // Stop the introduced shadowing and count the number of required unlinks. 2058 // Stop the introduced shadowing and count the number of required unlinks.
2059 // After shadowing stops, the original labels are unshadowed and the 2059 // After shadowing stops, the original labels are unshadowed and the
2060 // LabelShadows represent the formerly shadowing labels. 2060 // LabelShadows represent the formerly shadowing labels.
2061 int nof_unlinks = 0; 2061 bool has_unlinks = false;
2062 for (int i = 0; i <= nof_escapes; i++) { 2062 for (int i = 0; i <= nof_escapes; i++) {
2063 shadows[i]->StopShadowing(); 2063 shadows[i]->StopShadowing();
2064 if (shadows[i]->is_linked()) nof_unlinks++; 2064 has_unlinks = has_unlinks || shadows[i]->is_linked();
2065 } 2065 }
2066 function_return_is_shadowed_ = function_return_was_shadowed; 2066 function_return_is_shadowed_ = function_return_was_shadowed;
2067 2067
2068 // Get an external reference to the handler address.
2069 ExternalReference handler_address(Top::k_handler_address);
2070
2071 // The next handler address is at kNextIndex in the stack.
2068 const int kNextIndex = StackHandlerConstants::kNextOffset / kPointerSize; 2072 const int kNextIndex = StackHandlerConstants::kNextOffset / kPointerSize;
2069 // If we can fall off the end of the try block, unlink from try chain. 2073 // If we can fall off the end of the try block, unlink from try chain.
2070 if (has_valid_frame()) { 2074 if (has_valid_frame()) {
2071 // The next handler address is at kNextIndex in the stack.
2072 __ ldr(r1, frame_->ElementAt(kNextIndex)); 2075 __ ldr(r1, frame_->ElementAt(kNextIndex));
2073 __ mov(r3, Operand(ExternalReference(Top::k_handler_address))); 2076 __ mov(r3, Operand(handler_address));
2074 __ str(r1, MemOperand(r3)); 2077 __ str(r1, MemOperand(r3));
2075 frame_->Drop(StackHandlerConstants::kSize / kPointerSize); 2078 frame_->Drop(StackHandlerConstants::kSize / kPointerSize);
2076 if (nof_unlinks > 0) { 2079 if (has_unlinks) {
2077 exit.Jump(); 2080 exit.Jump();
2078 } 2081 }
2079 } 2082 }
2080 2083
2081 // Generate unlink code for the (formerly) shadowing labels that have been 2084 // Generate unlink code for the (formerly) shadowing labels that have been
2082 // jumped to. 2085 // jumped to.
2083 for (int i = 0; i <= nof_escapes; i++) { 2086 for (int i = 0; i <= nof_escapes; i++) {
2084 if (shadows[i]->is_linked()) { 2087 if (shadows[i]->is_linked()) {
2085 // Unlink from try chain; 2088 // Unlink from try chain;
2086 shadows[i]->Bind(); 2089 shadows[i]->Bind();
2087 // Because we can be jumping here (to spilled code) from unspilled 2090 // Because we can be jumping here (to spilled code) from unspilled
2088 // code, we need to reestablish a spilled frame at this block. 2091 // code, we need to reestablish a spilled frame at this block.
2089 frame_->SpillAll(); 2092 frame_->SpillAll();
2090 2093
2091 // Reload sp from the top handler, because some statements that we 2094 // Reload sp from the top handler, because some statements that we
2092 // break from (eg, for...in) may have left stuff on the stack. 2095 // break from (eg, for...in) may have left stuff on the stack.
2093 __ mov(r3, Operand(ExternalReference(Top::k_handler_address))); 2096 __ mov(r3, Operand(handler_address));
2094 __ ldr(sp, MemOperand(r3)); 2097 __ ldr(sp, MemOperand(r3));
2095 // The stack pointer was restored to just below the code slot 2098 // The stack pointer was restored to just below the code slot
2096 // (the topmost slot) in the handler. 2099 // (the topmost slot) in the handler.
2097 frame_->Forget(frame_->height() - handler_height + 1); 2100 frame_->Forget(frame_->height() - handler_height + 1);
2098 2101
2099 // kNextIndex is off by one because the code slot has already 2102 // kNextIndex is off by one because the code slot has already
2100 // been dropped. 2103 // been dropped.
2101 __ ldr(r1, frame_->ElementAt(kNextIndex - 1)); 2104 __ ldr(r1, frame_->ElementAt(kNextIndex - 1));
2102 __ str(r1, MemOperand(r3)); 2105 __ str(r1, MemOperand(r3));
2103 // The code slot has already been dropped from the handler. 2106 // The code slot has already been dropped from the handler.
(...skipping 17 matching lines...) Expand all
2121 #endif 2124 #endif
2122 VirtualFrame::SpilledScope spilled_scope(this); 2125 VirtualFrame::SpilledScope spilled_scope(this);
2123 Comment cmnt(masm_, "[ TryFinally"); 2126 Comment cmnt(masm_, "[ TryFinally");
2124 CodeForStatementPosition(node); 2127 CodeForStatementPosition(node);
2125 2128
2126 // State: Used to keep track of reason for entering the finally 2129 // State: Used to keep track of reason for entering the finally
2127 // block. Should probably be extended to hold information for 2130 // block. Should probably be extended to hold information for
2128 // break/continue from within the try block. 2131 // break/continue from within the try block.
2129 enum { FALLING, THROWING, JUMPING }; 2132 enum { FALLING, THROWING, JUMPING };
2130 2133
2131 JumpTarget unlink(this);
2132 JumpTarget try_block(this); 2134 JumpTarget try_block(this);
2133 JumpTarget finally_block(this); 2135 JumpTarget finally_block(this);
2134 2136
2135 try_block.Call(); 2137 try_block.Call();
2136 2138
2137 frame_->EmitPush(r0); // save exception object on the stack 2139 frame_->EmitPush(r0); // save exception object on the stack
2138 // In case of thrown exceptions, this is where we continue. 2140 // In case of thrown exceptions, this is where we continue.
2139 __ mov(r2, Operand(Smi::FromInt(THROWING))); 2141 __ mov(r2, Operand(Smi::FromInt(THROWING)));
2140 finally_block.Jump(); 2142 finally_block.Jump();
2141 2143
(...skipping 30 matching lines...) Expand all
2172 // Stop the introduced shadowing and count the number of required unlinks. 2174 // Stop the introduced shadowing and count the number of required unlinks.
2173 // After shadowing stops, the original labels are unshadowed and the 2175 // After shadowing stops, the original labels are unshadowed and the
2174 // LabelShadows represent the formerly shadowing labels. 2176 // LabelShadows represent the formerly shadowing labels.
2175 int nof_unlinks = 0; 2177 int nof_unlinks = 0;
2176 for (int i = 0; i <= nof_escapes; i++) { 2178 for (int i = 0; i <= nof_escapes; i++) {
2177 shadows[i]->StopShadowing(); 2179 shadows[i]->StopShadowing();
2178 if (shadows[i]->is_linked()) nof_unlinks++; 2180 if (shadows[i]->is_linked()) nof_unlinks++;
2179 } 2181 }
2180 function_return_is_shadowed_ = function_return_was_shadowed; 2182 function_return_is_shadowed_ = function_return_was_shadowed;
2181 2183
2182 // If we can fall off the end of the try block, set the state on the stack 2184 // Get an external reference to the handler address.
2183 // to FALLING. 2185 ExternalReference handler_address(Top::k_handler_address);
2186
2187 // The next handler address is at kNextIndex in the stack.
2188 const int kNextIndex = StackHandlerConstants::kNextOffset / kPointerSize;
2189 // If we can fall off the end of the try block, unlink from the try
2190 // chain and set the state on the frame to FALLING.
2184 if (has_valid_frame()) { 2191 if (has_valid_frame()) {
2185 __ mov(r0, Operand(Factory::undefined_value())); // fake TOS 2192 __ ldr(r1, frame_->ElementAt(kNextIndex));
2193 __ mov(r3, Operand(handler_address));
2194 __ str(r1, MemOperand(r3));
2195 frame_->Drop(StackHandlerConstants::kSize / kPointerSize);
2196
2197 // Fake a top of stack value (unneeded when FALLING) and set the
2198 // state in r2, then jump around the unlink blocks if any.
2199 __ mov(r0, Operand(Factory::undefined_value()));
2186 frame_->EmitPush(r0); 2200 frame_->EmitPush(r0);
2187 __ mov(r2, Operand(Smi::FromInt(FALLING))); 2201 __ mov(r2, Operand(Smi::FromInt(FALLING)));
2188 if (nof_unlinks > 0) { 2202 if (nof_unlinks > 0) {
2189 unlink.Jump(); 2203 finally_block.Jump();
2190 } 2204 }
2191 } 2205 }
2192 2206
2193 // Generate code to set the state for the (formerly) shadowing labels that 2207 // Generate code to unlink and set the state for the (formerly)
2194 // have been jumped to. 2208 // shadowing labels that have been jumped to.
2195 for (int i = 0; i <= nof_escapes; i++) { 2209 for (int i = 0; i <= nof_escapes; i++) {
2196 if (shadows[i]->is_linked()) { 2210 if (shadows[i]->is_linked()) {
2211 // If we have come from the shadowed return, the return value is
2212 // in (a non-refcounted reference to) r0. We must preserve it
2213 // until it is pushed.
2214 //
2197 // Because we can be jumping here (to spilled code) from 2215 // Because we can be jumping here (to spilled code) from
2198 // unspilled code, we need to reestablish a spilled frame at 2216 // unspilled code, we need to reestablish a spilled frame at
2199 // this block. 2217 // this block.
2200 shadows[i]->Bind(); 2218 shadows[i]->Bind();
2201 frame_->SpillAll(); 2219 frame_->SpillAll();
2220
2221 // Reload sp from the top handler, because some statements that
2222 // we break from (eg, for...in) may have left stuff on the
2223 // stack.
2224 __ mov(r3, Operand(handler_address));
2225 __ ldr(sp, MemOperand(r3));
2226 // The stack pointer was restored to the address slot in the handler.
2227 ASSERT(StackHandlerConstants::kNextOffset == 1 * kPointerSize);
2228 frame_->Forget(frame_->height() - handler_height + 1);
2229
2230 // Unlink this handler and drop it from the frame. The next
2231 // handler address is now on top of the frame.
2232 frame_->EmitPop(r1);
2233 __ str(r1, MemOperand(r3));
2234 // The top (code) and the second (handler) slot have both been
2235 // dropped already.
2236 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 2);
2237
2202 if (i == kReturnShadowIndex) { 2238 if (i == kReturnShadowIndex) {
2203 // If this label shadowed the function return, materialize the 2239 // If this label shadowed the function return, materialize the
2204 // return value on the stack. 2240 // return value on the stack.
2205 frame_->EmitPush(r0); 2241 frame_->EmitPush(r0);
2206 } else { 2242 } else {
2207 // Fake TOS for targets that shadowed breaks and continues. 2243 // Fake TOS for targets that shadowed breaks and continues.
2208 __ mov(r0, Operand(Factory::undefined_value())); 2244 __ mov(r0, Operand(Factory::undefined_value()));
2209 frame_->EmitPush(r0); 2245 frame_->EmitPush(r0);
2210 } 2246 }
2211 __ mov(r2, Operand(Smi::FromInt(JUMPING + i))); 2247 __ mov(r2, Operand(Smi::FromInt(JUMPING + i)));
2212 unlink.Jump(); 2248 if (--nof_unlinks > 0) {
2249 // If this is not the last unlink block, jump around the next.
2250 finally_block.Jump();
2251 }
2213 } 2252 }
2214 } 2253 }
2215 2254
2216 // Unlink from try chain;
2217 if (unlink.is_linked()) {
2218 unlink.Bind();
2219 }
2220
2221 // Control can reach here via a jump to unlink or by falling off the
2222 // end of the try block (with no unlinks).
2223 if (has_valid_frame()) {
2224 // Preserve TOS result in r0 across stack manipulation.
2225 frame_->EmitPop(r0);
2226 // Reload sp from the top handler, because some statements that we
2227 // break from (eg, for...in) may have left stuff on the stack.
2228 __ mov(r3, Operand(ExternalReference(Top::k_handler_address)));
2229 __ ldr(sp, MemOperand(r3));
2230 // The stack pointer was restored to just below the code slot (the
2231 // topmost slot) in the handler.
2232 frame_->Forget(frame_->height() - handler_height + 1);
2233 const int kNextIndex = (StackHandlerConstants::kNextOffset
2234 + StackHandlerConstants::kAddressDisplacement)
2235 / kPointerSize;
2236 __ ldr(r1, frame_->ElementAt(kNextIndex));
2237 __ str(r1, MemOperand(r3));
2238 ASSERT(StackHandlerConstants::kCodeOffset == 0);
2239 // Drop the rest of the handler (not including the already dropped
2240 // code slot).
2241 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
2242 // Restore the result to TOS.
2243 frame_->EmitPush(r0);
2244 }
2245
2246 // --- Finally block --- 2255 // --- Finally block ---
2247 finally_block.Bind(); 2256 finally_block.Bind();
2248 2257
2249 // Push the state on the stack. 2258 // Push the state on the stack.
2250 frame_->EmitPush(r2); 2259 frame_->EmitPush(r2);
2251 2260
2252 // We keep two elements on the stack - the (possibly faked) result 2261 // We keep two elements on the stack - the (possibly faked) result
2253 // and the state - while evaluating the finally block. Record it, so 2262 // and the state - while evaluating the finally block. Record it, so
2254 // that a break/continue crossing this statement can restore the 2263 // that a break/continue crossing this statement can restore the
2255 // stack. 2264 // stack.
(...skipping 2830 matching lines...) Expand 10 before | Expand all | Expand 10 after
5086 __ mov(r2, Operand(0)); 5095 __ mov(r2, Operand(0));
5087 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); 5096 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
5088 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), 5097 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)),
5089 RelocInfo::CODE_TARGET); 5098 RelocInfo::CODE_TARGET);
5090 } 5099 }
5091 5100
5092 5101
5093 #undef __ 5102 #undef __
5094 5103
5095 } } // namespace v8::internal 5104 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698