Chromium Code Reviews| Index: runtime/vm/isolate.cc |
| diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc |
| index 5071b6cd5f367ffdded29b40407fdda3d7df080a..8ece4f532e6a01d33fb68d673bc6b6df56cb1101 100644 |
| --- a/runtime/vm/isolate.cc |
| +++ b/runtime/vm/isolate.cc |
| @@ -5,6 +5,7 @@ |
| #include "vm/isolate.h" |
| #include "include/dart_api.h" |
| +#include "include/dart_native_api.h" |
| #include "platform/assert.h" |
| #include "platform/json.h" |
| #include "vm/code_observers.h" |
| @@ -157,7 +158,6 @@ class IsolateMessageHandler : public MessageHandler { |
| bool IsCurrentIsolate() const; |
| virtual Isolate* isolate() const { return isolate_; } |
| - private: |
| // Keep both these enums in sync with isolate_patch.dart. |
| // The different Isolate API message types. |
| enum { |
| @@ -178,6 +178,7 @@ class IsolateMessageHandler : public MessageHandler { |
| kAsEventAction = 2 |
| }; |
| + private: |
| // A result of false indicates that the isolate should terminate the |
| // processing of further events. |
| bool HandleLibMessage(const Array& message); |
| @@ -742,6 +743,7 @@ void Isolate::InitOnce() { |
| create_callback_ = NULL; |
| isolates_list_monitor_ = new Monitor(); |
| ASSERT(isolates_list_monitor_ != NULL); |
| + creation_enabled_ = true; |
|
turnidge
2015/08/04 21:39:02
Consider calling EnableIsolateCreation here?
zra
2015/08/05 06:23:06
Done.
|
| } |
| @@ -814,8 +816,13 @@ Isolate* Isolate::Init(const char* name_prefix, |
| result->compiler_stats_ = new CompilerStats(result); |
| } |
| ObjectIdRing::Init(result); |
| - // Add to isolate list. |
| - AddIsolateTolist(result); |
| + |
| + // Add to isolate list. Shutdown and delete the isolate on failure. |
| + if (!AddIsolateToList(result)) { |
| + result->Shutdown(); |
| + delete result; |
| + return NULL; |
| + } |
| return result; |
| } |
| @@ -1458,7 +1465,10 @@ void Isolate::Shutdown() { |
| HandleScope handle_scope(this); |
| // Write out the coverage data if collection has been enabled. |
| - CodeCoverage::Write(this); |
| + if ((this != Dart::vm_isolate()) && |
| + !ServiceIsolate::IsServiceIsolateDescendant(this)) { |
| + CodeCoverage::Write(this); |
| + } |
| if ((timeline_event_recorder_ != NULL) && |
| (FLAG_timeline_trace_dir != NULL)) { |
| @@ -1555,7 +1565,7 @@ Dart_EntropySource Isolate::entropy_source_callback_ = NULL; |
| Monitor* Isolate::isolates_list_monitor_ = NULL; |
| Isolate* Isolate::isolates_list_head_ = NULL; |
| - |
| +bool Isolate::creation_enabled_ = true; |
|
turnidge
2015/08/04 21:39:02
Maybe we should start this as false.
zra
2015/08/05 06:23:06
Done.
|
| void Isolate::IterateObjectPointers(ObjectPointerVisitor* visitor, |
| bool visit_prologue_weak_handles, |
| @@ -1904,12 +1914,16 @@ intptr_t Isolate::IsolateListLength() { |
| } |
| -void Isolate::AddIsolateTolist(Isolate* isolate) { |
| +bool Isolate::AddIsolateToList(Isolate* isolate) { |
| MonitorLocker ml(isolates_list_monitor_); |
| + if (!creation_enabled_) { |
| + return false; |
| + } |
| ASSERT(isolate != NULL); |
| ASSERT(isolate->next_ == NULL); |
| isolate->next_ = isolates_list_head_; |
| isolates_list_head_ = isolate; |
| + return true; |
| } |
| @@ -1931,7 +1945,9 @@ void Isolate::RemoveIsolateFromList(Isolate* isolate) { |
| previous = current; |
| current = current->next_; |
| } |
| - UNREACHABLE(); |
| + // If we are shutting down an isolate that tried to start after the VM |
| + // started going down, then it may not be in the list. |
|
turnidge
2015/08/04 21:39:02
I feel like there is a simpler version of this com
zra
2015/08/05 06:23:06
Done.
|
| + ASSERT(!creation_enabled_); |
| } |
| @@ -1945,9 +1961,33 @@ void Isolate::CheckForDuplicateThreadState(InterruptableThreadState* state) { |
| current = current->next_; |
| } |
| } |
| + |
| + |
| +int Isolate::IsolateCount() { |
| + MonitorLocker ml(isolates_list_monitor_); |
| + Isolate* current = isolates_list_head_; |
| + int count = 0; |
| + while (current) { |
| + count++; |
| + current = current->next_; |
| + } |
| + return count; |
| +} |
| #endif |
| +void Isolate::DisableIsolateCreation() { |
| + MonitorLocker ml(isolates_list_monitor_); |
| + creation_enabled_ = false; |
| +} |
| + |
| + |
| +void Isolate::EnableIsolateCreation() { |
| + MonitorLocker ml(isolates_list_monitor_); |
| + creation_enabled_ = true; |
| +} |
| + |
| + |
| template<class T> |
| T* Isolate::AllocateReusableHandle() { |
| T* handle = reinterpret_cast<T*>(reusable_handles_.AllocateScopedHandle()); |
| @@ -1956,6 +1996,61 @@ T* Isolate::AllocateReusableHandle() { |
| } |
| +void Isolate::KillIsolate(Isolate* isolate) { |
| + Dart_CObject kill_msg; |
| + Dart_CObject* list_values[4]; |
| + kill_msg.type = Dart_CObject_kArray; |
| + kill_msg.value.as_array.length = 4; |
| + kill_msg.value.as_array.values = list_values; |
| + |
| + Dart_CObject oob; |
| + oob.type = Dart_CObject_kInt32; |
| + oob.value.as_int32 = Message::kIsolateLibOOBMsg; |
| + list_values[0] = &oob; |
| + |
| + Dart_CObject kill; |
| + kill.type = Dart_CObject_kInt32; |
| + kill.value.as_int32 = IsolateMessageHandler::kKillMsg; |
| + list_values[1] = &kill; |
| + |
| + Dart_CObject cap; |
| + cap.type = Dart_CObject_kCapability; |
| + cap.value.as_capability.id = isolate->terminate_capability(); |
| + list_values[2] = ∩ |
| + |
| + Dart_CObject imm; |
| + imm.type = Dart_CObject_kInt32; |
| + imm.value.as_int32 = IsolateMessageHandler::kImmediateAction; |
| + list_values[3] = &imm; |
| + |
| + isolate->ScheduleInterrupts(Isolate::kMessageInterrupt); |
| + Dart_PostOOBCObject(isolate->main_port(), &kill_msg); |
| +} |
| + |
| + |
| +class IsolateKillerVisitor : public IsolateVisitor { |
| + public: |
| + IsolateKillerVisitor() {} |
| + |
| + virtual ~IsolateKillerVisitor() {} |
| + |
| + void VisitIsolate(Isolate* isolate) { |
| + ASSERT(isolate != NULL); |
| + if (ServiceIsolate::IsServiceIsolateDescendant(isolate) || |
| + (isolate == Dart::vm_isolate())) { |
| + return; |
| + } |
| + Isolate::KillIsolate(isolate); |
| + } |
| +}; |
| + |
| + |
| +void Isolate::KillAllIsolates() { |
| + IsolateKillerVisitor visitor; |
| + VisitIsolates(&visitor); |
| +} |
| + |
| + |
| static RawInstance* DeserializeObject(Isolate* isolate, |
| Zone* zone, |
| uint8_t* obj_data, |