dart-sdk/runtime/bin/dart_embedder_api_impl.cc

159 lines
5.1 KiB
C++
Raw Normal View History

// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#include "include/dart_embedder_api.h"
#include "bin/dartutils.h"
#include "bin/eventhandler.h"
#include "bin/isolate_data.h"
#include "bin/process.h"
#include "bin/secure_socket_filter.h"
#include "bin/thread.h"
#include "bin/utils.h"
#include "bin/vmservice_impl.h"
namespace dart {
namespace embedder {
static char* MallocFormatedString(const char* format, ...) {
va_list args;
va_start(args, format);
intptr_t len = vsnprintf(NULL, 0, format, args);
va_end(args);
char* buffer = reinterpret_cast<char*>(malloc(len + 1));
MSAN_UNPOISON(buffer, (len + 1));
va_list args2;
va_start(args2, format);
vsnprintf(buffer, (len + 1), format, args2);
va_end(args2);
return buffer;
}
bool InitOnce(char** error) {
if (!bin::DartUtils::SetOriginalWorkingDirectory()) {
bin::OSError err;
*error = MallocFormatedString("Error determining current directory: %s\n",
err.message());
return false;
}
bin::TimerUtils::InitOnce();
bin::Process::Init();
#if !defined(DART_IO_SECURE_SOCKET_DISABLED)
bin::SSLFilter::Init();
#endif
bin::EventHandler::Start();
return true;
}
void Cleanup() {
bin::Process::ClearAllSignalHandlers();
bin::EventHandler::Stop();
#if !defined(DART_IO_SECURE_SOCKET_DISABLED)
bin::SSLFilter::Cleanup();
#endif
bin::Process::Cleanup();
}
Dart_Isolate CreateKernelServiceIsolate(const IsolateCreationData& data,
const uint8_t* buffer,
intptr_t buffer_size,
char** error) {
Second attempt to reland "[vm/concurrency] Introduce concept of Isolate Groups" This reverts commit 3d14b75f972ca287cd892ff907cf04b22839af59. An Isolate Group (IG) is a collection of isolates which were spawned from the same source. This allows the VM to: * have a guarantee that all isolates within one IG can safely exchange structured objects (currently we rely on embedder for this guarantee) * hot-reload all isolates together (currently we only reload one isolate, leaving same-source isolates in inconsistent state) * make a shared heap for all isolates from the same IG, which paves the way for faster communication and sharing of immutable objects. All isolates within one IG will share the same IsolateGroupSource. **Embedder changes** This change makes breaking embedder API changes to support this new concept of Isolate Groups: The existing isolate lifecycle callbacks given to Dart_Initialize will become Isolate Group lifecycle callbacks. A new callback `initialize_isolate` callback will be added which can initialize a new isolate within an existing IG. Existing embedders can be updated by performing the following renames Dart_CreateIsolate -> Dart_CreateIsolateGroup Dart_IsolateCreateCallback -> Dart_IsolateGroupCreateCallback Dart_IsolateCleanupCallback -> Dart_IsolateGroupShutdownCallback Dart_CreateIsolateFromKernel -> Dart_CreateIsolateGroupFromKernel Dart_CurrentIsolateData -> Dart_CurrentIsolateGroupData Dart_IsolateData -> Dart_IsolateGroupData Dart_GetNativeIsolateData -> Dart_GetNativeIsolateGroupData Dart_InitializeParams.create -> Dart_InitializeParams.create_group Dart_InitializeParams.cleanup -> Dart_InitializeParams.shutdown_group Dart_InitializeParams.shutdown -> Dart_InitializeParams.shutdown_isolate By default `Isolate.spawn` will cause the creation of a new IG. Though an embedder can opt-into supporting multiple isolates within one IG by providing a callback to the newly added `Dart_InitializeParams.initialize_isolate`. The responsibility of this new callback is to initialize an existing isolate (which was setup by re-using source code from the spawning isolate - i.e. the one which used `Isolate.spawn`) by setting native resolvers, initializing global state, etc. Issue https://github.com/dart-lang/sdk/issues/36648 Issue https://github.com/dart-lang/sdk/issues/36097 Original review: https://dart-review.googlesource.com/c/sdk/+/105241 Difference to original review: * Give each isolate it's own [Loader] (for now) * Sort classes during initialization for spawned isolates if app-jit is used (to match main isolate) * Fix IsolateData memory leak if isolate startup fails Difference to first reland(Patchset 2): * Fix typo where memory was freed twice. Change-Id: Ib1c83fe83b629cd50ae6af90ee99fdd44da882d4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/108367 Commit-Queue: Alexander Aprelev <aam@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
2019-07-08 23:49:05 +00:00
Dart_Isolate kernel_isolate = Dart_CreateIsolateGroupFromKernel(
data.script_uri, data.main, buffer, buffer_size, data.flags,
Second attempt to reland "[vm/concurrency] Introduce concept of Isolate Groups" This reverts commit 3d14b75f972ca287cd892ff907cf04b22839af59. An Isolate Group (IG) is a collection of isolates which were spawned from the same source. This allows the VM to: * have a guarantee that all isolates within one IG can safely exchange structured objects (currently we rely on embedder for this guarantee) * hot-reload all isolates together (currently we only reload one isolate, leaving same-source isolates in inconsistent state) * make a shared heap for all isolates from the same IG, which paves the way for faster communication and sharing of immutable objects. All isolates within one IG will share the same IsolateGroupSource. **Embedder changes** This change makes breaking embedder API changes to support this new concept of Isolate Groups: The existing isolate lifecycle callbacks given to Dart_Initialize will become Isolate Group lifecycle callbacks. A new callback `initialize_isolate` callback will be added which can initialize a new isolate within an existing IG. Existing embedders can be updated by performing the following renames Dart_CreateIsolate -> Dart_CreateIsolateGroup Dart_IsolateCreateCallback -> Dart_IsolateGroupCreateCallback Dart_IsolateCleanupCallback -> Dart_IsolateGroupShutdownCallback Dart_CreateIsolateFromKernel -> Dart_CreateIsolateGroupFromKernel Dart_CurrentIsolateData -> Dart_CurrentIsolateGroupData Dart_IsolateData -> Dart_IsolateGroupData Dart_GetNativeIsolateData -> Dart_GetNativeIsolateGroupData Dart_InitializeParams.create -> Dart_InitializeParams.create_group Dart_InitializeParams.cleanup -> Dart_InitializeParams.shutdown_group Dart_InitializeParams.shutdown -> Dart_InitializeParams.shutdown_isolate By default `Isolate.spawn` will cause the creation of a new IG. Though an embedder can opt-into supporting multiple isolates within one IG by providing a callback to the newly added `Dart_InitializeParams.initialize_isolate`. The responsibility of this new callback is to initialize an existing isolate (which was setup by re-using source code from the spawning isolate - i.e. the one which used `Isolate.spawn`) by setting native resolvers, initializing global state, etc. Issue https://github.com/dart-lang/sdk/issues/36648 Issue https://github.com/dart-lang/sdk/issues/36097 Original review: https://dart-review.googlesource.com/c/sdk/+/105241 Difference to original review: * Give each isolate it's own [Loader] (for now) * Sort classes during initialization for spawned isolates if app-jit is used (to match main isolate) * Fix IsolateData memory leak if isolate startup fails Difference to first reland(Patchset 2): * Fix typo where memory was freed twice. Change-Id: Ib1c83fe83b629cd50ae6af90ee99fdd44da882d4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/108367 Commit-Queue: Alexander Aprelev <aam@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
2019-07-08 23:49:05 +00:00
data.isolate_group_data, data.isolate_data, error);
if (kernel_isolate == nullptr) {
return nullptr;
}
Dart_EnterScope();
Dart_Handle result = Dart_LoadScriptFromKernel(buffer, buffer_size);
if (Dart_IsError(result)) {
*error = Utils::StrDup(Dart_GetError(result));
Dart_ExitScope();
Dart_ShutdownIsolate();
return nullptr;
}
result = bin::DartUtils::PrepareForScriptLoading(/*is_service_isolate=*/false,
/*trace_loading=*/false);
Dart_ExitScope();
Dart_ExitIsolate();
return kernel_isolate;
}
Dart_Isolate CreateVmServiceIsolate(const IsolateCreationData& data,
const VmServiceConfiguration& config,
const uint8_t* isolate_data,
const uint8_t* isolate_instr,
char** error) {
if (data.flags == nullptr) {
*error = Utils::StrDup("Expected non-null flags");
return nullptr;
}
data.flags->load_vmservice_library = true;
Dart_Isolate service_isolate = Dart_CreateIsolateGroup(
data.script_uri, data.main, isolate_data, isolate_instr, data.flags,
data.isolate_group_data, data.isolate_data, error);
if (service_isolate == nullptr) {
return nullptr;
}
Dart_EnterScope();
// Load embedder specific bits and return.
if (!bin::VmService::Setup(config.ip, config.port, config.dev_mode,
config.disable_auth_codes,
config.write_service_info_filename,
/*trace_loading=*/false, config.deterministic,
/*enable_service_port_fallback=*/false,
/*wait_for_dds_to_advertise_service=*/false)) {
*error = Utils::StrDup(bin::VmService::GetErrorMessage());
return nullptr;
}
Dart_ExitScope();
Dart_ExitIsolate();
return service_isolate;
}
Dart_Isolate CreateVmServiceIsolateFromKernel(
const IsolateCreationData& data,
const VmServiceConfiguration& config,
const uint8_t* kernel_buffer,
intptr_t kernel_buffer_size,
char** error) {
if (data.flags == nullptr) {
*error = Utils::StrDup("Expected non-null flags");
return nullptr;
}
data.flags->load_vmservice_library = true;
Second attempt to reland "[vm/concurrency] Introduce concept of Isolate Groups" This reverts commit 3d14b75f972ca287cd892ff907cf04b22839af59. An Isolate Group (IG) is a collection of isolates which were spawned from the same source. This allows the VM to: * have a guarantee that all isolates within one IG can safely exchange structured objects (currently we rely on embedder for this guarantee) * hot-reload all isolates together (currently we only reload one isolate, leaving same-source isolates in inconsistent state) * make a shared heap for all isolates from the same IG, which paves the way for faster communication and sharing of immutable objects. All isolates within one IG will share the same IsolateGroupSource. **Embedder changes** This change makes breaking embedder API changes to support this new concept of Isolate Groups: The existing isolate lifecycle callbacks given to Dart_Initialize will become Isolate Group lifecycle callbacks. A new callback `initialize_isolate` callback will be added which can initialize a new isolate within an existing IG. Existing embedders can be updated by performing the following renames Dart_CreateIsolate -> Dart_CreateIsolateGroup Dart_IsolateCreateCallback -> Dart_IsolateGroupCreateCallback Dart_IsolateCleanupCallback -> Dart_IsolateGroupShutdownCallback Dart_CreateIsolateFromKernel -> Dart_CreateIsolateGroupFromKernel Dart_CurrentIsolateData -> Dart_CurrentIsolateGroupData Dart_IsolateData -> Dart_IsolateGroupData Dart_GetNativeIsolateData -> Dart_GetNativeIsolateGroupData Dart_InitializeParams.create -> Dart_InitializeParams.create_group Dart_InitializeParams.cleanup -> Dart_InitializeParams.shutdown_group Dart_InitializeParams.shutdown -> Dart_InitializeParams.shutdown_isolate By default `Isolate.spawn` will cause the creation of a new IG. Though an embedder can opt-into supporting multiple isolates within one IG by providing a callback to the newly added `Dart_InitializeParams.initialize_isolate`. The responsibility of this new callback is to initialize an existing isolate (which was setup by re-using source code from the spawning isolate - i.e. the one which used `Isolate.spawn`) by setting native resolvers, initializing global state, etc. Issue https://github.com/dart-lang/sdk/issues/36648 Issue https://github.com/dart-lang/sdk/issues/36097 Original review: https://dart-review.googlesource.com/c/sdk/+/105241 Difference to original review: * Give each isolate it's own [Loader] (for now) * Sort classes during initialization for spawned isolates if app-jit is used (to match main isolate) * Fix IsolateData memory leak if isolate startup fails Difference to first reland(Patchset 2): * Fix typo where memory was freed twice. Change-Id: Ib1c83fe83b629cd50ae6af90ee99fdd44da882d4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/108367 Commit-Queue: Alexander Aprelev <aam@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
2019-07-08 23:49:05 +00:00
Dart_Isolate service_isolate = Dart_CreateIsolateGroupFromKernel(
data.script_uri, data.main, kernel_buffer, kernel_buffer_size, data.flags,
Second attempt to reland "[vm/concurrency] Introduce concept of Isolate Groups" This reverts commit 3d14b75f972ca287cd892ff907cf04b22839af59. An Isolate Group (IG) is a collection of isolates which were spawned from the same source. This allows the VM to: * have a guarantee that all isolates within one IG can safely exchange structured objects (currently we rely on embedder for this guarantee) * hot-reload all isolates together (currently we only reload one isolate, leaving same-source isolates in inconsistent state) * make a shared heap for all isolates from the same IG, which paves the way for faster communication and sharing of immutable objects. All isolates within one IG will share the same IsolateGroupSource. **Embedder changes** This change makes breaking embedder API changes to support this new concept of Isolate Groups: The existing isolate lifecycle callbacks given to Dart_Initialize will become Isolate Group lifecycle callbacks. A new callback `initialize_isolate` callback will be added which can initialize a new isolate within an existing IG. Existing embedders can be updated by performing the following renames Dart_CreateIsolate -> Dart_CreateIsolateGroup Dart_IsolateCreateCallback -> Dart_IsolateGroupCreateCallback Dart_IsolateCleanupCallback -> Dart_IsolateGroupShutdownCallback Dart_CreateIsolateFromKernel -> Dart_CreateIsolateGroupFromKernel Dart_CurrentIsolateData -> Dart_CurrentIsolateGroupData Dart_IsolateData -> Dart_IsolateGroupData Dart_GetNativeIsolateData -> Dart_GetNativeIsolateGroupData Dart_InitializeParams.create -> Dart_InitializeParams.create_group Dart_InitializeParams.cleanup -> Dart_InitializeParams.shutdown_group Dart_InitializeParams.shutdown -> Dart_InitializeParams.shutdown_isolate By default `Isolate.spawn` will cause the creation of a new IG. Though an embedder can opt-into supporting multiple isolates within one IG by providing a callback to the newly added `Dart_InitializeParams.initialize_isolate`. The responsibility of this new callback is to initialize an existing isolate (which was setup by re-using source code from the spawning isolate - i.e. the one which used `Isolate.spawn`) by setting native resolvers, initializing global state, etc. Issue https://github.com/dart-lang/sdk/issues/36648 Issue https://github.com/dart-lang/sdk/issues/36097 Original review: https://dart-review.googlesource.com/c/sdk/+/105241 Difference to original review: * Give each isolate it's own [Loader] (for now) * Sort classes during initialization for spawned isolates if app-jit is used (to match main isolate) * Fix IsolateData memory leak if isolate startup fails Difference to first reland(Patchset 2): * Fix typo where memory was freed twice. Change-Id: Ib1c83fe83b629cd50ae6af90ee99fdd44da882d4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/108367 Commit-Queue: Alexander Aprelev <aam@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
2019-07-08 23:49:05 +00:00
data.isolate_group_data, data.isolate_data, error);
if (service_isolate == nullptr) {
return nullptr;
}
Dart_EnterScope();
// Load embedder specific bits and return.
if (!bin::VmService::Setup(config.ip, config.port, config.dev_mode,
config.disable_auth_codes,
config.write_service_info_filename,
/*trace_loading=*/false, config.deterministic,
/*enable_service_port_fallback=*/false,
/*wait_for_dds_to_advertise_service=*/false)) {
*error = Utils::StrDup(bin::VmService::GetErrorMessage());
return nullptr;
}
Dart_ExitScope();
Dart_ExitIsolate();
return service_isolate;
}
} // namespace embedder
} // namespace dart