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