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

Side by Side Diff: src/crankshaft/hydrogen.cc

Issue 1647093002: [crankshaft] Fix another deopt loop in slow mode for-in. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: comment Created 4 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
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-3650-3.js » ('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 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
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
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
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-3650-3.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698