| Index: runtime/lib/isolate.cc
|
| ===================================================================
|
| --- runtime/lib/isolate.cc (revision 6698)
|
| +++ runtime/lib/isolate.cc (working copy)
|
| @@ -10,7 +10,7 @@
|
| #include "vm/dart_entry.h"
|
| #include "vm/exceptions.h"
|
| #include "vm/longjump.h"
|
| -#include "vm/message.h"
|
| +#include "vm/message_handler.h"
|
| #include "vm/object.h"
|
| #include "vm/object_store.h"
|
| #include "vm/port.h"
|
| @@ -22,16 +22,13 @@
|
|
|
| class IsolateStartData {
|
| public:
|
| - IsolateStartData(Isolate* isolate,
|
| - char* library_url,
|
| + IsolateStartData(char* library_url,
|
| char* class_name,
|
| intptr_t port_id)
|
| - : isolate_(isolate),
|
| - library_url_(library_url),
|
| + : library_url_(library_url),
|
| class_name_(class_name),
|
| port_id_(port_id) {}
|
|
|
| - Isolate* isolate_;
|
| char* library_url_;
|
| char* class_name_;
|
| intptr_t port_id_;
|
| @@ -53,14 +50,11 @@
|
| }
|
|
|
|
|
| -// TODO(turnidge): Taking down the whole vm when an isolate fails is
|
| -// bad. Change this.
|
| -static void ProcessError(const Object& obj) {
|
| +static void StoreError(Isolate* isolate, const Object& obj) {
|
| ASSERT(obj.IsError());
|
| Error& error = Error::Handle();
|
| error ^= obj.raw();
|
| - OS::PrintErr("%s\n", error.ToErrorCString());
|
| - exit(255);
|
| + isolate->object_store()->set_sticky_error(error);
|
| }
|
|
|
|
|
| @@ -113,31 +107,29 @@
|
| }
|
|
|
|
|
| -static void RunIsolate(uword parameter) {
|
| - IsolateStartData* data = reinterpret_cast<IsolateStartData*>(parameter);
|
| - Isolate* isolate = data->isolate_;
|
| +static bool RunIsolate(uword parameter) {
|
| + Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
|
| + IsolateStartData* data =
|
| + reinterpret_cast<IsolateStartData*>(isolate->spawn_data());
|
| + isolate->set_spawn_data(NULL);
|
| char* library_url = data->library_url_;
|
| char* class_name = data->class_name_;
|
| intptr_t port_id = data->port_id_;
|
| delete data;
|
|
|
| - Isolate::SetCurrent(isolate);
|
| - // Intialize stack limit in case we are running isolate in a
|
| - // different thread than in which it was initialized.
|
| - isolate->SetStackLimitFromCurrentTOS(reinterpret_cast<uword>(&isolate));
|
| - LongJump* base = isolate->long_jump_base();
|
| - LongJump jump;
|
| - isolate->set_long_jump_base(&jump);
|
| - if (setjmp(*jump.Set()) == 0) {
|
| + {
|
| + StartIsolateScope start_scope(isolate);
|
| Zone zone(isolate);
|
| HandleScope handle_scope(isolate);
|
| ASSERT(ClassFinalizer::FinalizePendingClasses());
|
| // Lookup the target class by name, create an instance and call the run
|
| // method.
|
| const String& lib_name = String::Handle(String::NewSymbol(library_url));
|
| + free(library_url);
|
| const Library& lib = Library::Handle(Library::LookupLibrary(lib_name));
|
| ASSERT(!lib.IsNull());
|
| const String& cls_name = String::Handle(String::NewSymbol(class_name));
|
| + free(class_name);
|
| const Class& target_class = Class::Handle(lib.LookupClass(cls_name));
|
| // TODO(iposva): Deserialize or call the constructor after allocating.
|
| // For now, we only support a non-parameterized or raw target class.
|
| @@ -158,7 +150,8 @@
|
| arguments,
|
| kNoArgumentNames);
|
| if (result.IsError()) {
|
| - ProcessError(result);
|
| + StoreError(isolate, result);
|
| + return false;
|
| }
|
| ASSERT(result.IsNull());
|
| }
|
| @@ -171,7 +164,8 @@
|
| // TODO(iposva): Allocate the proper port number here.
|
| const Object& local_port = Object::Handle(ReceivePortCreate(port_id));
|
| if (local_port.IsError()) {
|
| - ProcessError(local_port);
|
| + StoreError(isolate, local_port);
|
| + return false;
|
| }
|
| GrowableArray<const Object*> arguments(1);
|
| arguments.Add(&local_port);
|
| @@ -181,28 +175,35 @@
|
| arguments,
|
| kNoArgumentNames);
|
| if (result.IsError()) {
|
| - ProcessError(result);
|
| + StoreError(isolate, result);
|
| + return false;
|
| }
|
| ASSERT(result.IsNull());
|
| - free(class_name);
|
| - free(library_url);
|
| - result = isolate->StandardRunLoop();
|
| - if (result.IsError()) {
|
| - ProcessError(result);
|
| - }
|
| - ASSERT(result.IsNull());
|
| + }
|
| + return true;
|
| +}
|
|
|
| - } else {
|
| +
|
| +static void ShutdownIsolate(uword parameter) {
|
| + Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
|
| + {
|
| + // Print the error if there is one. This may execute dart code to
|
| + // print the exception object, so we need to use a StartIsolateScope.
|
| + StartIsolateScope start_scope(isolate);
|
| Zone zone(isolate);
|
| HandleScope handle_scope(isolate);
|
| - const Error& error = Error::Handle(
|
| - Isolate::Current()->object_store()->sticky_error());
|
| - const char* errmsg = error.ToErrorCString();
|
| - OS::PrintErr("%s\n", errmsg);
|
| - exit(255);
|
| + Error& error = Error::Handle();
|
| + error = isolate->object_store()->sticky_error();
|
| + if (!error.IsNull()) {
|
| + OS::PrintErr("%s\n", error.ToErrorCString());
|
| + exit(255);
|
| + }
|
| }
|
| - isolate->set_long_jump_base(base);
|
| - Dart::ShutdownIsolate();
|
| + {
|
| + // Shut the isolate down.
|
| + SwitchIsolateScope switch_scope(isolate);
|
| + Dart::ShutdownIsolate();
|
| + }
|
| }
|
|
|
|
|
| @@ -292,15 +293,15 @@
|
| // loaded, this check will throw an exception if they are not loaded.
|
| if (init_successful && CheckArguments(library_url, class_name)) {
|
| port_id = spawned_isolate->main_port();
|
| - uword data = reinterpret_cast<uword>(
|
| - new IsolateStartData(spawned_isolate,
|
| - strdup(library_url),
|
| - strdup(class_name),
|
| - port_id));
|
| - int result = Thread::Start(RunIsolate, data);
|
| - if (result != 0) {
|
| - FATAL1("Failed to start isolate thread %d", result);
|
| - }
|
| + spawned_isolate->set_spawn_data(
|
| + reinterpret_cast<uword>(
|
| + new IsolateStartData(strdup(library_url),
|
| + strdup(class_name),
|
| + port_id)));
|
| + Isolate::SetCurrent(NULL);
|
| + spawned_isolate->message_handler()->Run(
|
| + Dart::thread_pool(), RunIsolate, ShutdownIsolate,
|
| + reinterpret_cast<uword>(spawned_isolate));
|
| } else {
|
| // Error spawning the isolate, maybe due to initialization errors or
|
| // errors while loading the application into spawned isolate, shut
|
| @@ -425,10 +426,8 @@
|
| }
|
|
|
| void Cleanup() {
|
| - Isolate* saved = Isolate::Current();
|
| - Isolate::SetCurrent(isolate());
|
| + SwitchIsolateScope switch_scope(isolate());
|
| Dart::ShutdownIsolate();
|
| - Isolate::SetCurrent(saved);
|
| }
|
|
|
| private:
|
| @@ -479,16 +478,12 @@
|
| }
|
|
|
|
|
| -static void RunIsolate2(uword parameter) {
|
| - SpawnState* state = reinterpret_cast<SpawnState*>(parameter);
|
| - Isolate* isolate = state->isolate();
|
| -
|
| - Isolate::SetCurrent(isolate);
|
| - // Intialize stack limit in case we are running isolate in a
|
| - // different thread than in which it was initialized.
|
| - isolate->SetStackLimitFromCurrentTOS(reinterpret_cast<uword>(&isolate));
|
| -
|
| +static bool RunIsolate2(uword parameter) {
|
| + Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
|
| + SpawnState* state = reinterpret_cast<SpawnState*>(isolate->spawn_data());
|
| + isolate->set_spawn_data(NULL);
|
| {
|
| + StartIsolateScope start_scope(isolate);
|
| Zone zone(isolate);
|
| HandleScope handle_scope(isolate);
|
| ASSERT(ClassFinalizer::FinalizePendingClasses());
|
| @@ -503,16 +498,11 @@
|
| const Array& kNoArgNames = Array::Handle();
|
| result = DartEntry::InvokeStatic(func, args, kNoArgNames);
|
| if (result.IsError()) {
|
| - ProcessError(result);
|
| + StoreError(isolate, result);
|
| + return false;
|
| }
|
| -
|
| - result = isolate->StandardRunLoop();
|
| - if (result.IsError()) {
|
| - ProcessError(result);
|
| - }
|
| - ASSERT(result.IsNull());
|
| }
|
| - Dart::ShutdownIsolate();
|
| + return true;
|
| }
|
|
|
|
|
| @@ -551,15 +541,10 @@
|
| }
|
|
|
| // Start the new isolate.
|
| - int result = Thread::Start(RunIsolate2, reinterpret_cast<uword>(state));
|
| - if (result != 0) {
|
| - const String& msg = String::Handle(String::NewFormatted(
|
| - "Failed to start thread for isolate '%s'. Error code '%d'.",
|
| - state->isolate()->name(), result));
|
| - state->Cleanup();
|
| - delete state;
|
| - ThrowIsolateSpawnException(msg);
|
| - }
|
| + state->isolate()->set_spawn_data(reinterpret_cast<uword>(state));
|
| + state->isolate()->message_handler()->Run(
|
| + Dart::thread_pool(), RunIsolate2, ShutdownIsolate,
|
| + reinterpret_cast<uword>(state->isolate()));
|
|
|
| arguments->SetReturn(port);
|
| }
|
|
|