| 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 |