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 11 matching lines...) Expand all Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
1759 reinterpret_cast<RawObject**>(®istered_service_extension_handlers_)); | 1754 reinterpret_cast<RawObject**>(®istered_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 Loading... |
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 Loading... |
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 |
OLD | NEW |