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 |