[turbofan] Keep AstGraphBuilder context chain length in sync.

This keeps the length of the context chain tracked by the environment
in sync even for local control flow commands. It removes the need to
guess the correct chain length at Environment::Merge points.

R=titzer@chromium.org

Review URL: https://codereview.chromium.org/1045703003

Cr-Commit-Position: refs/heads/master@{#27588}
This commit is contained in:
mstarzinger 2015-04-02 04:49:03 -07:00 committed by Commit bot
parent 4c0af45717
commit 9596b36c1d
2 changed files with 17 additions and 14 deletions

View File

@ -112,7 +112,7 @@ class AstGraphBuilder::ContextScope BASE_EMBEDDED {
: builder_(builder),
outer_(builder->execution_context()),
scope_(scope),
depth_(builder_->environment()->ContextStackDepth()) {
depth_(builder_->environment()->context_chain_length()) {
builder_->environment()->PushContext(context); // Push.
builder_->set_execution_context(this);
}
@ -120,7 +120,7 @@ class AstGraphBuilder::ContextScope BASE_EMBEDDED {
~ContextScope() {
builder_->set_execution_context(outer_); // Pop.
builder_->environment()->PopContext();
CHECK_EQ(depth_, builder_->environment()->ContextStackDepth());
CHECK_EQ(depth_, builder_->environment()->context_chain_length());
}
// Current scope during visitation.
@ -146,6 +146,7 @@ class AstGraphBuilder::ControlScope BASE_EMBEDDED {
explicit ControlScope(AstGraphBuilder* builder)
: builder_(builder),
outer_(builder->execution_control()),
context_length_(builder->environment()->context_chain_length()),
stack_height_(builder->environment()->stack_height()) {
builder_->set_execution_control(this); // Push.
}
@ -193,11 +194,13 @@ class AstGraphBuilder::ControlScope BASE_EMBEDDED {
Environment* environment() { return builder_->environment(); }
AstGraphBuilder* builder() const { return builder_; }
int context_length() const { return context_length_; }
int stack_height() const { return stack_height_; }
private:
AstGraphBuilder* builder_;
ControlScope* outer_;
int context_length_;
int stack_height_;
};
@ -450,9 +453,6 @@ bool AstGraphBuilder::CreateGraph(bool constant_context, bool stack_check) {
Environment env(this, scope, graph()->start());
set_environment(&env);
// Initialize control scope.
ControlScope control(this);
if (info()->is_osr()) {
// Use OSR normal entry as the start of the top-level environment.
// It will be replaced with {Dead} after typing and optimizations.
@ -463,6 +463,9 @@ bool AstGraphBuilder::CreateGraph(bool constant_context, bool stack_check) {
CreateFunctionContext(constant_context);
ContextScope incoming(this, scope, function_context_.get());
// Initialize control scope.
ControlScope control(this);
// Build receiver check for sloppy mode if necessary.
// TODO(mstarzinger/verwaest): Should this be moved back into the CallIC?
Node* original_receiver = env.Lookup(scope->receiver());
@ -813,7 +816,8 @@ void AstGraphBuilder::ControlScope::PerformCommand(Command command,
Environment* env = environment()->CopyAsUnreachable();
ControlScope* current = this;
while (current != NULL) {
environment()->Trim(current->stack_height());
environment()->TrimStack(current->stack_height());
environment()->TrimContextChain(current->context_length());
if (current->Execute(command, target, value)) break;
current = current->outer_;
}
@ -3334,8 +3338,7 @@ void AstGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) {
void AstGraphBuilder::Environment::Merge(Environment* other) {
DCHECK(values_.size() == other->values_.size());
// TODO(titzer): make context stack heights match.
DCHECK(contexts_.size() <= other->contexts_.size());
DCHECK(contexts_.size() == other->contexts_.size());
// Nothing to do if the other environment is dead.
if (other->IsMarkedAsUnreachable()) return;
@ -3350,10 +3353,7 @@ void AstGraphBuilder::Environment::Merge(Environment* other) {
graph()->NewNode(common()->Merge(1), arraysize(inputs), inputs, true);
effect_dependency_ = other->effect_dependency_;
values_ = other->values_;
// TODO(titzer): make context stack heights match.
size_t min = std::min(contexts_.size(), other->contexts_.size());
contexts_ = other->contexts_;
contexts_.resize(min, nullptr);
return;
}

View File

@ -384,6 +384,7 @@ class AstGraphBuilder::Environment : public ZoneObject {
int parameters_count() const { return parameters_count_; }
int locals_count() const { return locals_count_; }
int context_chain_length() { return static_cast<int>(contexts_.size()); }
int stack_height() {
return static_cast<int>(values()->size()) - parameters_count_ -
locals_count_;
@ -394,9 +395,13 @@ class AstGraphBuilder::Environment : public ZoneObject {
Node* Lookup(Variable* variable);
void MarkAllLocalsLive();
// Operations on the context chain.
Node* Context() const { return contexts_.back(); }
void PushContext(Node* context) { contexts()->push_back(context); }
void PopContext() { contexts()->pop_back(); }
void TrimContextChain(int trim_to_length) {
contexts()->resize(trim_to_length);
}
// Operations on the operand stack.
void Push(Node* node) {
@ -428,7 +433,7 @@ class AstGraphBuilder::Environment : public ZoneObject {
DCHECK(depth >= 0 && depth <= stack_height());
values()->erase(values()->end() - depth, values()->end());
}
void Trim(int trim_to_height) {
void TrimStack(int trim_to_height) {
int depth = stack_height() - trim_to_height;
DCHECK(depth >= 0 && depth <= stack_height());
values()->erase(values()->end() - depth, values()->end());
@ -478,8 +483,6 @@ class AstGraphBuilder::Environment : public ZoneObject {
return CopyAndShareLiveness();
}
int ContextStackDepth() { return static_cast<int>(contexts_.size()); }
private:
AstGraphBuilder* builder_;
int parameters_count_;