| OLD | NEW |
| 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 2210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2221 LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true); | 2221 LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true); |
| 2222 } | 2222 } |
| 2223 if (node->break_target()->is_linked()) { | 2223 if (node->break_target()->is_linked()) { |
| 2224 node->break_target()->Bind(); | 2224 node->break_target()->Bind(); |
| 2225 } | 2225 } |
| 2226 } | 2226 } |
| 2227 break; | 2227 break; |
| 2228 } | 2228 } |
| 2229 | 2229 |
| 2230 case LoopStatement::WHILE_LOOP: { | 2230 case LoopStatement::WHILE_LOOP: { |
| 2231 // TODO(260): This flag controls whether to duplicate the test | 2231 // Do not duplicate conditions with function literal |
| 2232 // at the bottom of the loop. Replace it with a better | 2232 // subexpressions. This can cause us to compile the function |
| 2233 // indication of when it is safe to do so. | 2233 // literal twice. |
| 2234 static const bool test_at_bottom = false; | 2234 bool test_at_bottom = !node->has_function_literal(); |
| 2235 | 2235 |
| 2236 JumpTarget body(this); // Initialized as forward-only. | |
| 2237 IncrementLoopNesting(); | 2236 IncrementLoopNesting(); |
| 2238 | 2237 |
| 2239 // If the condition is always false and has no side effects, we | 2238 // If the condition is always false and has no side effects, we |
| 2240 // do not need to compile anything. | 2239 // do not need to compile anything. |
| 2241 if (info == ALWAYS_FALSE) break; | 2240 if (info == ALWAYS_FALSE) break; |
| 2242 | 2241 |
| 2242 JumpTarget body; |
| 2243 if (test_at_bottom) { |
| 2244 body.Initialize(this, JumpTarget::BIDIRECTIONAL); |
| 2245 } else { |
| 2246 body.Initialize(this); |
| 2247 } |
| 2248 |
| 2243 // Based on the condition analysis, compile the test as necessary. | 2249 // Based on the condition analysis, compile the test as necessary. |
| 2244 if (info == ALWAYS_TRUE) { | 2250 if (info == ALWAYS_TRUE) { |
| 2245 // We will not compile the test expression. Label the top of | 2251 // We will not compile the test expression. Label the top of |
| 2246 // the loop with the continue target. | 2252 // the loop with the continue target. |
| 2247 node->continue_target()->Initialize(this, JumpTarget::BIDIRECTIONAL); | 2253 node->continue_target()->Initialize(this, JumpTarget::BIDIRECTIONAL); |
| 2248 node->continue_target()->Bind(); | 2254 node->continue_target()->Bind(); |
| 2249 } else { | 2255 } else { |
| 2250 ASSERT(info == DONT_KNOW); // ALWAYS_FALSE cannot reach here. | 2256 ASSERT(info == DONT_KNOW); // ALWAYS_FALSE cannot reach here. |
| 2251 if (test_at_bottom) { | 2257 if (test_at_bottom) { |
| 2252 // Continue is the test at the bottom, no need to label the | 2258 // Continue is the test at the bottom, no need to label the |
| 2253 // test at the top. The body is a backward target. | 2259 // test at the top. The body is a backward target. |
| 2254 node->continue_target()->Initialize(this); | 2260 node->continue_target()->Initialize(this); |
| 2255 body.make_bidirectional(); | |
| 2256 } else { | 2261 } else { |
| 2257 // Label the test at the top as the continue target. The | 2262 // Label the test at the top as the continue target. The |
| 2258 // body is a forward-only target. | 2263 // body is a forward-only target. |
| 2259 node->continue_target()->Initialize(this, JumpTarget::BIDIRECTIONAL); | 2264 node->continue_target()->Initialize(this, JumpTarget::BIDIRECTIONAL); |
| 2260 node->continue_target()->Bind(); | 2265 node->continue_target()->Bind(); |
| 2261 } | 2266 } |
| 2262 // Compile the test with the body as the true target and | 2267 // Compile the test with the body as the true target and |
| 2263 // preferred fall-through and with the break target as the | 2268 // preferred fall-through and with the break target as the |
| 2264 // false target. | 2269 // false target. |
| 2265 ControlDestination dest(&body, node->break_target(), true); | 2270 ControlDestination dest(&body, node->break_target(), true); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2314 | 2319 |
| 2315 // The break target may be already bound (by the condition), or | 2320 // The break target may be already bound (by the condition), or |
| 2316 // there may not be a valid frame. Bind it only if needed. | 2321 // there may not be a valid frame. Bind it only if needed. |
| 2317 if (node->break_target()->is_linked()) { | 2322 if (node->break_target()->is_linked()) { |
| 2318 node->break_target()->Bind(); | 2323 node->break_target()->Bind(); |
| 2319 } | 2324 } |
| 2320 break; | 2325 break; |
| 2321 } | 2326 } |
| 2322 | 2327 |
| 2323 case LoopStatement::FOR_LOOP: { | 2328 case LoopStatement::FOR_LOOP: { |
| 2324 // TODO(260): This flag controls whether to duplicate the test | 2329 // Do not duplicate conditions with function literal |
| 2325 // at the bottom of the loop. Replace it with a better | 2330 // subexpressions. This can cause us to compile the function |
| 2326 // indication of when it is safe to do so. | 2331 // literal twice. |
| 2327 static const bool test_at_bottom = false; | 2332 bool test_at_bottom = !node->has_function_literal(); |
| 2328 | |
| 2329 JumpTarget loop(this, JumpTarget::BIDIRECTIONAL); | |
| 2330 JumpTarget body(this); | |
| 2331 | 2333 |
| 2332 // Compile the init expression if present. | 2334 // Compile the init expression if present. |
| 2333 if (node->init() != NULL) { | 2335 if (node->init() != NULL) { |
| 2334 Visit(node->init()); | 2336 Visit(node->init()); |
| 2335 } | 2337 } |
| 2336 | 2338 |
| 2337 IncrementLoopNesting(); | 2339 IncrementLoopNesting(); |
| 2338 | 2340 |
| 2339 // If the condition is always false and has no side effects, we | 2341 // If the condition is always false and has no side effects, we |
| 2340 // do not need to compile anything else. | 2342 // do not need to compile anything else. |
| 2341 if (info == ALWAYS_FALSE) break; | 2343 if (info == ALWAYS_FALSE) break; |
| 2342 | 2344 |
| 2345 // Target for backward edge if no test at the bottom, otherwise |
| 2346 // unused. |
| 2347 JumpTarget loop(this, JumpTarget::BIDIRECTIONAL); |
| 2348 |
| 2349 // Target for backward edge if there is a test at the bottom, |
| 2350 // otherwise used as target for test at the top. |
| 2351 JumpTarget body; |
| 2352 if (test_at_bottom) { |
| 2353 body.Initialize(this, JumpTarget::BIDIRECTIONAL); |
| 2354 } else { |
| 2355 body.Initialize(this); |
| 2356 } |
| 2357 |
| 2343 // Based on the condition analysis, compile the test as necessary. | 2358 // Based on the condition analysis, compile the test as necessary. |
| 2344 if (info == ALWAYS_TRUE) { | 2359 if (info == ALWAYS_TRUE) { |
| 2345 // We will not compile the test expression. Label the top of | 2360 // We will not compile the test expression. Label the top of |
| 2346 // the loop. | 2361 // the loop. |
| 2347 if (node->next() == NULL) { | 2362 if (node->next() == NULL) { |
| 2348 // Use the continue target if there is no update expression. | 2363 // Use the continue target if there is no update expression. |
| 2349 node->continue_target()->Initialize(this, JumpTarget::BIDIRECTIONAL); | 2364 node->continue_target()->Initialize(this, JumpTarget::BIDIRECTIONAL); |
| 2350 node->continue_target()->Bind(); | 2365 node->continue_target()->Bind(); |
| 2351 } else { | 2366 } else { |
| 2352 // Otherwise use the backward loop target. | 2367 // Otherwise use the backward loop target. |
| (...skipping 4582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6935 | 6950 |
| 6936 // Slow-case: Go through the JavaScript implementation. | 6951 // Slow-case: Go through the JavaScript implementation. |
| 6937 __ bind(&slow); | 6952 __ bind(&slow); |
| 6938 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 6953 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
| 6939 } | 6954 } |
| 6940 | 6955 |
| 6941 | 6956 |
| 6942 #undef __ | 6957 #undef __ |
| 6943 | 6958 |
| 6944 } } // namespace v8::internal | 6959 } } // namespace v8::internal |
| OLD | NEW |