OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/crankshaft/hydrogen.h" | 5 #include "src/crankshaft/hydrogen.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/allocation-site-scopes.h" | 9 #include "src/allocation-site-scopes.h" |
10 #include "src/ast/ast-numbering.h" | 10 #include "src/ast/ast-numbering.h" |
(...skipping 5383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5394 | 5394 |
5395 compare_index->SetSuccessorAt(0, loop_body); | 5395 compare_index->SetSuccessorAt(0, loop_body); |
5396 compare_index->SetSuccessorAt(1, loop_successor); | 5396 compare_index->SetSuccessorAt(1, loop_successor); |
5397 FinishCurrentBlock(compare_index); | 5397 FinishCurrentBlock(compare_index); |
5398 | 5398 |
5399 set_current_block(loop_successor); | 5399 set_current_block(loop_successor); |
5400 Drop(5); | 5400 Drop(5); |
5401 | 5401 |
5402 set_current_block(loop_body); | 5402 set_current_block(loop_body); |
5403 | 5403 |
| 5404 // Compute the next enumerated value. |
5404 HValue* key = Add<HLoadKeyed>(array, index, index, nullptr, FAST_ELEMENTS); | 5405 HValue* key = Add<HLoadKeyed>(array, index, index, nullptr, FAST_ELEMENTS); |
5405 | 5406 |
| 5407 HBasicBlock* continue_block = nullptr; |
5406 if (fast) { | 5408 if (fast) { |
5407 // Check if the expected map still matches that of the enumerable. | 5409 // Check if expected map still matches that of the enumerable. |
5408 // If not just deoptimize. | |
5409 Add<HCheckMapValue>(enumerable, type); | 5410 Add<HCheckMapValue>(enumerable, type); |
5410 Bind(each_var, key); | 5411 Add<HSimulate>(stmt->FilterId()); |
5411 } else { | 5412 } else { |
| 5413 // We need the continue block here to be able to skip over invalidated keys. |
| 5414 continue_block = graph()->CreateBasicBlock(); |
| 5415 |
| 5416 // We cannot use the IfBuilder here, since we need to be able to jump |
| 5417 // over the loop body in case of undefined result from %ForInFilter, |
| 5418 // and the poor soul that is the IfBuilder get's really confused about |
| 5419 // such "advanced control flow requirements". |
| 5420 HBasicBlock* if_fast = graph()->CreateBasicBlock(); |
| 5421 HBasicBlock* if_slow = graph()->CreateBasicBlock(); |
| 5422 HBasicBlock* if_slow_pass = graph()->CreateBasicBlock(); |
| 5423 HBasicBlock* if_slow_skip = graph()->CreateBasicBlock(); |
| 5424 HBasicBlock* if_join = graph()->CreateBasicBlock(); |
| 5425 |
| 5426 // Check if expected map still matches that of the enumerable. |
5412 HValue* enumerable_map = | 5427 HValue* enumerable_map = |
5413 Add<HLoadNamedField>(enumerable, nullptr, HObjectAccess::ForMap()); | 5428 Add<HLoadNamedField>(enumerable, nullptr, HObjectAccess::ForMap()); |
5414 IfBuilder if_fast(this); | 5429 FinishCurrentBlock( |
5415 if_fast.If<HCompareObjectEqAndBranch>(enumerable_map, type); | 5430 New<HCompareObjectEqAndBranch>(enumerable_map, type, if_fast, if_slow)); |
5416 if_fast.Then(); | 5431 set_current_block(if_fast); |
5417 { | 5432 { |
| 5433 // The enum cache for enumerable is still valid, no need to check key. |
5418 Push(key); | 5434 Push(key); |
5419 Add<HSimulate>(stmt->FilterId()); | 5435 Goto(if_join); |
5420 } | 5436 } |
5421 if_fast.Else(); | 5437 set_current_block(if_slow); |
5422 { | 5438 { |
| 5439 // Check if key is still valid for enumerable. |
5423 Add<HPushArguments>(enumerable, key); | 5440 Add<HPushArguments>(enumerable, key); |
5424 Runtime::FunctionId function_id = Runtime::kForInFilter; | 5441 Runtime::FunctionId function_id = Runtime::kForInFilter; |
5425 Push(Add<HCallRuntime>(Runtime::FunctionForId(function_id), 2)); | 5442 Push(Add<HCallRuntime>(Runtime::FunctionForId(function_id), 2)); |
5426 Add<HSimulate>(stmt->FilterId()); | 5443 Add<HSimulate>(stmt->FilterId()); |
| 5444 FinishCurrentBlock(New<HCompareObjectEqAndBranch>( |
| 5445 Top(), graph()->GetConstantUndefined(), if_slow_skip, if_slow_pass)); |
5427 } | 5446 } |
5428 if_fast.End(); | 5447 set_current_block(if_slow_pass); |
| 5448 { Goto(if_join); } |
| 5449 set_current_block(if_slow_skip); |
| 5450 { |
| 5451 // The key is no longer valid for enumerable, skip it. |
| 5452 Drop(1); |
| 5453 Goto(continue_block); |
| 5454 } |
| 5455 if_join->SetJoinId(stmt->FilterId()); |
| 5456 set_current_block(if_join); |
5429 key = Pop(); | 5457 key = Pop(); |
5430 Bind(each_var, key); | |
5431 IfBuilder if_undefined(this); | |
5432 if_undefined.If<HCompareObjectEqAndBranch>(key, | |
5433 graph()->GetConstantUndefined()); | |
5434 if_undefined.ThenDeopt(Deoptimizer::kUndefined); | |
5435 if_undefined.End(); | |
5436 Add<HSimulate>(stmt->AssignmentId()); | |
5437 } | 5458 } |
5438 | 5459 |
| 5460 Bind(each_var, key); |
| 5461 Add<HSimulate>(stmt->AssignmentId()); |
| 5462 |
5439 BreakAndContinueInfo break_info(stmt, scope(), 5); | 5463 BreakAndContinueInfo break_info(stmt, scope(), 5); |
| 5464 break_info.set_continue_block(continue_block); |
5440 { | 5465 { |
5441 BreakAndContinueScope push(&break_info, this); | 5466 BreakAndContinueScope push(&break_info, this); |
5442 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry)); | 5467 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry)); |
5443 } | 5468 } |
5444 | 5469 |
5445 HBasicBlock* body_exit = | 5470 HBasicBlock* body_exit = |
5446 JoinContinue(stmt, current_block(), break_info.continue_block()); | 5471 JoinContinue(stmt, current_block(), break_info.continue_block()); |
5447 | 5472 |
5448 if (body_exit != NULL) { | 5473 if (body_exit != NULL) { |
5449 set_current_block(body_exit); | 5474 set_current_block(body_exit); |
(...skipping 8189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13639 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13664 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13640 } | 13665 } |
13641 | 13666 |
13642 #ifdef DEBUG | 13667 #ifdef DEBUG |
13643 graph_->Verify(false); // No full verify. | 13668 graph_->Verify(false); // No full verify. |
13644 #endif | 13669 #endif |
13645 } | 13670 } |
13646 | 13671 |
13647 } // namespace internal | 13672 } // namespace internal |
13648 } // namespace v8 | 13673 } // namespace v8 |
OLD | NEW |