Chromium Code Reviews| Index: runtime/vm/kernel_isolate.cc |
| diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc |
| index 8d682ab2cd786aa1a299925801b3a6d94dce674e..59fda4f0ff3dd08ff89f3ea00770400a3d4a1cbb 100644 |
| --- a/runtime/vm/kernel_isolate.cc |
| +++ b/runtime/vm/kernel_isolate.cc |
| @@ -5,6 +5,7 @@ |
| #include "vm/kernel_isolate.h" |
| #include "vm/compiler.h" |
| +#include "include/dart_native_api.h" |
| #include "vm/dart_api_impl.h" |
| #include "vm/dart_entry.h" |
| #include "vm/isolate.h" |
| @@ -33,7 +34,7 @@ DEFINE_FLAG(bool, |
| false, |
| "Parse scripts with Dart-to-Kernel parser"); |
| -const char* KernelIsolate::kName = "kernel-service"; |
| +const char* KernelIsolate::kName = DART_KERNEL_ISOLATE_NAME; |
| Dart_IsolateCreateCallback KernelIsolate::create_callback_ = NULL; |
| Monitor* KernelIsolate::monitor_ = new Monitor(); |
| Isolate* KernelIsolate::isolate_ = NULL; |
| @@ -74,7 +75,8 @@ class RunKernelTask : public ThreadPool::Task { |
| KernelIsolate::kName, NULL, NULL, NULL, &api_flags, NULL, &error)); |
| if (isolate == NULL) { |
| if (FLAG_trace_kernel) { |
| - OS::PrintErr("kernel-service: Isolate creation error: %s\n", error); |
| + OS::PrintErr(DART_KERNEL_ISOLATE_NAME ": Isolate creation error: %s\n", |
| + error); |
| } |
| KernelIsolate::SetKernelIsolate(NULL); |
| KernelIsolate::FinishedInitializing(); |
| @@ -104,7 +106,7 @@ class RunKernelTask : public ThreadPool::Task { |
| protected: |
| static void ShutdownIsolate(uword parameter) { |
| if (FLAG_trace_kernel) { |
| - OS::Print("kernel-service: ShutdownIsolate\n"); |
| + OS::Print(DART_KERNEL_ISOLATE_NAME ": ShutdownIsolate\n"); |
| } |
| Isolate* I = reinterpret_cast<Isolate*>(parameter); |
| ASSERT(KernelIsolate::IsKernelIsolate(I)); |
| @@ -123,18 +125,20 @@ class RunKernelTask : public ThreadPool::Task { |
| Error& error = Error::Handle(Z); |
| error = T->sticky_error(); |
| if (!error.IsNull() && !error.IsUnwindError()) { |
| - OS::PrintErr("kernel-service: Error: %s\n", error.ToErrorCString()); |
| + OS::PrintErr(DART_KERNEL_ISOLATE_NAME ": Error: %s\n", |
| + error.ToErrorCString()); |
| } |
| error = I->sticky_error(); |
| if (!error.IsNull() && !error.IsUnwindError()) { |
| - OS::PrintErr("kernel-service: Error: %s\n", error.ToErrorCString()); |
| + OS::PrintErr(DART_KERNEL_ISOLATE_NAME ": Error: %s\n", |
| + error.ToErrorCString()); |
| } |
| Dart::RunShutdownCallback(); |
| } |
| // Shut the isolate down. |
| Dart::ShutdownIsolate(I); |
| if (FLAG_trace_kernel) { |
| - OS::Print("kernel-service: Shutdown.\n"); |
| + OS::Print(DART_KERNEL_ISOLATE_NAME ": Shutdown.\n"); |
| } |
| } |
| @@ -148,7 +152,8 @@ class RunKernelTask : public ThreadPool::Task { |
| Library::Handle(Z, I->object_store()->root_library()); |
| if (root_library.IsNull()) { |
| if (FLAG_trace_kernel) { |
| - OS::Print("kernel-service: Embedder did not install a script."); |
| + OS::Print(DART_KERNEL_ISOLATE_NAME |
| + ": Embedder did not install a script."); |
| } |
| // Kernel isolate is not supported by embedder. |
| return false; |
| @@ -161,7 +166,8 @@ class RunKernelTask : public ThreadPool::Task { |
| if (entry.IsNull()) { |
| // Kernel isolate is not supported by embedder. |
| if (FLAG_trace_kernel) { |
| - OS::Print("kernel-service: Embedder did not provide a main function."); |
| + OS::Print(DART_KERNEL_ISOLATE_NAME |
| + ": Embedder did not provide a main function."); |
| } |
| return false; |
| } |
| @@ -173,7 +179,8 @@ class RunKernelTask : public ThreadPool::Task { |
| // Kernel isolate did not initialize properly. |
| if (FLAG_trace_kernel) { |
| const Error& error = Error::Cast(result); |
| - OS::Print("kernel-service: Calling main resulted in an error: %s", |
| + OS::Print(DART_KERNEL_ISOLATE_NAME |
| + ": Calling main resulted in an error: %s", |
| error.ToErrorCString()); |
| } |
| return false; |
| @@ -203,13 +210,13 @@ void KernelIsolate::InitCallback(Isolate* I) { |
| ASSERT(I != NULL); |
| ASSERT(I->name() != NULL); |
| if (!FLAG_use_dart_frontend || |
| - (strstr(I->name(), "kernel-service") == NULL)) { |
| + (strstr(I->name(), DART_KERNEL_ISOLATE_NAME) == NULL)) { |
| // Not kernel isolate. |
| return; |
| } |
| ASSERT(!Exists()); |
| if (FLAG_trace_kernel) { |
| - OS::Print("kernel-service: InitCallback for %s.\n", I->name()); |
| + OS::Print(DART_KERNEL_ISOLATE_NAME ": InitCallback for %s.\n", I->name()); |
| } |
| SetKernelIsolate(I); |
| } |
| @@ -238,11 +245,13 @@ void KernelIsolate::SetKernelIsolate(Isolate* isolate) { |
| isolate_ = isolate; |
| } |
| + |
| void KernelIsolate::SetLoadPort(Dart_Port port) { |
| MonitorLocker ml(monitor_); |
| kernel_port_ = port; |
| } |
| + |
| void KernelIsolate::FinishedInitializing() { |
| MonitorLocker ml(monitor_); |
| initializing_ = false; |
| @@ -261,6 +270,133 @@ Dart_Port KernelIsolate::WaitForKernelPort() { |
| return kernel_port_; |
| } |
| + |
| +class KernelCompilationRequest { |
|
kustermann
2017/01/30 12:14:26
: public StackResource
Vyacheslav Egorov (Google)
2017/01/30 19:34:14
Done.
|
| + public: |
| + KernelCompilationRequest() |
| + : monitor_(new Monitor()), |
| + port_(Dart_NewNativePort("kernel-compilation-port", |
| + &HandleResponse, |
| + false, |
| + this)) { |
| + result_.status = Dart_KernelCompilationStatus_Unknown; |
| + result_.error = NULL; |
| + result_.kernel = NULL; |
| + result_.kernel_size = 0; |
| + } |
| + |
| + ~KernelCompilationRequest() { |
| + Dart_CloseNativePort(port_); |
| + delete monitor_; |
| + } |
| + |
| + Dart_KernelCompilationResult SendAndWaitForResponse(Dart_Port kernel_port, |
| + const char* script_uri) { |
| + char* script_uri_copy = strdup(script_uri); |
| + |
| + // Build the [null, send_port, script_uri] message for the Kernel isolate: |
| + // null tag tells it that request came from this code, instead of Loader |
| + // so that it can given a more informative response. |
| + Dart_CObject tag; |
| + tag.type = Dart_CObject_kNull; |
| + |
| + Dart_CObject send_port; |
| + send_port.type = Dart_CObject_kSendPort; |
| + send_port.value.as_send_port.id = port_; |
| + send_port.value.as_send_port.origin_id = ILLEGAL_PORT; |
| + |
| + Dart_CObject uri; |
| + uri.type = Dart_CObject_kString; |
| + uri.value.as_string = script_uri_copy; |
| + |
| + static const intptr_t kMessageLen = 3; |
| + Dart_CObject* message_arr[kMessageLen] = {&tag, &send_port, &uri}; |
| + |
| + Dart_CObject message; |
| + message.type = Dart_CObject_kArray; |
| + message.value.as_array.length = kMessageLen; |
| + message.value.as_array.values = message_arr; |
| + |
| + // Send the message. |
| + Dart_PostCObject(kernel_port, &message); |
| + |
| + // Wait for reply to arrive. |
| + MonitorLocker ml(monitor_); |
| + while (result_.status == Dart_KernelCompilationStatus_Unknown) { |
| + ml.Wait(); |
| + } |
| + |
| + free(script_uri_copy); |
|
kustermann
2017/01/30 12:14:28
Why do you strdup() it first, and free it here. Ca
Vyacheslav Egorov (Google)
2017/01/30 19:34:14
Done.
|
| + return result_; |
| + } |
| + |
| + private: |
| + // Possible responses from the Kernel isolate: |
| + // |
| + // [Ok, Uint8List KernelBinary] |
| + // [Error, String error] |
| + // [Crash, String error] |
| + // |
| + void HandleResponseImpl(Dart_CObject* message) { |
| + ASSERT(message->type == Dart_CObject_kArray); |
| + ASSERT(message->value.as_array.length >= 1); |
| + |
| + Dart_CObject** response = message->value.as_array.values; |
| + |
| + MonitorLocker ml(monitor_); |
| + |
| + ASSERT(response[0]->type == Dart_CObject_kInt32); |
| + result_.status = static_cast<Dart_KernelCompilationStatus>( |
| + message->value.as_array.values[0]->value.as_int32); |
| + |
| + if (result_.status == Dart_KernelCompilationStatus_Ok) { |
| + ASSERT(response[1]->type == Dart_CObject_kTypedData); |
| + ASSERT(response[1]->value.as_typed_data.type == Dart_TypedData_kUint8); |
| + |
| + result_.kernel_size = response[1]->value.as_typed_data.length; |
| + result_.kernel = static_cast<uint8_t*>(malloc(result_.kernel_size)); |
| + memmove(result_.kernel, response[1]->value.as_typed_data.values, |
| + result_.kernel_size); |
| + } else { |
| + ASSERT(result_.status == Dart_KernelCompilationStatus_Crash || |
| + result_.status == Dart_KernelCompilationStatus_Error); |
| + // This is an error. |
| + ASSERT(response[1]->type == Dart_CObject_kString); |
| + result_.error = strdup(response[1]->value.as_string); |
| + } |
| + ml.NotifyAll(); |
|
siva
2017/01/24 02:38:02
Why does it have to do a notifyAll, it appears tha
kustermann
2017/01/30 12:14:26
Agreed. Notify() should be enough
Vyacheslav Egorov (Google)
2017/01/30 19:34:14
Done.
|
| + } |
| + |
| + static void HandleResponse(Dart_Port dest_port_id, |
| + Dart_CObject* message, |
| + void* peer) { |
| + static_cast<KernelCompilationRequest*>(peer)->HandleResponseImpl(message); |
| + } |
| + |
| + Monitor* monitor_; |
| + Dart_Port port_; |
| + |
| + Dart_KernelCompilationResult result_; |
|
siva
2017/01/24 02:38:02
The boiler plate DISALLOW_* stuff is missing.
kustermann
2017/01/30 12:14:28
I think it can be inherited via StackResource.
Vyacheslav Egorov (Google)
2017/01/30 19:34:14
Done.
|
| +}; |
| + |
| + |
| +Dart_KernelCompilationResult KernelIsolate::CompileToKernel( |
| + const char* script_uri) { |
| + // This must be the main script to be loaded. Wait for Kernel isolate |
| + // to finish initialization. |
| + Dart_Port kernel_port = WaitForKernelPort(); |
| + if (kernel_port == ILLEGAL_PORT) { |
| + Dart_KernelCompilationResult result; |
| + result.status = Dart_KernelCompilationStatus_Unknown; |
| + result.error = strdup("Error while initializing Kernel isolate"); |
| + return result; |
| + } |
| + |
| + KernelCompilationRequest request; |
| + return request.SendAndWaitForResponse(kernel_port, script_uri); |
| +} |
| + |
| + |
| #endif // DART_PRECOMPILED_RUNTIME |
| } // namespace dart |