| Index: src/compiler/ast-graph-builder.cc
|
| diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc
|
| index 2d92ca5d82626edae4bf3dfb9b4f82a0233c7f85..358336480434c09f314231336f1c464f9b600826 100644
|
| --- a/src/compiler/ast-graph-builder.cc
|
| +++ b/src/compiler/ast-graph-builder.cc
|
| @@ -599,7 +599,10 @@ void AstGraphBuilder::CreateGraphBody(bool stack_check) {
|
|
|
|
|
| void AstGraphBuilder::ClearNonLiveSlotsInFrameStates() {
|
| - if (!FLAG_analyze_environment_liveness) return;
|
| + if (!FLAG_analyze_environment_liveness ||
|
| + !info()->is_deoptimization_enabled()) {
|
| + return;
|
| + }
|
|
|
| NonLiveFrameStateSlotReplacer replacer(
|
| &state_values_cache_, jsgraph()->UndefinedConstant(),
|
| @@ -660,7 +663,9 @@ AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder,
|
| : builder_(builder),
|
| parameters_count_(scope->num_parameters() + 1),
|
| locals_count_(scope->num_stack_slots()),
|
| - liveness_block_(builder_->liveness_analyzer()->NewBlock()),
|
| + liveness_block_(IsLivenessAnalysisEnabled()
|
| + ? builder_->liveness_analyzer()->NewBlock()
|
| + : nullptr),
|
| values_(builder_->local_zone()),
|
| contexts_(builder_->local_zone()),
|
| control_dependency_(control_dependency),
|
| @@ -696,10 +701,12 @@ AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder,
|
| }
|
|
|
|
|
| -AstGraphBuilder::Environment::Environment(AstGraphBuilder::Environment* copy)
|
| +AstGraphBuilder::Environment::Environment(AstGraphBuilder::Environment* copy,
|
| + LivenessAnalyzerBlock* liveness_block)
|
| : builder_(copy->builder_),
|
| parameters_count_(copy->parameters_count_),
|
| locals_count_(copy->locals_count_),
|
| + liveness_block_(liveness_block),
|
| values_(copy->zone()),
|
| contexts_(copy->zone()),
|
| control_dependency_(copy->control_dependency_),
|
| @@ -713,14 +720,6 @@ AstGraphBuilder::Environment::Environment(AstGraphBuilder::Environment* copy)
|
| contexts_.reserve(copy->contexts_.size());
|
| contexts_.insert(contexts_.begin(), copy->contexts_.begin(),
|
| copy->contexts_.end());
|
| -
|
| - if (FLAG_analyze_environment_liveness) {
|
| - // Split the liveness blocks.
|
| - copy->liveness_block_ =
|
| - builder_->liveness_analyzer()->NewBlock(copy->liveness_block());
|
| - liveness_block_ =
|
| - builder_->liveness_analyzer()->NewBlock(copy->liveness_block());
|
| - }
|
| }
|
|
|
|
|
| @@ -733,7 +732,9 @@ void AstGraphBuilder::Environment::Bind(Variable* variable, Node* node) {
|
| } else {
|
| DCHECK(variable->IsStackLocal());
|
| values()->at(variable->index() + parameters_count_) = node;
|
| - if (FLAG_analyze_environment_liveness) {
|
| +
|
| + DCHECK(IsLivenessBlockConsistent());
|
| + if (liveness_block() != nullptr) {
|
| liveness_block()->Bind(variable->index());
|
| }
|
| }
|
| @@ -748,7 +749,8 @@ Node* AstGraphBuilder::Environment::Lookup(Variable* variable) {
|
| return values()->at(variable->index() + 1);
|
| } else {
|
| DCHECK(variable->IsStackLocal());
|
| - if (FLAG_analyze_environment_liveness) {
|
| + DCHECK(IsLivenessBlockConsistent());
|
| + if (liveness_block() != nullptr) {
|
| liveness_block()->Lookup(variable->index());
|
| }
|
| return values()->at(variable->index() + parameters_count_);
|
| @@ -757,7 +759,8 @@ Node* AstGraphBuilder::Environment::Lookup(Variable* variable) {
|
|
|
|
|
| void AstGraphBuilder::Environment::MarkAllLocalsLive() {
|
| - if (FLAG_analyze_environment_liveness) {
|
| + DCHECK(IsLivenessBlockConsistent());
|
| + if (liveness_block() != nullptr) {
|
| for (int i = 0; i < locals_count_; i++) {
|
| liveness_block()->Lookup(i);
|
| }
|
| @@ -766,15 +769,43 @@ void AstGraphBuilder::Environment::MarkAllLocalsLive() {
|
|
|
|
|
| AstGraphBuilder::Environment*
|
| +AstGraphBuilder::Environment::CopyForConditional() {
|
| + LivenessAnalyzerBlock* copy_liveness_block = nullptr;
|
| + if (liveness_block() != nullptr) {
|
| + copy_liveness_block =
|
| + builder_->liveness_analyzer()->NewBlock(liveness_block());
|
| + liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block());
|
| + }
|
| + return new (zone()) Environment(this, copy_liveness_block);
|
| +}
|
| +
|
| +
|
| +AstGraphBuilder::Environment*
|
| +AstGraphBuilder::Environment::CopyAsUnreachable() {
|
| + Environment* env = new (zone()) Environment(this, nullptr);
|
| + env->MarkAsUnreachable();
|
| + return env;
|
| +}
|
| +
|
| +
|
| +AstGraphBuilder::Environment*
|
| AstGraphBuilder::Environment::CopyAndShareLiveness() {
|
| - Environment* env = new (zone()) Environment(this);
|
| - if (FLAG_analyze_environment_liveness) {
|
| - env->liveness_block_ = liveness_block();
|
| + if (liveness_block() != nullptr) {
|
| + // Finish the current liveness block before copying.
|
| + liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block());
|
| }
|
| + Environment* env = new (zone()) Environment(this, liveness_block());
|
| return env;
|
| }
|
|
|
|
|
| +AstGraphBuilder::Environment* AstGraphBuilder::Environment::CopyForLoop(
|
| + BitVector* assigned, bool is_osr) {
|
| + PrepareForLoop(assigned, is_osr);
|
| + return CopyAndShareLiveness();
|
| +}
|
| +
|
| +
|
| void AstGraphBuilder::Environment::UpdateStateValues(Node** state_values,
|
| int offset, int count) {
|
| bool should_update = false;
|
| @@ -822,13 +853,27 @@ Node* AstGraphBuilder::Environment::Checkpoint(
|
| stack_node_, builder()->current_context(),
|
| builder()->GetFunctionClosure(),
|
| builder()->jsgraph()->UndefinedConstant());
|
| - if (FLAG_analyze_environment_liveness) {
|
| +
|
| + DCHECK(IsLivenessBlockConsistent());
|
| + if (liveness_block() != nullptr) {
|
| liveness_block()->Checkpoint(result);
|
| }
|
| return result;
|
| }
|
|
|
|
|
| +bool AstGraphBuilder::Environment::IsLivenessAnalysisEnabled() {
|
| + return FLAG_analyze_environment_liveness &&
|
| + builder()->info()->is_deoptimization_enabled();
|
| +}
|
| +
|
| +
|
| +bool AstGraphBuilder::Environment::IsLivenessBlockConsistent() {
|
| + return (!IsLivenessAnalysisEnabled() || IsMarkedAsUnreachable()) ==
|
| + (liveness_block() == nullptr);
|
| +}
|
| +
|
| +
|
| AstGraphBuilder::AstContext::AstContext(AstGraphBuilder* own,
|
| Expression::Context kind)
|
| : kind_(kind), owner_(own), outer_(own->ast_context()) {
|
| @@ -3464,9 +3509,13 @@ Node* AstGraphBuilder::MakeNode(const Operator* op, int value_input_count,
|
| }
|
| // Add implicit exception continuation for throwing nodes.
|
| if (!result->op()->HasProperty(Operator::kNoThrow) && inside_try_scope) {
|
| + // Copy the environment for the success continuation.
|
| + Environment* success_env = environment()->CopyForConditional();
|
| +
|
| Node* on_exception = graph()->NewNode(common()->IfException(), result);
|
| environment_->UpdateControlDependency(on_exception);
|
| execution_control()->ThrowValue(on_exception);
|
| + set_environment(success_env);
|
| }
|
| // Add implicit success continuation for throwing nodes.
|
| if (!result->op()->HasProperty(Operator::kNoThrow)) {
|
| @@ -3502,21 +3551,23 @@ void AstGraphBuilder::Environment::Merge(Environment* other) {
|
| if (this->IsMarkedAsUnreachable()) {
|
| Node* other_control = other->control_dependency_;
|
| Node* inputs[] = {other_control};
|
| - liveness_block_ = other->liveness_block_;
|
| control_dependency_ =
|
| graph()->NewNode(common()->Merge(1), arraysize(inputs), inputs, true);
|
| effect_dependency_ = other->effect_dependency_;
|
| values_ = other->values_;
|
| contexts_ = other->contexts_;
|
| + if (IsLivenessAnalysisEnabled()) {
|
| + liveness_block_ =
|
| + builder_->liveness_analyzer()->NewBlock(other->liveness_block());
|
| + }
|
| return;
|
| }
|
|
|
| // Record the merge for the local variable liveness calculation.
|
| - // Unfortunately, we have to mirror the logic in the MergeControl method:
|
| - // connect before merge or loop, or create a new merge otherwise.
|
| - if (FLAG_analyze_environment_liveness) {
|
| - if (GetControlDependency()->opcode() != IrOpcode::kLoop &&
|
| - GetControlDependency()->opcode() != IrOpcode::kMerge) {
|
| + // For loops, we are connecting a back edge into the existing block;
|
| + // for merges, we create a new merged block.
|
| + if (IsLivenessAnalysisEnabled()) {
|
| + if (GetControlDependency()->opcode() != IrOpcode::kLoop) {
|
| liveness_block_ =
|
| builder_->liveness_analyzer()->NewBlock(liveness_block());
|
| }
|
|
|