OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/dart.h" | 5 #include "vm/dart.h" |
6 | 6 |
7 #include "vm/code_observers.h" | 7 #include "vm/code_observers.h" |
8 #include "vm/cpu.h" | 8 #include "vm/cpu.h" |
9 #include "vm/dart_api_state.h" | 9 #include "vm/dart_api_state.h" |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 20 matching lines...) Expand all Loading... |
31 #include "vm/virtual_memory.h" | 31 #include "vm/virtual_memory.h" |
32 #include "vm/zone.h" | 32 #include "vm/zone.h" |
33 | 33 |
34 namespace dart { | 34 namespace dart { |
35 | 35 |
36 DECLARE_FLAG(bool, print_class_table); | 36 DECLARE_FLAG(bool, print_class_table); |
37 DECLARE_FLAG(bool, trace_isolates); | 37 DECLARE_FLAG(bool, trace_isolates); |
38 DECLARE_FLAG(bool, trace_time_all); | 38 DECLARE_FLAG(bool, trace_time_all); |
39 DEFINE_FLAG(bool, keep_code, false, | 39 DEFINE_FLAG(bool, keep_code, false, |
40 "Keep deoptimized code for profiling."); | 40 "Keep deoptimized code for profiling."); |
| 41 DEFINE_FLAG(bool, shutdown, true, "Do a clean shutdown of the VM"); |
41 | 42 |
42 Isolate* Dart::vm_isolate_ = NULL; | 43 Isolate* Dart::vm_isolate_ = NULL; |
43 ThreadPool* Dart::thread_pool_ = NULL; | 44 ThreadPool* Dart::thread_pool_ = NULL; |
44 DebugInfo* Dart::pprof_symbol_generator_ = NULL; | 45 DebugInfo* Dart::pprof_symbol_generator_ = NULL; |
45 ReadOnlyHandles* Dart::predefined_handles_ = NULL; | 46 ReadOnlyHandles* Dart::predefined_handles_ = NULL; |
46 | 47 |
47 // Structure for managing read-only global handles allocation used for | 48 // Structure for managing read-only global handles allocation used for |
48 // creating global read-only handles that are pre created and initialized | 49 // creating global read-only handles that are pre created and initialized |
49 // for use across all isolates. Having these global pre created handles | 50 // for use across all isolates. Having these global pre created handles |
50 // stored in the vm isolate ensures that we don't constantly create and | 51 // stored in the vm isolate ensures that we don't constantly create and |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 Isolate::SetInterruptCallback(interrupt); | 190 Isolate::SetInterruptCallback(interrupt); |
190 Isolate::SetUnhandledExceptionCallback(unhandled); | 191 Isolate::SetUnhandledExceptionCallback(unhandled); |
191 Isolate::SetShutdownCallback(shutdown); | 192 Isolate::SetShutdownCallback(shutdown); |
192 | 193 |
193 ServiceIsolate::Run(); | 194 ServiceIsolate::Run(); |
194 | 195 |
195 return NULL; | 196 return NULL; |
196 } | 197 } |
197 | 198 |
198 | 199 |
| 200 // This waits until only the VM isolate remains in the list. |
| 201 void Dart::WaitForIsolateShutdown() { |
| 202 ASSERT(!Isolate::creation_enabled_); |
| 203 MonitorLocker ml(Isolate::isolates_list_monitor_); |
| 204 while ((Isolate::isolates_list_head_ != NULL) && |
| 205 (Isolate::isolates_list_head_->next_ != NULL)) { |
| 206 ml.Wait(); |
| 207 } |
| 208 ASSERT(Isolate::isolates_list_head_ == Dart::vm_isolate()); |
| 209 } |
| 210 |
| 211 |
199 const char* Dart::Cleanup() { | 212 const char* Dart::Cleanup() { |
200 // Shutdown the service isolate before shutting down the thread pool. | 213 ASSERT(Isolate::Current() == NULL); |
201 ServiceIsolate::Shutdown(); | |
202 #if 0 | |
203 // Ideally we should shutdown the VM isolate here, but the thread pool | |
204 // shutdown does not seem to ensure that all the threads have stopped | |
205 // execution before it terminates, this results in racing isolates. | |
206 if (vm_isolate_ == NULL) { | 214 if (vm_isolate_ == NULL) { |
207 return "VM already terminated."; | 215 return "VM already terminated."; |
208 } | 216 } |
209 | 217 |
210 ASSERT(Isolate::Current() == NULL); | 218 // Shut down profiling. |
| 219 Profiler::Shutdown(); |
211 | 220 |
212 delete thread_pool_; | 221 if (FLAG_shutdown) { |
213 thread_pool_ = NULL; | 222 // Disable the creation of new isolates. |
| 223 Isolate::DisableIsolateCreation(); |
214 | 224 |
215 // Set the VM isolate as current isolate. | 225 // Send the OOB Kill message to all remaining application isolates. |
216 Thread::EnsureInit(); | 226 Isolate::KillAllIsolates(); |
217 Thread::EnterIsolate(vm_isolate_); | |
218 | 227 |
219 // There is a planned and known asymmetry here: We exit one scope for the VM | 228 // Shutdown the service isolate. |
220 // isolate to account for the scope that was entered in Dart_InitOnce. | 229 ServiceIsolate::Shutdown(); |
221 Dart_ExitScope(); | |
222 | 230 |
223 ShutdownIsolate(); | 231 // Wait for all application isolates and the service isolate to shutdown |
224 vm_isolate_ = NULL; | 232 // before shutting down the thread pool. |
| 233 WaitForIsolateShutdown(); |
225 | 234 |
226 TargetCPUFeatures::Cleanup(); | 235 // Shutdown the thread pool. On return, all thread pool threads have exited. |
227 StoreBuffer::ShutDown(); | 236 delete thread_pool_; |
228 #endif | 237 thread_pool_ = NULL; |
229 | 238 |
230 Profiler::Shutdown(); | 239 // Set the VM isolate as current isolate. |
| 240 Thread::EnsureInit(); |
| 241 Thread::EnterIsolate(vm_isolate_); |
| 242 |
| 243 ShutdownIsolate(); |
| 244 vm_isolate_ = NULL; |
| 245 ASSERT(Isolate::IsolateListLength() == 0); |
| 246 |
| 247 TargetCPUFeatures::Cleanup(); |
| 248 StoreBuffer::ShutDown(); |
| 249 } else { |
| 250 // Shutdown the service isolate. |
| 251 ServiceIsolate::Shutdown(); |
| 252 } |
| 253 |
231 CodeObservers::DeleteAll(); | 254 CodeObservers::DeleteAll(); |
232 Timeline::Shutdown(); | 255 Timeline::Shutdown(); |
233 Metric::Cleanup(); | 256 Metric::Cleanup(); |
234 | 257 |
235 return NULL; | 258 return NULL; |
236 } | 259 } |
237 | 260 |
238 | 261 |
239 Isolate* Dart::CreateIsolate(const char* name_prefix, | 262 Isolate* Dart::CreateIsolate(const char* name_prefix, |
240 const Dart_IsolateFlags& api_flags) { | 263 const Dart_IsolateFlags& api_flags) { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 return predefined_handles_->handles_.IsValidScopedHandle(address); | 404 return predefined_handles_->handles_.IsValidScopedHandle(address); |
382 } | 405 } |
383 | 406 |
384 | 407 |
385 bool Dart::IsReadOnlyApiHandle(Dart_Handle handle) { | 408 bool Dart::IsReadOnlyApiHandle(Dart_Handle handle) { |
386 ASSERT(predefined_handles_ != NULL); | 409 ASSERT(predefined_handles_ != NULL); |
387 return predefined_handles_->api_handles_.IsValidHandle(handle); | 410 return predefined_handles_->api_handles_.IsValidHandle(handle); |
388 } | 411 } |
389 | 412 |
390 } // namespace dart | 413 } // namespace dart |
OLD | NEW |