From 45c524e106872da1bcf2cb503df8449147564af6 Mon Sep 17 00:00:00 2001 From: Martin Kustermann Date: Tue, 15 May 2018 09:34:22 +0000 Subject: [PATCH] [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 Reviewed-by: Vyacheslav Egorov Reviewed-by: Alexander Markov --- runtime/vm/compiler/jit/compiler.cc | 25 +++++++++++++++++++++---- runtime/vm/object.cc | 1 + runtime/vm/object.h | 12 ++++++++++++ runtime/vm/raw_object.h | 9 +++++++-- runtime/vm/runtime_entry.cc | 4 +++- 5 files changed, 44 insertions(+), 7 deletions(-) diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc index 18225e6cb13..0430ef96509 100644 --- a/runtime/vm/compiler/jit/compiler.cc +++ b/runtime/vm/compiler/jit/compiler.cc @@ -1043,9 +1043,25 @@ 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) || - error.IsUnhandledException()) { + + 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", function.ToFullyQualifiedCString()); @@ -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 */ diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index e2cee15e41e..d0fb346f278 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc @@ -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); diff --git a/runtime/vm/object.h b/runtime/vm/object.h index e9af029f613..bd36b0734bc 100644 --- a/runtime/vm/object.h +++ b/runtime/vm/object.h @@ -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; diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h index 2e3e2f1a0ca..069647f4006 100644 --- a/runtime/vm/raw_object.h +++ b/runtime/vm/raw_object.h @@ -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 PackedHasNamedOptionalParameters; typedef BitField + BackgroundOptimizableBit; + typedef BitField PackedNumFixedParameters; typedef BitFieldbackground_compiler()->CompileOptimized(function); + // Continue in the same code. arguments.SetReturn(function); return;