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

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
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/compiler/osr.cc » ('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 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. 454 bool ok;
443 Node* closure = GetFunctionClosure(); 455 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
444 Node* inner_context = BuildLocalFunctionContext(incoming_context, closure); 456 if (heap_slots > 0) {
457 // Push a new inner context scope for the function.
458 Node* closure = GetFunctionClosure();
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) {
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 1188 matching lines...) Expand 10 before | Expand all | Expand 10 after
2409 receiver_check.Then(); 2441 receiver_check.Then();
2410 environment()->Push(BuildLoadGlobalProxy()); 2442 environment()->Push(BuildLoadGlobalProxy());
2411 receiver_check.Else(); 2443 receiver_check.Else();
2412 environment()->Push(receiver); 2444 environment()->Push(receiver);
2413 receiver_check.End(); 2445 receiver_check.End();
2414 return environment()->Pop(); 2446 return environment()->Pop();
2415 } 2447 }
2416 2448
2417 2449
2418 Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context, Node* closure) { 2450 Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context, Node* closure) {
2419 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
2420 if (heap_slots <= 0) return context;
2421
2422 // Allocate a new local context. 2451 // Allocate a new local context.
2423 const Operator* op = javascript()->CreateFunctionContext(); 2452 const Operator* op = javascript()->CreateFunctionContext();
2424 Node* local_context = NewNode(op, closure); 2453 Node* local_context = NewNode(op, closure);
2425 2454
2426 // Copy parameters into context if necessary. 2455 // Copy parameters into context if necessary.
2427 int num_parameters = info()->scope()->num_parameters(); 2456 int num_parameters = info()->scope()->num_parameters();
2428 for (int i = 0; i < num_parameters; i++) { 2457 for (int i = 0; i < num_parameters; i++) {
2429 Variable* variable = info()->scope()->parameter(i); 2458 Variable* variable = info()->scope()->parameter(i);
2430 if (!variable->IsContextSlot()) continue; 2459 if (!variable->IsContextSlot()) continue;
2431 // Temporary parameter node. The parameter indices are shifted by 1 2460 // Temporary parameter node. The parameter indices are shifted by 1
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after
2996 if (exit_control() != NULL) { 3025 if (exit_control() != NULL) {
2997 exit = MergeControl(exit_control(), exit); 3026 exit = MergeControl(exit_control(), exit);
2998 } 3027 }
2999 environment()->MarkAsUnreachable(); 3028 environment()->MarkAsUnreachable();
3000 set_exit_control(exit); 3029 set_exit_control(exit);
3001 } 3030 }
3002 3031
3003 3032
3004 void AstGraphBuilder::Environment::Merge(Environment* other) { 3033 void AstGraphBuilder::Environment::Merge(Environment* other) {
3005 DCHECK(values_.size() == other->values_.size()); 3034 DCHECK(values_.size() == other->values_.size());
3035 DCHECK(contexts_.size() <= other->contexts_.size());
3006 3036
3007 // Nothing to do if the other environment is dead. 3037 // Nothing to do if the other environment is dead.
3008 if (other->IsMarkedAsUnreachable()) return; 3038 if (other->IsMarkedAsUnreachable()) return;
3009 3039
3010 // Resurrect a dead environment by copying the contents of the other one and 3040 // Resurrect a dead environment by copying the contents of the other one and
3011 // placing a singleton merge as the new control dependency. 3041 // placing a singleton merge as the new control dependency.
3012 if (this->IsMarkedAsUnreachable()) { 3042 if (this->IsMarkedAsUnreachable()) {
3013 Node* other_control = other->control_dependency_; 3043 Node* other_control = other->control_dependency_;
3014 Node* inputs[] = {other_control}; 3044 Node* inputs[] = {other_control};
3015 control_dependency_ = 3045 control_dependency_ =
(...skipping 13 matching lines...) Expand all
3029 // the current environment's effect dependency accordingly. 3059 // the current environment's effect dependency accordingly.
3030 Node* effect = builder_->MergeEffect(this->GetEffectDependency(), 3060 Node* effect = builder_->MergeEffect(this->GetEffectDependency(),
3031 other->GetEffectDependency(), control); 3061 other->GetEffectDependency(), control);
3032 UpdateEffectDependency(effect); 3062 UpdateEffectDependency(effect);
3033 3063
3034 // Introduce Phi nodes for values that have differing input at merge points, 3064 // Introduce Phi nodes for values that have differing input at merge points,
3035 // potentially extending an existing Phi node if possible. 3065 // potentially extending an existing Phi node if possible.
3036 for (int i = 0; i < static_cast<int>(values_.size()); ++i) { 3066 for (int i = 0; i < static_cast<int>(values_.size()); ++i) {
3037 values_[i] = builder_->MergeValue(values_[i], other->values_[i], control); 3067 values_[i] = builder_->MergeValue(values_[i], other->values_[i], control);
3038 } 3068 }
3069 for (int i = 0; i < static_cast<int>(contexts_.size()); ++i) {
3070 contexts_[i] =
3071 builder_->MergeValue(contexts_[i], other->contexts_[i], control);
3072 }
3039 } 3073 }
3040 3074
3041 3075
3042 void AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned, 3076 void AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned,
3043 bool is_osr) { 3077 bool is_osr) {
3044 int size = static_cast<int>(values()->size()); 3078 int size = static_cast<int>(values()->size());
3045 3079
3046 Node* control = builder_->NewLoop(); 3080 Node* control = builder_->NewLoop();
3047 if (assigned == nullptr) { 3081 if (assigned == nullptr) {
3048 // Assume that everything is updated in the loop. 3082 // Assume that everything is updated in the loop.
3049 for (int i = 0; i < size; ++i) { 3083 for (int i = 0; i < size; ++i) {
3050 Node* phi = builder_->NewPhi(1, values()->at(i), control); 3084 values()->at(i) = builder_->NewPhi(1, values()->at(i), control);
3051 values()->at(i) = phi;
3052 } 3085 }
3053 } else { 3086 } else {
3054 // Only build phis for those locals assigned in this loop. 3087 // Only build phis for those locals assigned in this loop.
3055 for (int i = 0; i < size; ++i) { 3088 for (int i = 0; i < size; ++i) {
3056 if (i < assigned->length() && !assigned->Contains(i)) continue; 3089 if (i < assigned->length() && !assigned->Contains(i)) continue;
3057 Node* phi = builder_->NewPhi(1, values()->at(i), control); 3090 Node* phi = builder_->NewPhi(1, values()->at(i), control);
3058 values()->at(i) = phi; 3091 values()->at(i) = phi;
3059 } 3092 }
3060 } 3093 }
3061 Node* effect = builder_->NewEffectPhi(1, GetEffectDependency(), control); 3094 Node* effect = builder_->NewEffectPhi(1, GetEffectDependency(), control);
3062 UpdateEffectDependency(effect); 3095 UpdateEffectDependency(effect);
3063 3096
3097 if (builder_->info()->is_osr()) {
3098 // Introduce phis for all context values in the case of an OSR graph.
3099 for (int i = 0; i < static_cast<int>(contexts()->size()); ++i) {
3100 Node* val = contexts()->at(i);
3101 if (!IrOpcode::IsConstantOpcode(val->opcode())) {
3102 contexts()->at(i) = builder_->NewPhi(1, val, control);
3103 }
3104 }
3105 }
3106
3064 if (is_osr) { 3107 if (is_osr) {
3065 // Merge OSR values as inputs to the phis of the loop. 3108 // Merge OSR values as inputs to the phis of the loop.
3066 Graph* graph = builder_->graph(); 3109 Graph* graph = builder_->graph();
3067 Node* osr_loop_entry = builder_->graph()->NewNode( 3110 Node* osr_loop_entry = builder_->graph()->NewNode(
3068 builder_->common()->OsrLoopEntry(), graph->start(), graph->start()); 3111 builder_->common()->OsrLoopEntry(), graph->start(), graph->start());
3069 3112
3070 builder_->MergeControl(control, osr_loop_entry); 3113 builder_->MergeControl(control, osr_loop_entry);
3071 builder_->MergeEffect(effect, osr_loop_entry, control); 3114 builder_->MergeEffect(effect, osr_loop_entry, control);
3072 3115
3073 for (int i = 0; i < size; ++i) { 3116 for (int i = 0; i < size; ++i) {
3074 Node* val = values()->at(i); 3117 Node* val = values()->at(i);
3075 if (!IrOpcode::IsConstantOpcode(val->opcode())) { 3118 if (!IrOpcode::IsConstantOpcode(val->opcode())) {
3076 Node* osr_value = 3119 Node* osr_value =
3077 graph->NewNode(builder_->common()->OsrValue(i), osr_loop_entry); 3120 graph->NewNode(builder_->common()->OsrValue(i), osr_loop_entry);
3078 values()->at(i) = builder_->MergeValue(val, osr_value, control); 3121 values()->at(i) = builder_->MergeValue(val, osr_value, control);
3079 } 3122 }
3080 } 3123 }
3124
3125 // Rename all the contexts in the environment.
3126 // The innermost context is the OSR value, and the outer contexts are
3127 // reconstructed by dynamically walking up the context chain.
3128 Node* osr_context = nullptr;
3129 const Operator* op =
3130 builder_->javascript()->LoadContext(0, Context::PREVIOUS_INDEX, true);
3131 int last = static_cast<int>(contexts()->size() - 1);
3132 for (int i = last; i >= 0; i--) {
3133 Node* val = contexts()->at(i);
3134 if (!IrOpcode::IsConstantOpcode(val->opcode())) {
3135 osr_context = (i == last) ? builder_->NewCurrentContextOsrValue()
3136 : graph->NewNode(op, osr_context, osr_context,
3137 osr_loop_entry);
3138 contexts()->at(i) = builder_->MergeValue(val, osr_context, control);
3139 } else {
3140 osr_context = val;
3141 }
3142 }
3081 } 3143 }
3082 } 3144 }
3083 3145
3084 3146
3085 Node* AstGraphBuilder::NewPhi(int count, Node* input, Node* control) { 3147 Node* AstGraphBuilder::NewPhi(int count, Node* input, Node* control) {
3086 const Operator* phi_op = common()->Phi(kMachAnyTagged, count); 3148 const Operator* phi_op = common()->Phi(kMachAnyTagged, count);
3087 Node** buffer = EnsureInputBufferSize(count + 1); 3149 Node** buffer = EnsureInputBufferSize(count + 1);
3088 MemsetPointer(buffer, input, count); 3150 MemsetPointer(buffer, input, count);
3089 buffer[count] = control; 3151 buffer[count] = control;
3090 return graph()->NewNode(phi_op, count + 1, buffer, true); 3152 return graph()->NewNode(phi_op, count + 1, buffer, true);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
3150 // Phi does not exist yet, introduce one. 3212 // Phi does not exist yet, introduce one.
3151 value = NewPhi(inputs, value, control); 3213 value = NewPhi(inputs, value, control);
3152 value->ReplaceInput(inputs - 1, other); 3214 value->ReplaceInput(inputs - 1, other);
3153 } 3215 }
3154 return value; 3216 return value;
3155 } 3217 }
3156 3218
3157 } // namespace compiler 3219 } // namespace compiler
3158 } // namespace internal 3220 } // namespace internal
3159 } // namespace v8 3221 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/compiler/osr.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698