Chromium Code Reviews| Index: runtime/vm/isolate.cc |
| diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc |
| index abe9dda1ca83b1fb9e85bee5d6b66a63105de69b..292a315588839e2535576525b0aeb07da445d8c8 100644 |
| --- a/runtime/vm/isolate.cc |
| +++ b/runtime/vm/isolate.cc |
| @@ -315,8 +315,10 @@ Isolate::Isolate() |
| cha_used_(false), |
| object_id_ring_(NULL), |
| profiler_data_(NULL), |
| + thread_state_(NULL), |
| REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_INITIALIZERS) |
| - reusable_handles_() { |
| + reusable_handles_(), |
| + next_(NULL) { |
| if (FLAG_print_object_histogram && (Dart::vm_isolate() != NULL)) { |
| object_histogram_ = new ObjectHistogram(this); |
| } |
| @@ -343,12 +345,23 @@ Isolate::~Isolate() { |
| delete spawn_state_; |
| } |
| + |
| void Isolate::SetCurrent(Isolate* current) { |
| Isolate* old_current = Current(); |
| - if (old_current != current) { |
| + if (old_current != NULL) { |
| + old_current->set_thread_state(NULL); |
| Profiler::EndExecution(old_current); |
| - Thread::SetThreadLocal(isolate_key, reinterpret_cast<uword>(current)); |
| + } |
| + Thread::SetThreadLocal(isolate_key, reinterpret_cast<uword>(current)); |
| + if (current != NULL) { |
| + ASSERT(current->thread_state() == NULL); |
| + InterruptableThreadState* thread_state = |
| + ThreadInterrupter::GetCurrentThreadState(); |
| +#if defined(DEBUG) |
| + CheckForDuplicateThreadState(thread_state); |
| +#endif |
| Profiler::BeginExecution(current); |
| + current->set_thread_state(thread_state); |
| } |
| } |
| @@ -365,6 +378,8 @@ void Isolate::InitOnce() { |
| isolate_key = Thread::CreateThreadLocal(); |
| ASSERT(isolate_key != Thread::kUnsetThreadLocalKey); |
| create_callback_ = NULL; |
| + isolates_monitor_ = new Monitor(); |
| + ASSERT(isolates_monitor_ != NULL); |
| } |
| @@ -375,6 +390,9 @@ Isolate* Isolate::Init(const char* name_prefix) { |
| // Setup for profiling. |
| Profiler::InitProfilingForIsolate(result); |
| + // Add to isolate list. |
| + IsolateCreated(result); |
| + |
| // TODO(5411455): For now just set the recently created isolate as |
| // the current isolate. |
| SetCurrent(result); |
| @@ -749,6 +767,7 @@ void Isolate::Shutdown() { |
| // TODO(5411455): For now just make sure there are no current isolates |
| // as we are shutting down the isolate. |
| SetCurrent(NULL); |
| + IsolateShutdown(this); |
| Profiler::ShutdownProfilingForIsolate(this); |
| } |
| @@ -766,6 +785,10 @@ Dart_EntropySource Isolate::entropy_source_callback_ = NULL; |
| Dart_IsolateInterruptCallback Isolate::vmstats_callback_ = NULL; |
| Dart_ServiceIsolateCreateCalback Isolate::service_create_callback_ = NULL; |
| +Monitor* Isolate::isolates_monitor_ = NULL; |
| +Isolate* Isolate::isolates_head_ = NULL; |
| + |
| + |
| void Isolate::VisitObjectPointers(ObjectPointerVisitor* visitor, |
| bool visit_prologue_weak_handles, |
| bool validate_frames) { |
| @@ -866,6 +889,63 @@ void Isolate::PrintToJSONStream(JSONStream* stream) { |
| } |
| +void Isolate::VisitIsolates(IsolateVisitor* visitor) { |
| + if (visitor == NULL) { |
| + return; |
| + } |
| + MonitorLocker ml(isolates_monitor_); |
| + Isolate* current = isolates_head_; |
| + while (current) { |
| + visitor->VisitIsolate(current); |
| + current = current->next_; |
| + } |
| +} |
| + |
| + |
| +void Isolate::IsolateCreated(Isolate* isolate) { |
| + MonitorLocker ml(isolates_monitor_); |
| + ASSERT(isolate != NULL); |
| + ASSERT(isolate->next_ == NULL); |
| + isolate->next_ = isolates_head_; |
| + isolates_head_ = isolate; |
| +} |
| + |
| + |
| +void Isolate::IsolateShutdown(Isolate* isolate) { |
| + MonitorLocker ml(isolates_monitor_); |
| + ASSERT(isolate != NULL); |
| + Isolate* previous = NULL; |
| + Isolate* current = isolates_head_; |
| + while (current) { |
| + if (current == isolate) { |
| + if (current == isolates_head_) { |
| + isolates_head_ = current->next_; |
| + } else { |
| + ASSERT(previous != NULL); |
| + previous->next_ = current->next_; |
| + } |
| + return; |
| + } |
| + previous = current; |
| + current = current->next_; |
| + } |
|
siva
2014/02/06 00:37:24
Might be more efficient to write this as:
if (iso
Cutch
2014/02/06 17:51:51
Done.
|
| + UNREACHABLE(); |
| +} |
| + |
| + |
| +#if defined(DEBUG) |
| +void Isolate::CheckForDuplicateThreadState(InterruptableThreadState* state) { |
| + MonitorLocker ml(isolates_monitor_); |
| + ASSERT(state != NULL); |
| + Isolate* current = isolates_head_; |
| + while (current) { |
| + ASSERT(current->thread_state() != state); |
| + current = current->next_; |
| + } |
| +} |
| +#endif |
| + |
| + |
| template<class T> |
| T* Isolate::AllocateReusableHandle() { |
| T* handle = reinterpret_cast<T*>(reusable_handles_.AllocateScopedHandle()); |