Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(106)

Side by Side Diff: runtime/vm/isolate.cc

Issue 1541073002: Implement safepointing of threads (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: address-code-review-comments Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/isolate.h" 5 #include "vm/isolate.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "include/dart_native_api.h" 8 #include "include/dart_native_api.h"
9 #include "platform/assert.h" 9 #include "platform/assert.h"
10 #include "platform/text_buffer.h" 10 #include "platform/text_buffer.h"
(...skipping 11 matching lines...) Expand all
22 #include "vm/lockers.h" 22 #include "vm/lockers.h"
23 #include "vm/log.h" 23 #include "vm/log.h"
24 #include "vm/message_handler.h" 24 #include "vm/message_handler.h"
25 #include "vm/object_id_ring.h" 25 #include "vm/object_id_ring.h"
26 #include "vm/object_store.h" 26 #include "vm/object_store.h"
27 #include "vm/object.h" 27 #include "vm/object.h"
28 #include "vm/os_thread.h" 28 #include "vm/os_thread.h"
29 #include "vm/port.h" 29 #include "vm/port.h"
30 #include "vm/profiler.h" 30 #include "vm/profiler.h"
31 #include "vm/reusable_handles.h" 31 #include "vm/reusable_handles.h"
32 #include "vm/safepoint.h"
32 #include "vm/service.h" 33 #include "vm/service.h"
33 #include "vm/service_event.h" 34 #include "vm/service_event.h"
34 #include "vm/service_isolate.h" 35 #include "vm/service_isolate.h"
35 #include "vm/simulator.h" 36 #include "vm/simulator.h"
36 #include "vm/stack_frame.h" 37 #include "vm/stack_frame.h"
37 #include "vm/store_buffer.h" 38 #include "vm/store_buffer.h"
38 #include "vm/stub_code.h" 39 #include "vm/stub_code.h"
39 #include "vm/symbols.h" 40 #include "vm/symbols.h"
40 #include "vm/tags.h" 41 #include "vm/tags.h"
41 #include "vm/thread_interrupter.h" 42 #include "vm/thread_interrupter.h"
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 Isolate::Isolate(const Dart_IsolateFlags& api_flags) 737 Isolate::Isolate(const Dart_IsolateFlags& api_flags)
737 : stack_limit_(0), 738 : stack_limit_(0),
738 store_buffer_(new StoreBuffer()), 739 store_buffer_(new StoreBuffer()),
739 heap_(NULL), 740 heap_(NULL),
740 user_tag_(0), 741 user_tag_(0),
741 current_tag_(UserTag::null()), 742 current_tag_(UserTag::null()),
742 default_tag_(UserTag::null()), 743 default_tag_(UserTag::null()),
743 class_table_(), 744 class_table_(),
744 single_step_(false), 745 single_step_(false),
745 thread_registry_(new ThreadRegistry()), 746 thread_registry_(new ThreadRegistry()),
747 safepoint_handler_(new SafepointHandler(this)),
746 message_notify_callback_(NULL), 748 message_notify_callback_(NULL),
747 name_(NULL), 749 name_(NULL),
748 debugger_name_(NULL), 750 debugger_name_(NULL),
749 start_time_(OS::GetCurrentTimeMicros()), 751 start_time_(OS::GetCurrentTimeMicros()),
750 main_port_(0), 752 main_port_(0),
751 origin_id_(0), 753 origin_id_(0),
752 pause_capability_(0), 754 pause_capability_(0),
753 terminate_capability_(0), 755 terminate_capability_(0),
754 errors_fatal_(true), 756 errors_fatal_(true),
755 object_store_(NULL), 757 object_store_(NULL),
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 delete object_id_ring_; 831 delete object_id_ring_;
830 object_id_ring_ = NULL; 832 object_id_ring_ = NULL;
831 delete pause_loop_monitor_; 833 delete pause_loop_monitor_;
832 pause_loop_monitor_ = NULL; 834 pause_loop_monitor_ = NULL;
833 ASSERT(spawn_count_ == 0); 835 ASSERT(spawn_count_ == 0);
834 delete spawn_count_monitor_; 836 delete spawn_count_monitor_;
835 if (compiler_stats_ != NULL) { 837 if (compiler_stats_ != NULL) {
836 delete compiler_stats_; 838 delete compiler_stats_;
837 compiler_stats_ = NULL; 839 compiler_stats_ = NULL;
838 } 840 }
841 delete safepoint_handler_;
839 delete thread_registry_; 842 delete thread_registry_;
840 } 843 }
841 844
842 845
843 #if defined(DEBUG)
844 bool Isolate::IsIsolateOf(Thread* thread) {
845 return this == thread->isolate();
846 }
847 #endif // DEBUG
848
849
850 void Isolate::InitOnce() { 846 void Isolate::InitOnce() {
851 create_callback_ = NULL; 847 create_callback_ = NULL;
852 isolates_list_monitor_ = new Monitor(); 848 isolates_list_monitor_ = new Monitor();
853 ASSERT(isolates_list_monitor_ != NULL); 849 ASSERT(isolates_list_monitor_ != NULL);
854 EnableIsolateCreation(); 850 EnableIsolateCreation();
855 } 851 }
856 852
857 853
858 Isolate* Isolate::Init(const char* name_prefix, 854 Isolate* Isolate::Init(const char* name_prefix,
859 const Dart_IsolateFlags& api_flags, 855 const Dart_IsolateFlags& api_flags,
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after
1444 } 1440 }
1445 uword interrupt_bits = stack_limit_ & kInterruptsMask; 1441 uword interrupt_bits = stack_limit_ & kInterruptsMask;
1446 stack_limit_ = saved_stack_limit_; 1442 stack_limit_ = saved_stack_limit_;
1447 return interrupt_bits; 1443 return interrupt_bits;
1448 } 1444 }
1449 1445
1450 1446
1451 RawError* Isolate::HandleInterrupts() { 1447 RawError* Isolate::HandleInterrupts() {
1452 uword interrupt_bits = GetAndClearInterrupts(); 1448 uword interrupt_bits = GetAndClearInterrupts();
1453 if ((interrupt_bits & kVMInterrupt) != 0) { 1449 if ((interrupt_bits & kVMInterrupt) != 0) {
1454 thread_registry()->CheckSafepoint();
1455 if (store_buffer()->Overflowed()) { 1450 if (store_buffer()->Overflowed()) {
1456 if (FLAG_verbose_gc) { 1451 if (FLAG_verbose_gc) {
1457 OS::PrintErr("Scavenge scheduled by store buffer overflow.\n"); 1452 OS::PrintErr("Scavenge scheduled by store buffer overflow.\n");
1458 } 1453 }
1459 heap()->CollectGarbage(Heap::kNew); 1454 heap()->CollectGarbage(Heap::kNew);
1460 } 1455 }
1461 } 1456 }
1462 if ((interrupt_bits & kMessageInterrupt) != 0) { 1457 if ((interrupt_bits & kMessageInterrupt) != 0) {
1463 MessageHandler::MessageStatus status = 1458 MessageHandler::MessageStatus status =
1464 message_handler()->HandleOOBMessages(); 1459 message_handler()->HandleOOBMessages();
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1753 reinterpret_cast<RawObject**>(&registered_service_extension_handlers_)); 1748 reinterpret_cast<RawObject**>(&registered_service_extension_handlers_));
1754 1749
1755 // Visit objects in the debugger. 1750 // Visit objects in the debugger.
1756 debugger()->VisitObjectPointers(visitor); 1751 debugger()->VisitObjectPointers(visitor);
1757 1752
1758 // Visit objects that are being used for deoptimization. 1753 // Visit objects that are being used for deoptimization.
1759 if (deopt_context() != NULL) { 1754 if (deopt_context() != NULL) {
1760 deopt_context()->VisitObjectPointers(visitor); 1755 deopt_context()->VisitObjectPointers(visitor);
1761 } 1756 }
1762 1757
1763 // Visit objects in thread registry (e.g., Dart stack, handles in zones). 1758 // Visit objects in all threads (e.g., Dart stack, handles in zones).
1764 thread_registry()->VisitObjectPointers(visitor, validate_frames); 1759 thread_registry()->VisitObjectPointers(visitor, validate_frames);
1765 } 1760 }
1766 1761
1767 1762
1768 void Isolate::VisitWeakPersistentHandles(HandleVisitor* visitor) { 1763 void Isolate::VisitWeakPersistentHandles(HandleVisitor* visitor) {
1769 if (api_state() != NULL) { 1764 if (api_state() != NULL) {
1770 api_state()->VisitWeakHandles(visitor); 1765 api_state()->VisitWeakHandles(visitor);
1771 } 1766 }
1772 } 1767 }
1773 1768
1774 1769
1770 void Isolate::PrepareForGC() {
1771 thread_registry()->PrepareForGC();
1772 }
1773
1774
1775 static const char* ExceptionPauseInfoToServiceEnum(Dart_ExceptionPauseInfo pi) { 1775 static const char* ExceptionPauseInfoToServiceEnum(Dart_ExceptionPauseInfo pi) {
1776 switch (pi) { 1776 switch (pi) {
1777 case kPauseOnAllExceptions: 1777 case kPauseOnAllExceptions:
1778 return "All"; 1778 return "All";
1779 case kNoPauseOnExceptions: 1779 case kNoPauseOnExceptions:
1780 return "None"; 1780 return "None";
1781 case kPauseOnUnhandledExceptions: 1781 case kPauseOnUnhandledExceptions:
1782 return "Unhandled"; 1782 return "Unhandled";
1783 default: 1783 default:
1784 UNIMPLEMENTED(); 1784 UNIMPLEMENTED();
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after
2322 2322
2323 2323
2324 void Isolate::WaitForOutstandingSpawns() { 2324 void Isolate::WaitForOutstandingSpawns() {
2325 MonitorLocker ml(spawn_count_monitor_); 2325 MonitorLocker ml(spawn_count_monitor_);
2326 while (spawn_count_ > 0) { 2326 while (spawn_count_ > 0) {
2327 ml.Wait(); 2327 ml.Wait();
2328 } 2328 }
2329 } 2329 }
2330 2330
2331 2331
2332 Monitor* Isolate::threads_lock() const {
2333 return thread_registry_->threads_lock();
2334 }
2335
2336
2337 Thread* Isolate::ScheduleThread(bool is_mutator, bool bypass_safepoint) {
2338 // Schedule the thread into the isolate by associating
2339 // a 'Thread' structure with it (this is done while we are holding
2340 // the thread registry lock).
2341 Thread* thread = NULL;
2342 OSThread* os_thread = OSThread::Current();
2343 if (os_thread != NULL) {
2344 MonitorLocker ml(threads_lock());
2345
2346 // If a safepoint operation is in progress wait for it
2347 // to finish before scheduling this thread in.
2348 while (!bypass_safepoint && safepoint_handler()->safepoint_in_progress()) {
2349 ml.Wait();
2350 }
2351
2352 // Now get a free Thread structure.
2353 thread = thread_registry()->GetFreeThreadLocked(this, is_mutator);
2354 ASSERT(thread != NULL);
2355
2356 // Set up other values and set the TLS value.
2357 thread->isolate_ = this;
2358 ASSERT(heap() != NULL);
2359 thread->heap_ = heap();
2360 thread->set_os_thread(os_thread);
2361 ASSERT(thread->execution_state() == Thread::kThreadInVM);
2362 thread->set_safepoint_state(0);
2363 thread->set_vm_tag(VMTag::kVMTagId);
2364 os_thread->set_thread(thread);
2365 if (is_mutator) {
2366 mutator_thread_ = thread;
2367 }
2368 Thread::SetCurrent(thread);
2369 os_thread->EnableThreadInterrupts();
2370 }
2371 return thread;
2372 }
2373
2374
2375 void Isolate::UnscheduleThread(Thread* thread,
2376 bool is_mutator,
2377 bool bypass_safepoint) {
2378 // Disassociate the 'Thread' structure and unschedule the thread
2379 // from this isolate.
2380 MonitorLocker ml(threads_lock());
2381 if (!bypass_safepoint) {
2382 // Ensure that the thread reports itself as being at a safepoint.
2383 thread->EnterSafepoint();
2384 }
2385 OSThread* os_thread = thread->os_thread();
2386 ASSERT(os_thread != NULL);
2387 os_thread->DisableThreadInterrupts();
2388 os_thread->set_thread(NULL);
2389 OSThread::SetCurrent(os_thread);
2390 if (is_mutator) {
2391 mutator_thread_ = NULL;
2392 }
2393 thread->isolate_ = NULL;
2394 thread->heap_ = NULL;
2395 thread->set_os_thread(NULL);
2396 thread->set_execution_state(Thread::kThreadInVM);
2397 thread->set_safepoint_state(0);
2398 // Return thread structure.
2399 thread_registry()->ReturnThreadLocked(is_mutator, thread);
2400 }
2401
2402
2332 static RawInstance* DeserializeObject(Thread* thread, 2403 static RawInstance* DeserializeObject(Thread* thread,
2333 uint8_t* obj_data, 2404 uint8_t* obj_data,
2334 intptr_t obj_len) { 2405 intptr_t obj_len) {
2335 if (obj_data == NULL) { 2406 if (obj_data == NULL) {
2336 return Instance::null(); 2407 return Instance::null();
2337 } 2408 }
2338 MessageSnapshotReader reader(obj_data, obj_len, thread); 2409 MessageSnapshotReader reader(obj_data, obj_len, thread);
2339 Zone* zone = thread->zone(); 2410 Zone* zone = thread->zone();
2340 const Object& obj = Object::Handle(zone, reader.ReadObject()); 2411 const Object& obj = Object::Handle(zone, reader.ReadObject());
2341 ASSERT(!obj.IsError()); 2412 ASSERT(!obj.IsError());
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
2557 void IsolateSpawnState::DecrementSpawnCount() { 2628 void IsolateSpawnState::DecrementSpawnCount() {
2558 ASSERT(spawn_count_monitor_ != NULL); 2629 ASSERT(spawn_count_monitor_ != NULL);
2559 ASSERT(spawn_count_ != NULL); 2630 ASSERT(spawn_count_ != NULL);
2560 MonitorLocker ml(spawn_count_monitor_); 2631 MonitorLocker ml(spawn_count_monitor_);
2561 ASSERT(*spawn_count_ > 0); 2632 ASSERT(*spawn_count_ > 0);
2562 *spawn_count_ = *spawn_count_ - 1; 2633 *spawn_count_ = *spawn_count_ - 1;
2563 ml.Notify(); 2634 ml.Notify();
2564 } 2635 }
2565 2636
2566 } // namespace dart 2637 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698