| 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 24 matching lines...) Expand all Loading... |
| 35 namespace dart { | 35 namespace dart { |
| 36 | 36 |
| 37 DECLARE_FLAG(bool, print_class_table); | 37 DECLARE_FLAG(bool, print_class_table); |
| 38 DECLARE_FLAG(bool, trace_isolates); | 38 DECLARE_FLAG(bool, trace_isolates); |
| 39 DECLARE_FLAG(bool, trace_time_all); | 39 DECLARE_FLAG(bool, trace_time_all); |
| 40 DECLARE_FLAG(bool, pause_isolates_on_start); | 40 DECLARE_FLAG(bool, pause_isolates_on_start); |
| 41 DECLARE_FLAG(bool, pause_isolates_on_exit); | 41 DECLARE_FLAG(bool, pause_isolates_on_exit); |
| 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"); | 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"); |
| 45 | 46 |
| 46 Isolate* Dart::vm_isolate_ = NULL; | 47 Isolate* Dart::vm_isolate_ = NULL; |
| 48 int64_t Dart::start_time_ = 0; |
| 47 ThreadPool* Dart::thread_pool_ = NULL; | 49 ThreadPool* Dart::thread_pool_ = NULL; |
| 48 DebugInfo* Dart::pprof_symbol_generator_ = NULL; | 50 DebugInfo* Dart::pprof_symbol_generator_ = NULL; |
| 49 ReadOnlyHandles* Dart::predefined_handles_ = NULL; | 51 ReadOnlyHandles* Dart::predefined_handles_ = NULL; |
| 50 const uint8_t* Dart::instructions_snapshot_buffer_ = NULL; | 52 const uint8_t* Dart::instructions_snapshot_buffer_ = NULL; |
| 51 | 53 |
| 52 // Structure for managing read-only global handles allocation used for | 54 // Structure for managing read-only global handles allocation used for |
| 53 // creating global read-only handles that are pre created and initialized | 55 // creating global read-only handles that are pre created and initialized |
| 54 // for use across all isolates. Having these global pre created handles | 56 // for use across all isolates. Having these global pre created handles |
| 55 // stored in the vm isolate ensures that we don't constantly create and | 57 // stored in the vm isolate ensures that we don't constantly create and |
| 56 // destroy handles for read-only objects referred in the VM code | 58 // destroy handles for read-only objects referred in the VM code |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 ASSERT(vm_isolate_ == NULL); | 128 ASSERT(vm_isolate_ == NULL); |
| 127 ASSERT(Flags::Initialized()); | 129 ASSERT(Flags::Initialized()); |
| 128 const bool is_vm_isolate = true; | 130 const bool is_vm_isolate = true; |
| 129 const bool precompiled = instructions_snapshot != NULL; | 131 const bool precompiled = instructions_snapshot != NULL; |
| 130 | 132 |
| 131 // Setup default flags for the VM isolate. | 133 // Setup default flags for the VM isolate. |
| 132 Isolate::Flags vm_flags; | 134 Isolate::Flags vm_flags; |
| 133 Dart_IsolateFlags api_flags; | 135 Dart_IsolateFlags api_flags; |
| 134 vm_flags.CopyTo(&api_flags); | 136 vm_flags.CopyTo(&api_flags); |
| 135 vm_isolate_ = Isolate::Init("vm-isolate", api_flags, is_vm_isolate); | 137 vm_isolate_ = Isolate::Init("vm-isolate", api_flags, is_vm_isolate); |
| 138 start_time_ = vm_isolate_->start_time(); |
| 136 vm_isolate_->set_compilation_allowed(!precompiled); | 139 vm_isolate_->set_compilation_allowed(!precompiled); |
| 137 // Verify assumptions about executing in the VM isolate. | 140 // Verify assumptions about executing in the VM isolate. |
| 138 ASSERT(vm_isolate_ == Isolate::Current()); | 141 ASSERT(vm_isolate_ == Isolate::Current()); |
| 139 ASSERT(vm_isolate_ == Thread::Current()->isolate()); | 142 ASSERT(vm_isolate_ == Thread::Current()->isolate()); |
| 140 | 143 |
| 141 Thread* T = Thread::Current(); | 144 Thread* T = Thread::Current(); |
| 142 ASSERT(T != NULL); | 145 ASSERT(T != NULL); |
| 143 StackZone zone(T); | 146 StackZone zone(T); |
| 144 HandleScope handle_scope(T); | 147 HandleScope handle_scope(T); |
| 145 Object::InitNull(vm_isolate_); | 148 Object::InitNull(vm_isolate_); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 ASSERT(Isolate::isolates_list_head_ == Dart::vm_isolate()); | 230 ASSERT(Isolate::isolates_list_head_ == Dart::vm_isolate()); |
| 228 } | 231 } |
| 229 | 232 |
| 230 | 233 |
| 231 const char* Dart::Cleanup() { | 234 const char* Dart::Cleanup() { |
| 232 ASSERT(Isolate::Current() == NULL); | 235 ASSERT(Isolate::Current() == NULL); |
| 233 if (vm_isolate_ == NULL) { | 236 if (vm_isolate_ == NULL) { |
| 234 return "VM already terminated."; | 237 return "VM already terminated."; |
| 235 } | 238 } |
| 236 | 239 |
| 240 if (FLAG_trace_shutdown) { |
| 241 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Starting shutdown\n", |
| 242 timestamp()); |
| 243 } |
| 244 |
| 237 if (FLAG_profiler) { | 245 if (FLAG_profiler) { |
| 238 // Shut down profiling. | 246 // Shut down profiling. |
| 247 if (FLAG_trace_shutdown) { |
| 248 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down profiling\n", |
| 249 timestamp()); |
| 250 } |
| 239 Profiler::Shutdown(); | 251 Profiler::Shutdown(); |
| 240 } | 252 } |
| 241 | 253 |
| 242 | 254 |
| 243 { | 255 { |
| 244 // Set the VM isolate as current isolate when shutting down | 256 // Set the VM isolate as current isolate when shutting down |
| 245 // Metrics so that we can use a StackZone. | 257 // Metrics so that we can use a StackZone. |
| 258 if (FLAG_trace_shutdown) { |
| 259 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Entering vm isolate\n", |
| 260 timestamp()); |
| 261 } |
| 246 bool result = Thread::EnterIsolate(vm_isolate_); | 262 bool result = Thread::EnterIsolate(vm_isolate_); |
| 247 ASSERT(result); | 263 ASSERT(result); |
| 248 Metric::Cleanup(); | 264 Metric::Cleanup(); |
| 249 Thread::ExitIsolate(); | 265 Thread::ExitIsolate(); |
| 250 } | 266 } |
| 251 | 267 |
| 252 if (FLAG_shutdown) { | 268 if (FLAG_shutdown) { |
| 253 // Disable the creation of new isolates. | 269 // Disable the creation of new isolates. |
| 270 if (FLAG_trace_shutdown) { |
| 271 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Disabling isolate creation\n", |
| 272 timestamp()); |
| 273 } |
| 254 Isolate::DisableIsolateCreation(); | 274 Isolate::DisableIsolateCreation(); |
| 255 | 275 |
| 256 // Send the OOB Kill message to all remaining application isolates. | 276 // Send the OOB Kill message to all remaining application isolates. |
| 277 if (FLAG_trace_shutdown) { |
| 278 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Killing all app isolates\n", |
| 279 timestamp()); |
| 280 } |
| 257 Isolate::KillAllIsolates(Isolate::kInternalKillMsg); | 281 Isolate::KillAllIsolates(Isolate::kInternalKillMsg); |
| 258 | 282 |
| 259 // Shutdown the service isolate. | 283 // Shutdown the service isolate. |
| 284 if (FLAG_trace_shutdown) { |
| 285 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down service isolate\n", |
| 286 timestamp()); |
| 287 } |
| 260 ServiceIsolate::Shutdown(); | 288 ServiceIsolate::Shutdown(); |
| 261 | 289 |
| 262 // Wait for all application isolates and the service isolate to shutdown | 290 // Wait for all application isolates and the service isolate to shutdown |
| 263 // before shutting down the thread pool. | 291 // before shutting down the thread pool. |
| 292 if (FLAG_trace_shutdown) { |
| 293 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Waiting for isolate shutdown\n", |
| 294 timestamp()); |
| 295 } |
| 264 WaitForIsolateShutdown(); | 296 WaitForIsolateShutdown(); |
| 265 | 297 |
| 266 // Shutdown the thread pool. On return, all thread pool threads have exited. | 298 // Shutdown the thread pool. On return, all thread pool threads have exited. |
| 299 if (FLAG_trace_shutdown) { |
| 300 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleting thread pool\n", |
| 301 timestamp()); |
| 302 } |
| 267 delete thread_pool_; | 303 delete thread_pool_; |
| 268 thread_pool_ = NULL; | 304 thread_pool_ = NULL; |
| 269 | 305 |
| 270 // Disable creation of any new OSThread structures which means no more new | 306 // Disable creation of any new OSThread structures which means no more new |
| 271 // threads can do an EnterIsolate. This must come after isolate shutdown | 307 // threads can do an EnterIsolate. This must come after isolate shutdown |
| 272 // because new threads may need to be spawned to shutdown the isolates. | 308 // because new threads may need to be spawned to shutdown the isolates. |
| 273 // This must come after deletion of the thread pool to avoid a race in which | 309 // This must come after deletion of the thread pool to avoid a race in which |
| 274 // a thread spawned by the thread pool does not exit through the thread | 310 // a thread spawned by the thread pool does not exit through the thread |
| 275 // pool, messing up its bookkeeping. | 311 // pool, messing up its bookkeeping. |
| 312 if (FLAG_trace_shutdown) { |
| 313 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Disabling OS Thread creation\n", |
| 314 timestamp()); |
| 315 } |
| 276 OSThread::DisableOSThreadCreation(); | 316 OSThread::DisableOSThreadCreation(); |
| 277 | 317 |
| 278 // Set the VM isolate as current isolate. | 318 // Set the VM isolate as current isolate. |
| 319 if (FLAG_trace_shutdown) { |
| 320 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Cleaning up vm isolate\n", |
| 321 timestamp()); |
| 322 } |
| 279 bool result = Thread::EnterIsolate(vm_isolate_); | 323 bool result = Thread::EnterIsolate(vm_isolate_); |
| 280 ASSERT(result); | 324 ASSERT(result); |
| 281 | 325 |
| 282 ShutdownIsolate(); | 326 ShutdownIsolate(); |
| 283 vm_isolate_ = NULL; | 327 vm_isolate_ = NULL; |
| 284 ASSERT(Isolate::IsolateListLength() == 0); | 328 ASSERT(Isolate::IsolateListLength() == 0); |
| 285 | 329 |
| 286 TargetCPUFeatures::Cleanup(); | 330 TargetCPUFeatures::Cleanup(); |
| 287 StoreBuffer::ShutDown(); | 331 StoreBuffer::ShutDown(); |
| 288 | 332 |
| 289 // Delete the current thread's TLS and set it's TLS to null. | 333 // Delete the current thread's TLS and set it's TLS to null. |
| 290 // If it is the last thread then the destructor would call | 334 // If it is the last thread then the destructor would call |
| 291 // OSThread::Cleanup. | 335 // OSThread::Cleanup. |
| 292 OSThread* os_thread = OSThread::Current(); | 336 OSThread* os_thread = OSThread::Current(); |
| 293 OSThread::SetCurrent(NULL); | 337 OSThread::SetCurrent(NULL); |
| 294 delete os_thread; | 338 delete os_thread; |
| 339 if (FLAG_trace_shutdown) { |
| 340 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleted os_thread\n", |
| 341 timestamp()); |
| 342 } |
| 295 } else { | 343 } else { |
| 296 // Shutdown the service isolate. | 344 // Shutdown the service isolate. |
| 345 if (FLAG_trace_shutdown) { |
| 346 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down service isolate\n", |
| 347 timestamp()); |
| 348 } |
| 297 ServiceIsolate::Shutdown(); | 349 ServiceIsolate::Shutdown(); |
| 298 | 350 |
| 299 // Disable thread creation. | 351 // Disable thread creation. |
| 352 if (FLAG_trace_shutdown) { |
| 353 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Disabling OS Thread creation\n", |
| 354 timestamp()); |
| 355 } |
| 300 OSThread::DisableOSThreadCreation(); | 356 OSThread::DisableOSThreadCreation(); |
| 301 } | 357 } |
| 302 | 358 |
| 359 if (FLAG_trace_shutdown) { |
| 360 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleting code observers\n", |
| 361 timestamp()); |
| 362 } |
| 303 CodeObservers::DeleteAll(); | 363 CodeObservers::DeleteAll(); |
| 304 if (FLAG_support_timeline) { | 364 if (FLAG_support_timeline) { |
| 365 if (FLAG_trace_shutdown) { |
| 366 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down timeline\n", |
| 367 timestamp()); |
| 368 } |
| 305 Timeline::Shutdown(); | 369 Timeline::Shutdown(); |
| 306 } | 370 } |
| 371 if (FLAG_trace_shutdown) { |
| 372 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Done\n", timestamp()); |
| 373 } |
| 307 | 374 |
| 308 return NULL; | 375 return NULL; |
| 309 } | 376 } |
| 310 | 377 |
| 311 | 378 |
| 312 Isolate* Dart::CreateIsolate(const char* name_prefix, | 379 Isolate* Dart::CreateIsolate(const char* name_prefix, |
| 313 const Dart_IsolateFlags& api_flags) { | 380 const Dart_IsolateFlags& api_flags) { |
| 314 // Create a new isolate. | 381 // Create a new isolate. |
| 315 Isolate* isolate = Isolate::Init(name_prefix, api_flags); | 382 Isolate* isolate = Isolate::Init(name_prefix, api_flags); |
| 316 return isolate; | 383 return isolate; |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 } | 526 } |
| 460 | 527 |
| 461 | 528 |
| 462 void Dart::ShutdownIsolate() { | 529 void Dart::ShutdownIsolate() { |
| 463 Isolate* isolate = Isolate::Current(); | 530 Isolate* isolate = Isolate::Current(); |
| 464 isolate->Shutdown(); | 531 isolate->Shutdown(); |
| 465 delete isolate; | 532 delete isolate; |
| 466 } | 533 } |
| 467 | 534 |
| 468 | 535 |
| 536 int64_t Dart::timestamp() { |
| 537 return ((OS::GetCurrentTimeMicros() - Dart::start_time_) / |
| 538 kMillisecondsPerSecond); |
| 539 } |
| 540 |
| 541 |
| 469 uword Dart::AllocateReadOnlyHandle() { | 542 uword Dart::AllocateReadOnlyHandle() { |
| 470 ASSERT(Isolate::Current() == Dart::vm_isolate()); | 543 ASSERT(Isolate::Current() == Dart::vm_isolate()); |
| 471 ASSERT(predefined_handles_ != NULL); | 544 ASSERT(predefined_handles_ != NULL); |
| 472 return predefined_handles_->handles_.AllocateScopedHandle(); | 545 return predefined_handles_->handles_.AllocateScopedHandle(); |
| 473 } | 546 } |
| 474 | 547 |
| 475 | 548 |
| 476 LocalHandle* Dart::AllocateReadOnlyApiHandle() { | 549 LocalHandle* Dart::AllocateReadOnlyApiHandle() { |
| 477 ASSERT(Isolate::Current() == Dart::vm_isolate()); | 550 ASSERT(Isolate::Current() == Dart::vm_isolate()); |
| 478 ASSERT(predefined_handles_ != NULL); | 551 ASSERT(predefined_handles_ != NULL); |
| 479 return predefined_handles_->api_handles_.AllocateHandle(); | 552 return predefined_handles_->api_handles_.AllocateHandle(); |
| 480 } | 553 } |
| 481 | 554 |
| 482 | 555 |
| 483 bool Dart::IsReadOnlyHandle(uword address) { | 556 bool Dart::IsReadOnlyHandle(uword address) { |
| 484 ASSERT(predefined_handles_ != NULL); | 557 ASSERT(predefined_handles_ != NULL); |
| 485 return predefined_handles_->handles_.IsValidScopedHandle(address); | 558 return predefined_handles_->handles_.IsValidScopedHandle(address); |
| 486 } | 559 } |
| 487 | 560 |
| 488 | 561 |
| 489 bool Dart::IsReadOnlyApiHandle(Dart_Handle handle) { | 562 bool Dart::IsReadOnlyApiHandle(Dart_Handle handle) { |
| 490 ASSERT(predefined_handles_ != NULL); | 563 ASSERT(predefined_handles_ != NULL); |
| 491 return predefined_handles_->api_handles_.IsValidHandle(handle); | 564 return predefined_handles_->api_handles_.IsValidHandle(handle); |
| 492 } | 565 } |
| 493 | 566 |
| 494 } // namespace dart | 567 } // namespace dart |
| OLD | NEW |