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

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: fix-typo Created 4 years, 10 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
« no previous file with comments | « runtime/vm/isolate.h ('k') | runtime/vm/lockers.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 697 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 Isolate::Isolate(const Dart_IsolateFlags& api_flags) 740 Isolate::Isolate(const Dart_IsolateFlags& api_flags)
740 : stack_limit_(0), 741 : stack_limit_(0),
741 store_buffer_(new StoreBuffer()), 742 store_buffer_(new StoreBuffer()),
742 heap_(NULL), 743 heap_(NULL),
743 user_tag_(0), 744 user_tag_(0),
744 current_tag_(UserTag::null()), 745 current_tag_(UserTag::null()),
745 default_tag_(UserTag::null()), 746 default_tag_(UserTag::null()),
746 class_table_(), 747 class_table_(),
747 single_step_(false), 748 single_step_(false),
748 thread_registry_(new ThreadRegistry()), 749 thread_registry_(new ThreadRegistry()),
750 safepoint_handler_(new SafepointHandler(this)),
749 message_notify_callback_(NULL), 751 message_notify_callback_(NULL),
750 name_(NULL), 752 name_(NULL),
751 debugger_name_(NULL), 753 debugger_name_(NULL),
752 start_time_(OS::GetCurrentTimeMicros()), 754 start_time_(OS::GetCurrentTimeMicros()),
753 main_port_(0), 755 main_port_(0),
754 origin_id_(0), 756 origin_id_(0),
755 pause_capability_(0), 757 pause_capability_(0),
756 terminate_capability_(0), 758 terminate_capability_(0),
757 errors_fatal_(true), 759 errors_fatal_(true),
758 object_store_(NULL), 760 object_store_(NULL),
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 delete object_id_ring_; 834 delete object_id_ring_;
833 object_id_ring_ = NULL; 835 object_id_ring_ = NULL;
834 delete pause_loop_monitor_; 836 delete pause_loop_monitor_;
835 pause_loop_monitor_ = NULL; 837 pause_loop_monitor_ = NULL;
836 ASSERT(spawn_count_ == 0); 838 ASSERT(spawn_count_ == 0);
837 delete spawn_count_monitor_; 839 delete spawn_count_monitor_;
838 if (compiler_stats_ != NULL) { 840 if (compiler_stats_ != NULL) {
839 delete compiler_stats_; 841 delete compiler_stats_;
840 compiler_stats_ = NULL; 842 compiler_stats_ = NULL;
841 } 843 }
844 delete safepoint_handler_;
842 delete thread_registry_; 845 delete thread_registry_;
843 } 846 }
844 847
845 848
846 #if defined(DEBUG)
847 bool Isolate::IsIsolateOf(Thread* thread) {
848 return this == thread->isolate();
849 }
850 #endif // DEBUG
851
852
853 void Isolate::InitOnce() { 849 void Isolate::InitOnce() {
854 create_callback_ = NULL; 850 create_callback_ = NULL;
855 isolates_list_monitor_ = new Monitor(); 851 isolates_list_monitor_ = new Monitor();
856 ASSERT(isolates_list_monitor_ != NULL); 852 ASSERT(isolates_list_monitor_ != NULL);
857 EnableIsolateCreation(); 853 EnableIsolateCreation();
858 } 854 }
859 855
860 856
861 Isolate* Isolate::Init(const char* name_prefix, 857 Isolate* Isolate::Init(const char* name_prefix,
862 const Dart_IsolateFlags& api_flags, 858 const Dart_IsolateFlags& api_flags,
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after
1450 } 1446 }
1451 uword interrupt_bits = stack_limit_ & kInterruptsMask; 1447 uword interrupt_bits = stack_limit_ & kInterruptsMask;
1452 stack_limit_ = saved_stack_limit_; 1448 stack_limit_ = saved_stack_limit_;
1453 return interrupt_bits; 1449 return interrupt_bits;
1454 } 1450 }
1455 1451
1456 1452
1457 RawError* Isolate::HandleInterrupts() { 1453 RawError* Isolate::HandleInterrupts() {
1458 uword interrupt_bits = GetAndClearInterrupts(); 1454 uword interrupt_bits = GetAndClearInterrupts();
1459 if ((interrupt_bits & kVMInterrupt) != 0) { 1455 if ((interrupt_bits & kVMInterrupt) != 0) {
1460 thread_registry()->CheckSafepoint();
1461 if (store_buffer()->Overflowed()) { 1456 if (store_buffer()->Overflowed()) {
1462 if (FLAG_verbose_gc) { 1457 if (FLAG_verbose_gc) {
1463 OS::PrintErr("Scavenge scheduled by store buffer overflow.\n"); 1458 OS::PrintErr("Scavenge scheduled by store buffer overflow.\n");
1464 } 1459 }
1465 heap()->CollectGarbage(Heap::kNew); 1460 heap()->CollectGarbage(Heap::kNew);
1466 } 1461 }
1467 } 1462 }
1468 if ((interrupt_bits & kMessageInterrupt) != 0) { 1463 if ((interrupt_bits & kMessageInterrupt) != 0) {
1469 MessageHandler::MessageStatus status = 1464 MessageHandler::MessageStatus status =
1470 message_handler()->HandleOOBMessages(); 1465 message_handler()->HandleOOBMessages();
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1759 reinterpret_cast<RawObject**>(&registered_service_extension_handlers_)); 1754 reinterpret_cast<RawObject**>(&registered_service_extension_handlers_));
1760 1755
1761 // Visit objects in the debugger. 1756 // Visit objects in the debugger.
1762 debugger()->VisitObjectPointers(visitor); 1757 debugger()->VisitObjectPointers(visitor);
1763 1758
1764 // Visit objects that are being used for deoptimization. 1759 // Visit objects that are being used for deoptimization.
1765 if (deopt_context() != NULL) { 1760 if (deopt_context() != NULL) {
1766 deopt_context()->VisitObjectPointers(visitor); 1761 deopt_context()->VisitObjectPointers(visitor);
1767 } 1762 }
1768 1763
1769 // Visit objects in thread registry (e.g., Dart stack, handles in zones). 1764 // Visit objects in all threads (e.g., Dart stack, handles in zones).
1770 thread_registry()->VisitObjectPointers(visitor, validate_frames); 1765 thread_registry()->VisitObjectPointers(visitor, validate_frames);
1771 } 1766 }
1772 1767
1773 1768
1774 void Isolate::VisitWeakPersistentHandles(HandleVisitor* visitor) { 1769 void Isolate::VisitWeakPersistentHandles(HandleVisitor* visitor) {
1775 if (api_state() != NULL) { 1770 if (api_state() != NULL) {
1776 api_state()->VisitWeakHandles(visitor); 1771 api_state()->VisitWeakHandles(visitor);
1777 } 1772 }
1778 } 1773 }
1779 1774
1780 1775
1776 void Isolate::PrepareForGC() {
1777 thread_registry()->PrepareForGC();
1778 }
1779
1780
1781 static const char* ExceptionPauseInfoToServiceEnum(Dart_ExceptionPauseInfo pi) { 1781 static const char* ExceptionPauseInfoToServiceEnum(Dart_ExceptionPauseInfo pi) {
1782 switch (pi) { 1782 switch (pi) {
1783 case kPauseOnAllExceptions: 1783 case kPauseOnAllExceptions:
1784 return "All"; 1784 return "All";
1785 case kNoPauseOnExceptions: 1785 case kNoPauseOnExceptions:
1786 return "None"; 1786 return "None";
1787 case kPauseOnUnhandledExceptions: 1787 case kPauseOnUnhandledExceptions:
1788 return "Unhandled"; 1788 return "Unhandled";
1789 default: 1789 default:
1790 UNIMPLEMENTED(); 1790 UNIMPLEMENTED();
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after
2328 2328
2329 2329
2330 void Isolate::WaitForOutstandingSpawns() { 2330 void Isolate::WaitForOutstandingSpawns() {
2331 MonitorLocker ml(spawn_count_monitor_); 2331 MonitorLocker ml(spawn_count_monitor_);
2332 while (spawn_count_ > 0) { 2332 while (spawn_count_ > 0) {
2333 ml.Wait(); 2333 ml.Wait();
2334 } 2334 }
2335 } 2335 }
2336 2336
2337 2337
2338 Monitor* Isolate::threads_lock() const {
2339 return thread_registry_->threads_lock();
2340 }
2341
2342
2343 Thread* Isolate::ScheduleThread(bool is_mutator, bool bypass_safepoint) {
2344 // Schedule the thread into the isolate by associating
2345 // a 'Thread' structure with it (this is done while we are holding
2346 // the thread registry lock).
2347 Thread* thread = NULL;
2348 OSThread* os_thread = OSThread::Current();
2349 if (os_thread != NULL) {
2350 MonitorLocker ml(threads_lock());
2351
2352 // If a safepoint operation is in progress wait for it
2353 // to finish before scheduling this thread in.
2354 while (!bypass_safepoint && safepoint_handler()->safepoint_in_progress()) {
2355 ml.Wait();
2356 }
2357
2358 // Now get a free Thread structure.
2359 thread = thread_registry()->GetFreeThreadLocked(this, is_mutator);
2360 ASSERT(thread != NULL);
2361
2362 // Set up other values and set the TLS value.
2363 thread->isolate_ = this;
2364 ASSERT(heap() != NULL);
2365 thread->heap_ = heap();
2366 thread->set_os_thread(os_thread);
2367 ASSERT(thread->execution_state() == Thread::kThreadInVM);
2368 thread->set_safepoint_state(0);
2369 thread->set_vm_tag(VMTag::kVMTagId);
2370 os_thread->set_thread(thread);
2371 if (is_mutator) {
2372 mutator_thread_ = thread;
2373 }
2374 Thread::SetCurrent(thread);
2375 os_thread->EnableThreadInterrupts();
2376 }
2377 return thread;
2378 }
2379
2380
2381 void Isolate::UnscheduleThread(Thread* thread,
2382 bool is_mutator,
2383 bool bypass_safepoint) {
2384 // Disassociate the 'Thread' structure and unschedule the thread
2385 // from this isolate.
2386 MonitorLocker ml(threads_lock());
2387 if (!bypass_safepoint) {
2388 // Ensure that the thread reports itself as being at a safepoint.
2389 thread->EnterSafepoint();
2390 }
2391 OSThread* os_thread = thread->os_thread();
2392 ASSERT(os_thread != NULL);
2393 os_thread->DisableThreadInterrupts();
2394 os_thread->set_thread(NULL);
2395 OSThread::SetCurrent(os_thread);
2396 if (is_mutator) {
2397 mutator_thread_ = NULL;
2398 }
2399 thread->isolate_ = NULL;
2400 thread->heap_ = NULL;
2401 thread->set_os_thread(NULL);
2402 thread->set_execution_state(Thread::kThreadInVM);
2403 thread->set_safepoint_state(0);
2404 // Return thread structure.
2405 thread_registry()->ReturnThreadLocked(is_mutator, thread);
2406 }
2407
2408
2338 static RawInstance* DeserializeObject(Thread* thread, 2409 static RawInstance* DeserializeObject(Thread* thread,
2339 uint8_t* obj_data, 2410 uint8_t* obj_data,
2340 intptr_t obj_len) { 2411 intptr_t obj_len) {
2341 if (obj_data == NULL) { 2412 if (obj_data == NULL) {
2342 return Instance::null(); 2413 return Instance::null();
2343 } 2414 }
2344 MessageSnapshotReader reader(obj_data, obj_len, thread); 2415 MessageSnapshotReader reader(obj_data, obj_len, thread);
2345 Zone* zone = thread->zone(); 2416 Zone* zone = thread->zone();
2346 const Object& obj = Object::Handle(zone, reader.ReadObject()); 2417 const Object& obj = Object::Handle(zone, reader.ReadObject());
2347 ASSERT(!obj.IsError()); 2418 ASSERT(!obj.IsError());
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
2559 void IsolateSpawnState::DecrementSpawnCount() { 2630 void IsolateSpawnState::DecrementSpawnCount() {
2560 ASSERT(spawn_count_monitor_ != NULL); 2631 ASSERT(spawn_count_monitor_ != NULL);
2561 ASSERT(spawn_count_ != NULL); 2632 ASSERT(spawn_count_ != NULL);
2562 MonitorLocker ml(spawn_count_monitor_); 2633 MonitorLocker ml(spawn_count_monitor_);
2563 ASSERT(*spawn_count_ > 0); 2634 ASSERT(*spawn_count_ > 0);
2564 *spawn_count_ = *spawn_count_ - 1; 2635 *spawn_count_ = *spawn_count_ - 1;
2565 ml.Notify(); 2636 ml.Notify();
2566 } 2637 }
2567 2638
2568 } // namespace dart 2639 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/isolate.h ('k') | runtime/vm/lockers.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698