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

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: self-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 690 matching lines...) Expand 10 before | Expand all | Expand 10 after
732 Isolate::Isolate(const Dart_IsolateFlags& api_flags) 733 Isolate::Isolate(const Dart_IsolateFlags& api_flags)
733 : stack_limit_(0), 734 : stack_limit_(0),
734 store_buffer_(new StoreBuffer()), 735 store_buffer_(new StoreBuffer()),
735 heap_(NULL), 736 heap_(NULL),
736 user_tag_(0), 737 user_tag_(0),
737 current_tag_(UserTag::null()), 738 current_tag_(UserTag::null()),
738 default_tag_(UserTag::null()), 739 default_tag_(UserTag::null()),
739 class_table_(), 740 class_table_(),
740 single_step_(false), 741 single_step_(false),
741 thread_registry_(new ThreadRegistry()), 742 thread_registry_(new ThreadRegistry()),
743 safepoint_handler_(new SafepointHandler(this)),
742 message_notify_callback_(NULL), 744 message_notify_callback_(NULL),
743 name_(NULL), 745 name_(NULL),
744 debugger_name_(NULL), 746 debugger_name_(NULL),
745 start_time_(OS::GetCurrentTimeMicros()), 747 start_time_(OS::GetCurrentTimeMicros()),
746 main_port_(0), 748 main_port_(0),
747 origin_id_(0), 749 origin_id_(0),
748 pause_capability_(0), 750 pause_capability_(0),
749 terminate_capability_(0), 751 terminate_capability_(0),
750 errors_fatal_(true), 752 errors_fatal_(true),
751 object_store_(NULL), 753 object_store_(NULL),
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
821 ASSERT(deopt_context_ == NULL); // No deopt in progress when isolate deleted. 823 ASSERT(deopt_context_ == NULL); // No deopt in progress when isolate deleted.
822 delete spawn_state_; 824 delete spawn_state_;
823 delete object_id_ring_; 825 delete object_id_ring_;
824 object_id_ring_ = NULL; 826 object_id_ring_ = NULL;
825 delete pause_loop_monitor_; 827 delete pause_loop_monitor_;
826 pause_loop_monitor_ = NULL; 828 pause_loop_monitor_ = NULL;
827 if (compiler_stats_ != NULL) { 829 if (compiler_stats_ != NULL) {
828 delete compiler_stats_; 830 delete compiler_stats_;
829 compiler_stats_ = NULL; 831 compiler_stats_ = NULL;
830 } 832 }
833 delete safepoint_handler_;
831 delete thread_registry_; 834 delete thread_registry_;
832 } 835 }
833 836
834 837
835 #if defined(DEBUG)
836 bool Isolate::IsIsolateOf(Thread* thread) {
837 return this == thread->isolate();
838 }
839 #endif // DEBUG
840
841
842 void Isolate::InitOnce() { 838 void Isolate::InitOnce() {
843 create_callback_ = NULL; 839 create_callback_ = NULL;
844 isolates_list_monitor_ = new Monitor(); 840 isolates_list_monitor_ = new Monitor();
845 ASSERT(isolates_list_monitor_ != NULL); 841 ASSERT(isolates_list_monitor_ != NULL);
846 EnableIsolateCreation(); 842 EnableIsolateCreation();
847 } 843 }
848 844
849 845
850 Isolate* Isolate::Init(const char* name_prefix, 846 Isolate* Isolate::Init(const char* name_prefix,
851 const Dart_IsolateFlags& api_flags, 847 const Dart_IsolateFlags& api_flags,
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after
1433 } 1429 }
1434 uword interrupt_bits = stack_limit_ & kInterruptsMask; 1430 uword interrupt_bits = stack_limit_ & kInterruptsMask;
1435 stack_limit_ = saved_stack_limit_; 1431 stack_limit_ = saved_stack_limit_;
1436 return interrupt_bits; 1432 return interrupt_bits;
1437 } 1433 }
1438 1434
1439 1435
1440 RawError* Isolate::HandleInterrupts() { 1436 RawError* Isolate::HandleInterrupts() {
1441 uword interrupt_bits = GetAndClearInterrupts(); 1437 uword interrupt_bits = GetAndClearInterrupts();
1442 if ((interrupt_bits & kVMInterrupt) != 0) { 1438 if ((interrupt_bits & kVMInterrupt) != 0) {
1443 thread_registry()->CheckSafepoint();
1444 if (store_buffer()->Overflowed()) { 1439 if (store_buffer()->Overflowed()) {
1445 if (FLAG_verbose_gc) { 1440 if (FLAG_verbose_gc) {
1446 OS::PrintErr("Scavenge scheduled by store buffer overflow.\n"); 1441 OS::PrintErr("Scavenge scheduled by store buffer overflow.\n");
1447 } 1442 }
1448 heap()->CollectGarbage(Heap::kNew); 1443 heap()->CollectGarbage(Heap::kNew);
1449 } 1444 }
1450 } 1445 }
1451 if ((interrupt_bits & kMessageInterrupt) != 0) { 1446 if ((interrupt_bits & kMessageInterrupt) != 0) {
1452 MessageHandler::MessageStatus status = 1447 MessageHandler::MessageStatus status =
1453 message_handler()->HandleOOBMessages(); 1448 message_handler()->HandleOOBMessages();
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1742 reinterpret_cast<RawObject**>(&registered_service_extension_handlers_)); 1737 reinterpret_cast<RawObject**>(&registered_service_extension_handlers_));
1743 1738
1744 // Visit objects in the debugger. 1739 // Visit objects in the debugger.
1745 debugger()->VisitObjectPointers(visitor); 1740 debugger()->VisitObjectPointers(visitor);
1746 1741
1747 // Visit objects that are being used for deoptimization. 1742 // Visit objects that are being used for deoptimization.
1748 if (deopt_context() != NULL) { 1743 if (deopt_context() != NULL) {
1749 deopt_context()->VisitObjectPointers(visitor); 1744 deopt_context()->VisitObjectPointers(visitor);
1750 } 1745 }
1751 1746
1752 // Visit objects in thread registry (e.g., Dart stack, handles in zones). 1747 // Visit objects in all threads (e.g., Dart stack, handles in zones).
1753 thread_registry()->VisitObjectPointers(visitor, validate_frames); 1748 thread_registry()->VisitObjectPointers(visitor, validate_frames);
1754 } 1749 }
1755 1750
1756 1751
1757 void Isolate::VisitWeakPersistentHandles(HandleVisitor* visitor) { 1752 void Isolate::VisitWeakPersistentHandles(HandleVisitor* visitor) {
1758 if (api_state() != NULL) { 1753 if (api_state() != NULL) {
1759 api_state()->VisitWeakHandles(visitor); 1754 api_state()->VisitWeakHandles(visitor);
1760 } 1755 }
1761 } 1756 }
1762 1757
1763 1758
1759 void Isolate::PrepareForGC() {
1760 thread_registry()->PrepareForGC();
1761 }
1762
1763
1764 static const char* ExceptionPauseInfoToServiceEnum(Dart_ExceptionPauseInfo pi) { 1764 static const char* ExceptionPauseInfoToServiceEnum(Dart_ExceptionPauseInfo pi) {
1765 switch (pi) { 1765 switch (pi) {
1766 case kPauseOnAllExceptions: 1766 case kPauseOnAllExceptions:
1767 return "All"; 1767 return "All";
1768 case kNoPauseOnExceptions: 1768 case kNoPauseOnExceptions:
1769 return "None"; 1769 return "None";
1770 case kPauseOnUnhandledExceptions: 1770 case kPauseOnUnhandledExceptions:
1771 return "Unhandled"; 1771 return "Unhandled";
1772 default: 1772 default:
1773 UNIMPLEMENTED(); 1773 UNIMPLEMENTED();
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after
2297 VisitIsolates(&visitor); 2297 VisitIsolates(&visitor);
2298 } 2298 }
2299 2299
2300 2300
2301 void Isolate::KillIfExists(Isolate* isolate, LibMsgId msg_id) { 2301 void Isolate::KillIfExists(Isolate* isolate, LibMsgId msg_id) {
2302 IsolateKillerVisitor visitor(isolate, msg_id); 2302 IsolateKillerVisitor visitor(isolate, msg_id);
2303 VisitIsolates(&visitor); 2303 VisitIsolates(&visitor);
2304 } 2304 }
2305 2305
2306 2306
2307 Monitor* Isolate::threads_lock() const {
2308 return thread_registry_->threads_lock();
2309 }
2310
2311
2312 Thread* Isolate::ScheduleThread(bool is_mutator, bool bypass_safepoint) {
2313 // Schedule the thread into the isolate by associating
2314 // a 'Thread' structure with it (this is done while we are holding
2315 // the thread registry lock).
2316 Thread* thread = NULL;
2317 OSThread* os_thread = OSThread::Current();
2318 if (os_thread != NULL) {
2319 MonitorLocker ml(threads_lock());
2320
2321 // If a safepoint operation is in progress wait for it
2322 // to finish before scheduling this thread in.
2323 while (!bypass_safepoint && safepoint_handler()->safepoint_in_progress()) {
2324 ml.Wait();
2325 }
2326
2327 // Now get a free Thread structure.
2328 thread = thread_registry()->GetFreeThreadLocked(this, is_mutator);
2329 ASSERT(thread != NULL);
2330
2331 // Set up other values and set the TLS value.
2332 thread->isolate_ = this;
2333 ASSERT(heap() != NULL);
2334 thread->heap_ = heap();
2335 thread->set_os_thread(os_thread);
2336 ASSERT(thread->execution_state() == Thread::kThreadInVM);
2337 thread->set_safepoint_state(0);
2338 thread->set_vm_tag(VMTag::kVMTagId);
2339 os_thread->set_thread(thread);
2340 if (is_mutator) {
2341 mutator_thread_ = thread;
2342 }
2343 Thread::SetCurrent(thread);
2344 os_thread->EnableThreadInterrupts();
2345 }
2346 return thread;
2347 }
2348
2349
2350 void Isolate::UnscheduleThread(Thread* thread,
2351 bool is_mutator,
2352 bool bypass_safepoint) {
2353 // Disassociate the 'Thread' structure and unschedule the thread
2354 // from this isolate.
2355 {
zra 2016/01/08 23:32:07 Extra { }
siva 2016/01/12 21:26:22 Fixed this code by removing the extra { }
2356 MonitorLocker ml(threads_lock());
2357 if (!bypass_safepoint) {
2358 // Ensure that the thread reports itself as being at a safepoint.
2359 thread->EnterSafepoint();
2360 }
2361 OSThread* os_thread = thread->os_thread();
2362 ASSERT(os_thread != NULL);
2363 os_thread->DisableThreadInterrupts();
2364 os_thread->set_thread(NULL);
2365 OSThread::SetCurrent(os_thread);
2366 if (is_mutator) {
2367 mutator_thread_ = NULL;
2368 }
2369 thread->isolate_ = NULL;
2370 thread->heap_ = NULL;
2371 thread->set_os_thread(NULL);
2372 thread->set_execution_state(Thread::kThreadInVM);
2373 thread->set_safepoint_state(0);
2374 // Return thread structure.
2375 thread_registry()->ReturnThreadLocked(is_mutator, thread);
2376 }
2377 }
2378
2379
2307 static RawInstance* DeserializeObject(Thread* thread, 2380 static RawInstance* DeserializeObject(Thread* thread,
2308 uint8_t* obj_data, 2381 uint8_t* obj_data,
2309 intptr_t obj_len) { 2382 intptr_t obj_len) {
2310 if (obj_data == NULL) { 2383 if (obj_data == NULL) {
2311 return Instance::null(); 2384 return Instance::null();
2312 } 2385 }
2313 MessageSnapshotReader reader(obj_data, obj_len, thread); 2386 MessageSnapshotReader reader(obj_data, obj_len, thread);
2314 Zone* zone = thread->zone(); 2387 Zone* zone = thread->zone();
2315 const Object& obj = Object::Handle(zone, reader.ReadObject()); 2388 const Object& obj = Object::Handle(zone, reader.ReadObject());
2316 ASSERT(!obj.IsError()); 2389 ASSERT(!obj.IsError());
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
2515 } 2588 }
2516 2589
2517 2590
2518 RawInstance* IsolateSpawnState::BuildMessage(Thread* thread) { 2591 RawInstance* IsolateSpawnState::BuildMessage(Thread* thread) {
2519 return DeserializeObject(thread, 2592 return DeserializeObject(thread,
2520 serialized_message_, serialized_message_len_); 2593 serialized_message_, serialized_message_len_);
2521 } 2594 }
2522 2595
2523 2596
2524 } // namespace dart 2597 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698