Index: runtime/lib/isolate.cc |
=================================================================== |
--- runtime/lib/isolate.cc (revision 20976) |
+++ runtime/lib/isolate.cc (working copy) |
@@ -42,12 +42,6 @@ |
} |
-static void StoreError(Isolate* isolate, const Object& obj) { |
- ASSERT(obj.IsError()); |
- isolate->object_store()->set_sticky_error(Error::Cast(obj)); |
-} |
- |
- |
// TODO(turnidge): Move to DartLibraryCalls. |
static RawObject* ReceivePortCreate(intptr_t port_id) { |
Isolate* isolate = Isolate::Current(); |
@@ -82,37 +76,6 @@ |
} |
-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); |
- StackZone zone(isolate); |
- HandleScope handle_scope(isolate); |
- Error& error = Error::Handle(); |
- error = isolate->object_store()->sticky_error(); |
- if (!error.IsNull()) { |
- OS::PrintErr("in ShutdownIsolate: %s\n", error.ToErrorCString()); |
- } |
- } |
- { |
- // Shut the isolate down. |
- SwitchIsolateScope switch_scope(isolate); |
- Dart::ShutdownIsolate(); |
- } |
-} |
- |
- |
-static char* GetRootScriptUri(Isolate* isolate) { |
- const Library& library = |
- Library::Handle(isolate->object_store()->root_library()); |
- ASSERT(!library.IsNull()); |
- const String& script_name = String::Handle(library.url()); |
- return isolate->current_zone()->MakeCopyOfString(script_name.ToCString()); |
-} |
- |
- |
DEFINE_NATIVE_ENTRY(ReceivePortImpl_factory, 1) { |
ASSERT(AbstractTypeArguments::CheckedHandle( |
arguments->NativeArgAt(0)).IsNull()); |
@@ -202,100 +165,7 @@ |
} |
-class SpawnState { |
- public: |
- SpawnState(const Function& func, const Function& callback_func) |
- : isolate_(NULL), |
- script_url_(NULL), |
- library_url_(NULL), |
- function_name_(NULL), |
- exception_callback_name_(NULL) { |
- script_url_ = strdup(GetRootScriptUri(Isolate::Current())); |
- const Class& cls = Class::Handle(func.Owner()); |
- ASSERT(cls.IsTopLevel()); |
- const Library& lib = Library::Handle(cls.library()); |
- const String& lib_url = String::Handle(lib.url()); |
- library_url_ = strdup(lib_url.ToCString()); |
- |
- const String& func_name = String::Handle(func.name()); |
- function_name_ = strdup(func_name.ToCString()); |
- if (!callback_func.IsNull()) { |
- const String& callback_name = String::Handle(callback_func.name()); |
- exception_callback_name_ = strdup(callback_name.ToCString()); |
- } else { |
- exception_callback_name_ = strdup("_unhandledExceptionCallback"); |
- } |
- } |
- |
- explicit SpawnState(const char* script_url) |
- : isolate_(NULL), |
- library_url_(NULL), |
- function_name_(NULL), |
- exception_callback_name_(NULL) { |
- script_url_ = strdup(script_url); |
- library_url_ = NULL; |
- function_name_ = strdup("main"); |
- exception_callback_name_ = strdup("_unhandledExceptionCallback"); |
- } |
- |
- ~SpawnState() { |
- free(script_url_); |
- free(library_url_); |
- free(function_name_); |
- free(exception_callback_name_); |
- } |
- |
- Isolate* isolate() const { return isolate_; } |
- void set_isolate(Isolate* value) { isolate_ = value; } |
- char* script_url() const { return script_url_; } |
- char* library_url() const { return library_url_; } |
- char* function_name() const { return function_name_; } |
- char* exception_callback_name() const { return exception_callback_name_; } |
- |
- RawObject* ResolveFunction() { |
- // Resolve the library. |
- Library& lib = Library::Handle(); |
- if (library_url()) { |
- const String& lib_url = String::Handle(String::New(library_url())); |
- lib = Library::LookupLibrary(lib_url); |
- if (lib.IsNull() || lib.IsError()) { |
- const String& msg = String::Handle(String::NewFormatted( |
- "Unable to find library '%s'.", library_url())); |
- return LanguageError::New(msg); |
- } |
- } else { |
- lib = isolate()->object_store()->root_library(); |
- } |
- ASSERT(!lib.IsNull()); |
- |
- // Resolve the function. |
- const String& func_name = |
- String::Handle(String::New(function_name())); |
- const Function& func = Function::Handle(lib.LookupLocalFunction(func_name)); |
- if (func.IsNull()) { |
- const String& msg = String::Handle(String::NewFormatted( |
- "Unable to resolve function '%s' in library '%s'.", |
- function_name(), (library_url() ? library_url() : script_url()))); |
- return LanguageError::New(msg); |
- } |
- return func.raw(); |
- } |
- |
- void Cleanup() { |
- SwitchIsolateScope switch_scope(isolate()); |
- Dart::ShutdownIsolate(); |
- } |
- |
- private: |
- Isolate* isolate_; |
- char* script_url_; |
- char* library_url_; |
- char* function_name_; |
- char* exception_callback_name_; |
-}; |
- |
- |
-static bool CreateIsolate(SpawnState* state, char** error) { |
+static bool CreateIsolate(IsolateSpawnState* state, char** error) { |
Isolate* parent_isolate = Isolate::Current(); |
Dart_IsolateCreateCallback callback = Isolate::CreateCallback(); |
@@ -306,87 +176,23 @@ |
} |
void* init_data = parent_isolate->init_callback_data(); |
- bool retval = (callback)(state->script_url(), |
- state->function_name(), |
- init_data, |
- error); |
- if (!retval) { |
+ Isolate* child_isolate = reinterpret_cast<Isolate*>( |
+ (callback)(state->script_url(), |
+ state->function_name(), |
+ init_data, |
+ error)); |
+ if (child_isolate == NULL) { |
Isolate::SetCurrent(parent_isolate); |
return false; |
} |
+ state->set_isolate(reinterpret_cast<Isolate*>(child_isolate)); |
- Isolate* child_isolate = Isolate::Current(); |
- ASSERT(child_isolate); |
- state->set_isolate(child_isolate); |
- |
- // Attempt to resolve the entry function now, so that we fail fast |
- // in the case that the function cannot be resolved. |
- // |
- // TODO(turnidge): Revisit this once we have an isolate death api. |
- bool resolve_error = false; |
- { |
- StackZone zone(child_isolate); |
- HandleScope handle_scope(child_isolate); |
- const Object& result = Object::Handle(state->ResolveFunction()); |
- if (result.IsError()) { |
- Error& errobj = Error::Handle(); |
- errobj ^= result.raw(); |
- *error = strdup(errobj.ToErrorCString()); |
- resolve_error = true; |
- } else { |
- const String& callback_name = |
- String::Handle(child_isolate, |
- String::New(state->exception_callback_name())); |
- child_isolate->object_store()-> |
- set_unhandled_exception_handler(callback_name); |
- } |
- } |
- if (resolve_error) { |
- Dart::ShutdownIsolate(); |
- Isolate::SetCurrent(parent_isolate); |
- return false; |
- } |
- |
Isolate::SetCurrent(parent_isolate); |
return true; |
} |
-static bool RunIsolate(uword parameter) { |
- Isolate* isolate = reinterpret_cast<Isolate*>(parameter); |
- SpawnState* state = reinterpret_cast<SpawnState*>(isolate->spawn_data()); |
- isolate->set_spawn_data(0); |
- { |
- StartIsolateScope start_scope(isolate); |
- StackZone zone(isolate); |
- HandleScope handle_scope(isolate); |
- if (!ClassFinalizer::FinalizePendingClasses()) { |
- // Error is in sticky error already. |
- return false; |
- } |
- |
- Object& result = Object::Handle(); |
- result = state->ResolveFunction(); |
- delete state; |
- state = NULL; |
- if (result.IsError()) { |
- StoreError(isolate, result); |
- return false; |
- } |
- ASSERT(result.IsFunction()); |
- Function& func = Function::Handle(isolate); |
- func ^= result.raw(); |
- result = DartEntry::InvokeFunction(func, Object::empty_array()); |
- if (result.IsError()) { |
- StoreError(isolate, result); |
- return false; |
- } |
- } |
- return true; |
-} |
- |
- |
-static RawObject* Spawn(NativeArguments* arguments, SpawnState* state) { |
+static RawObject* Spawn(NativeArguments* arguments, IsolateSpawnState* state) { |
// Create a new isolate. |
char* error = NULL; |
if (!CreateIsolate(state, &error)) { |
@@ -405,11 +211,12 @@ |
Exceptions::PropagateError(Error::Cast(port)); |
} |
- // Start the new isolate. |
+ // Start the new isolate if it is already marked as runnable. |
+ MutexLocker ml(state->isolate()->mutex()); |
state->isolate()->set_spawn_data(reinterpret_cast<uword>(state)); |
- state->isolate()->message_handler()->Run( |
- Dart::thread_pool(), RunIsolate, ShutdownIsolate, |
- reinterpret_cast<uword>(state->isolate())); |
+ if (state->isolate()->is_runnable()) { |
+ state->isolate()->Run(); |
+ } |
return port.raw(); |
} |
@@ -464,7 +271,7 @@ |
} |
#endif |
- return Spawn(arguments, new SpawnState(func, callback_func)); |
+ return Spawn(arguments, new IsolateSpawnState(func, callback_func)); |
} |
@@ -482,7 +289,7 @@ |
ThrowIsolateSpawnException(msg); |
} |
- return Spawn(arguments, new SpawnState(canonical_uri)); |
+ return Spawn(arguments, new IsolateSpawnState(canonical_uri)); |
} |