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

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

Issue 1748953003: - Add assertions in MutexLocker/MonitorLocker to ensure that the code enclosed (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: code-review-comments Created 4 years, 9 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 804 matching lines...) Expand 10 before | Expand all | Expand 10 after
815 pending_service_extension_calls_(GrowableObjectArray::null()), 815 pending_service_extension_calls_(GrowableObjectArray::null()),
816 registered_service_extension_handlers_(GrowableObjectArray::null()), 816 registered_service_extension_handlers_(GrowableObjectArray::null()),
817 metrics_list_head_(NULL), 817 metrics_list_head_(NULL),
818 compilation_allowed_(true), 818 compilation_allowed_(true),
819 all_classes_finalized_(false), 819 all_classes_finalized_(false),
820 next_(NULL), 820 next_(NULL),
821 pause_loop_monitor_(NULL), 821 pause_loop_monitor_(NULL),
822 cha_invalidation_gen_(kInvalidGen), 822 cha_invalidation_gen_(kInvalidGen),
823 field_invalidation_gen_(kInvalidGen), 823 field_invalidation_gen_(kInvalidGen),
824 prefix_invalidation_gen_(kInvalidGen), 824 prefix_invalidation_gen_(kInvalidGen),
825 boxed_field_list_monitor_(new Monitor()), 825 boxed_field_list_mutex_(new Mutex()),
826 boxed_field_list_(GrowableObjectArray::null()), 826 boxed_field_list_(GrowableObjectArray::null()),
827 spawn_count_monitor_(new Monitor()), 827 spawn_count_monitor_(new Monitor()),
828 spawn_count_(0) { 828 spawn_count_(0) {
829 NOT_IN_PRODUCT(FlagsCopyFrom(api_flags)); 829 NOT_IN_PRODUCT(FlagsCopyFrom(api_flags));
830 // TODO(asiva): A Thread is not available here, need to figure out 830 // TODO(asiva): A Thread is not available here, need to figure out
831 // how the vm_tag (kEmbedderTagId) can be set, these tags need to 831 // how the vm_tag (kEmbedderTagId) can be set, these tags need to
832 // move to the OSThread structure. 832 // move to the OSThread structure.
833 set_user_tag(UserTags::kDefaultUserTag); 833 set_user_tag(UserTags::kDefaultUserTag);
834 } 834 }
835 835
(...skipping 20 matching lines...) Expand all
856 delete message_handler_; 856 delete message_handler_;
857 message_handler_ = NULL; // Fail fast if we send messages to a dead isolate. 857 message_handler_ = NULL; // Fail fast if we send messages to a dead isolate.
858 ASSERT(deopt_context_ == NULL); // No deopt in progress when isolate deleted. 858 ASSERT(deopt_context_ == NULL); // No deopt in progress when isolate deleted.
859 delete spawn_state_; 859 delete spawn_state_;
860 if (FLAG_support_service) { 860 if (FLAG_support_service) {
861 delete object_id_ring_; 861 delete object_id_ring_;
862 } 862 }
863 object_id_ring_ = NULL; 863 object_id_ring_ = NULL;
864 delete pause_loop_monitor_; 864 delete pause_loop_monitor_;
865 pause_loop_monitor_ = NULL; 865 pause_loop_monitor_ = NULL;
866 delete boxed_field_list_monitor_; 866 delete boxed_field_list_mutex_;
867 boxed_field_list_monitor_ = NULL; 867 boxed_field_list_mutex_ = NULL;
868 ASSERT(spawn_count_ == 0); 868 ASSERT(spawn_count_ == 0);
869 delete spawn_count_monitor_; 869 delete spawn_count_monitor_;
870 if (compiler_stats_ != NULL) { 870 if (compiler_stats_ != NULL) {
871 delete compiler_stats_; 871 delete compiler_stats_;
872 compiler_stats_ = NULL; 872 compiler_stats_ = NULL;
873 } 873 }
874 delete safepoint_handler_; 874 delete safepoint_handler_;
875 delete thread_registry_; 875 delete thread_registry_;
876 } 876 }
877 877
(...skipping 984 matching lines...) Expand 10 before | Expand all | Expand 10 after
1862 visitor->VisitPointer( 1862 visitor->VisitPointer(
1863 reinterpret_cast<RawObject**>(&pending_service_extension_calls_)); 1863 reinterpret_cast<RawObject**>(&pending_service_extension_calls_));
1864 1864
1865 // Visit the registered service extension handlers. 1865 // Visit the registered service extension handlers.
1866 visitor->VisitPointer( 1866 visitor->VisitPointer(
1867 reinterpret_cast<RawObject**>(&registered_service_extension_handlers_)); 1867 reinterpret_cast<RawObject**>(&registered_service_extension_handlers_));
1868 1868
1869 // Visit the boxed_field_list. 1869 // Visit the boxed_field_list.
1870 // 'boxed_field_list_' access via mutator and background compilation threads 1870 // 'boxed_field_list_' access via mutator and background compilation threads
1871 // is guarded with a monitor. This means that we can visit it only 1871 // is guarded with a monitor. This means that we can visit it only
1872 // when at safepoint or the boxed_field_list_monitor_ lock has been taken. 1872 // when at safepoint or the boxed_field_list_mutex_ lock has been taken.
1873 visitor->VisitPointer(reinterpret_cast<RawObject**>(&boxed_field_list_)); 1873 visitor->VisitPointer(reinterpret_cast<RawObject**>(&boxed_field_list_));
1874 1874
1875 // Visit objects in the debugger. 1875 // Visit objects in the debugger.
1876 if (FLAG_support_debugger) { 1876 if (FLAG_support_debugger) {
1877 debugger()->VisitObjectPointers(visitor); 1877 debugger()->VisitObjectPointers(visitor);
1878 } 1878 }
1879 1879
1880 // Visit objects that are being used for deoptimization. 1880 // Visit objects that are being used for deoptimization.
1881 if (deopt_context() != NULL) { 1881 if (deopt_context() != NULL) {
1882 deopt_context()->VisitObjectPointers(visitor); 1882 deopt_context()->VisitObjectPointers(visitor);
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
2076 2076
2077 2077
2078 void Isolate::set_registered_service_extension_handlers( 2078 void Isolate::set_registered_service_extension_handlers(
2079 const GrowableObjectArray& value) { 2079 const GrowableObjectArray& value) {
2080 registered_service_extension_handlers_ = value.raw(); 2080 registered_service_extension_handlers_ = value.raw();
2081 } 2081 }
2082 2082
2083 2083
2084 void Isolate::AddDeoptimizingBoxedField(const Field& field) { 2084 void Isolate::AddDeoptimizingBoxedField(const Field& field) {
2085 ASSERT(field.IsOriginal()); 2085 ASSERT(field.IsOriginal());
2086 MonitorLocker ml(boxed_field_list_monitor_); 2086 // The enclosed code allocates objects and can potentially trigger a GC,
2087 // ensure that we account for safepoints when grabbing the lock.
2088 SafepointMutexLocker ml(boxed_field_list_mutex_);
2087 if (boxed_field_list_ == GrowableObjectArray::null()) { 2089 if (boxed_field_list_ == GrowableObjectArray::null()) {
2088 boxed_field_list_ = GrowableObjectArray::New(Heap::kOld); 2090 boxed_field_list_ = GrowableObjectArray::New(Heap::kOld);
2089 } 2091 }
2090 const GrowableObjectArray& array = 2092 const GrowableObjectArray& array =
2091 GrowableObjectArray::Handle(boxed_field_list_); 2093 GrowableObjectArray::Handle(boxed_field_list_);
2092 array.Add(field, Heap::kOld); 2094 array.Add(field, Heap::kOld);
2093 } 2095 }
2094 2096
2095 2097
2096 RawField* Isolate::GetDeoptimizingBoxedField() { 2098 RawField* Isolate::GetDeoptimizingBoxedField() {
2097 MonitorLocker ml(boxed_field_list_monitor_); 2099 MutexLocker ml(boxed_field_list_mutex_);
2098 if (boxed_field_list_ == GrowableObjectArray::null()) { 2100 if (boxed_field_list_ == GrowableObjectArray::null()) {
2099 return Field::null(); 2101 return Field::null();
2100 } 2102 }
2101 const GrowableObjectArray& array = 2103 const GrowableObjectArray& array =
2102 GrowableObjectArray::Handle(boxed_field_list_); 2104 GrowableObjectArray::Handle(boxed_field_list_);
2103 if (array.Length() == 0) { 2105 if (array.Length() == 0) {
2104 return Field::null(); 2106 return Field::null();
2105 } 2107 }
2106 return Field::RawCast(array.RemoveLast()); 2108 return Field::RawCast(array.RemoveLast());
2107 } 2109 }
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
2310 2312
2311 Dart_MessageNotifyCallback saved_notify_callback = 2313 Dart_MessageNotifyCallback saved_notify_callback =
2312 message_notify_callback(); 2314 message_notify_callback();
2313 set_message_notify_callback(Isolate::WakePauseEventHandler); 2315 set_message_notify_callback(Isolate::WakePauseEventHandler);
2314 2316
2315 bool resume = false; 2317 bool resume = false;
2316 while (true) { 2318 while (true) {
2317 // Handle all available vm service messages, up to a resume 2319 // Handle all available vm service messages, up to a resume
2318 // request. 2320 // request.
2319 while (!resume && Dart_HasServiceMessages()) { 2321 while (!resume && Dart_HasServiceMessages()) {
2320 pause_loop_monitor_->Exit(); 2322 ml.Exit();
2321 resume = Dart_HandleServiceMessages(); 2323 resume = Dart_HandleServiceMessages();
2322 pause_loop_monitor_->Enter(); 2324 ml.Enter();
2323 } 2325 }
2324 if (resume) { 2326 if (resume) {
2325 break; 2327 break;
2326 } 2328 }
2327 2329
2328 // Wait for more service messages. 2330 // Wait for more service messages.
2329 Monitor::WaitResult res = ml.Wait(); 2331 Monitor::WaitResult res = ml.Wait();
2330 ASSERT(res == Monitor::kNotified); 2332 ASSERT(res == Monitor::kNotified);
2331 } 2333 }
2332 set_message_notify_callback(saved_notify_callback); 2334 set_message_notify_callback(saved_notify_callback);
2333 Dart_ExitScope(); 2335 Dart_ExitScope();
2334 } 2336 }
2335 2337
2336 2338
2337 void Isolate::VisitIsolates(IsolateVisitor* visitor) { 2339 void Isolate::VisitIsolates(IsolateVisitor* visitor) {
2338 if (visitor == NULL) { 2340 if (visitor == NULL) {
2339 return; 2341 return;
2340 } 2342 }
2341 MonitorLocker ml(isolates_list_monitor_); 2343 // The visitor could potentially run code that could safepoint so use
2344 // SafepointMonitorLocker to ensure the lock has safepoint checks.
2345 SafepointMonitorLocker ml(isolates_list_monitor_);
2342 Isolate* current = isolates_list_head_; 2346 Isolate* current = isolates_list_head_;
2343 while (current) { 2347 while (current) {
2344 visitor->VisitIsolate(current); 2348 visitor->VisitIsolate(current);
2345 current = current->next_; 2349 current = current->next_;
2346 } 2350 }
2347 } 2351 }
2348 2352
2349 2353
2350 intptr_t Isolate::IsolateListLength() { 2354 intptr_t Isolate::IsolateListLength() {
2351 MonitorLocker ml(isolates_list_monitor_); 2355 MonitorLocker ml(isolates_list_monitor_);
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
2521 } 2525 }
2522 2526
2523 2527
2524 Thread* Isolate::ScheduleThread(bool is_mutator, bool bypass_safepoint) { 2528 Thread* Isolate::ScheduleThread(bool is_mutator, bool bypass_safepoint) {
2525 // Schedule the thread into the isolate by associating 2529 // Schedule the thread into the isolate by associating
2526 // a 'Thread' structure with it (this is done while we are holding 2530 // a 'Thread' structure with it (this is done while we are holding
2527 // the thread registry lock). 2531 // the thread registry lock).
2528 Thread* thread = NULL; 2532 Thread* thread = NULL;
2529 OSThread* os_thread = OSThread::Current(); 2533 OSThread* os_thread = OSThread::Current();
2530 if (os_thread != NULL) { 2534 if (os_thread != NULL) {
2531 MonitorLocker ml(threads_lock()); 2535 // We are about to associate the thread with an isolate and it would
2536 // not be possible to correctly track no_safepoint_scope_depth for the
2537 // thread in the constructor/destructor of MonitorLocker,
2538 // so we create a MonitorLocker object which does not do any
2539 // no_safepoint_scope_depth increments/decrements.
2540 MonitorLocker ml(threads_lock(), false);
2532 2541
2533 // If a safepoint operation is in progress wait for it 2542 // If a safepoint operation is in progress wait for it
2534 // to finish before scheduling this thread in. 2543 // to finish before scheduling this thread in.
2535 while (!bypass_safepoint && safepoint_handler()->safepoint_in_progress()) { 2544 while (!bypass_safepoint && safepoint_handler()->safepoint_in_progress()) {
2536 ml.Wait(); 2545 ml.Wait();
2537 } 2546 }
2538 2547
2539 // Now get a free Thread structure. 2548 // Now get a free Thread structure.
2540 thread = thread_registry()->GetFreeThreadLocked(this, is_mutator); 2549 thread = thread_registry()->GetFreeThreadLocked(this, is_mutator);
2541 ASSERT(thread != NULL); 2550 ASSERT(thread != NULL);
2542 2551
2543 // Set up other values and set the TLS value. 2552 // Set up other values and set the TLS value.
2544 thread->isolate_ = this; 2553 thread->isolate_ = this;
2545 ASSERT(heap() != NULL); 2554 ASSERT(heap() != NULL);
2546 thread->heap_ = heap(); 2555 thread->heap_ = heap();
2547 thread->set_os_thread(os_thread); 2556 thread->set_os_thread(os_thread);
2548 ASSERT(thread->execution_state() == Thread::kThreadInVM); 2557 ASSERT(thread->execution_state() == Thread::kThreadInVM);
2549 thread->set_safepoint_state(0); 2558 thread->set_safepoint_state(0);
2550 thread->set_vm_tag(VMTag::kVMTagId); 2559 thread->set_vm_tag(VMTag::kVMTagId);
2560 ASSERT(thread->no_safepoint_scope_depth() == 0);
2551 os_thread->set_thread(thread); 2561 os_thread->set_thread(thread);
2552 if (is_mutator) { 2562 if (is_mutator) {
2553 mutator_thread_ = thread; 2563 mutator_thread_ = thread;
2554 } 2564 }
2555 Thread::SetCurrent(thread); 2565 Thread::SetCurrent(thread);
2556 os_thread->EnableThreadInterrupts(); 2566 os_thread->EnableThreadInterrupts();
2557 } 2567 }
2558 return thread; 2568 return thread;
2559 } 2569 }
2560 2570
2561 2571
2562 void Isolate::UnscheduleThread(Thread* thread, 2572 void Isolate::UnscheduleThread(Thread* thread,
2563 bool is_mutator, 2573 bool is_mutator,
2564 bool bypass_safepoint) { 2574 bool bypass_safepoint) {
2565 // Disassociate the 'Thread' structure and unschedule the thread 2575 // Disassociate the 'Thread' structure and unschedule the thread
2566 // from this isolate. 2576 // from this isolate.
2567 MonitorLocker ml(threads_lock()); 2577 // We are disassociating the thread from an isolate and it would
2578 // not be possible to correctly track no_safepoint_scope_depth for the
2579 // thread in the constructor/destructor of MonitorLocker,
2580 // so we create a MonitorLocker object which does not do any
2581 // no_safepoint_scope_depth increments/decrements.
2582 MonitorLocker ml(threads_lock(), false);
2568 if (!bypass_safepoint) { 2583 if (!bypass_safepoint) {
2569 // Ensure that the thread reports itself as being at a safepoint. 2584 // Ensure that the thread reports itself as being at a safepoint.
2570 thread->EnterSafepoint(); 2585 thread->EnterSafepoint();
2571 } 2586 }
2572 OSThread* os_thread = thread->os_thread(); 2587 OSThread* os_thread = thread->os_thread();
2573 ASSERT(os_thread != NULL); 2588 ASSERT(os_thread != NULL);
2574 os_thread->DisableThreadInterrupts(); 2589 os_thread->DisableThreadInterrupts();
2575 os_thread->set_thread(NULL); 2590 os_thread->set_thread(NULL);
2576 OSThread::SetCurrent(os_thread); 2591 OSThread::SetCurrent(os_thread);
2577 if (is_mutator) { 2592 if (is_mutator) {
2578 mutator_thread_ = NULL; 2593 mutator_thread_ = NULL;
2579 } 2594 }
2580 thread->isolate_ = NULL; 2595 thread->isolate_ = NULL;
2581 thread->heap_ = NULL; 2596 thread->heap_ = NULL;
2582 thread->set_os_thread(NULL); 2597 thread->set_os_thread(NULL);
2583 thread->set_execution_state(Thread::kThreadInVM); 2598 thread->set_execution_state(Thread::kThreadInVM);
2584 thread->set_safepoint_state(0); 2599 thread->set_safepoint_state(0);
2600 ASSERT(thread->no_safepoint_scope_depth() == 0);
2585 // Return thread structure. 2601 // Return thread structure.
2586 thread_registry()->ReturnThreadLocked(is_mutator, thread); 2602 thread_registry()->ReturnThreadLocked(is_mutator, thread);
2587 } 2603 }
2588 2604
2589 2605
2590 static RawInstance* DeserializeObject(Thread* thread, 2606 static RawInstance* DeserializeObject(Thread* thread,
2591 uint8_t* obj_data, 2607 uint8_t* obj_data,
2592 intptr_t obj_len) { 2608 intptr_t obj_len) {
2593 if (obj_data == NULL) { 2609 if (obj_data == NULL) {
2594 return Instance::null(); 2610 return Instance::null();
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
2810 void IsolateSpawnState::DecrementSpawnCount() { 2826 void IsolateSpawnState::DecrementSpawnCount() {
2811 ASSERT(spawn_count_monitor_ != NULL); 2827 ASSERT(spawn_count_monitor_ != NULL);
2812 ASSERT(spawn_count_ != NULL); 2828 ASSERT(spawn_count_ != NULL);
2813 MonitorLocker ml(spawn_count_monitor_); 2829 MonitorLocker ml(spawn_count_monitor_);
2814 ASSERT(*spawn_count_ > 0); 2830 ASSERT(*spawn_count_ > 0);
2815 *spawn_count_ = *spawn_count_ - 1; 2831 *spawn_count_ = *spawn_count_ - 1;
2816 ml.Notify(); 2832 ml.Notify();
2817 } 2833 }
2818 2834
2819 } // namespace dart 2835 } // 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