Index: runtime/vm/isolate.cc |
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc |
index 16b70e466c5ecd6054680bbd4b05c90e9340ea08..ec61d1adf6aef53be3019ebb2a4703def9fc2bac 100644 |
--- a/runtime/vm/isolate.cc |
+++ b/runtime/vm/isolate.cc |
@@ -1433,12 +1433,28 @@ void Isolate::Shutdown() { |
} |
#endif // DEBUG |
+ // First, perform higher-level cleanup that may need to allocate. |
+ { |
+ // Ensure we have a zone and handle scope so that we can call VM functions. |
+ StackZone stack_zone(this); |
+ HandleScope handle_scope(this); |
+ |
+ // Write out the coverage data if collection has been enabled. |
+ CodeCoverage::Write(this); |
+ |
+ if ((timeline_event_recorder_ != NULL) && |
+ (FLAG_timeline_trace_dir != NULL)) { |
+ timeline_event_recorder_->WriteTo(FLAG_timeline_trace_dir); |
+ } |
+ } |
+ |
// Remove this isolate from the list *before* we start tearing it down, to |
// avoid exposing it in a state of decay. |
RemoveIsolateFromList(this); |
if (heap_ != NULL) { |
// Wait for any concurrent GC tasks to finish before shutting down. |
+ // TODO(koda): Support faster sweeper shutdown (e.g., after current page). |
PageSpace* old_space = heap_->old_space(); |
MonitorLocker ml(old_space->tasks_lock()); |
while (old_space->tasks() > 0) { |
@@ -1446,11 +1462,13 @@ void Isolate::Shutdown() { |
} |
} |
- // Create an area where we do have a zone and a handle scope so that we can |
- // call VM functions while tearing this isolate down. |
+ // Then, proceed with low-level teardown. |
{ |
+ // Ensure we have a zone and handle scope so that we can call VM functions, |
+ // but we no longer allocate new heap objects. |
StackZone stack_zone(this); |
HandleScope handle_scope(this); |
+ NoSafepointScope no_safepoint_scope; |
if (compiler_stats_ != NULL) { |
compiler_stats()->Print(); |
@@ -1474,9 +1492,6 @@ void Isolate::Shutdown() { |
// Dump all accumulated timer data for the isolate. |
timer_list_.ReportTimers(); |
- // Write out the coverage data if collection has been enabled. |
- CodeCoverage::Write(this); |
- |
// Finalize any weak persistent handles with a non-null referent. |
FinalizeWeakPersistentHandlesVisitor visitor; |
api_state()->weak_persistent_handles().VisitHandles(&visitor); |
@@ -1489,12 +1504,16 @@ void Isolate::Shutdown() { |
OS::Print("[-] Stopping isolate:\n" |
"\tisolate: %s\n", name()); |
} |
+ } |
- if ((timeline_event_recorder_ != NULL) && |
- (FLAG_timeline_trace_dir != NULL)) { |
- timeline_event_recorder_->WriteTo(FLAG_timeline_trace_dir); |
- } |
+#if defined(DEBUG) |
+ // No concurrent sweeper tasks should be running at this point. |
+ if (heap_ != NULL) { |
+ PageSpace* old_space = heap_->old_space(); |
+ MonitorLocker ml(old_space->tasks_lock()); |
+ ASSERT(old_space->tasks() == 0); |
} |
+#endif |
// TODO(5411455): For now just make sure there are no current isolates |
// as we are shutting down the isolate. |