Commit 069fcf4c authored by mstarzinger's avatar mstarzinger Committed by Commit bot

[turbofan] Decouple OSR entry from {OsrPoll} bytecode.

This makes sure OSR entry points can be added without having special
{OsrPoll} instructions in the bytecode stream. Eventually we might end
up merging back-branches and OSR polls together. Any loop header can be
used as an OSR entry point.

R=bmeurer@chromium.org
BUG=v8:4764

Review-Url: https://codereview.chromium.org/2329933003
Cr-Commit-Position: refs/heads/master@{#39373}
parent b9b350cb
......@@ -648,10 +648,6 @@ VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) {
}
bool BytecodeGraphBuilder::CreateGraph() {
// Set up the basic structure of the graph. Outputs for {Start} are
// the formal parameters (including the receiver) plus context and
// closure.
// Set up the basic structure of the graph. Outputs for {Start} are the formal
// parameters (including the receiver) plus new target, number of arguments,
// context and closure.
......@@ -663,10 +659,6 @@ bool BytecodeGraphBuilder::CreateGraph() {
GetFunctionContext());
set_environment(&env);
// For OSR add an {OsrNormalEntry} as the start of the top-level environment.
// It will be replaced with {Dead} after typing and optimizations.
if (!osr_ast_id_.IsNone()) NewNode(common()->OsrNormalEntry());
VisitBytecodes();
// Finish the basic structure of the graph.
......@@ -704,12 +696,14 @@ void BytecodeGraphBuilder::VisitBytecodes() {
set_loop_analysis(&loop_analysis);
interpreter::BytecodeArrayIterator iterator(bytecode_array());
set_bytecode_iterator(&iterator);
BuildOSRNormalEntryPoint();
while (!iterator.done()) {
int current_offset = iterator.current_offset();
EnterAndExitExceptionHandlers(current_offset);
SwitchToMergeEnvironment(current_offset);
if (environment() != nullptr) {
BuildLoopHeaderEnvironment(current_offset);
BuildOSRLoopEntryPoint(current_offset);
switch (iterator.current_bytecode()) {
#define BYTECODE_CASE(name, ...) \
......@@ -1632,14 +1626,7 @@ void BytecodeGraphBuilder::VisitStackCheck() {
environment()->RecordAfterState(node, &states);
}
void BytecodeGraphBuilder::VisitOsrPoll() {
// TODO(4764): This should be moved into the {VisitBytecodes} once we merge
// the polling with existing bytecode. This will also guarantee that we are
// not missing the OSR entry point, which we wouldn't catch right now.
if (osr_ast_id_.ToInt() == bytecode_iterator().current_offset()) {
environment()->PrepareForOsr();
}
}
void BytecodeGraphBuilder::VisitOsrPoll() {}
void BytecodeGraphBuilder::VisitReturn() {
BuildLoopExitsForFunctionExit();
......@@ -1812,6 +1799,25 @@ void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) {
set_environment(nullptr);
}
void BytecodeGraphBuilder::BuildOSRLoopEntryPoint(int current_offset) {
if (!osr_ast_id_.IsNone() && osr_ast_id_.ToInt() == current_offset) {
// For OSR add a special {OsrLoopEntry} node into the current loop header.
// It will be turned into a usable entry by the OSR deconstruction.
environment()->PrepareForOsr();
}
}
void BytecodeGraphBuilder::BuildOSRNormalEntryPoint() {
if (!osr_ast_id_.IsNone()) {
// For OSR add an {OsrNormalEntry} as the the top-level environment start.
// It will be replaced with {Dead} by the OSR deconstruction.
NewNode(common()->OsrNormalEntry());
// Note that the requested OSR entry point must be the target of a backward
// branch, otherwise there will not be a proper loop header available.
DCHECK(branch_analysis()->backward_branches_target(osr_ast_id_.ToInt()));
}
}
void BytecodeGraphBuilder::BuildLoopExitsForBranch(int target_offset) {
int origin_offset = bytecode_iterator().current_offset();
// Only build loop exits for forward edges.
......
......@@ -170,6 +170,10 @@ class BytecodeGraphBuilder {
// Simulates control flow that exits the function body.
void MergeControlToLeaveFunction(Node* exit);
// Builds entry points that are used by OSR deconstruction.
void BuildOSRLoopEntryPoint(int current_offset);
void BuildOSRNormalEntryPoint();
// Builds loop exit nodes for every exited loop between the current bytecode
// offset and {target_offset}.
void BuildLoopExitsForBranch(int target_offset);
......
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