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

Side by Side Diff: src/compiler/ast-graph-builder.cc

Issue 921083004: [turbofan] Rename context stack as part of the environment for OSR. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 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
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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/compiler/ast-graph-builder.h" 5 #include "src/compiler/ast-graph-builder.h"
6 6
7 #include "src/compiler.h" 7 #include "src/compiler.h"
8 #include "src/compiler/ast-loop-assignment-analyzer.h" 8 #include "src/compiler/ast-loop-assignment-analyzer.h"
9 #include "src/compiler/control-builders.h" 9 #include "src/compiler/control-builders.h"
10 #include "src/compiler/linkage.h" 10 #include "src/compiler/linkage.h"
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 102
103 // Scoped class tracking context objects created by the visitor. Represents 103 // Scoped class tracking context objects created by the visitor. Represents
104 // mutations of the context chain within the function body and allows to 104 // mutations of the context chain within the function body and allows to
105 // change the current {scope} and {context} during visitation. 105 // change the current {scope} and {context} during visitation.
106 class AstGraphBuilder::ContextScope BASE_EMBEDDED { 106 class AstGraphBuilder::ContextScope BASE_EMBEDDED {
107 public: 107 public:
108 ContextScope(AstGraphBuilder* builder, Scope* scope, Node* context) 108 ContextScope(AstGraphBuilder* builder, Scope* scope, Node* context)
109 : builder_(builder), 109 : builder_(builder),
110 outer_(builder->execution_context()), 110 outer_(builder->execution_context()),
111 scope_(scope), 111 scope_(scope),
112 context_(context) { 112 depth_(builder_->environment()->ContextStackDepth()) {
113 builder_->set_execution_context(this); // Push. 113 builder_->environment()->PushContext(context); // Push.
114 builder_->set_execution_context(this);
114 } 115 }
115 116
116 ~ContextScope() { 117 ~ContextScope() {
117 builder_->set_execution_context(outer_); // Pop. 118 builder_->set_execution_context(outer_); // Pop.
119 builder_->environment()->PopContext();
120 CHECK_EQ(depth_, builder_->environment()->ContextStackDepth());
118 } 121 }
119 122
120 // Current scope during visitation. 123 // Current scope during visitation.
121 Scope* scope() const { return scope_; } 124 Scope* scope() const { return scope_; }
122 // Current context node during visitation.
123 Node* context() const { return context_; }
124 125
125 private: 126 private:
126 AstGraphBuilder* builder_; 127 AstGraphBuilder* builder_;
127 ContextScope* outer_; 128 ContextScope* outer_;
128 Scope* scope_; 129 Scope* scope_;
129 Node* context_; 130 int depth_;
130 }; 131 };
131 132
132 133
133 // Scoped class tracking control statements entered by the visitor. There are 134 // Scoped class tracking control statements entered by the visitor. There are
134 // different types of statements participating in this stack to properly track 135 // different types of statements participating in this stack to properly track
135 // local as well as non-local control flow: 136 // local as well as non-local control flow:
136 // - IterationStatement : Allows proper 'break' and 'continue' behavior. 137 // - IterationStatement : Allows proper 'break' and 'continue' behavior.
137 // - BreakableStatement : Allows 'break' from block and switch statements. 138 // - BreakableStatement : Allows 'break' from block and switch statements.
138 // - TryCatchStatement : Intercepts 'throw' and implicit exceptional edges. 139 // - TryCatchStatement : Intercepts 'throw' and implicit exceptional edges.
139 // - TryFinallyStatement: Intercepts 'break', 'continue', 'throw' and 'return'. 140 // - TryFinallyStatement: Intercepts 'break', 'continue', 'throw' and 'return'.
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info, 372 AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info,
372 JSGraph* jsgraph, LoopAssignmentAnalysis* loop) 373 JSGraph* jsgraph, LoopAssignmentAnalysis* loop)
373 : local_zone_(local_zone), 374 : local_zone_(local_zone),
374 info_(info), 375 info_(info),
375 jsgraph_(jsgraph), 376 jsgraph_(jsgraph),
376 environment_(nullptr), 377 environment_(nullptr),
377 ast_context_(nullptr), 378 ast_context_(nullptr),
378 globals_(0, local_zone), 379 globals_(0, local_zone),
379 execution_control_(nullptr), 380 execution_control_(nullptr),
380 execution_context_(nullptr), 381 execution_context_(nullptr),
382 function_context_(nullptr),
381 input_buffer_size_(0), 383 input_buffer_size_(0),
382 input_buffer_(nullptr), 384 input_buffer_(nullptr),
383 exit_control_(nullptr), 385 exit_control_(nullptr),
384 loop_assignment_analysis_(loop) { 386 loop_assignment_analysis_(loop) {
385 InitializeAstVisitor(info->isolate(), local_zone); 387 InitializeAstVisitor(info->isolate(), local_zone);
386 } 388 }
387 389
388 390
389 Node* AstGraphBuilder::GetFunctionClosure() { 391 Node* AstGraphBuilder::GetFunctionClosure() {
390 if (!function_closure_.is_set()) { 392 if (!function_closure_.is_set()) {
391 const Operator* op = 393 const Operator* op =
392 common()->Parameter(Linkage::kJSFunctionCallClosureParamIndex); 394 common()->Parameter(Linkage::kJSFunctionCallClosureParamIndex);
393 Node* node = NewNode(op, graph()->start()); 395 Node* node = NewNode(op, graph()->start());
394 function_closure_.set(node); 396 function_closure_.set(node);
395 } 397 }
396 return function_closure_.get(); 398 return function_closure_.get();
397 } 399 }
398 400
399 401
400 Node* AstGraphBuilder::GetFunctionContext() { 402 Node* AstGraphBuilder::GetFunctionContext() {
401 if (!function_context_.is_set()) { 403 DCHECK(function_context_ != nullptr);
402 // Parameter (arity + 1) is special for the outer context of the function 404 return function_context_;
403 const Operator* op = common()->Parameter(info()->num_parameters() + 1);
404 Node* node = NewNode(op, graph()->start());
405 function_context_.set(node);
406 }
407 return function_context_.get();
408 } 405 }
409 406
410 407
408 Node* AstGraphBuilder::NewOuterContextParam() {
409 // Parameter (arity + 1) is special for the outer context of the function
410 const Operator* op = common()->Parameter(info()->num_parameters() + 1);
411 return NewNode(op, graph()->start());
412 }
413
414
415 Node* AstGraphBuilder::NewCurrentContextOsrValue() {
416 // TODO(titzer): use a real OSR value here; a parameter works by accident.
417 // Parameter (arity + 1) is special for the outer context of the function
418 const Operator* op = common()->Parameter(info()->num_parameters() + 1);
419 return NewNode(op, graph()->start());
420 }
421
422
411 bool AstGraphBuilder::CreateGraph() { 423 bool AstGraphBuilder::CreateGraph() {
412 Scope* scope = info()->scope(); 424 Scope* scope = info()->scope();
413 DCHECK(graph() != NULL); 425 DCHECK(graph() != NULL);
414 426
415 // Set up the basic structure of the graph. 427 // Set up the basic structure of the graph.
416 int parameter_count = info()->num_parameters(); 428 int parameter_count = info()->num_parameters();
417 graph()->SetStart(graph()->NewNode(common()->Start(parameter_count))); 429 graph()->SetStart(graph()->NewNode(common()->Start(parameter_count)));
418 430
419 // Initialize control scope. 431 // Initialize control scope.
420 ControlScope control(this, 0); 432 ControlScope control(this, 0);
421 433
422 // Initialize the top-level environment. 434 // Initialize the top-level environment.
423 Environment env(this, scope, graph()->start()); 435 Environment env(this, scope, graph()->start());
424 set_environment(&env); 436 set_environment(&env);
425 437
426 if (info()->is_osr()) { 438 if (info()->is_osr()) {
427 // Use OSR normal entry as the start of the top-level environment. 439 // Use OSR normal entry as the start of the top-level environment.
428 // It will be replaced with {Dead} after typing and optimizations. 440 // It will be replaced with {Dead} after typing and optimizations.
429 NewNode(common()->OsrNormalEntry()); 441 NewNode(common()->OsrNormalEntry());
430 } 442 }
431 443
432 // Initialize the incoming context. 444 // Initialize the incoming context.
433 Node* incoming_context = GetFunctionContext(); 445 function_context_ = NewOuterContextParam();
434 ContextScope incoming(this, scope, incoming_context); 446 ContextScope incoming(this, scope, function_context_);
435 447
436 // Build receiver check for sloppy mode if necessary. 448 // Build receiver check for sloppy mode if necessary.
437 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC? 449 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC?
438 Node* original_receiver = env.Lookup(scope->receiver()); 450 Node* original_receiver = env.Lookup(scope->receiver());
439 Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); 451 Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver);
440 env.Bind(scope->receiver(), patched_receiver); 452 env.Bind(scope->receiver(), patched_receiver);
441 453
442 // Build node to initialize local function context.
443 Node* closure = GetFunctionClosure(); 454 Node* closure = GetFunctionClosure();
Michael Starzinger 2015/02/17 10:34:37 nit: The closure is only needed in the case we bui
titzer 2015/02/17 10:44:16 Tried that, but nope. GetFunctionClosure() has a s
444 Node* inner_context = BuildLocalFunctionContext(incoming_context, closure); 455 bool ok;
456 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
457 if (heap_slots > 0) {
458 // Push a new inner context scope for the function.
459 Node* inner_context = BuildLocalFunctionContext(function_context_, closure);
460 ContextScope top_context(this, scope, inner_context);
461 ok = CreateGraphBody();
462 } else {
463 // Simply use the outer function context in building the graph.
464 ok = CreateGraphBody();
465 }
445 466
446 // Push top-level function context for the function body. 467 // Finish the basic structure of the graph.
447 ContextScope top_context(this, scope, inner_context); 468 if (ok) {
Michael Starzinger 2015/02/17 10:34:37 It should be safe to also do this in the case of s
titzer 2015/02/17 10:44:16 Tried that too, but nope, the environment's contro
titzer 2015/02/17 11:24:36 Disregard previous comment.
469 environment()->UpdateControlDependency(exit_control());
470 graph()->SetEnd(NewNode(common()->End()));
471 }
448 472
473 return ok;
474 }
475
476
477 bool AstGraphBuilder::CreateGraphBody() {
478 Scope* scope = info()->scope();
449 // Build the arguments object if it is used. 479 // Build the arguments object if it is used.
450 BuildArgumentsObject(scope->arguments()); 480 BuildArgumentsObject(scope->arguments());
451 481
452 // Build rest arguments array if it is used. 482 // Build rest arguments array if it is used.
453 int rest_index; 483 int rest_index;
454 Variable* rest_parameter = scope->rest_parameter(&rest_index); 484 Variable* rest_parameter = scope->rest_parameter(&rest_index);
455 BuildRestArgumentsArray(rest_parameter, rest_index); 485 BuildRestArgumentsArray(rest_parameter, rest_index);
456 486
457 // Emit tracing call if requested to do so. 487 // Emit tracing call if requested to do so.
458 if (FLAG_trace) { 488 if (FLAG_trace) {
(...skipping 19 matching lines...) Expand all
478 // Emit tracing call if requested to do so. 508 // Emit tracing call if requested to do so.
479 if (FLAG_trace) { 509 if (FLAG_trace) {
480 // TODO(mstarzinger): Only traces implicit return. 510 // TODO(mstarzinger): Only traces implicit return.
481 Node* return_value = jsgraph()->UndefinedConstant(); 511 Node* return_value = jsgraph()->UndefinedConstant();
482 NewNode(javascript()->CallRuntime(Runtime::kTraceExit, 1), return_value); 512 NewNode(javascript()->CallRuntime(Runtime::kTraceExit, 1), return_value);
483 } 513 }
484 514
485 // Return 'undefined' in case we can fall off the end. 515 // Return 'undefined' in case we can fall off the end.
486 BuildReturn(jsgraph()->UndefinedConstant()); 516 BuildReturn(jsgraph()->UndefinedConstant());
487 517
488 // Finish the basic structure of the graph.
489 environment()->UpdateControlDependency(exit_control());
490 graph()->SetEnd(NewNode(common()->End()));
491
492 return true; 518 return true;
493 } 519 }
494 520
495 521
496 // Left-hand side can only be a property, a global or a variable slot. 522 // Left-hand side can only be a property, a global or a variable slot.
497 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 523 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
498 524
499 525
500 // Determine the left-hand side kind of an assignment. 526 // Determine the left-hand side kind of an assignment.
501 static LhsKind DetermineLhsKind(Expression* expr) { 527 static LhsKind DetermineLhsKind(Expression* expr) {
502 Property* property = expr->AsProperty(); 528 Property* property = expr->AsProperty();
503 DCHECK(expr->IsValidReferenceExpression()); 529 DCHECK(expr->IsValidReferenceExpression());
504 LhsKind lhs_kind = 530 LhsKind lhs_kind =
505 (property == NULL) ? VARIABLE : (property->key()->IsPropertyName()) 531 (property == NULL) ? VARIABLE : (property->key()->IsPropertyName())
506 ? NAMED_PROPERTY 532 ? NAMED_PROPERTY
507 : KEYED_PROPERTY; 533 : KEYED_PROPERTY;
508 return lhs_kind; 534 return lhs_kind;
509 } 535 }
510 536
511 537
512 AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder, 538 AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder,
513 Scope* scope, 539 Scope* scope,
514 Node* control_dependency) 540 Node* control_dependency)
515 : builder_(builder), 541 : builder_(builder),
516 parameters_count_(scope->num_parameters() + 1), 542 parameters_count_(scope->num_parameters() + 1),
517 locals_count_(scope->num_stack_slots()), 543 locals_count_(scope->num_stack_slots()),
518 values_(builder_->local_zone()), 544 values_(builder_->local_zone()),
545 contexts_(builder_->local_zone()),
519 control_dependency_(control_dependency), 546 control_dependency_(control_dependency),
520 effect_dependency_(control_dependency), 547 effect_dependency_(control_dependency),
521 parameters_node_(nullptr), 548 parameters_node_(nullptr),
522 locals_node_(nullptr), 549 locals_node_(nullptr),
523 stack_node_(nullptr) { 550 stack_node_(nullptr) {
524 DCHECK_EQ(scope->num_parameters() + 1, parameters_count()); 551 DCHECK_EQ(scope->num_parameters() + 1, parameters_count());
525 552
526 // Bind the receiver variable. 553 // Bind the receiver variable.
527 Node* receiver = builder->graph()->NewNode(common()->Parameter(0), 554 Node* receiver = builder->graph()->NewNode(common()->Parameter(0),
528 builder->graph()->start()); 555 builder->graph()->start());
(...skipping 12 matching lines...) Expand all
541 values()->insert(values()->end(), locals_count(), undefined_constant); 568 values()->insert(values()->end(), locals_count(), undefined_constant);
542 } 569 }
543 570
544 571
545 AstGraphBuilder::Environment::Environment( 572 AstGraphBuilder::Environment::Environment(
546 const AstGraphBuilder::Environment* copy) 573 const AstGraphBuilder::Environment* copy)
547 : builder_(copy->builder_), 574 : builder_(copy->builder_),
548 parameters_count_(copy->parameters_count_), 575 parameters_count_(copy->parameters_count_),
549 locals_count_(copy->locals_count_), 576 locals_count_(copy->locals_count_),
550 values_(copy->zone()), 577 values_(copy->zone()),
578 contexts_(copy->zone()),
551 control_dependency_(copy->control_dependency_), 579 control_dependency_(copy->control_dependency_),
552 effect_dependency_(copy->effect_dependency_), 580 effect_dependency_(copy->effect_dependency_),
553 parameters_node_(copy->parameters_node_), 581 parameters_node_(copy->parameters_node_),
554 locals_node_(copy->locals_node_), 582 locals_node_(copy->locals_node_),
555 stack_node_(copy->stack_node_) { 583 stack_node_(copy->stack_node_) {
556 const size_t kStackEstimate = 7; // optimum from experimentation! 584 const size_t kStackEstimate = 7; // optimum from experimentation!
557 values_.reserve(copy->values_.size() + kStackEstimate); 585 values_.reserve(copy->values_.size() + kStackEstimate);
558 values_.insert(values_.begin(), copy->values_.begin(), copy->values_.end()); 586 values_.insert(values_.begin(), copy->values_.begin(), copy->values_.end());
587 contexts_.reserve(copy->contexts_.size());
588 contexts_.insert(contexts_.begin(), copy->contexts_.begin(),
589 copy->contexts_.end());
559 } 590 }
560 591
561 592
562 void AstGraphBuilder::Environment::UpdateStateValues(Node** state_values, 593 void AstGraphBuilder::Environment::UpdateStateValues(Node** state_values,
563 int offset, int count) { 594 int offset, int count) {
564 bool should_update = false; 595 bool should_update = false;
565 Node** env_values = (count == 0) ? NULL : &values()->at(offset); 596 Node** env_values = (count == 0) ? NULL : &values()->at(offset);
566 if (*state_values == NULL || (*state_values)->InputCount() != count) { 597 if (*state_values == NULL || (*state_values)->InputCount() != count) {
567 should_update = true; 598 should_update = true;
568 } else { 599 } else {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 return environment()->Pop(); 684 return environment()->Pop();
654 } 685 }
655 686
656 687
657 Scope* AstGraphBuilder::current_scope() const { 688 Scope* AstGraphBuilder::current_scope() const {
658 return execution_context_->scope(); 689 return execution_context_->scope();
659 } 690 }
660 691
661 692
662 Node* AstGraphBuilder::current_context() const { 693 Node* AstGraphBuilder::current_context() const {
663 return execution_context_->context(); 694 return environment()->Context();
664 } 695 }
665 696
666 697
667 void AstGraphBuilder::ControlScope::PerformCommand(Command command, 698 void AstGraphBuilder::ControlScope::PerformCommand(Command command,
668 Statement* target, 699 Statement* target,
669 Node* value) { 700 Node* value) {
670 Environment* env = environment()->CopyAsUnreachable(); 701 Environment* env = environment()->CopyAsUnreachable();
671 ControlScope* current = this; 702 ControlScope* current = this;
672 while (current != NULL) { 703 while (current != NULL) {
673 if (current->Execute(command, target, value)) break; 704 if (current->Execute(command, target, value)) break;
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after
1196 Visit(stmt->try_block()); 1227 Visit(stmt->try_block());
1197 } 1228 }
1198 try_control.EndTry(); 1229 try_control.EndTry();
1199 1230
1200 // Create a catch scope that binds the exception. 1231 // Create a catch scope that binds the exception.
1201 Node* exception = try_control.GetExceptionNode(); 1232 Node* exception = try_control.GetExceptionNode();
1202 Unique<String> name = MakeUnique(stmt->variable()->name()); 1233 Unique<String> name = MakeUnique(stmt->variable()->name());
1203 const Operator* op = javascript()->CreateCatchContext(name); 1234 const Operator* op = javascript()->CreateCatchContext(name);
1204 Node* context = NewNode(op, exception, GetFunctionClosure()); 1235 Node* context = NewNode(op, exception, GetFunctionClosure());
1205 PrepareFrameState(context, BailoutId::None()); 1236 PrepareFrameState(context, BailoutId::None());
1206 ContextScope scope(this, stmt->scope(), context); 1237 {
1207 DCHECK(stmt->scope()->declarations()->is_empty()); 1238 ContextScope scope(this, stmt->scope(), context);
1208 1239 DCHECK(stmt->scope()->declarations()->is_empty());
1209 // Evaluate the catch-block. 1240 // Evaluate the catch-block.
1210 Visit(stmt->catch_block()); 1241 Visit(stmt->catch_block());
1242 }
1211 try_control.EndCatch(); 1243 try_control.EndCatch();
1212 1244
1213 // TODO(mstarzinger): Remove bailout once everything works. 1245 // TODO(mstarzinger): Remove bailout once everything works.
1214 if (!FLAG_turbo_exceptions) SetStackOverflow(); 1246 if (!FLAG_turbo_exceptions) SetStackOverflow();
1215 } 1247 }
1216 1248
1217 1249
1218 void AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 1250 void AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
1219 TryFinallyBuilder try_control(this); 1251 TryFinallyBuilder try_control(this);
1220 1252
(...skipping 1202 matching lines...) Expand 10 before | Expand all | Expand 10 after
2423 receiver_check.Then(); 2455 receiver_check.Then();
2424 environment()->Push(BuildLoadGlobalProxy()); 2456 environment()->Push(BuildLoadGlobalProxy());
2425 receiver_check.Else(); 2457 receiver_check.Else();
2426 environment()->Push(receiver); 2458 environment()->Push(receiver);
2427 receiver_check.End(); 2459 receiver_check.End();
2428 return environment()->Pop(); 2460 return environment()->Pop();
2429 } 2461 }
2430 2462
2431 2463
2432 Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context, Node* closure) { 2464 Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context, Node* closure) {
2433 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
2434 if (heap_slots <= 0) return context;
2435
2436 // Allocate a new local context. 2465 // Allocate a new local context.
2437 const Operator* op = javascript()->CreateFunctionContext(); 2466 const Operator* op = javascript()->CreateFunctionContext();
2438 Node* local_context = NewNode(op, closure); 2467 Node* local_context = NewNode(op, closure);
2439 2468
2440 // Copy parameters into context if necessary. 2469 // Copy parameters into context if necessary.
2441 int num_parameters = info()->scope()->num_parameters(); 2470 int num_parameters = info()->scope()->num_parameters();
2442 for (int i = 0; i < num_parameters; i++) { 2471 for (int i = 0; i < num_parameters; i++) {
2443 Variable* variable = info()->scope()->parameter(i); 2472 Variable* variable = info()->scope()->parameter(i);
2444 if (!variable->IsContextSlot()) continue; 2473 if (!variable->IsContextSlot()) continue;
2445 // Temporary parameter node. The parameter indices are shifted by 1 2474 // Temporary parameter node. The parameter indices are shifted by 1
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after
2999 if (exit_control() != NULL) { 3028 if (exit_control() != NULL) {
3000 exit = MergeControl(exit_control(), exit); 3029 exit = MergeControl(exit_control(), exit);
3001 } 3030 }
3002 environment()->MarkAsUnreachable(); 3031 environment()->MarkAsUnreachable();
3003 set_exit_control(exit); 3032 set_exit_control(exit);
3004 } 3033 }
3005 3034
3006 3035
3007 void AstGraphBuilder::Environment::Merge(Environment* other) { 3036 void AstGraphBuilder::Environment::Merge(Environment* other) {
3008 DCHECK(values_.size() == other->values_.size()); 3037 DCHECK(values_.size() == other->values_.size());
3038 DCHECK(contexts_.size() <= other->contexts_.size());
3009 3039
3010 // Nothing to do if the other environment is dead. 3040 // Nothing to do if the other environment is dead.
3011 if (other->IsMarkedAsUnreachable()) return; 3041 if (other->IsMarkedAsUnreachable()) return;
3012 3042
3013 // Resurrect a dead environment by copying the contents of the other one and 3043 // Resurrect a dead environment by copying the contents of the other one and
3014 // placing a singleton merge as the new control dependency. 3044 // placing a singleton merge as the new control dependency.
3015 if (this->IsMarkedAsUnreachable()) { 3045 if (this->IsMarkedAsUnreachable()) {
3016 Node* other_control = other->control_dependency_; 3046 Node* other_control = other->control_dependency_;
3017 Node* inputs[] = {other_control}; 3047 Node* inputs[] = {other_control};
3018 control_dependency_ = 3048 control_dependency_ =
(...skipping 13 matching lines...) Expand all
3032 // the current environment's effect dependency accordingly. 3062 // the current environment's effect dependency accordingly.
3033 Node* effect = builder_->MergeEffect(this->GetEffectDependency(), 3063 Node* effect = builder_->MergeEffect(this->GetEffectDependency(),
3034 other->GetEffectDependency(), control); 3064 other->GetEffectDependency(), control);
3035 UpdateEffectDependency(effect); 3065 UpdateEffectDependency(effect);
3036 3066
3037 // Introduce Phi nodes for values that have differing input at merge points, 3067 // Introduce Phi nodes for values that have differing input at merge points,
3038 // potentially extending an existing Phi node if possible. 3068 // potentially extending an existing Phi node if possible.
3039 for (int i = 0; i < static_cast<int>(values_.size()); ++i) { 3069 for (int i = 0; i < static_cast<int>(values_.size()); ++i) {
3040 values_[i] = builder_->MergeValue(values_[i], other->values_[i], control); 3070 values_[i] = builder_->MergeValue(values_[i], other->values_[i], control);
3041 } 3071 }
3072 for (int i = 0; i < static_cast<int>(contexts_.size()); ++i) {
3073 contexts_[i] =
3074 builder_->MergeValue(contexts_[i], other->contexts_[i], control);
3075 }
3042 } 3076 }
3043 3077
3044 3078
3045 void AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned, 3079 void AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned,
3046 bool is_osr) { 3080 bool is_osr) {
3047 int size = static_cast<int>(values()->size()); 3081 int size = static_cast<int>(values()->size());
3048 3082
3049 Node* control = builder_->NewLoop(); 3083 Node* control = builder_->NewLoop();
3050 if (assigned == nullptr) { 3084 if (assigned == nullptr) {
3051 // Assume that everything is updated in the loop. 3085 // Assume that everything is updated in the loop.
3052 for (int i = 0; i < size; ++i) { 3086 for (int i = 0; i < size; ++i) {
3053 Node* phi = builder_->NewPhi(1, values()->at(i), control); 3087 values()->at(i) = builder_->NewPhi(1, values()->at(i), control);
3054 values()->at(i) = phi;
3055 } 3088 }
3056 } else { 3089 } else {
3057 // Only build phis for those locals assigned in this loop. 3090 // Only build phis for those locals assigned in this loop.
3058 for (int i = 0; i < size; ++i) { 3091 for (int i = 0; i < size; ++i) {
3059 if (i < assigned->length() && !assigned->Contains(i)) continue; 3092 if (i < assigned->length() && !assigned->Contains(i)) continue;
3060 Node* phi = builder_->NewPhi(1, values()->at(i), control); 3093 Node* phi = builder_->NewPhi(1, values()->at(i), control);
3061 values()->at(i) = phi; 3094 values()->at(i) = phi;
3062 } 3095 }
3063 } 3096 }
3064 Node* effect = builder_->NewEffectPhi(1, GetEffectDependency(), control); 3097 Node* effect = builder_->NewEffectPhi(1, GetEffectDependency(), control);
3065 UpdateEffectDependency(effect); 3098 UpdateEffectDependency(effect);
3066 3099
3100 if (builder_->info()->is_osr()) {
3101 // Introduce phis for all context values in the case of an OSR graph.
3102 for (int i = 0; i < static_cast<int>(contexts()->size()); ++i) {
3103 Node* val = contexts()->at(i);
3104 if (!IrOpcode::IsConstantOpcode(val->opcode())) {
3105 contexts()->at(i) = builder_->NewPhi(1, val, control);
3106 }
3107 }
3108 }
3109
3067 if (is_osr) { 3110 if (is_osr) {
3068 // Merge OSR values as inputs to the phis of the loop. 3111 // Merge OSR values as inputs to the phis of the loop.
3069 Graph* graph = builder_->graph(); 3112 Graph* graph = builder_->graph();
3070 Node* osr_loop_entry = builder_->graph()->NewNode( 3113 Node* osr_loop_entry = builder_->graph()->NewNode(
3071 builder_->common()->OsrLoopEntry(), graph->start(), graph->start()); 3114 builder_->common()->OsrLoopEntry(), graph->start(), graph->start());
3072 3115
3073 builder_->MergeControl(control, osr_loop_entry); 3116 builder_->MergeControl(control, osr_loop_entry);
3074 builder_->MergeEffect(effect, osr_loop_entry, control); 3117 builder_->MergeEffect(effect, osr_loop_entry, control);
3075 3118
3076 for (int i = 0; i < size; ++i) { 3119 for (int i = 0; i < size; ++i) {
3077 Node* val = values()->at(i); 3120 Node* val = values()->at(i);
3078 if (!IrOpcode::IsConstantOpcode(val->opcode())) { 3121 if (!IrOpcode::IsConstantOpcode(val->opcode())) {
3079 Node* osr_value = 3122 Node* osr_value =
3080 graph->NewNode(builder_->common()->OsrValue(i), osr_loop_entry); 3123 graph->NewNode(builder_->common()->OsrValue(i), osr_loop_entry);
3081 values()->at(i) = builder_->MergeValue(val, osr_value, control); 3124 values()->at(i) = builder_->MergeValue(val, osr_value, control);
3082 } 3125 }
3083 } 3126 }
3127
3128 // Rename all the contexts in the environment.
3129 // The innermost context is the OSR value, and the outer contexts are
3130 // reconstructed by dynamically walking up the context chain.
3131 Node* osr_context = nullptr;
3132 const Operator* op =
3133 builder_->javascript()->LoadContext(0, Context::PREVIOUS_INDEX, true);
3134 int last = static_cast<int>(contexts()->size() - 1);
3135 for (int i = last; i >= 0; i--) {
3136 Node* val = contexts()->at(i);
3137 if (!IrOpcode::IsConstantOpcode(val->opcode())) {
3138 osr_context = (i == last) ? builder_->NewCurrentContextOsrValue()
3139 : graph->NewNode(op, osr_context, osr_context,
3140 osr_loop_entry);
3141 contexts()->at(i) = builder_->MergeValue(val, osr_context, control);
3142 } else {
3143 osr_context = val;
3144 }
3145 }
3084 } 3146 }
3085 } 3147 }
3086 3148
3087 3149
3088 Node* AstGraphBuilder::NewPhi(int count, Node* input, Node* control) { 3150 Node* AstGraphBuilder::NewPhi(int count, Node* input, Node* control) {
3089 const Operator* phi_op = common()->Phi(kMachAnyTagged, count); 3151 const Operator* phi_op = common()->Phi(kMachAnyTagged, count);
3090 Node** buffer = EnsureInputBufferSize(count + 1); 3152 Node** buffer = EnsureInputBufferSize(count + 1);
3091 MemsetPointer(buffer, input, count); 3153 MemsetPointer(buffer, input, count);
3092 buffer[count] = control; 3154 buffer[count] = control;
3093 return graph()->NewNode(phi_op, count + 1, buffer, true); 3155 return graph()->NewNode(phi_op, count + 1, buffer, true);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
3163 Node* dead_node = graph()->NewNode(common()->Dead()); 3225 Node* dead_node = graph()->NewNode(common()->Dead());
3164 dead_control_.set(dead_node); 3226 dead_control_.set(dead_node);
3165 return dead_node; 3227 return dead_node;
3166 } 3228 }
3167 return dead_control_.get(); 3229 return dead_control_.get();
3168 } 3230 }
3169 3231
3170 } // namespace compiler 3232 } // namespace compiler
3171 } // namespace internal 3233 } // namespace internal
3172 } // namespace v8 3234 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698