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/become.h" | 7 #include "vm/become.h" |
8 #include "vm/clustered_snapshot.h" | 8 #include "vm/clustered_snapshot.h" |
9 #include "vm/code_observers.h" | 9 #include "vm/code_observers.h" |
10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 23 matching lines...) Expand all Loading... |
34 #include "vm/timeline.h" | 34 #include "vm/timeline.h" |
35 #include "vm/virtual_memory.h" | 35 #include "vm/virtual_memory.h" |
36 #include "vm/zone.h" | 36 #include "vm/zone.h" |
37 | 37 |
38 namespace dart { | 38 namespace dart { |
39 | 39 |
40 DECLARE_FLAG(bool, print_class_table); | 40 DECLARE_FLAG(bool, print_class_table); |
41 DECLARE_FLAG(bool, trace_time_all); | 41 DECLARE_FLAG(bool, trace_time_all); |
42 DEFINE_FLAG(bool, keep_code, false, | 42 DEFINE_FLAG(bool, keep_code, false, |
43 "Keep deoptimized code for profiling."); | 43 "Keep deoptimized code for profiling."); |
44 DEFINE_FLAG(bool, shutdown, true, "Do a clean shutdown of the VM"); | |
45 DEFINE_FLAG(bool, trace_shutdown, false, "Trace VM shutdown on stderr"); | 44 DEFINE_FLAG(bool, trace_shutdown, false, "Trace VM shutdown on stderr"); |
46 | 45 |
47 Isolate* Dart::vm_isolate_ = NULL; | 46 Isolate* Dart::vm_isolate_ = NULL; |
48 int64_t Dart::start_time_ = 0; | 47 int64_t Dart::start_time_ = 0; |
49 ThreadPool* Dart::thread_pool_ = NULL; | 48 ThreadPool* Dart::thread_pool_ = NULL; |
50 DebugInfo* Dart::pprof_symbol_generator_ = NULL; | 49 DebugInfo* Dart::pprof_symbol_generator_ = NULL; |
51 ReadOnlyHandles* Dart::predefined_handles_ = NULL; | 50 ReadOnlyHandles* Dart::predefined_handles_ = NULL; |
52 Snapshot::Kind Dart::snapshot_kind_ = Snapshot::kInvalid; | 51 Snapshot::Kind Dart::snapshot_kind_ = Snapshot::kInvalid; |
53 const uint8_t* Dart::instructions_snapshot_buffer_ = NULL; | 52 const uint8_t* Dart::instructions_snapshot_buffer_ = NULL; |
54 const uint8_t* Dart::data_snapshot_buffer_ = NULL; | 53 const uint8_t* Dart::data_snapshot_buffer_ = NULL; |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 if (FLAG_trace_shutdown) { | 367 if (FLAG_trace_shutdown) { |
369 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Entering vm isolate\n", | 368 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Entering vm isolate\n", |
370 timestamp()); | 369 timestamp()); |
371 } | 370 } |
372 bool result = Thread::EnterIsolate(vm_isolate_); | 371 bool result = Thread::EnterIsolate(vm_isolate_); |
373 ASSERT(result); | 372 ASSERT(result); |
374 Metric::Cleanup(); | 373 Metric::Cleanup(); |
375 Thread::ExitIsolate(); | 374 Thread::ExitIsolate(); |
376 } | 375 } |
377 | 376 |
378 if (FLAG_shutdown) { | 377 // Disable the creation of new isolates. |
379 // Disable the creation of new isolates. | 378 if (FLAG_trace_shutdown) { |
| 379 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Disabling isolate creation\n", |
| 380 timestamp()); |
| 381 } |
| 382 Isolate::DisableIsolateCreation(); |
| 383 |
| 384 // Send the OOB Kill message to all remaining application isolates. |
| 385 if (FLAG_trace_shutdown) { |
| 386 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Killing all app isolates\n", |
| 387 timestamp()); |
| 388 } |
| 389 Isolate::KillAllIsolates(Isolate::kInternalKillMsg); |
| 390 |
| 391 // Wait for all isolates, but the service and the vm isolate to shut down. |
| 392 // Only do that if there is a service isolate running. |
| 393 if (ServiceIsolate::IsRunning()) { |
380 if (FLAG_trace_shutdown) { | 394 if (FLAG_trace_shutdown) { |
381 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Disabling isolate creation\n", | 395 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down app isolates\n", |
382 timestamp()); | 396 timestamp()); |
383 } | 397 } |
384 Isolate::DisableIsolateCreation(); | 398 WaitForApplicationIsolateShutdown(); |
| 399 } |
385 | 400 |
386 // Send the OOB Kill message to all remaining application isolates. | 401 // Shutdown the service isolate. |
387 if (FLAG_trace_shutdown) { | 402 if (FLAG_trace_shutdown) { |
388 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Killing all app isolates\n", | 403 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down service isolate\n", |
389 timestamp()); | 404 timestamp()); |
390 } | 405 } |
391 Isolate::KillAllIsolates(Isolate::kInternalKillMsg); | 406 ServiceIsolate::Shutdown(); |
392 | 407 |
393 // Wait for all isolates, but the service and the vm isolate to shut down. | 408 // Wait for the remaining isolate (service isolate) to shutdown |
394 // Only do that if there is a service isolate running. | 409 // before shutting down the thread pool. |
395 if (ServiceIsolate::IsRunning()) { | 410 if (FLAG_trace_shutdown) { |
396 if (FLAG_trace_shutdown) { | 411 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Waiting for isolate shutdown\n", |
397 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down app isolates\n", | 412 timestamp()); |
398 timestamp()); | 413 } |
399 } | 414 WaitForIsolateShutdown(); |
400 WaitForApplicationIsolateShutdown(); | |
401 } | |
402 | 415 |
403 // Shutdown the service isolate. | 416 // Shutdown the thread pool. On return, all thread pool threads have exited. |
404 if (FLAG_trace_shutdown) { | 417 if (FLAG_trace_shutdown) { |
405 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down service isolate\n", | 418 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleting thread pool\n", |
406 timestamp()); | 419 timestamp()); |
407 } | 420 } |
408 ServiceIsolate::Shutdown(); | 421 delete thread_pool_; |
| 422 thread_pool_ = NULL; |
409 | 423 |
410 // Wait for the remaining isolate (service isolate) to shutdown | 424 // Disable creation of any new OSThread structures which means no more new |
411 // before shutting down the thread pool. | 425 // threads can do an EnterIsolate. This must come after isolate shutdown |
412 if (FLAG_trace_shutdown) { | 426 // because new threads may need to be spawned to shutdown the isolates. |
413 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Waiting for isolate shutdown\n", | 427 // This must come after deletion of the thread pool to avoid a race in which |
414 timestamp()); | 428 // a thread spawned by the thread pool does not exit through the thread |
415 } | 429 // pool, messing up its bookkeeping. |
416 WaitForIsolateShutdown(); | 430 if (FLAG_trace_shutdown) { |
| 431 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Disabling OS Thread creation\n", |
| 432 timestamp()); |
| 433 } |
| 434 OSThread::DisableOSThreadCreation(); |
417 | 435 |
418 // Shutdown the thread pool. On return, all thread pool threads have exited. | 436 // Set the VM isolate as current isolate. |
419 if (FLAG_trace_shutdown) { | 437 if (FLAG_trace_shutdown) { |
420 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleting thread pool\n", | 438 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Cleaning up vm isolate\n", |
421 timestamp()); | 439 timestamp()); |
422 } | 440 } |
423 delete thread_pool_; | 441 bool result = Thread::EnterIsolate(vm_isolate_); |
424 thread_pool_ = NULL; | 442 ASSERT(result); |
425 | 443 |
426 // Disable creation of any new OSThread structures which means no more new | 444 ShutdownIsolate(); |
427 // threads can do an EnterIsolate. This must come after isolate shutdown | 445 vm_isolate_ = NULL; |
428 // because new threads may need to be spawned to shutdown the isolates. | 446 ASSERT(Isolate::IsolateListLength() == 0); |
429 // This must come after deletion of the thread pool to avoid a race in which | |
430 // a thread spawned by the thread pool does not exit through the thread | |
431 // pool, messing up its bookkeeping. | |
432 if (FLAG_trace_shutdown) { | |
433 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Disabling OS Thread creation\n", | |
434 timestamp()); | |
435 } | |
436 OSThread::DisableOSThreadCreation(); | |
437 | 447 |
438 // Set the VM isolate as current isolate. | 448 TargetCPUFeatures::Cleanup(); |
439 if (FLAG_trace_shutdown) { | 449 StoreBuffer::ShutDown(); |
440 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Cleaning up vm isolate\n", | |
441 timestamp()); | |
442 } | |
443 bool result = Thread::EnterIsolate(vm_isolate_); | |
444 ASSERT(result); | |
445 | 450 |
446 ShutdownIsolate(); | 451 // Delete the current thread's TLS and set it's TLS to null. |
447 vm_isolate_ = NULL; | 452 // If it is the last thread then the destructor would call |
448 ASSERT(Isolate::IsolateListLength() == 0); | 453 // OSThread::Cleanup. |
449 | 454 OSThread* os_thread = OSThread::Current(); |
450 TargetCPUFeatures::Cleanup(); | 455 OSThread::SetCurrent(NULL); |
451 StoreBuffer::ShutDown(); | 456 delete os_thread; |
452 | 457 if (FLAG_trace_shutdown) { |
453 // Delete the current thread's TLS and set it's TLS to null. | 458 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleted os_thread\n", |
454 // If it is the last thread then the destructor would call | 459 timestamp()); |
455 // OSThread::Cleanup. | |
456 OSThread* os_thread = OSThread::Current(); | |
457 OSThread::SetCurrent(NULL); | |
458 delete os_thread; | |
459 if (FLAG_trace_shutdown) { | |
460 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleted os_thread\n", | |
461 timestamp()); | |
462 } | |
463 } else { | |
464 // Shutdown the service isolate. | |
465 if (FLAG_trace_shutdown) { | |
466 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down service isolate\n", | |
467 timestamp()); | |
468 } | |
469 ServiceIsolate::Shutdown(); | |
470 | |
471 // Disable thread creation. | |
472 if (FLAG_trace_shutdown) { | |
473 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Disabling OS Thread creation\n", | |
474 timestamp()); | |
475 } | |
476 OSThread::DisableOSThreadCreation(); | |
477 } | 460 } |
478 | 461 |
479 if (FLAG_trace_shutdown) { | 462 if (FLAG_trace_shutdown) { |
480 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleting code observers\n", | 463 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleting code observers\n", |
481 timestamp()); | 464 timestamp()); |
482 } | 465 } |
483 NOT_IN_PRODUCT(CodeObservers::DeleteAll()); | 466 NOT_IN_PRODUCT(CodeObservers::DeleteAll()); |
484 if (FLAG_support_timeline) { | 467 if (FLAG_support_timeline) { |
485 if (FLAG_trace_shutdown) { | 468 if (FLAG_trace_shutdown) { |
486 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down timeline\n", | 469 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down timeline\n", |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 return predefined_handles_->handles_.IsValidScopedHandle(address); | 717 return predefined_handles_->handles_.IsValidScopedHandle(address); |
735 } | 718 } |
736 | 719 |
737 | 720 |
738 bool Dart::IsReadOnlyApiHandle(Dart_Handle handle) { | 721 bool Dart::IsReadOnlyApiHandle(Dart_Handle handle) { |
739 ASSERT(predefined_handles_ != NULL); | 722 ASSERT(predefined_handles_ != NULL); |
740 return predefined_handles_->api_handles_.IsValidHandle(handle); | 723 return predefined_handles_->api_handles_.IsValidHandle(handle); |
741 } | 724 } |
742 | 725 |
743 } // namespace dart | 726 } // namespace dart |
OLD | NEW |