[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: Michael Stanton <mvstanton@chromium.org> Reviewed-by: Maya Lekova <mslekova@chromium.org> Cr-Commit-Position: refs/heads/master@{#62712}
This commit is contained in:
parent
b58298803a
commit
e5678a6536
@ -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_; }
|
||||
|
21
test/mjsunit/compiler/generator-jump-targets.js
Normal file
21
test/mjsunit/compiler/generator-jump-targets.js
Normal file
@ -0,0 +1,21 @@
|
||||
// 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);
|
Loading…
Reference in New Issue
Block a user