| Index: runtime/vm/isolate.cc
|
| diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
|
| index a62ac0ea989415e03b76dcc5f658511fe4edd706..d31093839e371c9f3741dc71f7e7ac2db769326d 100644
|
| --- a/runtime/vm/isolate.cc
|
| +++ b/runtime/vm/isolate.cc
|
| @@ -29,6 +29,7 @@
|
| #include "vm/port.h"
|
| #include "vm/profiler.h"
|
| #include "vm/reusable_handles.h"
|
| +#include "vm/safepoint.h"
|
| #include "vm/service.h"
|
| #include "vm/service_event.h"
|
| #include "vm/service_isolate.h"
|
| @@ -746,6 +747,7 @@ Isolate::Isolate(const Dart_IsolateFlags& api_flags)
|
| class_table_(),
|
| single_step_(false),
|
| thread_registry_(new ThreadRegistry()),
|
| + safepoint_handler_(new SafepointHandler(this)),
|
| message_notify_callback_(NULL),
|
| name_(NULL),
|
| debugger_name_(NULL),
|
| @@ -839,17 +841,11 @@ Isolate::~Isolate() {
|
| delete compiler_stats_;
|
| compiler_stats_ = NULL;
|
| }
|
| + delete safepoint_handler_;
|
| delete thread_registry_;
|
| }
|
|
|
|
|
| -#if defined(DEBUG)
|
| -bool Isolate::IsIsolateOf(Thread* thread) {
|
| - return this == thread->isolate();
|
| -}
|
| -#endif // DEBUG
|
| -
|
| -
|
| void Isolate::InitOnce() {
|
| create_callback_ = NULL;
|
| isolates_list_monitor_ = new Monitor();
|
| @@ -1457,7 +1453,6 @@ uword Isolate::GetAndClearInterrupts() {
|
| RawError* Isolate::HandleInterrupts() {
|
| uword interrupt_bits = GetAndClearInterrupts();
|
| if ((interrupt_bits & kVMInterrupt) != 0) {
|
| - thread_registry()->CheckSafepoint();
|
| if (store_buffer()->Overflowed()) {
|
| if (FLAG_verbose_gc) {
|
| OS::PrintErr("Scavenge scheduled by store buffer overflow.\n");
|
| @@ -1766,7 +1761,7 @@ void Isolate::VisitObjectPointers(ObjectPointerVisitor* visitor,
|
| deopt_context()->VisitObjectPointers(visitor);
|
| }
|
|
|
| - // Visit objects in thread registry (e.g., Dart stack, handles in zones).
|
| + // Visit objects in all threads (e.g., Dart stack, handles in zones).
|
| thread_registry()->VisitObjectPointers(visitor, validate_frames);
|
| }
|
|
|
| @@ -1778,6 +1773,11 @@ void Isolate::VisitWeakPersistentHandles(HandleVisitor* visitor) {
|
| }
|
|
|
|
|
| +void Isolate::PrepareForGC() {
|
| + thread_registry()->PrepareForGC();
|
| +}
|
| +
|
| +
|
| static const char* ExceptionPauseInfoToServiceEnum(Dart_ExceptionPauseInfo pi) {
|
| switch (pi) {
|
| case kPauseOnAllExceptions:
|
| @@ -2335,6 +2335,77 @@ void Isolate::WaitForOutstandingSpawns() {
|
| }
|
|
|
|
|
| +Monitor* Isolate::threads_lock() const {
|
| + return thread_registry_->threads_lock();
|
| +}
|
| +
|
| +
|
| +Thread* Isolate::ScheduleThread(bool is_mutator, bool bypass_safepoint) {
|
| + // Schedule the thread into the isolate by associating
|
| + // a 'Thread' structure with it (this is done while we are holding
|
| + // the thread registry lock).
|
| + Thread* thread = NULL;
|
| + OSThread* os_thread = OSThread::Current();
|
| + if (os_thread != NULL) {
|
| + MonitorLocker ml(threads_lock());
|
| +
|
| + // If a safepoint operation is in progress wait for it
|
| + // to finish before scheduling this thread in.
|
| + while (!bypass_safepoint && safepoint_handler()->safepoint_in_progress()) {
|
| + ml.Wait();
|
| + }
|
| +
|
| + // Now get a free Thread structure.
|
| + thread = thread_registry()->GetFreeThreadLocked(this, is_mutator);
|
| + ASSERT(thread != NULL);
|
| +
|
| + // Set up other values and set the TLS value.
|
| + thread->isolate_ = this;
|
| + ASSERT(heap() != NULL);
|
| + thread->heap_ = heap();
|
| + thread->set_os_thread(os_thread);
|
| + ASSERT(thread->execution_state() == Thread::kThreadInVM);
|
| + thread->set_safepoint_state(0);
|
| + thread->set_vm_tag(VMTag::kVMTagId);
|
| + os_thread->set_thread(thread);
|
| + if (is_mutator) {
|
| + mutator_thread_ = thread;
|
| + }
|
| + Thread::SetCurrent(thread);
|
| + os_thread->EnableThreadInterrupts();
|
| + }
|
| + return thread;
|
| +}
|
| +
|
| +
|
| +void Isolate::UnscheduleThread(Thread* thread,
|
| + bool is_mutator,
|
| + bool bypass_safepoint) {
|
| + // Disassociate the 'Thread' structure and unschedule the thread
|
| + // from this isolate.
|
| + MonitorLocker ml(threads_lock());
|
| + if (!bypass_safepoint) {
|
| + // Ensure that the thread reports itself as being at a safepoint.
|
| + thread->EnterSafepoint();
|
| + }
|
| + OSThread* os_thread = thread->os_thread();
|
| + ASSERT(os_thread != NULL);
|
| + os_thread->DisableThreadInterrupts();
|
| + os_thread->set_thread(NULL);
|
| + OSThread::SetCurrent(os_thread);
|
| + if (is_mutator) {
|
| + mutator_thread_ = NULL;
|
| + }
|
| + thread->isolate_ = NULL;
|
| + thread->heap_ = NULL;
|
| + thread->set_os_thread(NULL);
|
| + thread->set_execution_state(Thread::kThreadInVM);
|
| + thread->set_safepoint_state(0);
|
| + // Return thread structure.
|
| + thread_registry()->ReturnThreadLocked(is_mutator, thread);
|
| +}
|
| +
|
| +
|
| static RawInstance* DeserializeObject(Thread* thread,
|
| uint8_t* obj_data,
|
| intptr_t obj_len) {
|
|
|