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