[VM] Mark functions on BG compiler bailouts specially, allow them to be re-optimized on main thread

In some cases, bailouts in the bg compiler, e.g. caused by class
finalization, mark functions as unoptimizable, which can significantly
slow down an application.

Instead of doing this, we mark these functions as non-optimizable on the
BG compiler and trigger re-compilations on the main thread.

Change-Id: Ifbb6aa7972818be8fa1313427e38d8b5576053e3
Reviewed-on: https://dart-review.googlesource.com/54886
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
Martin Kustermann 2018-05-15 09:34:22 +00:00 committed by commit-bot@chromium.org
parent 68f2db2f66
commit 45c524e106
5 changed files with 44 additions and 7 deletions

View file

@ -1043,8 +1043,24 @@ static RawObject* CompileFunctionHelper(CompilationPipeline* pipeline,
// We got an error during compilation.
error = thread->sticky_error();
thread->clear_sticky_error();
if ((error.IsLanguageError() &&
LanguageError::Cast(error).kind() == Report::kBailout) ||
if (error.raw() == Object::background_compilation_error().raw()) {
if (FLAG_trace_compiler) {
THR_Print(
"--> disabling background optimizations for '%s' (will "
"try to re-compile on isolate thread again)\n",
function.ToFullyQualifiedCString());
}
// Ensure we don't attempt to re-compile the function on the
// background compiler.
function.set_is_background_optimizable(false);
// Trigger another optimization soon on the main thread.
function.SetUsageCounter(FLAG_optimization_counter_threshold);
} else if ((error.IsLanguageError() &&
LanguageError::Cast(error).kind() ==
Report::kBailout) ||
error.IsUnhandledException()) {
if (FLAG_trace_compiler) {
THR_Print("--> disabling optimizations for '%s'\n",
@ -1287,7 +1303,8 @@ RawObject* Compiler::CompileOptimizedFunction(Thread* thread,
// not currently allowed.
ASSERT(!thread->IsMutatorThread() || (osr_id != kNoOSRDeoptId) ||
!FLAG_background_compilation ||
BackgroundCompiler::IsDisabled(Isolate::Current()));
BackgroundCompiler::IsDisabled(Isolate::Current()) ||
!function.is_background_optimizable());
CompilationPipeline* pipeline =
CompilationPipeline::New(thread->zone(), function);
return CompileFunctionHelper(pipeline, function, true, /* optimized */

View file

@ -7059,6 +7059,7 @@ RawFunction* Function::New(const String& name,
NOT_IN_PRECOMPILED(result.set_inlining_depth(0));
NOT_IN_PRECOMPILED(result.set_kernel_offset(0));
result.set_is_optimizable(is_native ? false : true);
result.set_is_background_optimizable(is_native ? false : true);
result.set_is_inlinable(true);
result.set_allows_hoisting_check_class(true);
result.set_allows_bounds_check_generalization(true);

View file

@ -2859,6 +2859,18 @@ class Function : public Object {
FOR_EACH_FUNCTION_KIND_BIT(DEFINE_ACCESSORS)
#undef DEFINE_ACCESSORS
// Indicates whether this function can be optimized on the background compiler
// thread.
bool is_background_optimizable() const {
return RawFunction::BackgroundOptimizableBit::decode(
raw_ptr()->packed_fields_);
}
void set_is_background_optimizable(bool value) const {
set_packed_fields(RawFunction::BackgroundOptimizableBit::update(
value, raw_ptr()->packed_fields_));
}
private:
void set_ic_data_array(const Array& value) const;
void SetInstructionsSafe(const Code& value) const;

View file

@ -888,7 +888,7 @@ class RawFunction : public RawObject {
};
static constexpr intptr_t kMaxFixedParametersBits = 15;
static constexpr intptr_t kMaxOptionalParametersBits = 15;
static constexpr intptr_t kMaxOptionalParametersBits = 14;
private:
// So that the SkippedCodeFunctions::DetachCode can null out the code fields.
@ -951,8 +951,13 @@ class RawFunction : public RawObject {
typedef BitField<uint32_t, bool, PackedIsNoSuchMethodForwarder::kNextBit, 1>
PackedHasNamedOptionalParameters;
typedef BitField<uint32_t,
uint16_t,
bool,
PackedHasNamedOptionalParameters::kNextBit,
1>
BackgroundOptimizableBit;
typedef BitField<uint32_t,
uint16_t,
BackgroundOptimizableBit::kNextBit,
kMaxFixedParametersBits>
PackedNumFixedParameters;
typedef BitField<uint32_t,

View file

@ -2015,7 +2015,8 @@ DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) {
if (FLAG_enable_inlining_annotations) {
FATAL("Cannot enable inlining annotations and background compilation");
}
if (!BackgroundCompiler::IsDisabled(isolate)) {
if (!BackgroundCompiler::IsDisabled(isolate) &&
function.is_background_optimizable()) {
if (FLAG_background_compilation_stop_alot) {
BackgroundCompiler::Stop(isolate);
}
@ -2026,6 +2027,7 @@ DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) {
function.SetUsageCounter(INT_MIN);
BackgroundCompiler::Start(isolate);
isolate->background_compiler()->CompileOptimized(function);
// Continue in the same code.
arguments.SetReturn(function);
return;