| Index: src/compiler/ast-graph-builder.cc
|
| diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc
|
| index 68cf58905f87e1f62e0d2186409657ba29861d39..b292a2e49efd8e26020d9ad36a8ea96f1e150cc6 100644
|
| --- a/src/compiler/ast-graph-builder.cc
|
| +++ b/src/compiler/ast-graph-builder.cc
|
| @@ -787,6 +787,10 @@ AstGraphBuilder::Environment::CopyAsUnreachable() {
|
| return env;
|
| }
|
|
|
| +AstGraphBuilder::Environment* AstGraphBuilder::Environment::CopyForOsrEntry() {
|
| + return new (zone())
|
| + Environment(this, builder_->liveness_analyzer()->NewBlock());
|
| +}
|
|
|
| AstGraphBuilder::Environment*
|
| AstGraphBuilder::Environment::CopyAndShareLiveness() {
|
| @@ -801,8 +805,15 @@ AstGraphBuilder::Environment::CopyAndShareLiveness() {
|
|
|
| AstGraphBuilder::Environment* AstGraphBuilder::Environment::CopyForLoop(
|
| BitVector* assigned, bool is_osr) {
|
| - PrepareForLoop(assigned, is_osr);
|
| - return CopyAndShareLiveness();
|
| + PrepareForLoop(assigned);
|
| + Environment* loop = CopyAndShareLiveness();
|
| + if (is_osr) {
|
| + // Create and merge the OSR entry if necessary.
|
| + Environment* osr_env = CopyForOsrEntry();
|
| + osr_env->PrepareForOsrEntry();
|
| + loop->Merge(osr_env);
|
| + }
|
| + return loop;
|
| }
|
|
|
|
|
| @@ -4182,9 +4193,39 @@ void AstGraphBuilder::Environment::Merge(Environment* other) {
|
| }
|
| }
|
|
|
| +void AstGraphBuilder::Environment::PrepareForOsrEntry() {
|
| + int size = static_cast<int>(values()->size());
|
| + Graph* graph = builder_->graph();
|
| +
|
| + // Set the control and effect to the OSR loop entry.
|
| + Node* osr_loop_entry = graph->NewNode(builder_->common()->OsrLoopEntry(),
|
| + graph->start(), graph->start());
|
| + UpdateControlDependency(osr_loop_entry);
|
| + UpdateEffectDependency(osr_loop_entry);
|
| + // Set OSR values.
|
| + for (int i = 0; i < size; ++i) {
|
| + values()->at(i) =
|
| + graph->NewNode(builder_->common()->OsrValue(i), osr_loop_entry);
|
| + }
|
| +
|
| + // Set the contexts.
|
| + // 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);
|
| + const Operator* op_inner =
|
| + builder_->common()->OsrValue(Linkage::kOsrContextSpillSlotIndex);
|
| + int last = static_cast<int>(contexts()->size() - 1);
|
| + for (int i = last; i >= 0; i--) {
|
| + osr_context = (i == last) ? graph->NewNode(op_inner, osr_loop_entry)
|
| + : graph->NewNode(op, osr_context, osr_context,
|
| + osr_loop_entry);
|
| + contexts()->at(i) = osr_context;
|
| + }
|
| +}
|
|
|
| -void AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned,
|
| - bool is_osr) {
|
| +void AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned) {
|
| int size = static_cast<int>(values()->size());
|
|
|
| Node* control = builder_->NewLoop();
|
| @@ -4219,40 +4260,6 @@ void AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned,
|
| contexts()->at(i) = builder_->NewPhi(1, context, control);
|
| }
|
| }
|
| -
|
| - if (is_osr) {
|
| - // Merge OSR values as inputs to the phis of the loop.
|
| - Graph* graph = builder_->graph();
|
| - Node* osr_loop_entry = builder_->graph()->NewNode(
|
| - builder_->common()->OsrLoopEntry(), graph->start(), graph->start());
|
| -
|
| - builder_->MergeControl(control, osr_loop_entry);
|
| - builder_->MergeEffect(effect, osr_loop_entry, control);
|
| -
|
| - for (int i = 0; i < size; ++i) {
|
| - Node* value = values()->at(i);
|
| - Node* osr_value =
|
| - graph->NewNode(builder_->common()->OsrValue(i), osr_loop_entry);
|
| - values()->at(i) = builder_->MergeValue(value, 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);
|
| - const Operator* op_inner =
|
| - builder_->common()->OsrValue(Linkage::kOsrContextSpillSlotIndex);
|
| - int last = static_cast<int>(contexts()->size() - 1);
|
| - for (int i = last; i >= 0; i--) {
|
| - Node* context = contexts()->at(i);
|
| - osr_context = (i == last) ? graph->NewNode(op_inner, osr_loop_entry)
|
| - : graph->NewNode(op, osr_context, osr_context,
|
| - osr_loop_entry);
|
| - contexts()->at(i) = builder_->MergeValue(context, osr_context, control);
|
| - }
|
| - }
|
| }
|
|
|
|
|
|
|