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

Unified Diff: runtime/vm/isolate.cc

Issue 1371193005: VM restart + shutdown fixes (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: more code review Created 5 years, 2 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.h » ('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 6089f2db721e057c24b9e4878c09bc754eedab5f..e542420ccd43edcd0e597f7a34a09c246f4dc59f 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -178,7 +178,7 @@ class IsolateMessageHandler : public MessageHandler {
const char* name() const;
void MessageNotify(Message::Priority priority);
- bool HandleMessage(Message* message);
+ MessageStatus HandleMessage(Message* message);
void NotifyPauseOnStart();
void NotifyPauseOnExit();
@@ -194,7 +194,7 @@ class IsolateMessageHandler : public MessageHandler {
// processing of further events.
RawError* HandleLibMessage(const Array& message);
- bool ProcessUnhandledException(const Error& result);
+ MessageStatus ProcessUnhandledException(const Error& result);
Isolate* isolate_;
};
@@ -285,7 +285,8 @@ RawError* IsolateMessageHandler::HandleLibMessage(const Array& message) {
break;
}
case Isolate::kKillMsg:
- case Isolate::kInternalKillMsg: {
+ case Isolate::kInternalKillMsg:
+ case Isolate::kVMRestartMsg: {
// [ OOB, kKillMsg, terminate capability, priority ]
if (message.Length() != 4) return Error::null();
Object& obj = Object::Handle(I, message.At(3));
@@ -293,8 +294,8 @@ RawError* IsolateMessageHandler::HandleLibMessage(const Array& message) {
const intptr_t priority = Smi::Cast(obj).Value();
if (priority == Isolate::kImmediateAction) {
obj = message.At(2);
- // Signal that the isolate should stop execution.
if (I->VerifyTerminateCapability(obj)) {
+ // We will kill the current isolate by returning an UnwindError.
if (msg_type == Isolate::kKillMsg) {
const String& msg = String::Handle(String::New(
"isolate terminated by Isolate.kill"));
@@ -302,14 +303,22 @@ RawError* IsolateMessageHandler::HandleLibMessage(const Array& message) {
UnwindError::Handle(UnwindError::New(msg));
error.set_is_user_initiated(true);
return error.raw();
- } else {
- // TODO(turnidge): We should give the message handler a way
- // to detect when an isolate is unwinding.
- I->message_handler()->set_pause_on_start(false);
- I->message_handler()->set_pause_on_exit(false);
+ } else if (msg_type == Isolate::kInternalKillMsg) {
const String& msg = String::Handle(String::New(
"isolate terminated by vm"));
return UnwindError::New(msg);
+ } else if (msg_type == Isolate::kVMRestartMsg) {
+ // If this is the main isolate, this request to restart
+ // will be caught and handled in the embedder. Otherwise
+ // this unwind error will cause the isolate to exit.
+ const String& msg = String::Handle(String::New(
+ "isolate terminated for vm restart"));
+ const UnwindError& error =
+ UnwindError::Handle(UnwindError::New(msg));
+ error.set_is_vm_restart(true);
+ return error.raw();
+ } else {
+ UNREACHABLE();
}
} else {
return Error::null();
@@ -421,7 +430,8 @@ void IsolateMessageHandler::MessageNotify(Message::Priority priority) {
}
-bool IsolateMessageHandler::HandleMessage(Message* message) {
+MessageHandler::MessageStatus IsolateMessageHandler::HandleMessage(
+ Message* message) {
ASSERT(IsCurrentIsolate());
Thread* thread = Thread::Current();
StackZone stack_zone(thread);
@@ -450,7 +460,7 @@ bool IsolateMessageHandler::HandleMessage(Message* message) {
} else {
delete message;
}
- return true;
+ return kOK;
}
}
@@ -474,7 +484,7 @@ bool IsolateMessageHandler::HandleMessage(Message* message) {
Instance& msg = Instance::Handle(zone);
msg ^= msg_obj.raw(); // Can't use Instance::Cast because may be null.
- bool success = true;
+ MessageStatus status = kOK;
if (message->IsOOB()) {
// OOB messages are expected to be fixed length arrays where the first
// element is a Smi describing the OOB destination. Messages that do not
@@ -492,7 +502,7 @@ bool IsolateMessageHandler::HandleMessage(Message* message) {
case Message::kIsolateLibOOBMsg: {
const Error& error = Error::Handle(HandleLibMessage(oob_msg));
if (!error.IsNull()) {
- success = ProcessUnhandledException(error);
+ status = ProcessUnhandledException(error);
}
break;
}
@@ -519,7 +529,7 @@ bool IsolateMessageHandler::HandleMessage(Message* message) {
(Smi::Cast(oob_tag).Value() == Message::kDelayedIsolateLibOOBMsg)) {
const Error& error = Error::Handle(HandleLibMessage(msg_arr));
if (!error.IsNull()) {
- success = ProcessUnhandledException(error);
+ status = ProcessUnhandledException(error);
}
}
}
@@ -528,22 +538,22 @@ bool IsolateMessageHandler::HandleMessage(Message* message) {
const Object& result = Object::Handle(zone,
DartLibraryCalls::HandleMessage(msg_handler, msg));
if (result.IsError()) {
- success = ProcessUnhandledException(Error::Cast(result));
+ status = ProcessUnhandledException(Error::Cast(result));
} else {
ASSERT(result.IsNull());
}
}
delete message;
- if (success) {
+ if (status == kOK) {
const Object& result =
Object::Handle(zone, I->InvokePendingServiceExtensionCalls());
if (result.IsError()) {
- success = ProcessUnhandledException(Error::Cast(result));
+ status = ProcessUnhandledException(Error::Cast(result));
} else {
ASSERT(result.IsNull());
}
}
- return success;
+ return status;
}
@@ -587,7 +597,25 @@ bool IsolateMessageHandler::IsCurrentIsolate() const {
}
-bool IsolateMessageHandler::ProcessUnhandledException(const Error& result) {
+static MessageHandler::MessageStatus StoreError(Isolate* isolate,
+ const Error& error) {
+ isolate->object_store()->set_sticky_error(error);
+ if (error.IsUnwindError()) {
+ const UnwindError& unwind = UnwindError::Cast(error);
+ if (!unwind.is_user_initiated()) {
+ if (unwind.is_vm_restart()) {
+ return MessageHandler::kRestart;
+ } else {
+ return MessageHandler::kShutdown;
+ }
+ }
+ }
+ return MessageHandler::kError;
+}
+
+
+MessageHandler::MessageStatus IsolateMessageHandler::ProcessUnhandledException(
+ const Error& result) {
// Notify the debugger about specific unhandled exceptions which are withheld
// when being thrown.
if (result.IsUnhandledException()) {
@@ -631,9 +659,9 @@ bool IsolateMessageHandler::ProcessUnhandledException(const Error& result) {
exc_str = String::New(result.ToErrorCString());
}
if (result.IsUnwindError()) {
- // Unwind errors are always fatal and don't notify listeners.
- I->object_store()->set_sticky_error(result);
- return false;
+ // When unwinding we don't notify error listeners and we ignore
+ // whether errors are fatal for the current isolate.
+ return StoreError(I, result);
} else {
bool has_listener = I->NotifyErrorListeners(exc_str, stacktrace_str);
if (I->ErrorsFatal()) {
@@ -642,10 +670,10 @@ bool IsolateMessageHandler::ProcessUnhandledException(const Error& result) {
} else {
I->object_store()->set_sticky_error(result);
}
- return false;
+ return kError;
}
}
- return true;
+ return kOK;
}
@@ -1308,13 +1336,7 @@ bool Isolate::NotifyErrorListeners(const String& msg,
}
-static void StoreError(Isolate* isolate, const Object& obj) {
- ASSERT(obj.IsError());
- isolate->object_store()->set_sticky_error(Error::Cast(obj));
-}
-
-
-static bool RunIsolate(uword parameter) {
+static MessageHandler::MessageStatus RunIsolate(uword parameter) {
Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
IsolateSpawnState* state = NULL;
Thread* thread = Thread::Current();
@@ -1348,15 +1370,19 @@ static bool RunIsolate(uword parameter) {
if (!ClassFinalizer::ProcessPendingClasses()) {
// Error is in sticky error already.
- return false;
+#if defined(DEBUG)
+ const Error& error =
+ Error::Handle(isolate->object_store()->sticky_error());
+ ASSERT(!error.IsUnwindError());
+#endif
+ return MessageHandler::kError;
}
Object& result = Object::Handle();
result = state->ResolveFunction();
bool is_spawn_uri = state->is_spawn_uri();
if (result.IsError()) {
- StoreError(isolate, result);
- return false;
+ return StoreError(isolate, Error::Cast(result));
}
ASSERT(result.IsFunction());
Function& func = Function::Handle(isolate);
@@ -1411,11 +1437,10 @@ static bool RunIsolate(uword parameter) {
result = DartEntry::InvokeFunction(entry_point, args);
if (result.IsError()) {
- StoreError(isolate, result);
- return false;
+ return StoreError(isolate, Error::Cast(result));
}
}
- return true;
+ return MessageHandler::kOK;
}
@@ -1474,8 +1499,9 @@ RawError* Isolate::HandleInterrupts() {
}
}
if ((interrupt_bits & kMessageInterrupt) != 0) {
- bool ok = message_handler()->HandleOOBMessages();
- if (!ok) {
+ MessageHandler::MessageStatus status =
+ message_handler()->HandleOOBMessages();
+ if (status != MessageHandler::kOK) {
// False result from HandleOOBMessages signals that the isolate should
// be terminating.
if (FLAG_trace_isolates) {
@@ -1483,8 +1509,8 @@ RawError* Isolate::HandleInterrupts() {
"\tisolate: %s\n", name());
}
const Error& error = Error::Handle(object_store()->sticky_error());
+ ASSERT(!error.IsNull() && error.IsUnwindError());
object_store()->clear_sticky_error();
- ASSERT(!error.IsNull());
return error.raw();
}
}
@@ -2293,7 +2319,7 @@ C* Isolate::AllocateReusableHandle() {
}
-void Isolate::KillLocked() {
+void Isolate::KillLocked(LibMsgId msg_id) {
Dart_CObject kill_msg;
Dart_CObject* list_values[4];
kill_msg.type = Dart_CObject_kArray;
@@ -2307,7 +2333,7 @@ void Isolate::KillLocked() {
Dart_CObject msg_type;
msg_type.type = Dart_CObject_kInt32;
- msg_type.value.as_int32 = Isolate::kInternalKillMsg;
+ msg_type.value.as_int32 = msg_id;
list_values[1] = &msg_type;
Dart_CObject cap;
@@ -2338,10 +2364,11 @@ void Isolate::KillLocked() {
class IsolateKillerVisitor : public IsolateVisitor {
public:
- IsolateKillerVisitor() : target_(NULL) {}
+ explicit IsolateKillerVisitor(Isolate::LibMsgId msg_id)
+ : target_(NULL), msg_id_(msg_id) {}
- explicit IsolateKillerVisitor(Isolate* isolate)
- : target_(isolate) {
+ IsolateKillerVisitor(Isolate* isolate, Isolate::LibMsgId msg_id)
+ : target_(isolate), msg_id_(msg_id) {
ASSERT(isolate != Dart::vm_isolate());
}
@@ -2350,7 +2377,7 @@ class IsolateKillerVisitor : public IsolateVisitor {
void VisitIsolate(Isolate* isolate) {
ASSERT(isolate != NULL);
if (ShouldKill(isolate)) {
- isolate->KillLocked();
+ isolate->KillLocked(msg_id_);
}
}
@@ -2365,17 +2392,18 @@ class IsolateKillerVisitor : public IsolateVisitor {
}
Isolate* target_;
+ Isolate::LibMsgId msg_id_;
};
-void Isolate::KillAllIsolates() {
- IsolateKillerVisitor visitor;
+void Isolate::KillAllIsolates(LibMsgId msg_id) {
+ IsolateKillerVisitor visitor(msg_id);
VisitIsolates(&visitor);
}
-void Isolate::KillIfExists(Isolate* isolate) {
- IsolateKillerVisitor visitor(isolate);
+void Isolate::KillIfExists(Isolate* isolate, LibMsgId msg_id) {
+ IsolateKillerVisitor visitor(isolate, msg_id);
VisitIsolates(&visitor);
}
« no previous file with comments | « runtime/vm/isolate.h ('k') | runtime/vm/message_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698