| 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/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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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**>(®istered_service_extension_handlers_)); | 1867 reinterpret_cast<RawObject**>(®istered_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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |