| 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 |