| 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 26 matching lines...) Expand all Loading... |
| 37 #include "vm/zone.h" | 37 #include "vm/zone.h" |
| 38 | 38 |
| 39 namespace dart { | 39 namespace dart { |
| 40 | 40 |
| 41 DECLARE_FLAG(bool, print_class_table); | 41 DECLARE_FLAG(bool, print_class_table); |
| 42 DECLARE_FLAG(bool, trace_time_all); | 42 DECLARE_FLAG(bool, trace_time_all); |
| 43 DEFINE_FLAG(bool, keep_code, false, "Keep deoptimized code for profiling."); | 43 DEFINE_FLAG(bool, keep_code, false, "Keep deoptimized code for profiling."); |
| 44 DEFINE_FLAG(bool, trace_shutdown, false, "Trace VM shutdown on stderr"); | 44 DEFINE_FLAG(bool, trace_shutdown, false, "Trace VM shutdown on stderr"); |
| 45 | 45 |
| 46 Isolate* Dart::vm_isolate_ = NULL; | 46 Isolate* Dart::vm_isolate_ = NULL; |
| 47 int64_t Dart::start_time_ = 0; | 47 int64_t Dart::start_time_micros_ = 0; |
| 48 ThreadPool* Dart::thread_pool_ = NULL; | 48 ThreadPool* Dart::thread_pool_ = NULL; |
| 49 DebugInfo* Dart::pprof_symbol_generator_ = NULL; | 49 DebugInfo* Dart::pprof_symbol_generator_ = NULL; |
| 50 ReadOnlyHandles* Dart::predefined_handles_ = NULL; | 50 ReadOnlyHandles* Dart::predefined_handles_ = NULL; |
| 51 Snapshot::Kind Dart::snapshot_kind_ = Snapshot::kInvalid; | 51 Snapshot::Kind Dart::snapshot_kind_ = Snapshot::kInvalid; |
| 52 const uint8_t* Dart::instructions_snapshot_buffer_ = NULL; | 52 const uint8_t* Dart::instructions_snapshot_buffer_ = NULL; |
| 53 const uint8_t* Dart::data_snapshot_buffer_ = NULL; | 53 const uint8_t* Dart::data_snapshot_buffer_ = NULL; |
| 54 Dart_ThreadExitCallback Dart::thread_exit_callback_ = NULL; | 54 Dart_ThreadExitCallback Dart::thread_exit_callback_ = NULL; |
| 55 Dart_FileOpenCallback Dart::file_open_callback_ = NULL; | 55 Dart_FileOpenCallback Dart::file_open_callback_ = NULL; |
| 56 Dart_FileReadCallback Dart::file_read_callback_ = NULL; | 56 Dart_FileReadCallback Dart::file_read_callback_ = NULL; |
| 57 Dart_FileWriteCallback Dart::file_write_callback_ = NULL; | 57 Dart_FileWriteCallback Dart::file_write_callback_ = NULL; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 Dart_GetVMServiceAssetsArchive get_service_assets) { | 136 Dart_GetVMServiceAssetsArchive get_service_assets) { |
| 137 CheckOffsets(); | 137 CheckOffsets(); |
| 138 // TODO(iposva): Fix race condition here. | 138 // TODO(iposva): Fix race condition here. |
| 139 if (vm_isolate_ != NULL || !Flags::Initialized()) { | 139 if (vm_isolate_ != NULL || !Flags::Initialized()) { |
| 140 return strdup("VM already initialized or flags not initialized."); | 140 return strdup("VM already initialized or flags not initialized."); |
| 141 } | 141 } |
| 142 set_thread_exit_callback(thread_exit); | 142 set_thread_exit_callback(thread_exit); |
| 143 SetFileCallbacks(file_open, file_read, file_write, file_close); | 143 SetFileCallbacks(file_open, file_read, file_write, file_close); |
| 144 set_entropy_source_callback(entropy_source); | 144 set_entropy_source_callback(entropy_source); |
| 145 OS::InitOnce(); | 145 OS::InitOnce(); |
| 146 start_time_micros_ = OS::GetCurrentMonotonicMicros(); |
| 146 VirtualMemory::InitOnce(); | 147 VirtualMemory::InitOnce(); |
| 147 OSThread::InitOnce(); | 148 OSThread::InitOnce(); |
| 148 if (FLAG_support_timeline) { | 149 if (FLAG_support_timeline) { |
| 149 Timeline::InitOnce(); | 150 Timeline::InitOnce(); |
| 150 } | 151 } |
| 151 NOT_IN_PRODUCT( | 152 NOT_IN_PRODUCT( |
| 152 TimelineDurationScope tds(Timeline::GetVMStream(), "Dart::InitOnce")); | 153 TimelineDurationScope tds(Timeline::GetVMStream(), "Dart::InitOnce")); |
| 153 Isolate::InitOnce(); | 154 Isolate::InitOnce(); |
| 154 PortMap::InitOnce(); | 155 PortMap::InitOnce(); |
| 155 FreeListElement::InitOnce(); | 156 FreeListElement::InitOnce(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 176 thread_pool_ = new ThreadPool(); | 177 thread_pool_ = new ThreadPool(); |
| 177 { | 178 { |
| 178 ASSERT(vm_isolate_ == NULL); | 179 ASSERT(vm_isolate_ == NULL); |
| 179 ASSERT(Flags::Initialized()); | 180 ASSERT(Flags::Initialized()); |
| 180 const bool is_vm_isolate = true; | 181 const bool is_vm_isolate = true; |
| 181 | 182 |
| 182 // Setup default flags for the VM isolate. | 183 // Setup default flags for the VM isolate. |
| 183 Dart_IsolateFlags api_flags; | 184 Dart_IsolateFlags api_flags; |
| 184 Isolate::FlagsInitialize(&api_flags); | 185 Isolate::FlagsInitialize(&api_flags); |
| 185 vm_isolate_ = Isolate::Init("vm-isolate", api_flags, is_vm_isolate); | 186 vm_isolate_ = Isolate::Init("vm-isolate", api_flags, is_vm_isolate); |
| 186 start_time_ = vm_isolate_->start_time(); | |
| 187 // Verify assumptions about executing in the VM isolate. | 187 // Verify assumptions about executing in the VM isolate. |
| 188 ASSERT(vm_isolate_ == Isolate::Current()); | 188 ASSERT(vm_isolate_ == Isolate::Current()); |
| 189 ASSERT(vm_isolate_ == Thread::Current()->isolate()); | 189 ASSERT(vm_isolate_ == Thread::Current()->isolate()); |
| 190 | 190 |
| 191 Thread* T = Thread::Current(); | 191 Thread* T = Thread::Current(); |
| 192 ASSERT(T != NULL); | 192 ASSERT(T != NULL); |
| 193 StackZone zone(T); | 193 StackZone zone(T); |
| 194 HandleScope handle_scope(T); | 194 HandleScope handle_scope(T); |
| 195 Object::InitNull(vm_isolate_); | 195 Object::InitNull(vm_isolate_); |
| 196 ObjectStore::Init(vm_isolate_); | 196 ObjectStore::Init(vm_isolate_); |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 } | 351 } |
| 352 | 352 |
| 353 | 353 |
| 354 const char* Dart::Cleanup() { | 354 const char* Dart::Cleanup() { |
| 355 ASSERT(Isolate::Current() == NULL); | 355 ASSERT(Isolate::Current() == NULL); |
| 356 if (vm_isolate_ == NULL) { | 356 if (vm_isolate_ == NULL) { |
| 357 return "VM already terminated."; | 357 return "VM already terminated."; |
| 358 } | 358 } |
| 359 | 359 |
| 360 if (FLAG_trace_shutdown) { | 360 if (FLAG_trace_shutdown) { |
| 361 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Starting shutdown\n", timestamp()); | 361 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Starting shutdown\n", |
| 362 UptimeMillis()); |
| 362 } | 363 } |
| 363 | 364 |
| 364 if (FLAG_profiler) { | 365 if (FLAG_profiler) { |
| 365 // Shut down profiling. | 366 // Shut down profiling. |
| 366 if (FLAG_trace_shutdown) { | 367 if (FLAG_trace_shutdown) { |
| 367 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down profiling\n", | 368 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down profiling\n", |
| 368 timestamp()); | 369 UptimeMillis()); |
| 369 } | 370 } |
| 370 Profiler::Shutdown(); | 371 Profiler::Shutdown(); |
| 371 } | 372 } |
| 372 | 373 |
| 373 | 374 |
| 374 { | 375 { |
| 375 // Set the VM isolate as current isolate when shutting down | 376 // Set the VM isolate as current isolate when shutting down |
| 376 // Metrics so that we can use a StackZone. | 377 // Metrics so that we can use a StackZone. |
| 377 if (FLAG_trace_shutdown) { | 378 if (FLAG_trace_shutdown) { |
| 378 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Entering vm isolate\n", | 379 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Entering vm isolate\n", |
| 379 timestamp()); | 380 UptimeMillis()); |
| 380 } | 381 } |
| 381 bool result = Thread::EnterIsolate(vm_isolate_); | 382 bool result = Thread::EnterIsolate(vm_isolate_); |
| 382 ASSERT(result); | 383 ASSERT(result); |
| 383 Metric::Cleanup(); | 384 Metric::Cleanup(); |
| 384 Thread::ExitIsolate(); | 385 Thread::ExitIsolate(); |
| 385 } | 386 } |
| 386 | 387 |
| 387 // Disable the creation of new isolates. | 388 // Disable the creation of new isolates. |
| 388 if (FLAG_trace_shutdown) { | 389 if (FLAG_trace_shutdown) { |
| 389 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Disabling isolate creation\n", | 390 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Disabling isolate creation\n", |
| 390 timestamp()); | 391 UptimeMillis()); |
| 391 } | 392 } |
| 392 Isolate::DisableIsolateCreation(); | 393 Isolate::DisableIsolateCreation(); |
| 393 | 394 |
| 394 // Send the OOB Kill message to all remaining application isolates. | 395 // Send the OOB Kill message to all remaining application isolates. |
| 395 if (FLAG_trace_shutdown) { | 396 if (FLAG_trace_shutdown) { |
| 396 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Killing all app isolates\n", | 397 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Killing all app isolates\n", |
| 397 timestamp()); | 398 UptimeMillis()); |
| 398 } | 399 } |
| 399 Isolate::KillAllIsolates(Isolate::kInternalKillMsg); | 400 Isolate::KillAllIsolates(Isolate::kInternalKillMsg); |
| 400 | 401 |
| 401 // Wait for all isolates, but the service and the vm isolate to shut down. | 402 // Wait for all isolates, but the service and the vm isolate to shut down. |
| 402 // Only do that if there is a service isolate running. | 403 // Only do that if there is a service isolate running. |
| 403 if (ServiceIsolate::IsRunning()) { | 404 if (ServiceIsolate::IsRunning()) { |
| 404 if (FLAG_trace_shutdown) { | 405 if (FLAG_trace_shutdown) { |
| 405 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down app isolates\n", | 406 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down app isolates\n", |
| 406 timestamp()); | 407 UptimeMillis()); |
| 407 } | 408 } |
| 408 WaitForApplicationIsolateShutdown(); | 409 WaitForApplicationIsolateShutdown(); |
| 409 } | 410 } |
| 410 | 411 |
| 411 // Shutdown the service isolate. | 412 // Shutdown the service isolate. |
| 412 if (FLAG_trace_shutdown) { | 413 if (FLAG_trace_shutdown) { |
| 413 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down service isolate\n", | 414 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down service isolate\n", |
| 414 timestamp()); | 415 UptimeMillis()); |
| 415 } | 416 } |
| 416 ServiceIsolate::Shutdown(); | 417 ServiceIsolate::Shutdown(); |
| 417 | 418 |
| 418 // Wait for the remaining isolate (service isolate) to shutdown | 419 // Wait for the remaining isolate (service isolate) to shutdown |
| 419 // before shutting down the thread pool. | 420 // before shutting down the thread pool. |
| 420 if (FLAG_trace_shutdown) { | 421 if (FLAG_trace_shutdown) { |
| 421 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Waiting for isolate shutdown\n", | 422 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Waiting for isolate shutdown\n", |
| 422 timestamp()); | 423 UptimeMillis()); |
| 423 } | 424 } |
| 424 WaitForIsolateShutdown(); | 425 WaitForIsolateShutdown(); |
| 425 | 426 |
| 426 // Shutdown the thread pool. On return, all thread pool threads have exited. | 427 // Shutdown the thread pool. On return, all thread pool threads have exited. |
| 427 if (FLAG_trace_shutdown) { | 428 if (FLAG_trace_shutdown) { |
| 428 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleting thread pool\n", | 429 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleting thread pool\n", |
| 429 timestamp()); | 430 UptimeMillis()); |
| 430 } | 431 } |
| 431 delete thread_pool_; | 432 delete thread_pool_; |
| 432 thread_pool_ = NULL; | 433 thread_pool_ = NULL; |
| 433 | 434 |
| 434 // Disable creation of any new OSThread structures which means no more new | 435 // Disable creation of any new OSThread structures which means no more new |
| 435 // threads can do an EnterIsolate. This must come after isolate shutdown | 436 // threads can do an EnterIsolate. This must come after isolate shutdown |
| 436 // because new threads may need to be spawned to shutdown the isolates. | 437 // because new threads may need to be spawned to shutdown the isolates. |
| 437 // This must come after deletion of the thread pool to avoid a race in which | 438 // This must come after deletion of the thread pool to avoid a race in which |
| 438 // a thread spawned by the thread pool does not exit through the thread | 439 // a thread spawned by the thread pool does not exit through the thread |
| 439 // pool, messing up its bookkeeping. | 440 // pool, messing up its bookkeeping. |
| 440 if (FLAG_trace_shutdown) { | 441 if (FLAG_trace_shutdown) { |
| 441 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Disabling OS Thread creation\n", | 442 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Disabling OS Thread creation\n", |
| 442 timestamp()); | 443 UptimeMillis()); |
| 443 } | 444 } |
| 444 OSThread::DisableOSThreadCreation(); | 445 OSThread::DisableOSThreadCreation(); |
| 445 | 446 |
| 446 // Set the VM isolate as current isolate. | 447 // Set the VM isolate as current isolate. |
| 447 if (FLAG_trace_shutdown) { | 448 if (FLAG_trace_shutdown) { |
| 448 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Cleaning up vm isolate\n", | 449 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Cleaning up vm isolate\n", |
| 449 timestamp()); | 450 UptimeMillis()); |
| 450 } | 451 } |
| 451 bool result = Thread::EnterIsolate(vm_isolate_); | 452 bool result = Thread::EnterIsolate(vm_isolate_); |
| 452 ASSERT(result); | 453 ASSERT(result); |
| 453 | 454 |
| 454 ShutdownIsolate(); | 455 ShutdownIsolate(); |
| 455 vm_isolate_ = NULL; | 456 vm_isolate_ = NULL; |
| 456 ASSERT(Isolate::IsolateListLength() == 0); | 457 ASSERT(Isolate::IsolateListLength() == 0); |
| 457 | 458 |
| 458 TargetCPUFeatures::Cleanup(); | 459 TargetCPUFeatures::Cleanup(); |
| 459 StoreBuffer::ShutDown(); | 460 StoreBuffer::ShutDown(); |
| 460 | 461 |
| 461 // Delete the current thread's TLS and set it's TLS to null. | 462 // Delete the current thread's TLS and set it's TLS to null. |
| 462 // If it is the last thread then the destructor would call | 463 // If it is the last thread then the destructor would call |
| 463 // OSThread::Cleanup. | 464 // OSThread::Cleanup. |
| 464 OSThread* os_thread = OSThread::Current(); | 465 OSThread* os_thread = OSThread::Current(); |
| 465 OSThread::SetCurrent(NULL); | 466 OSThread::SetCurrent(NULL); |
| 466 delete os_thread; | 467 delete os_thread; |
| 467 if (FLAG_trace_shutdown) { | 468 if (FLAG_trace_shutdown) { |
| 468 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleted os_thread\n", timestamp()); | 469 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleted os_thread\n", |
| 470 UptimeMillis()); |
| 469 } | 471 } |
| 470 | 472 |
| 471 if (FLAG_trace_shutdown) { | 473 if (FLAG_trace_shutdown) { |
| 472 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleting code observers\n", | 474 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleting code observers\n", |
| 473 timestamp()); | 475 UptimeMillis()); |
| 474 } | 476 } |
| 475 NOT_IN_PRODUCT(CodeObservers::DeleteAll()); | 477 NOT_IN_PRODUCT(CodeObservers::DeleteAll()); |
| 476 if (FLAG_support_timeline) { | 478 if (FLAG_support_timeline) { |
| 477 if (FLAG_trace_shutdown) { | 479 if (FLAG_trace_shutdown) { |
| 478 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down timeline\n", | 480 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down timeline\n", |
| 479 timestamp()); | 481 UptimeMillis()); |
| 480 } | 482 } |
| 481 Timeline::Shutdown(); | 483 Timeline::Shutdown(); |
| 482 } | 484 } |
| 483 if (FLAG_trace_shutdown) { | 485 if (FLAG_trace_shutdown) { |
| 484 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Done\n", timestamp()); | 486 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Done\n", UptimeMillis()); |
| 485 } | 487 } |
| 486 | 488 |
| 487 return NULL; | 489 return NULL; |
| 488 } | 490 } |
| 489 | 491 |
| 490 | 492 |
| 491 Isolate* Dart::CreateIsolate(const char* name_prefix, | 493 Isolate* Dart::CreateIsolate(const char* name_prefix, |
| 492 const Dart_IsolateFlags& api_flags) { | 494 const Dart_IsolateFlags& api_flags) { |
| 493 // Create a new isolate. | 495 // Create a new isolate. |
| 494 Isolate* isolate = Isolate::Init(name_prefix, api_flags); | 496 Isolate* isolate = Isolate::Init(name_prefix, api_flags); |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 } | 707 } |
| 706 | 708 |
| 707 | 709 |
| 708 void Dart::ShutdownIsolate() { | 710 void Dart::ShutdownIsolate() { |
| 709 Isolate* isolate = Isolate::Current(); | 711 Isolate* isolate = Isolate::Current(); |
| 710 isolate->Shutdown(); | 712 isolate->Shutdown(); |
| 711 delete isolate; | 713 delete isolate; |
| 712 } | 714 } |
| 713 | 715 |
| 714 | 716 |
| 715 int64_t Dart::timestamp() { | 717 int64_t Dart::UptimeMicros() { |
| 716 return ((OS::GetCurrentTimeMicros() - Dart::start_time_) / | 718 return OS::GetCurrentMonotonicMicros() - Dart::start_time_micros_; |
| 717 kMillisecondsPerSecond); | |
| 718 } | 719 } |
| 719 | 720 |
| 720 | 721 |
| 721 uword Dart::AllocateReadOnlyHandle() { | 722 uword Dart::AllocateReadOnlyHandle() { |
| 722 ASSERT(Isolate::Current() == Dart::vm_isolate()); | 723 ASSERT(Isolate::Current() == Dart::vm_isolate()); |
| 723 ASSERT(predefined_handles_ != NULL); | 724 ASSERT(predefined_handles_ != NULL); |
| 724 return predefined_handles_->handles_.AllocateScopedHandle(); | 725 return predefined_handles_->handles_.AllocateScopedHandle(); |
| 725 } | 726 } |
| 726 | 727 |
| 727 | 728 |
| 728 LocalHandle* Dart::AllocateReadOnlyApiHandle() { | 729 LocalHandle* Dart::AllocateReadOnlyApiHandle() { |
| 729 ASSERT(Isolate::Current() == Dart::vm_isolate()); | 730 ASSERT(Isolate::Current() == Dart::vm_isolate()); |
| 730 ASSERT(predefined_handles_ != NULL); | 731 ASSERT(predefined_handles_ != NULL); |
| 731 return predefined_handles_->api_handles_.AllocateHandle(); | 732 return predefined_handles_->api_handles_.AllocateHandle(); |
| 732 } | 733 } |
| 733 | 734 |
| 734 | 735 |
| 735 bool Dart::IsReadOnlyHandle(uword address) { | 736 bool Dart::IsReadOnlyHandle(uword address) { |
| 736 ASSERT(predefined_handles_ != NULL); | 737 ASSERT(predefined_handles_ != NULL); |
| 737 return predefined_handles_->handles_.IsValidScopedHandle(address); | 738 return predefined_handles_->handles_.IsValidScopedHandle(address); |
| 738 } | 739 } |
| 739 | 740 |
| 740 | 741 |
| 741 bool Dart::IsReadOnlyApiHandle(Dart_Handle handle) { | 742 bool Dart::IsReadOnlyApiHandle(Dart_Handle handle) { |
| 742 ASSERT(predefined_handles_ != NULL); | 743 ASSERT(predefined_handles_ != NULL); |
| 743 return predefined_handles_->api_handles_.IsValidHandle(handle); | 744 return predefined_handles_->api_handles_.IsValidHandle(handle); |
| 744 } | 745 } |
| 745 | 746 |
| 746 } // namespace dart | 747 } // namespace dart |
| OLD | NEW |