Commit e5678a65 authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[turbofan] Make serializer properly handle resume targets

The bytecode graph builder may insert additional jumps for the
SwitchOnGeneratorState bytecode and for loop headers. This plays into
what the graph builder considers dead/alive. We want the serializer to
process all the bytecodes that the graph builder will process, so the
serializer needs to do something similar.

Bug: v8:7790
Change-Id: I1f1d51f4a8951149e365b3c998cef7f613bb4953
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1647694
Commit-Queue: Georg Neis <neis@chromium.org>
Reviewed-by: 's avatarMichael Stanton <mvstanton@chromium.org>
Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62712}
parent b5829880
......@@ -6,6 +6,7 @@
#include <sstream>
#include "src/compiler/bytecode-analysis.h"
#include "src/compiler/js-heap-broker.h"
#include "src/compiler/vector-slot-pair.h"
#include "src/handles/handles-inl.h"
......@@ -481,37 +482,54 @@ class ExceptionHandlerMatcher {
std::set<int>::const_iterator handlers_iterator_;
};
void SerializerForBackgroundCompilation::TraverseBytecode() {
BytecodeArrayRef bytecode_array(
broker(), handle(environment()->function().shared()->GetBytecodeArray(),
broker()->isolate()));
broker()->GetBytecodeAnalysis(
bytecode_array.object(), osr_offset(),
Handle<BytecodeArray> SerializerForBackgroundCompilation::bytecode_array()
const {
return handle(environment()->function().shared()->GetBytecodeArray(),
broker()->isolate());
}
BytecodeAnalysis const& SerializerForBackgroundCompilation::GetBytecodeAnalysis(
bool serialize) {
return broker()->GetBytecodeAnalysis(
bytecode_array(), osr_offset(),
flags() &
SerializerForBackgroundCompilationFlag::kAnalyzeEnvironmentLiveness,
true);
bytecode_array.SerializeForCompilation();
BytecodeArrayIterator iterator(bytecode_array.object());
ExceptionHandlerMatcher handler_matcher(iterator, bytecode_array.object());
serialize);
}
void SerializerForBackgroundCompilation::TraverseBytecode() {
BytecodeAnalysis const& bytecode_analysis = GetBytecodeAnalysis(true);
BytecodeArrayRef(broker(), bytecode_array()).SerializeForCompilation();
BytecodeArrayIterator iterator(bytecode_array());
ExceptionHandlerMatcher handler_matcher(iterator, bytecode_array());
for (; !iterator.done(); iterator.Advance()) {
IncorporateJumpTargetEnvironment(iterator.current_offset());
int const current_offset = iterator.current_offset();
IncorporateJumpTargetEnvironment(current_offset);
TRACE_BROKER(broker(),
"Handling bytecode: " << iterator.current_offset() << " "
"Handling bytecode: " << current_offset << " "
<< iterator.current_bytecode());
TRACE_BROKER(broker(), "Current environment: " << *environment());
if (environment()->IsDead()) {
if (iterator.current_bytecode() ==
interpreter::Bytecode::kResumeGenerator ||
handler_matcher.CurrentBytecodeIsExceptionHandlerStart()) {
if (handler_matcher.CurrentBytecodeIsExceptionHandlerStart()) {
environment()->Revive();
} else {
continue; // Skip this bytecode since TF won't generate code for it.
}
}
if (bytecode_analysis.IsLoopHeader(current_offset)) {
// Graph builder might insert jumps to resume targets in the loop body.
LoopInfo const& loop_info =
bytecode_analysis.GetLoopInfoFor(current_offset);
for (const auto& target : loop_info.resume_jump_targets()) {
ContributeToJumpTargetEnvironment(target.target_offset());
}
}
switch (iterator.current_bytecode()) {
#define DEFINE_BYTECODE_CASE(name) \
case interpreter::Bytecode::k##name: \
......@@ -1291,6 +1309,13 @@ void SerializerForBackgroundCompilation::VisitSwitchOnSmiNoFeedback(
}
}
void SerializerForBackgroundCompilation::VisitSwitchOnGeneratorState(
interpreter::BytecodeArrayIterator* iterator) {
for (const auto& target : GetBytecodeAnalysis(false).resume_jump_targets()) {
ContributeToJumpTargetEnvironment(target.target_offset());
}
}
void SerializerForBackgroundCompilation::Environment::ExportRegisterHints(
interpreter::Register first, size_t count, HintsVector& dst) {
const int reg_base = first.index();
......
......@@ -7,9 +7,10 @@
#include "src/base/optional.h"
#include "src/compiler/access-info.h"
#include "src/utils/utils.h"
#include "src/compiler/bytecode-analysis.h"
#include "src/handles/handles.h"
#include "src/handles/maybe-handles.h"
#include "src/utils/utils.h"
#include "src/zone/zone-containers.h"
namespace v8 {
......@@ -34,8 +35,7 @@ namespace compiler {
V(CallRuntimeForPair) \
V(Debugger) \
V(ResumeGenerator) \
V(SuspendGenerator) \
V(SwitchOnGeneratorState)
V(SuspendGenerator)
#define KILL_ENVIRONMENT_LIST(V) \
V(Abort) \
......@@ -210,6 +210,7 @@ namespace compiler {
V(StaNamedOwnProperty) \
V(StaNamedProperty) \
V(Star) \
V(SwitchOnGeneratorState) \
V(SwitchOnSmiNoFeedback) \
V(TestIn) \
CLEAR_ACCUMULATOR_LIST(V) \
......@@ -430,6 +431,9 @@ class SerializerForBackgroundCompilation {
void ContributeToJumpTargetEnvironment(int target_offset);
void IncorporateJumpTargetEnvironment(int target_offset);
Handle<BytecodeArray> bytecode_array() const;
BytecodeAnalysis const& GetBytecodeAnalysis(bool serialize);
JSHeapBroker* broker() const { return broker_; }
CompilationDependencies* dependencies() const { return dependencies_; }
Zone* zone() const { return zone_; }
......
// Copyright 2019 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
var gaga = 42;
function* foo(x, b) {
if (b) return;
x.p;
while (true) {
gaga;
yield;
}
}
%PrepareFunctionForOptimization(foo);
foo({p:42}, true);
foo({p:42}, true);
%OptimizeFunctionOnNextCall(foo);
const g = foo({p:42}, false);
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