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

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

Issue 27084: Experimental: restore the test at the bottom of for and while loops.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: '' Created 11 years, 10 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 | no next file » | 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 2231 matching lines...) Expand 10 before | Expand all | Expand 10 after
2242 LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true); 2242 LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true);
2243 } 2243 }
2244 if (node->break_target()->is_linked()) { 2244 if (node->break_target()->is_linked()) {
2245 node->break_target()->Bind(); 2245 node->break_target()->Bind();
2246 } 2246 }
2247 } 2247 }
2248 break; 2248 break;
2249 } 2249 }
2250 2250
2251 case LoopStatement::WHILE_LOOP: { 2251 case LoopStatement::WHILE_LOOP: {
2252 JumpTarget body(this, JumpTarget::BIDIRECTIONAL);
2252 IncrementLoopNesting(); 2253 IncrementLoopNesting();
2253 2254
2254 // If the test is never true and has no side effects there is no need 2255 // Based on the condition analysis, compile the test if
2255 // to compile the test or body. 2256 // necessary and label the body if necessary.
2256 if (info == ALWAYS_FALSE) break; 2257 if (info == ALWAYS_TRUE) {
2258 // We will not compile the test expression. Label the top of
2259 // the loop with the continue target.
2260 node->continue_target()->Initialize(this, JumpTarget::BIDIRECTIONAL);
2261 node->continue_target()->Bind();
2262 } else if (info == ALWAYS_FALSE) {
Kasper Lund 2009/02/24 08:52:55 I actually preferred to have this as a separate ch
Kevin Millikin (Chromium) 2009/02/24 08:56:32 Easily done.
2263 // We will not compile the test or the body. Nothing is
2264 // labeled.
2265 break;
2266 } else {
2267 ASSERT(info == DONT_KNOW);
2268 node->continue_target()->Initialize(this);
2269 // Compile the test with the body as the true target and
2270 // preferred fall-through and with the break target as the
2271 // false target.
2272 ControlDestination dest(&body, node->break_target(), true);
2273 LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true);
2257 2274
2258 // Label the top of the loop with the continue target for the backward 2275 if (dest.false_was_fall_through()) {
2259 // CFG edge. 2276 // If we don't have dangling jumps to the body, the test is
2260 node->continue_target()->Initialize(this, JumpTarget::BIDIRECTIONAL); 2277 // unconditionally false and we do not need to compile the
2261 node->continue_target()->Bind(); 2278 // body.
2279 if (!body.is_linked()) break;
2262 2280
2263 // If the test is always true and has no side effects there is no need 2281 // Otherwise, jump around the body on the fall through and
2264 // to compile it. We only compile the test when we do not know its 2282 // then bind the body target.
2265 // outcome or it may have side effects. 2283 node->break_target()->Unuse();
2266 JumpTarget body(this); 2284 node->break_target()->Jump();
2267 ControlDestination dest(&body, node->break_target(), true); 2285 body.Bind();
2268 if (info == DONT_KNOW) { 2286 }
2269 LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true);
2270 } 2287 }
2271 2288
2272 if (dest.false_was_fall_through()) { 2289 // The (stack check at the start of the) body was labeled.
2273 // The break target was bound. We may have dangling jumps to 2290 // Compile it.
2274 // the body.
2275 if (!body.is_linked()) break;
2276
2277 // We have dangling jumps to the body target.
2278 node->break_target()->Unuse();
2279 node->break_target()->Jump();
2280 body.Bind();
2281 }
2282
2283 // The body target has just been bound or else we didn't compile
2284 // the test.
2285 CheckStack(); // TODO(1222600): ignore if body contains calls. 2291 CheckStack(); // TODO(1222600): ignore if body contains calls.
2286 Visit(node->body()); 2292 Visit(node->body());
2287 2293
2288 // If control flow can fall out of the body, jump back to the top. 2294 // Compile the test if necessary and jump back.
2289 if (has_valid_frame()) { 2295 if (info == ALWAYS_TRUE) {
2290 node->continue_target()->Jump(); 2296 // The body has been labeled with the continue target.
2297 if (has_valid_frame()) {
2298 node->continue_target()->Jump();
2299 }
2300 } else {
2301 ASSERT(info == DONT_KNOW); // ALWAYS_FALSE cannot reach here.
2302 if (node->continue_target()->is_linked()) {
2303 node->continue_target()->Bind();
2304 }
2305
2306 // If control can reach the bottom by falling off the body or
2307 // a continue in the body, (re)compile the test at the bottom.
2308 if (has_valid_frame()) {
2309 // The break target is the fall-through (body is a backward
2310 // jump from here).
2311 ControlDestination dest(&body, node->break_target(), false);
2312 LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true);
2313 }
2291 } 2314 }
2315
2316 // The break target may be already bound (by the condition), or
2317 // there may not be a valid frame. Bind it only if needed.
2292 if (node->break_target()->is_linked()) { 2318 if (node->break_target()->is_linked()) {
2293 node->break_target()->Bind(); 2319 node->break_target()->Bind();
2294 } 2320 }
2295 break; 2321 break;
2296 } 2322 }
2297 2323
2298 case LoopStatement::FOR_LOOP: { 2324 case LoopStatement::FOR_LOOP: {
2299 JumpTarget loop(this, JumpTarget::BIDIRECTIONAL); 2325 JumpTarget body(this, JumpTarget::BIDIRECTIONAL);
2326
2327 // Compile the init expression if present.
2300 if (node->init() != NULL) { 2328 if (node->init() != NULL) {
2301 Visit(node->init()); 2329 Visit(node->init());
2302 } 2330 }
2303 2331
2304 IncrementLoopNesting(); 2332 IncrementLoopNesting();
2305 // If the test is never true and has no side effects there is no need
2306 // to compile the test or body.
2307 if (info == ALWAYS_FALSE) break;
2308 2333
2309 // Label the top of the loop for the backward CFG edge. If there is 2334 // Based on the condition analysis, compile the test if
2310 // no update expression we can use the continue target. 2335 // necessary and label the body if necessary.
2311 if (node->next() == NULL) { 2336 if (info == ALWAYS_TRUE) {
2312 node->continue_target()->Initialize(this, JumpTarget::BIDIRECTIONAL); 2337 // We will not compile the test expression. Label the top of
2313 node->continue_target()->Bind(); 2338 // the loop with the continue target if there is no update
2339 // expression, otherwise with the body target.
2340 if (node->next() == NULL) {
2341 node->continue_target()->Initialize(this, JumpTarget::BIDIRECTIONAL);
2342 node->continue_target()->Bind();
2343 } else {
2344 node->continue_target()->Initialize(this);
2345 body.Bind();
2346 }
2347 } else if (info == ALWAYS_FALSE) {
2348 // We will not compile the test, the body, or the update
2349 // expression. Nothing is labeled.
2350 break;
Kasper Lund 2009/02/24 08:52:55 Same here. Move ALWAYS_FALSE check to beginning of
2314 } else { 2351 } else {
2352 ASSERT(info == DONT_KNOW);
2315 node->continue_target()->Initialize(this); 2353 node->continue_target()->Initialize(this);
2316 loop.Bind(); 2354 // Compile the test with the body as the true target and
2355 // preferred fall-through and with the break target as the
2356 // false target.
2357 ControlDestination dest(&body, node->break_target(), true);
2358 LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true);
2359
2360 if (dest.false_was_fall_through()) {
2361 // If we don't have dangling jumps to the body, the test is
2362 // unconditionally false and we do not need to compile the
2363 // body.
2364 if (!body.is_linked()) break;
2365
2366 // Otherwise, jump around the body on the fall through and
2367 // then bind the body target.
2368 node->break_target()->Unuse();
2369 node->break_target()->Jump();
2370 body.Bind();
2371 }
2317 } 2372 }
2318 2373
2319 // If the test is always true and has no side effects there is no need 2374 // The (stack check at the start of the) body was labeled.
2320 // to compile it. We only compile the test when we do not know its 2375 // Compile it.
2321 // outcome or it has side effects.
2322 JumpTarget body(this);
2323 ControlDestination dest(&body, node->break_target(), true);
2324 if (info == DONT_KNOW) {
2325 LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true);
2326 }
2327
2328 if (dest.false_was_fall_through()) {
2329 // The break target was bound. We may have dangling jumps to
2330 // the body.
2331 if (!body.is_linked()) break;
2332
2333 node->break_target()->Unuse();
2334 node->break_target()->Jump();
2335 body.Bind();
2336 }
2337
2338 // The body target has just been bound or else we didn't compile
2339 // the test.
2340 CheckStack(); // TODO(1222600): ignore if body contains calls. 2376 CheckStack(); // TODO(1222600): ignore if body contains calls.
2341 Visit(node->body()); 2377 Visit(node->body());
2342 2378
2343 if (node->next() == NULL) { 2379 // If there is an update expression, compile it if necessary.
2344 // If there is no update statement and control flow can fall out 2380 if (node->next() != NULL) {
2345 // of the loop, jump to the continue label. 2381 // We did not use the continue target for the body.
2346 if (has_valid_frame()) {
2347 node->continue_target()->Jump();
2348 }
2349 if (node->break_target()->is_linked()) {
2350 node->break_target()->Bind();
2351 }
2352
2353 } else {
2354 // If there is an update statement and control flow can reach it
2355 // via falling out of the body of the loop or continuing, we
2356 // compile the update statement.
2357 if (node->continue_target()->is_linked()) { 2382 if (node->continue_target()->is_linked()) {
2358 node->continue_target()->Bind(); 2383 node->continue_target()->Bind();
2359 } 2384 }
2385
2386 // Control can reach the update by falling out of the body or
2387 // by a continue in the body.
2360 if (has_valid_frame()) { 2388 if (has_valid_frame()) {
2361 // Record source position of the statement as this code which is 2389 // Record the source position of the statement as this code
2362 // after the code for the body actually belongs to the loop 2390 // which is after the code for the body actually belongs to
2363 // statement and not the body. 2391 // the loop statement and not the body.
2364 CodeForStatementPosition(node); 2392 CodeForStatementPosition(node);
2365 Visit(node->next()); 2393 Visit(node->next());
2366 loop.Jump();
2367 }
2368 if (node->break_target()->is_linked()) {
2369 node->break_target()->Bind();
2370 } 2394 }
2371 } 2395 }
2372 2396
2397 // Compile the test if necessary and jump back.
2398 if (info == ALWAYS_TRUE) {
2399 if (has_valid_frame()) {
2400 if (node->next() == NULL) {
2401 node->continue_target()->Jump();
2402 } else {
2403 body.Jump();
2404 }
2405 }
2406 } else {
2407 ASSERT(info == DONT_KNOW); // ALWAYS_FALSE cannot reach here.
2408 if (node->continue_target()->is_linked()) {
2409 // We can have dangling jumps to the continue target if
2410 // there was no update expression.
2411 node->continue_target()->Bind();
2412 }
2413
2414 // Control can reach the test at the bottom by falling out of
2415 // the body, by a continue in the body, or from the update
2416 // expression.
2417 if (has_valid_frame()) {
2418 // The break target is the fall-through (body is a backward
2419 // jump from here).
2420 ControlDestination dest(&body, node->break_target(), false);
2421 LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true);
2422 }
2423 }
2424
2425 // The break target may be already bound (by the condition), or
2426 // there may not be a valid frame. Bind it only if needed.
2427 if (node->break_target()->is_linked()) {
2428 node->break_target()->Bind();
2429 }
2373 break; 2430 break;
2374 } 2431 }
2375 } 2432 }
2376 2433
2377 DecrementLoopNesting(); 2434 DecrementLoopNesting();
2378 } 2435 }
2379 2436
2380 2437
2381 void CodeGenerator::VisitForInStatement(ForInStatement* node) { 2438 void CodeGenerator::VisitForInStatement(ForInStatement* node) {
2382 ASSERT(!in_spilled_code()); 2439 ASSERT(!in_spilled_code());
(...skipping 4284 matching lines...) Expand 10 before | Expand all | Expand 10 after
6667 6724
6668 // Slow-case: Go through the JavaScript implementation. 6725 // Slow-case: Go through the JavaScript implementation.
6669 __ bind(&slow); 6726 __ bind(&slow);
6670 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 6727 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
6671 } 6728 }
6672 6729
6673 6730
6674 #undef __ 6731 #undef __
6675 6732
6676 } } // namespace v8::internal 6733 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698