Index: runtime/vm/compiler.cc |
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc |
index 21d572122dc9fe241ee3ac94c61a28a47781f9e5..9f3c02fe43aad0407ae535f5999b0f6d4bae07d4 100644 |
--- a/runtime/vm/compiler.cc |
+++ b/runtime/vm/compiler.cc |
@@ -1035,6 +1035,10 @@ bool CompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) { |
// Do not Garbage collect during this stage and instead allow the |
// heap to grow. |
NoHeapGrowthControlScope no_growth_control; |
+ if (!isolate()->background_compiler()->is_running()) { |
+ // The background compiler is being stopped. |
+ Compiler::AbortBackgroundCompilation(Thread::kNoDeoptId); |
+ } |
FinalizeCompilation(&assembler, &graph_compiler, flow_graph); |
} |
if (isolate()->heap()->NeedsGarbageCollection()) { |
@@ -1594,11 +1598,7 @@ class BackgroundCompilationQueue { |
public: |
BackgroundCompilationQueue() : first_(NULL), last_(NULL) {} |
virtual ~BackgroundCompilationQueue() { |
- while (!IsEmpty()) { |
- QueueElement* e = Remove(); |
- delete e; |
- } |
- ASSERT((first_ == NULL) && (last_ == NULL)); |
+ Clear(); |
} |
void VisitObjectPointers(ObjectPointerVisitor* visitor) { |
@@ -1660,6 +1660,14 @@ class BackgroundCompilationQueue { |
return false; |
} |
+ void Clear() { |
+ while (!IsEmpty()) { |
+ QueueElement* e = Remove(); |
+ delete e; |
+ } |
+ ASSERT((first_ == NULL) && (last_ == NULL)); |
+ } |
+ |
private: |
QueueElement* first_; |
QueueElement* last_; |
@@ -1725,10 +1733,17 @@ void BackgroundCompiler::Run() { |
QueueElement* qelem = NULL; |
{ MonitorLocker ml(queue_monitor_); |
- qelem = function_queue()->Remove(); |
- function = function_queue()->PeekFunction(); |
+ if (function_queue()->IsEmpty()) { |
+ // We are shutting down, queue was cleared. |
+ function = Function::null(); |
+ } else { |
+ qelem = function_queue()->Remove(); |
+ function = function_queue()->PeekFunction(); |
+ } |
+ } |
+ if (qelem != NULL) { |
+ delete qelem; |
} |
- delete qelem; |
} |
} |
Thread::ExitIsolateAsHelper(); |
@@ -1778,8 +1793,9 @@ void BackgroundCompiler::Stop(BackgroundCompiler* task) { |
bool* task_done = task->done_; |
// Wake up compiler task and stop it. |
{ |
- MonitorLocker ml(task->queue_monitor_); |
+ MonitorLocker ml(queue_monitor); |
task->running_ = false; |
+ function_queue->Clear(); |
// 'task' will be deleted by thread pool. |
task = NULL; |
ml.Notify(); // Stop waiting for the queue. |