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

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

Issue 1221103003: [turbofan] Move context specialization into JSContextSpecializer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix predicate. Created 5 years, 5 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/js-context-specialization.h » ('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/js-type-feedback.h" 10 #include "src/compiler/js-type-feedback.h"
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 if (!function_closure_.is_set()) { 476 if (!function_closure_.is_set()) {
477 const Operator* op = common()->Parameter( 477 const Operator* op = common()->Parameter(
478 Linkage::kJSFunctionCallClosureParamIndex, "%closure"); 478 Linkage::kJSFunctionCallClosureParamIndex, "%closure");
479 Node* node = NewNode(op, graph()->start()); 479 Node* node = NewNode(op, graph()->start());
480 function_closure_.set(node); 480 function_closure_.set(node);
481 } 481 }
482 return function_closure_.get(); 482 return function_closure_.get();
483 } 483 }
484 484
485 485
486 void AstGraphBuilder::CreateFunctionContext(bool constant_context) { 486 Node* AstGraphBuilder::GetFunctionContext() {
487 function_context_.set(constant_context 487 if (!function_context_.is_set()) {
488 ? jsgraph()->HeapConstant(info()->context()) 488 const Operator* op = common()->Parameter(
489 : NewOuterContextParam()); 489 info()->num_parameters_including_this(), "%context");
490 Node* node = NewNode(op, graph()->start());
491 function_context_.set(node);
492 }
493 return function_context_.get();
490 } 494 }
491 495
492 496
493 Node* AstGraphBuilder::NewOuterContextParam() { 497 bool AstGraphBuilder::CreateGraph(bool stack_check) {
494 // Parameter (arity + 1) is special for the outer context of the function
495 const Operator* op =
496 common()->Parameter(info()->num_parameters_including_this(), "%context");
497 return NewNode(op, graph()->start());
498 }
499
500
501 Node* AstGraphBuilder::NewCurrentContextOsrValue() {
502 // TODO(titzer): use a real OSR value here; a parameter works by accident.
503 // Parameter (arity + 1) is special for the outer context of the function
504 const Operator* op = common()->Parameter(
505 info()->num_parameters_including_this(), "%osr-context");
506 return NewNode(op, graph()->start());
507 }
508
509
510 bool AstGraphBuilder::CreateGraph(bool constant_context, bool stack_check) {
511 Scope* scope = info()->scope(); 498 Scope* scope = info()->scope();
512 DCHECK(graph() != NULL); 499 DCHECK(graph() != NULL);
513 500
514 // Set up the basic structure of the graph. 501 // Set up the basic structure of the graph.
515 int parameter_count = info()->num_parameters(); 502 int parameter_count = info()->num_parameters();
516 graph()->SetStart(graph()->NewNode(common()->Start(parameter_count))); 503 graph()->SetStart(graph()->NewNode(common()->Start(parameter_count)));
517 504
518 // Initialize the top-level environment. 505 // Initialize the top-level environment.
519 Environment env(this, scope, graph()->start()); 506 Environment env(this, scope, graph()->start());
520 set_environment(&env); 507 set_environment(&env);
521 508
522 if (info()->is_osr()) { 509 if (info()->is_osr()) {
523 // Use OSR normal entry as the start of the top-level environment. 510 // Use OSR normal entry as the start of the top-level environment.
524 // It will be replaced with {Dead} after typing and optimizations. 511 // It will be replaced with {Dead} after typing and optimizations.
525 NewNode(common()->OsrNormalEntry()); 512 NewNode(common()->OsrNormalEntry());
526 } 513 }
527 514
528 // Initialize the incoming context. 515 // Initialize the incoming context.
529 CreateFunctionContext(constant_context); 516 ContextScope incoming(this, scope, GetFunctionContext());
530 ContextScope incoming(this, scope, function_context_.get());
531 517
532 // Initialize control scope. 518 // Initialize control scope.
533 ControlScope control(this); 519 ControlScope control(this);
534 520
535 // Build receiver check for sloppy mode if necessary. 521 // Build receiver check for sloppy mode if necessary.
536 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC? 522 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC?
537 Node* patched_receiver = nullptr; 523 Node* patched_receiver = nullptr;
538 if (scope->has_this_declaration()) { 524 if (scope->has_this_declaration()) {
539 Node* original_receiver = NewNode(common()->Parameter(0), graph()->start()); 525 Node* original_receiver = NewNode(common()->Parameter(0), graph()->start());
540 patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); 526 patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver);
541 if (scope->receiver()->IsStackAllocated()) { 527 if (scope->receiver()->IsStackAllocated()) {
542 env.Bind(scope->receiver(), patched_receiver); 528 env.Bind(scope->receiver(), patched_receiver);
543 } 529 }
544 } 530 }
545 531
546 // Build function context only if there are context allocated variables. 532 // Build function context only if there are context allocated variables.
547 if (info()->num_heap_slots() > 0) { 533 if (info()->num_heap_slots() > 0) {
548 // Push a new inner context scope for the function. 534 // Push a new inner context scope for the function.
549 Node* inner_context = 535 Node* inner_context =
550 BuildLocalFunctionContext(function_context_.get(), patched_receiver); 536 BuildLocalFunctionContext(GetFunctionContext(), patched_receiver);
551 ContextScope top_context(this, scope, inner_context); 537 ContextScope top_context(this, scope, inner_context);
552 CreateGraphBody(stack_check); 538 CreateGraphBody(stack_check);
553 } else { 539 } else {
554 // Simply use the outer function context in building the graph. 540 // Simply use the outer function context in building the graph.
555 CreateGraphBody(stack_check); 541 CreateGraphBody(stack_check);
556 } 542 }
557 543
558 // Finish the basic structure of the graph. 544 // Finish the basic structure of the graph.
559 DCHECK_NE(0u, exit_controls_.size()); 545 DCHECK_NE(0u, exit_controls_.size());
560 int const input_count = static_cast<int>(exit_controls_.size()); 546 int const input_count = static_cast<int>(exit_controls_.size());
(...skipping 3068 matching lines...) Expand 10 before | Expand all | Expand 10 after
3629 Node* global = BuildLoadGlobalObject(); 3615 Node* global = BuildLoadGlobalObject();
3630 Node* builtins = 3616 Node* builtins =
3631 BuildLoadObjectField(global, JSGlobalObject::kBuiltinsOffset); 3617 BuildLoadObjectField(global, JSGlobalObject::kBuiltinsOffset);
3632 return builtins; 3618 return builtins;
3633 } 3619 }
3634 3620
3635 3621
3636 Node* AstGraphBuilder::BuildLoadGlobalObject() { 3622 Node* AstGraphBuilder::BuildLoadGlobalObject() {
3637 const Operator* load_op = 3623 const Operator* load_op =
3638 javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true); 3624 javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true);
3639 return NewNode(load_op, function_context_.get()); 3625 return NewNode(load_op, GetFunctionContext());
3640 } 3626 }
3641 3627
3642 3628
3643 Node* AstGraphBuilder::BuildLoadGlobalProxy() { 3629 Node* AstGraphBuilder::BuildLoadGlobalProxy() {
3644 Node* global = BuildLoadGlobalObject(); 3630 Node* global = BuildLoadGlobalObject();
3645 Node* proxy = 3631 Node* proxy =
3646 BuildLoadObjectField(global, JSGlobalObject::kGlobalProxyOffset); 3632 BuildLoadObjectField(global, JSGlobalObject::kGlobalProxyOffset);
3647 return proxy; 3633 return proxy;
3648 } 3634 }
3649 3635
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
4056 // Connect the Loop node to end via a Terminate node. 4042 // Connect the Loop node to end via a Terminate node.
4057 Node* terminate = builder_->graph()->NewNode( 4043 Node* terminate = builder_->graph()->NewNode(
4058 builder_->common()->Terminate(), effect, control); 4044 builder_->common()->Terminate(), effect, control);
4059 builder_->exit_controls_.push_back(terminate); 4045 builder_->exit_controls_.push_back(terminate);
4060 } 4046 }
4061 4047
4062 if (builder_->info()->is_osr()) { 4048 if (builder_->info()->is_osr()) {
4063 // Introduce phis for all context values in the case of an OSR graph. 4049 // Introduce phis for all context values in the case of an OSR graph.
4064 for (int i = 0; i < static_cast<int>(contexts()->size()); ++i) { 4050 for (int i = 0; i < static_cast<int>(contexts()->size()); ++i) {
4065 Node* val = contexts()->at(i); 4051 Node* val = contexts()->at(i);
4066 if (!IrOpcode::IsConstantOpcode(val->opcode())) { 4052 if (!IrOpcode::IsConstantOpcode(val->opcode()) &&
4053 (val != builder_->GetFunctionContext() ||
4054 !builder_->info()->is_context_specializing())) {
4067 contexts()->at(i) = builder_->NewPhi(1, val, control); 4055 contexts()->at(i) = builder_->NewPhi(1, val, control);
4068 } 4056 }
4069 } 4057 }
4070 } 4058 }
4071 4059
4072 if (is_osr) { 4060 if (is_osr) {
4073 // Merge OSR values as inputs to the phis of the loop. 4061 // Merge OSR values as inputs to the phis of the loop.
4074 Graph* graph = builder_->graph(); 4062 Graph* graph = builder_->graph();
4075 Node* osr_loop_entry = builder_->graph()->NewNode( 4063 Node* osr_loop_entry = builder_->graph()->NewNode(
4076 builder_->common()->OsrLoopEntry(), graph->start(), graph->start()); 4064 builder_->common()->OsrLoopEntry(), graph->start(), graph->start());
4077 4065
4078 builder_->MergeControl(control, osr_loop_entry); 4066 builder_->MergeControl(control, osr_loop_entry);
4079 builder_->MergeEffect(effect, osr_loop_entry, control); 4067 builder_->MergeEffect(effect, osr_loop_entry, control);
4080 4068
4081 for (int i = 0; i < size; ++i) { 4069 for (int i = 0; i < size; ++i) {
4082 Node* val = values()->at(i); 4070 Node* val = values()->at(i);
4083 if (!IrOpcode::IsConstantOpcode(val->opcode())) { 4071 if (!IrOpcode::IsConstantOpcode(val->opcode())) {
4084 Node* osr_value = 4072 Node* osr_value =
4085 graph->NewNode(builder_->common()->OsrValue(i), osr_loop_entry); 4073 graph->NewNode(builder_->common()->OsrValue(i), osr_loop_entry);
4086 values()->at(i) = builder_->MergeValue(val, osr_value, control); 4074 values()->at(i) = builder_->MergeValue(val, osr_value, control);
4087 } 4075 }
4088 } 4076 }
4089 4077
4090 // Rename all the contexts in the environment. 4078 // Rename all the contexts in the environment.
4091 // The innermost context is the OSR value, and the outer contexts are 4079 // The innermost context is the OSR value, and the outer contexts are
4092 // reconstructed by dynamically walking up the context chain. 4080 // reconstructed by dynamically walking up the context chain.
4081 // TODO(titzer): use a real OSR value here; a parameter works by accident.
titzer 2015/07/03 09:28:17 To get rid of this TODO, we need a special OSR val
Michael Starzinger 2015/07/06 13:08:40 Done, see: https://codereview.chromium.org/1213043
4082 Node* innermost_context = graph->NewNode(
4083 builder_->common()->Parameter(
4084 builder_->info()->num_parameters_including_this(), "%osr-context"),
4085 graph->start());
4093 Node* osr_context = nullptr; 4086 Node* osr_context = nullptr;
4094 const Operator* op = 4087 const Operator* op =
4095 builder_->javascript()->LoadContext(0, Context::PREVIOUS_INDEX, true); 4088 builder_->javascript()->LoadContext(0, Context::PREVIOUS_INDEX, true);
4096 int last = static_cast<int>(contexts()->size() - 1); 4089 int last = static_cast<int>(contexts()->size() - 1);
4097 for (int i = last; i >= 0; i--) { 4090 for (int i = last; i >= 0; i--) {
4098 Node* val = contexts()->at(i); 4091 Node* val = contexts()->at(i);
4099 if (!IrOpcode::IsConstantOpcode(val->opcode())) { 4092 if (!IrOpcode::IsConstantOpcode(val->opcode()) &&
4100 osr_context = (i == last) ? builder_->NewCurrentContextOsrValue() 4093 (val != builder_->GetFunctionContext() ||
4094 !builder_->info()->is_context_specializing())) {
4095 osr_context = (i == last) ? innermost_context
4101 : graph->NewNode(op, osr_context, osr_context, 4096 : graph->NewNode(op, osr_context, osr_context,
4102 osr_loop_entry); 4097 osr_loop_entry);
4103 contexts()->at(i) = builder_->MergeValue(val, osr_context, control); 4098 contexts()->at(i) = builder_->MergeValue(val, osr_context, control);
4104 } else { 4099 } else {
4105 osr_context = val; 4100 osr_context = val;
4106 } 4101 }
4107 } 4102 }
4108 } 4103 }
4109 } 4104 }
4110 4105
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
4177 // Phi does not exist yet, introduce one. 4172 // Phi does not exist yet, introduce one.
4178 value = NewPhi(inputs, value, control); 4173 value = NewPhi(inputs, value, control);
4179 value->ReplaceInput(inputs - 1, other); 4174 value->ReplaceInput(inputs - 1, other);
4180 } 4175 }
4181 return value; 4176 return value;
4182 } 4177 }
4183 4178
4184 } // namespace compiler 4179 } // namespace compiler
4185 } // namespace internal 4180 } // namespace internal
4186 } // namespace v8 4181 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/compiler/js-context-specialization.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698