Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(492)

Unified Diff: runtime/vm/compiler.cc

Issue 1884213004: Fix a crash in debugger, add flag --stress-test-background-compilation, add asserts. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/compiler.h ('k') | runtime/vm/object.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/compiler.cc
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 8d3b319d5717492eb6450219d041f96c1e0311df..610b7b7e3774e01802eda05931e9e453c19fed2b 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -55,6 +55,7 @@ DEFINE_FLAG(int, max_deoptimization_counter_threshold, 16,
"How many times we allow deoptimization before we disallow optimization.");
DEFINE_FLAG(bool, loop_invariant_code_motion, true,
"Do loop invariant code motion.");
+DEFINE_FLAG(charp, optimization_filter, NULL, "Optimize only named function");
DEFINE_FLAG(bool, print_flow_graph, false, "Print the IR flow graph.");
DEFINE_FLAG(bool, print_flow_graph_optimized, false,
"Print the IR flow graph when optimizing.");
@@ -62,7 +63,13 @@ DEFINE_FLAG(bool, print_ic_data_map, false,
"Print the deopt-id to ICData map in optimizing compiler.");
DEFINE_FLAG(bool, print_code_source_map, false, "Print code source map.");
DEFINE_FLAG(bool, range_analysis, true, "Enable range analysis");
+DEFINE_FLAG(bool, stress_test_background_compilation, false,
+ "Keep background compiler running all the time");
+DEFINE_FLAG(bool, stop_on_excessive_deoptimization, false,
+ "Debugging: stops program if deoptimizing same function too often");
DEFINE_FLAG(bool, trace_compiler, false, "Trace compiler operations.");
+DEFINE_FLAG(bool, trace_failed_optimization_attempts, false,
+ "Traces all failed optimization attempts");
DEFINE_FLAG(bool, trace_optimizing_compiler, false,
"Trace only optimizing compiler operations.");
DEFINE_FLAG(bool, trace_bailout, false, "Print bailout from ssa compiler.");
@@ -163,6 +170,69 @@ DEFINE_RUNTIME_ENTRY(CompileFunction, 1) {
}
+bool Compiler::CanOptimizeFunction(Thread* thread, const Function& function) {
+ if (FLAG_support_debugger) {
+ Isolate* isolate = thread->isolate();
+ if (isolate->debugger()->IsStepping() ||
+ isolate->debugger()->HasBreakpoint(function, thread->zone())) {
+ // We cannot set breakpoints and single step in optimized code,
+ // so do not optimize the function.
+ function.set_usage_counter(0);
+ return false;
+ }
+ }
+ if (function.deoptimization_counter() >=
+ FLAG_max_deoptimization_counter_threshold) {
+ if (FLAG_trace_failed_optimization_attempts ||
+ FLAG_stop_on_excessive_deoptimization) {
+ THR_Print("Too many deoptimizations: %s\n",
+ function.ToFullyQualifiedCString());
+ if (FLAG_stop_on_excessive_deoptimization) {
+ FATAL("Stop on excessive deoptimization");
+ }
+ }
+ // The function will not be optimized any longer. This situation can occur
+ // mostly with small optimization counter thresholds.
+ function.SetIsOptimizable(false);
+ function.set_usage_counter(INT_MIN);
+ return false;
+ }
+ if (FLAG_optimization_filter != NULL) {
+ // FLAG_optimization_filter is a comma-separated list of strings that are
+ // matched against the fully-qualified function name.
+ char* save_ptr; // Needed for strtok_r.
+ const char* function_name = function.ToFullyQualifiedCString();
+ intptr_t len = strlen(FLAG_optimization_filter) + 1; // Length with \0.
+ char* filter = new char[len];
+ strncpy(filter, FLAG_optimization_filter, len); // strtok modifies arg 1.
+ char* token = strtok_r(filter, ",", &save_ptr);
+ bool found = false;
+ while (token != NULL) {
+ if (strstr(function_name, token) != NULL) {
+ found = true;
+ break;
+ }
+ token = strtok_r(NULL, ",", &save_ptr);
+ }
+ delete[] filter;
+ if (!found) {
+ function.set_usage_counter(INT_MIN);
+ return false;
+ }
+ }
+ if (!function.IsOptimizable()) {
+ // Huge methods (code size above --huge_method_cutoff_in_code_size) become
+ // non-optimizable only after the code has been generated.
+ if (FLAG_trace_failed_optimization_attempts) {
+ THR_Print("Not optimizable: %s\n", function.ToFullyQualifiedCString());
+ }
+ function.set_usage_counter(INT_MIN);
+ return false;
+ }
+ return true;
+}
+
+
bool Compiler::IsBackgroundCompilation() {
// For now: compilation in non mutator thread is the background compoilation.
return !Thread::Current()->IsMutatorThread();
@@ -542,7 +612,8 @@ NOT_IN_PRODUCT(
THR_Print("--> FAIL: Loading invalidation.");
}
}
- if (code_is_valid) {
+ // Setting breakpoints at runtime could make a function non-optimizable.
+ if (code_is_valid && Compiler::CanOptimizeFunction(thread(), function)) {
const bool is_osr = osr_id() != Compiler::kNoOSRDeoptId;
ASSERT(!is_osr); // OSR is not compiled in background.
function.InstallOptimizedCode(code, is_osr);
@@ -1611,7 +1682,6 @@ class QueueElement {
explicit QueueElement(const Function& function)
: next_(NULL),
function_(function.raw()) {
- ASSERT(Thread::Current()->IsMutatorThread());
}
virtual ~QueueElement() {
@@ -1784,6 +1854,13 @@ void BackgroundCompiler::Run() {
function = Function::null();
} else {
qelem = function_queue()->Remove();
+ if (FLAG_stress_test_background_compilation) {
+ const Function& old = Function::Handle(qelem->Function());
+ if (Compiler::CanOptimizeFunction(thread, old)) {
+ QueueElement* repeat_qelem = new QueueElement(old);
+ function_queue()->Add(repeat_qelem);
+ }
+ }
function = function_queue()->PeekFunction();
}
}
@@ -1925,6 +2002,12 @@ bool Compiler::IsBackgroundCompilation() {
}
+bool Compiler::CanOptimizeFunction(Thread* thread, const Function& function) {
+ UNREACHABLE();
+ return false;
+}
+
+
RawError* Compiler::Compile(const Library& library, const Script& script) {
UNREACHABLE();
return Error::null();
« no previous file with comments | « runtime/vm/compiler.h ('k') | runtime/vm/object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698