Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1772)

Unified Diff: runtime/vm/isolate.cc

Issue 1275353005: VM thread shutdown. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/isolate.cc
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 10873ae03c37990f98114808b4acab3361a9455b..0056efcdacebafd50577407f41f6b4174d281fd8 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -5,11 +5,13 @@
#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"
#include "vm/compiler_stats.h"
#include "vm/coverage.h"
+#include "vm/dart_api_message.h"
#include "vm/dart_api_state.h"
#include "vm/dart_entry.h"
#include "vm/debugger.h"
@@ -165,7 +167,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 {
@@ -186,6 +187,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);
@@ -749,6 +751,7 @@ void Isolate::InitOnce() {
create_callback_ = NULL;
isolates_list_monitor_ = new Monitor();
ASSERT(isolates_list_monitor_ != NULL);
+ EnableIsolateCreation();
}
@@ -827,8 +830,14 @@ 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->LowLevelShutdown();
+ Thread::ExitIsolate();
+ delete result;
+ return NULL;
+ }
return result;
}
@@ -1454,6 +1463,50 @@ class FinalizeWeakPersistentHandlesVisitor : public HandleVisitor {
};
+void Isolate::LowLevelShutdown() {
+ // Ensure we have a zone and handle scope so that we can call VM functions,
+ // but we no longer allocate new heap objects.
+ StackZone stack_zone(this);
+ HandleScope handle_scope(this);
+ NoSafepointScope no_safepoint_scope;
+
+ if (compiler_stats_ != NULL) {
+ compiler_stats()->Print();
+ }
+
+ // Notify exit listeners that this isolate is shutting down.
+ if (object_store() != NULL) {
+ NotifyExitListeners();
+ }
+
+ // Clean up debugger resources.
+ debugger()->Shutdown();
+
+ // Close all the ports owned by this isolate.
+ PortMap::ClosePorts(message_handler());
+
+ // Fail fast if anybody tries to post any more messsages to this isolate.
+ delete message_handler();
+ set_message_handler(NULL);
+
+ // Dump all accumulated timer data for the isolate.
+ timer_list_.ReportTimers();
+
+ // Finalize any weak persistent handles with a non-null referent.
+ FinalizeWeakPersistentHandlesVisitor visitor;
+ api_state()->weak_persistent_handles().VisitHandles(&visitor);
+ api_state()->prologue_weak_persistent_handles().VisitHandles(&visitor);
+
+ if (FLAG_trace_isolates) {
+ heap()->PrintSizes();
+ megamorphic_cache_table()->PrintSizes();
+ Symbols::DumpStats();
+ OS::Print("[-] Stopping isolate:\n"
+ "\tisolate: %s\n", name());
+ }
+}
+
+
void Isolate::Shutdown() {
ASSERT(this == Isolate::Current());
ASSERT(top_resource() == NULL);
@@ -1471,7 +1524,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)) {
@@ -1494,48 +1550,7 @@ void Isolate::Shutdown() {
}
// Then, proceed with low-level teardown.
- {
- // Ensure we have a zone and handle scope so that we can call VM functions,
- // but we no longer allocate new heap objects.
- StackZone stack_zone(this);
- HandleScope handle_scope(this);
- NoSafepointScope no_safepoint_scope;
-
- if (compiler_stats_ != NULL) {
- compiler_stats()->Print();
- }
-
- // Notify exit listeners that this isolate is shutting down.
- if (object_store() != NULL) {
- NotifyExitListeners();
- }
-
- // Clean up debugger resources.
- debugger()->Shutdown();
-
- // Close all the ports owned by this isolate.
- PortMap::ClosePorts(message_handler());
-
- // Fail fast if anybody tries to post any more messsages to this isolate.
- delete message_handler();
- set_message_handler(NULL);
-
- // Dump all accumulated timer data for the isolate.
- timer_list_.ReportTimers();
-
- // Finalize any weak persistent handles with a non-null referent.
- FinalizeWeakPersistentHandlesVisitor visitor;
- api_state()->weak_persistent_handles().VisitHandles(&visitor);
- api_state()->prologue_weak_persistent_handles().VisitHandles(&visitor);
-
- if (FLAG_trace_isolates) {
- heap()->PrintSizes();
- megamorphic_cache_table()->PrintSizes();
- Symbols::DumpStats();
- OS::Print("[-] Stopping isolate:\n"
- "\tisolate: %s\n", name());
- }
- }
+ LowLevelShutdown();
#if defined(DEBUG)
// No concurrent sweeper tasks should be running at this point.
@@ -1568,7 +1583,7 @@ Dart_EntropySource Isolate::entropy_source_callback_ = NULL;
Monitor* Isolate::isolates_list_monitor_ = NULL;
Isolate* Isolate::isolates_list_head_ = NULL;
-
+bool Isolate::creation_enabled_ = false;
void Isolate::IterateObjectPointers(ObjectPointerVisitor* visitor,
bool visit_prologue_weak_handles,
@@ -1909,12 +1924,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;
}
@@ -1936,7 +1955,8 @@ void Isolate::RemoveIsolateFromList(Isolate* isolate) {
previous = current;
current = current->next_;
}
- UNREACHABLE();
+ // If we are shutting down the VM, the isolate may not be in the list.
+ ASSERT(!creation_enabled_);
}
@@ -1953,6 +1973,18 @@ void Isolate::CheckForDuplicateThreadState(InterruptableThreadState* state) {
#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());
@@ -1961,6 +1993,73 @@ T* Isolate::AllocateReusableHandle() {
}
+void Isolate::KillIsolate(Isolate* isolate) {
Ivan Posva 2015/08/17 13:35:51 Why is this not an instance method?
zra 2015/08/18 06:23:14 Done.
+ 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] = &cap;
+
+ Dart_CObject imm;
+ imm.type = Dart_CObject_kInt32;
+ imm.value.as_int32 = IsolateMessageHandler::kImmediateAction;
+ list_values[3] = &imm;
+
+ isolate->ScheduleInterrupts(Isolate::kMessageInterrupt);
Ivan Posva 2015/08/17 13:35:51 What is this interrupt for? It will likely be hand
zra 2015/08/18 06:23:14 I was following the pattern in the implementation
+ {
+ uint8_t* buffer = NULL;
+ ApiMessageWriter writer(&buffer, allocator);
+ bool success = writer.WriteCMessage(&kill_msg);
+ ASSERT(success);
+
+ // Post the message at the given port.
+ success = PortMap::PostMessage(new Message(isolate->main_port(),
+ buffer,
+ writer.BytesWritten(),
+ Message::kOOBPriority));
+ ASSERT(success);
+ }
+}
+
+
+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);
Ivan Posva 2015/08/17 13:35:51 ditto isolate->Kill();
zra 2015/08/18 06:23:14 Done.
+ }
+};
+
+
+void Isolate::KillAllIsolates() {
+ IsolateKillerVisitor visitor;
+ VisitIsolates(&visitor);
+}
+
+
static RawInstance* DeserializeObject(Isolate* isolate,
Zone* zone,
uint8_t* obj_data,

Powered by Google App Engine
This is Rietveld 408576698