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