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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: src/compiler/ast-graph-builder.cc
diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc
index 277f0d5c8598a6a1822a9eaa17a92875c12e2069..da0841dd8fedf1b4757631e728c9561c086977d1 100644
--- a/src/compiler/ast-graph-builder.cc
+++ b/src/compiler/ast-graph-builder.cc
@@ -109,24 +109,25 @@ class AstGraphBuilder::ContextScope BASE_EMBEDDED {
: builder_(builder),
outer_(builder->execution_context()),
scope_(scope),
- context_(context) {
- builder_->set_execution_context(this); // Push.
+ depth_(builder_->environment()->ContextStackDepth()) {
+ builder_->environment()->PushContext(context); // Push.
+ builder_->set_execution_context(this);
}
~ContextScope() {
builder_->set_execution_context(outer_); // Pop.
+ builder_->environment()->PopContext();
+ CHECK_EQ(depth_, builder_->environment()->ContextStackDepth());
}
// Current scope during visitation.
Scope* scope() const { return scope_; }
- // Current context node during visitation.
- Node* context() const { return context_; }
private:
AstGraphBuilder* builder_;
ContextScope* outer_;
Scope* scope_;
- Node* context_;
+ int depth_;
};
@@ -378,6 +379,7 @@ AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info,
globals_(0, local_zone),
execution_control_(nullptr),
execution_context_(nullptr),
+ function_context_(nullptr),
input_buffer_size_(0),
input_buffer_(nullptr),
exit_control_(nullptr),
@@ -398,13 +400,23 @@ Node* AstGraphBuilder::GetFunctionClosure() {
Node* AstGraphBuilder::GetFunctionContext() {
- if (!function_context_.is_set()) {
- // Parameter (arity + 1) is special for the outer context of the function
- const Operator* op = common()->Parameter(info()->num_parameters() + 1);
- Node* node = NewNode(op, graph()->start());
- function_context_.set(node);
- }
- return function_context_.get();
+ DCHECK(function_context_ != nullptr);
+ return function_context_;
+}
+
+
+Node* AstGraphBuilder::NewOuterContextParam() {
+ // Parameter (arity + 1) is special for the outer context of the function
+ const Operator* op = common()->Parameter(info()->num_parameters() + 1);
+ return NewNode(op, graph()->start());
+}
+
+
+Node* AstGraphBuilder::NewCurrentContextOsrValue() {
+ // TODO(titzer): use a real OSR value here; a parameter works by accident.
+ // Parameter (arity + 1) is special for the outer context of the function
+ const Operator* op = common()->Parameter(info()->num_parameters() + 1);
+ return NewNode(op, graph()->start());
}
@@ -430,8 +442,8 @@ bool AstGraphBuilder::CreateGraph() {
}
// Initialize the incoming context.
- Node* incoming_context = GetFunctionContext();
- ContextScope incoming(this, scope, incoming_context);
+ function_context_ = NewOuterContextParam();
+ ContextScope incoming(this, scope, function_context_);
// Build receiver check for sloppy mode if necessary.
// TODO(mstarzinger/verwaest): Should this be moved back into the CallIC?
@@ -439,13 +451,31 @@ bool AstGraphBuilder::CreateGraph() {
Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver);
env.Bind(scope->receiver(), patched_receiver);
- // Build node to initialize local function context.
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
- Node* inner_context = BuildLocalFunctionContext(incoming_context, closure);
+ bool ok;
+ int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
+ if (heap_slots > 0) {
+ // Push a new inner context scope for the function.
+ Node* inner_context = BuildLocalFunctionContext(function_context_, closure);
+ ContextScope top_context(this, scope, inner_context);
+ ok = CreateGraphBody();
+ } else {
+ // Simply use the outer function context in building the graph.
+ ok = CreateGraphBody();
+ }
+
+ // Finish the basic structure of the graph.
+ 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.
+ environment()->UpdateControlDependency(exit_control());
+ graph()->SetEnd(NewNode(common()->End()));
+ }
+
+ return ok;
+}
- // Push top-level function context for the function body.
- ContextScope top_context(this, scope, inner_context);
+bool AstGraphBuilder::CreateGraphBody() {
+ Scope* scope = info()->scope();
// Build the arguments object if it is used.
BuildArgumentsObject(scope->arguments());
@@ -485,10 +515,6 @@ bool AstGraphBuilder::CreateGraph() {
// Return 'undefined' in case we can fall off the end.
BuildReturn(jsgraph()->UndefinedConstant());
- // Finish the basic structure of the graph.
- environment()->UpdateControlDependency(exit_control());
- graph()->SetEnd(NewNode(common()->End()));
-
return true;
}
@@ -516,6 +542,7 @@ AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder,
parameters_count_(scope->num_parameters() + 1),
locals_count_(scope->num_stack_slots()),
values_(builder_->local_zone()),
+ contexts_(builder_->local_zone()),
control_dependency_(control_dependency),
effect_dependency_(control_dependency),
parameters_node_(nullptr),
@@ -548,6 +575,7 @@ AstGraphBuilder::Environment::Environment(
parameters_count_(copy->parameters_count_),
locals_count_(copy->locals_count_),
values_(copy->zone()),
+ contexts_(copy->zone()),
control_dependency_(copy->control_dependency_),
effect_dependency_(copy->effect_dependency_),
parameters_node_(copy->parameters_node_),
@@ -556,6 +584,9 @@ AstGraphBuilder::Environment::Environment(
const size_t kStackEstimate = 7; // optimum from experimentation!
values_.reserve(copy->values_.size() + kStackEstimate);
values_.insert(values_.begin(), copy->values_.begin(), copy->values_.end());
+ contexts_.reserve(copy->contexts_.size());
+ contexts_.insert(contexts_.begin(), copy->contexts_.begin(),
+ copy->contexts_.end());
}
@@ -660,7 +691,7 @@ Scope* AstGraphBuilder::current_scope() const {
Node* AstGraphBuilder::current_context() const {
- return execution_context_->context();
+ return environment()->Context();
}
@@ -1203,11 +1234,12 @@ void AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
const Operator* op = javascript()->CreateCatchContext(name);
Node* context = NewNode(op, exception, GetFunctionClosure());
PrepareFrameState(context, BailoutId::None());
- ContextScope scope(this, stmt->scope(), context);
- DCHECK(stmt->scope()->declarations()->is_empty());
-
- // Evaluate the catch-block.
- Visit(stmt->catch_block());
+ {
+ ContextScope scope(this, stmt->scope(), context);
+ DCHECK(stmt->scope()->declarations()->is_empty());
+ // Evaluate the catch-block.
+ Visit(stmt->catch_block());
+ }
try_control.EndCatch();
// TODO(mstarzinger): Remove bailout once everything works.
@@ -2430,9 +2462,6 @@ Node* AstGraphBuilder::BuildPatchReceiverToGlobalProxy(Node* receiver) {
Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context, Node* closure) {
- int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
- if (heap_slots <= 0) return context;
-
// Allocate a new local context.
const Operator* op = javascript()->CreateFunctionContext();
Node* local_context = NewNode(op, closure);
@@ -3006,6 +3035,7 @@ void AstGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) {
void AstGraphBuilder::Environment::Merge(Environment* other) {
DCHECK(values_.size() == other->values_.size());
+ DCHECK(contexts_.size() <= other->contexts_.size());
// Nothing to do if the other environment is dead.
if (other->IsMarkedAsUnreachable()) return;
@@ -3039,6 +3069,10 @@ void AstGraphBuilder::Environment::Merge(Environment* other) {
for (int i = 0; i < static_cast<int>(values_.size()); ++i) {
values_[i] = builder_->MergeValue(values_[i], other->values_[i], control);
}
+ for (int i = 0; i < static_cast<int>(contexts_.size()); ++i) {
+ contexts_[i] =
+ builder_->MergeValue(contexts_[i], other->contexts_[i], control);
+ }
}
@@ -3050,8 +3084,7 @@ void AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned,
if (assigned == nullptr) {
// Assume that everything is updated in the loop.
for (int i = 0; i < size; ++i) {
- Node* phi = builder_->NewPhi(1, values()->at(i), control);
- values()->at(i) = phi;
+ values()->at(i) = builder_->NewPhi(1, values()->at(i), control);
}
} else {
// Only build phis for those locals assigned in this loop.
@@ -3064,6 +3097,16 @@ void AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned,
Node* effect = builder_->NewEffectPhi(1, GetEffectDependency(), control);
UpdateEffectDependency(effect);
+ if (builder_->info()->is_osr()) {
+ // Introduce phis for all context values in the case of an OSR graph.
+ for (int i = 0; i < static_cast<int>(contexts()->size()); ++i) {
+ Node* val = contexts()->at(i);
+ if (!IrOpcode::IsConstantOpcode(val->opcode())) {
+ contexts()->at(i) = builder_->NewPhi(1, val, control);
+ }
+ }
+ }
+
if (is_osr) {
// Merge OSR values as inputs to the phis of the loop.
Graph* graph = builder_->graph();
@@ -3081,6 +3124,25 @@ void AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned,
values()->at(i) = builder_->MergeValue(val, osr_value, control);
}
}
+
+ // Rename all the contexts in the environment.
+ // The innermost context is the OSR value, and the outer contexts are
+ // reconstructed by dynamically walking up the context chain.
+ Node* osr_context = nullptr;
+ const Operator* op =
+ builder_->javascript()->LoadContext(0, Context::PREVIOUS_INDEX, true);
+ int last = static_cast<int>(contexts()->size() - 1);
+ for (int i = last; i >= 0; i--) {
+ Node* val = contexts()->at(i);
+ if (!IrOpcode::IsConstantOpcode(val->opcode())) {
+ osr_context = (i == last) ? builder_->NewCurrentContextOsrValue()
+ : graph->NewNode(op, osr_context, osr_context,
+ osr_loop_entry);
+ contexts()->at(i) = builder_->MergeValue(val, osr_context, control);
+ } else {
+ osr_context = val;
+ }
+ }
}
}

Powered by Google App Engine
This is Rietveld 408576698