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

Unified Diff: runtime/vm/isolate.cc

Issue 1275353005: VM thread shutdown. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Merge Created 5 years, 3 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
« no previous file with comments | « runtime/vm/isolate.h ('k') | runtime/vm/message_handler.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/isolate.cc
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 379287a67b4f94a77a36c0263c45cb0529b70d12..e05790b900e296289170ad7a2ead0cd5794b82da 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);
@@ -768,6 +770,7 @@ void Isolate::InitOnce() {
create_callback_ = NULL;
isolates_list_monitor_ = new Monitor();
ASSERT(isolates_list_monitor_ != NULL);
+ EnableIsolateCreation();
}
@@ -846,8 +849,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;
}
@@ -1462,6 +1471,70 @@ 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.
+ Thread* thread = Thread::Current();
+ StackZone stack_zone(thread);
+ HandleScope handle_scope(thread);
+ NoSafepointScope no_safepoint_scope;
+
+ if (compiler_stats_ != NULL) {
+ OS::Print("%s", compiler_stats()->PrintToZone());
+ }
+
+ // 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();
+
+ // Before analyzing the isolate's timeline blocks- close all of them.
+ CloseAllTimelineBlocks();
+
+ // Dump all timing data for the isolate.
+ if (FLAG_timing) {
+ TimelinePauseTrace tpt;
+ tpt.Print();
+ }
+
+ // 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();
+ MegamorphicCacheTable::PrintSizes(this);
+ Symbols::DumpStats();
+ OS::Print("[-] Stopping isolate:\n"
+ "\tisolate: %s\n", name());
+ }
+ if (FLAG_print_metrics) {
+ LogBlock lb;
+ THR_Print("Printing metrics for %s\n", name());
+#define ISOLATE_METRIC_PRINT(type, variable, name, unit) \
+ THR_Print("%s\n", metric_##variable##_.ToString());
+
+ ISOLATE_METRIC_LIST(ISOLATE_METRIC_PRINT);
+#undef ISOLATE_METRIC_PRINT
+ THR_Print("\n");
+ }
+}
+
+
void Isolate::Shutdown() {
ASSERT(this == Isolate::Current());
ASSERT(top_resource() == NULL);
@@ -1481,7 +1554,10 @@ void Isolate::Shutdown() {
HandleScope handle_scope(thread);
// Write out the coverage data if collection has been enabled.
- CodeCoverage::Write(this);
+ if ((this != Dart::vm_isolate()) &&
+ !ServiceIsolate::IsServiceIsolateDescendant(this)) {
+ CodeCoverage::Write(this);
+ }
}
// Remove this isolate from the list *before* we start tearing it down, to
@@ -1499,66 +1575,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(thread);
- HandleScope handle_scope(thread);
- NoSafepointScope no_safepoint_scope;
-
- if (compiler_stats_ != NULL) {
- OS::Print("%s", compiler_stats()->PrintToZone());
- }
-
- // 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();
-
- // Before analyzing the isolate's timeline blocks- close all of them.
- CloseAllTimelineBlocks();
-
- // Dump all timing data for the isolate.
- if (FLAG_timing) {
- TimelinePauseTrace tpt;
- tpt.Print();
- }
-
- // 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();
- MegamorphicCacheTable::PrintSizes(this);
- Symbols::DumpStats();
- OS::Print("[-] Stopping isolate:\n"
- "\tisolate: %s\n", name());
- }
- if (FLAG_print_metrics) {
- LogBlock lb;
- THR_Print("Printing metrics for %s\n", name());
-#define ISOLATE_METRIC_PRINT(type, variable, name, unit) \
- THR_Print("%s\n", metric_##variable##_.ToString());
- ISOLATE_METRIC_LIST(ISOLATE_METRIC_PRINT);
-#undef ISOLATE_METRIC_PRINT
- THR_Print("\n");
- }
- }
+ LowLevelShutdown();
#if defined(DEBUG)
// No concurrent sweeper tasks should be running at this point.
@@ -1602,7 +1619,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,
@@ -2112,12 +2129,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;
}
@@ -2126,6 +2147,9 @@ void Isolate::RemoveIsolateFromList(Isolate* isolate) {
ASSERT(isolate != NULL);
if (isolate == isolates_list_head_) {
isolates_list_head_ = isolate->next_;
+ if (!creation_enabled_) {
+ ml.Notify();
+ }
return;
}
Isolate* previous = NULL;
@@ -2134,12 +2158,28 @@ void Isolate::RemoveIsolateFromList(Isolate* isolate) {
if (current == isolate) {
ASSERT(previous != NULL);
previous->next_ = current->next_;
+ if (!creation_enabled_) {
+ ml.Notify();
+ }
return;
}
previous = current;
current = current->next_;
}
- UNREACHABLE();
+ // If we are shutting down the VM, the isolate may not be in the list.
+ ASSERT(!creation_enabled_);
+}
+
+
+void Isolate::DisableIsolateCreation() {
+ MonitorLocker ml(isolates_list_monitor_);
+ creation_enabled_ = false;
+}
+
+
+void Isolate::EnableIsolateCreation() {
+ MonitorLocker ml(isolates_list_monitor_);
+ creation_enabled_ = true;
}
@@ -2151,6 +2191,93 @@ C* Isolate::AllocateReusableHandle() {
}
+void Isolate::KillLocked() {
+ 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 = terminate_capability();
+ list_values[2] = ∩
+
+ Dart_CObject imm;
+ imm.type = Dart_CObject_kInt32;
+ imm.value.as_int32 = IsolateMessageHandler::kImmediateAction;
+ list_values[3] = &imm;
+
+ {
+ 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(main_port(),
+ buffer,
+ writer.BytesWritten(),
+ Message::kOOBPriority));
+ ASSERT(success);
+ }
+}
+
+
+class IsolateKillerVisitor : public IsolateVisitor {
+ public:
+ IsolateKillerVisitor() : target_(NULL) {}
+
+ explicit IsolateKillerVisitor(Isolate* isolate)
+ : target_(isolate) {
+ ASSERT(isolate != Dart::vm_isolate());
+ }
+
+ virtual ~IsolateKillerVisitor() {}
+
+ void VisitIsolate(Isolate* isolate) {
+ ASSERT(isolate != NULL);
+ if (ShouldKill(isolate)) {
+ isolate->KillLocked();
+ }
+ }
+
+ private:
+ bool ShouldKill(Isolate* isolate) {
+ // If a target_ is specified, then only kill the target_.
+ // Otherwise, don't kill the service isolate or vm isolate.
+ return (((target_ != NULL) && (isolate == target_)) ||
+ ((target_ == NULL) &&
+ !ServiceIsolate::IsServiceIsolateDescendant(isolate) &&
+ (isolate != Dart::vm_isolate())));
+ }
+
+ Isolate* target_;
+};
+
+
+void Isolate::KillAllIsolates() {
+ IsolateKillerVisitor visitor;
+ VisitIsolates(&visitor);
+}
+
+
+void Isolate::KillIfExists(Isolate* isolate) {
+ IsolateKillerVisitor visitor(isolate);
+ VisitIsolates(&visitor);
+}
+
+
static RawInstance* DeserializeObject(Thread* thread,
uint8_t* obj_data,
intptr_t obj_len) {
« no previous file with comments | « runtime/vm/isolate.h ('k') | runtime/vm/message_handler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698