Commit 962fd4ae authored by mstarzinger's avatar mstarzinger Committed by Commit bot

[interpreter] Elide OSR polling from fake loops.

This makes sure we are not inserting {OsrPoll} instructions for any
statements that are not actually loops and have no back edges. Without
back edges the {BytecodeGraphBuilder} is unable to deduce loop ranges
and hence cannot construct a graph for OSR entry.

R=neis@chromium.org
TEST=mjsunit/regress/regress-5252
BUG=v8:5252

Review-Url: https://codereview.chromium.org/2200733002
Cr-Commit-Position: refs/heads/master@{#38233}
parent eaebdd85
...@@ -1052,13 +1052,14 @@ void BytecodeGenerator::VisitIterationBody(IterationStatement* stmt, ...@@ -1052,13 +1052,14 @@ void BytecodeGenerator::VisitIterationBody(IterationStatement* stmt,
void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
LoopBuilder loop_builder(builder()); LoopBuilder loop_builder(builder());
VisitIterationHeader(stmt, &loop_builder);
if (stmt->cond()->ToBooleanIsFalse()) { if (stmt->cond()->ToBooleanIsFalse()) {
VisitIterationBody(stmt, &loop_builder); VisitIterationBody(stmt, &loop_builder);
} else if (stmt->cond()->ToBooleanIsTrue()) { } else if (stmt->cond()->ToBooleanIsTrue()) {
VisitIterationHeader(stmt, &loop_builder);
VisitIterationBody(stmt, &loop_builder); VisitIterationBody(stmt, &loop_builder);
loop_builder.JumpToHeader(); loop_builder.JumpToHeader();
} else { } else {
VisitIterationHeader(stmt, &loop_builder);
VisitIterationBody(stmt, &loop_builder); VisitIterationBody(stmt, &loop_builder);
builder()->SetExpressionAsStatementPosition(stmt->cond()); builder()->SetExpressionAsStatementPosition(stmt->cond());
VisitForAccumulatorValue(stmt->cond()); VisitForAccumulatorValue(stmt->cond());
......
...@@ -102,11 +102,21 @@ void LoopBuilder::LoopHeader(ZoneVector<BytecodeLabel>* additional_labels) { ...@@ -102,11 +102,21 @@ void LoopBuilder::LoopHeader(ZoneVector<BytecodeLabel>* additional_labels) {
} }
} }
void LoopBuilder::JumpToHeader() {
// Loop must have closed form, i.e. all loop elements are within the loop,
// the loop header precedes the body and next elements in the loop.
DCHECK(loop_header_.is_bound());
builder()->Jump(&loop_header_);
}
void LoopBuilder::EndLoop() { void LoopBuilder::JumpToHeaderIfTrue() {
// Loop must have closed form, i.e. all loop elements are within the loop, // Loop must have closed form, i.e. all loop elements are within the loop,
// the loop header precedes the body and next elements in the loop. // the loop header precedes the body and next elements in the loop.
DCHECK(loop_header_.is_bound()); DCHECK(loop_header_.is_bound());
builder()->JumpIfTrue(&loop_header_);
}
void LoopBuilder::EndLoop() {
builder()->Bind(&loop_end_); builder()->Bind(&loop_end_);
SetBreakTarget(loop_end_); SetBreakTarget(loop_end_);
} }
......
...@@ -89,8 +89,8 @@ class LoopBuilder final : public BreakableControlFlowBuilder { ...@@ -89,8 +89,8 @@ class LoopBuilder final : public BreakableControlFlowBuilder {
~LoopBuilder(); ~LoopBuilder();
void LoopHeader(ZoneVector<BytecodeLabel>* additional_labels); void LoopHeader(ZoneVector<BytecodeLabel>* additional_labels);
void JumpToHeader() { builder()->Jump(&loop_header_); } void JumpToHeader();
void JumpToHeaderIfTrue() { builder()->JumpIfTrue(&loop_header_); } void JumpToHeaderIfTrue();
void SetContinueTarget(); void SetContinueTarget();
void EndLoop(); void EndLoop();
......
...@@ -51,13 +51,13 @@ snippet: " ...@@ -51,13 +51,13 @@ snippet: "
" "
frame size: 1 frame size: 1
parameter count: 1 parameter count: 1
bytecode array length: 23 bytecode array length: 22
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 45 S> */ B(LdaSmi), U8(1), /* 45 S> */ B(LdaSmi), U8(1),
B(Star), R(0), B(Star), R(0),
/* 48 E> */ B(StackCheck), /* 48 E> */ B(StackCheck),
/* 55 S> */ B(Ldar), R(0), /* 55 S> */ B(Nop),
/* 69 E> */ B(Add), R(0), /* 69 E> */ B(Add), R(0),
B(Star), R(0), B(Star), R(0),
/* 77 S> */ B(LdaSmi), U8(10), /* 77 S> */ B(LdaSmi), U8(10),
......
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --ignition --ignition-osr --turbo-from-bytecode
(function TestNonLoopyLoop() {
function f() {
do {
%OptimizeOsr();
return 23;
} while(false)
}
assertEquals(23, f());
assertEquals(23, f());
})();
(function TestNonLoopyGenerator() {
function* g() {
do {
%OptimizeOsr();
yield 23;
yield 42;
} while(false)
return 999;
}
var gen = g();
assertEquals({ value:23, done:false }, gen.next());
assertEquals({ value:42, done:false }, gen.next());
assertEquals({ value:999, done:true }, gen.next());
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment