Skip to content

Commit

Permalink
Initialize service isolate from kernel file, rather than from embedde…
Browse files Browse the repository at this point in the history
…d sources. (flutter#4263)

* Read core platform kernel file during Dart initialization.

Currently service isolate is initialized from the source code parsed by VM.
This CL changes it so service isolate created during Dart initialization
is created from the kernel platform.dill file if it is present in the application
bundle. Then this platform kernel file is kept in dart_init module and reused
for application sciprt isolates.

* Reformat and merge

* Use accessor method

* Avoid passing running_from_kernel param. Add TODO for cleanup. Rename param.
  • Loading branch information
aam authored Oct 25, 2017
1 parent 28e0805 commit ec19da1
Show file tree
Hide file tree
Showing 18 changed files with 125 additions and 111 deletions.
4 changes: 1 addition & 3 deletions content_handler/runtime_holder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -266,10 +266,8 @@ void RuntimeHolder::CreateView(
isolate_snapshot_instr = reinterpret_cast<const uint8_t*>(
dlsym(dylib_handle_, "_kDartIsolateSnapshotInstructions"));
}
std::vector<uint8_t> empty_platform_kernel;
runtime_->CreateDartController(script_uri, isolate_snapshot_data,
isolate_snapshot_instr,
std::move(empty_platform_kernel));
isolate_snapshot_instr);

runtime_->SetViewportMetrics(viewport_metrics_);

Expand Down
32 changes: 10 additions & 22 deletions runtime/dart_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ std::string ResolvePath(std::string path) {

} // namespace

DartController::DartController()
: ui_dart_state_(nullptr), platform_kernel_bytes(nullptr) {}
DartController::DartController() : ui_dart_state_(nullptr) {}

DartController::~DartController() {
if (ui_dart_state_) {
Expand All @@ -57,9 +56,6 @@ DartController::~DartController() {
Dart_ShutdownIsolate();
delete ui_dart_state_;
}
if (platform_kernel_bytes) {
free(platform_kernel_bytes);
}
}

const std::string DartController::main_entrypoint_ = "main";
Expand Down Expand Up @@ -181,27 +177,19 @@ tonic::DartErrorHandleType DartController::RunFromSource(
return error;
}

void DartController::CreateIsolateFor(
const std::string& script_uri,
const uint8_t* isolate_snapshot_data,
const uint8_t* isolate_snapshot_instr,
const std::vector<uint8_t>& platform_kernel,
std::unique_ptr<UIDartState> state) {
void DartController::CreateIsolateFor(const std::string& script_uri,
const uint8_t* isolate_snapshot_data,
const uint8_t* isolate_snapshot_instr,
std::unique_ptr<UIDartState> state) {
char* error = nullptr;

Dart_Isolate isolate;
if (!platform_kernel.empty()) {
// Copy kernel bytes so they won't go away after we exit this method.
// This is needed because original kernel data has to be available
// during code execution.
CopyVectorBytes(platform_kernel, platform_kernel_bytes);
void* platform_kernel = GetKernelPlatformBinary();

Dart_Isolate isolate;
if (platform_kernel != nullptr) {
isolate = Dart_CreateIsolateFromKernel(
script_uri.c_str(), "main",
Dart_ReadKernelBinary(platform_kernel_bytes, platform_kernel.size(),
ReleaseFetchedBytes),
nullptr /* flags */, static_cast<tonic::DartState*>(state.get()),
&error);
script_uri.c_str(), "main", platform_kernel, nullptr /* flags */,
static_cast<tonic::DartState*>(state.get()), &error);
} else {
isolate =
Dart_CreateIsolate(script_uri.c_str(), "main", isolate_snapshot_data,
Expand Down
6 changes: 0 additions & 6 deletions runtime/dart_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ class DartController {
void CreateIsolateFor(const std::string& script_uri,
const uint8_t* isolate_snapshot_data,
const uint8_t* isolate_snapshot_instr,
const std::vector<uint8_t>& platform_kernel,
std::unique_ptr<UIDartState> ui_dart_state);

UIDartState* dart_state() const { return ui_dart_state_; }
Expand All @@ -53,11 +52,6 @@ class DartController {
// object is deleted.
UIDartState* ui_dart_state_;

// Kernel binary image of platform core libraries. This is copied and
// maintained for dart script lifespan, so that kernel loading mechanism can
// incrementally build the dart objects from it.
uint8_t* platform_kernel_bytes;

FXL_DISALLOW_COPY_AND_ASSIGN(DartController);
};
} // namespace blink
Expand Down
53 changes: 39 additions & 14 deletions runtime/dart_init.cc
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,14 @@ static ServiceIsolateHook g_service_isolate_hook = nullptr;
static RegisterNativeServiceProtocolExtensionHook
g_register_native_service_protocol_extensions_hook = nullptr;

// Kernel representation of core dart libraries(loaded from platform.dill).
// TODO(aam): This (and platform_data below) have to be released when engine
// gets torn down. At that point we could also call Dart_Cleanup to complete
// Dart VM cleanup.
static void* kernel_platform = nullptr;
// Bytes actually read from platform.dill that are referenced by kernel_platform
static std::vector<uint8_t> platform_data;

void IsolateShutdownCallback(void* callback_data) {
if (tonic::DartStickyError::IsSet()) {
tonic::DartApiScope api_scope;
Expand Down Expand Up @@ -194,10 +202,19 @@ Dart_Isolate ServiceIsolateCreateCallback(const char* script_uri,
return nullptr;
#else // FLUTTER_RUNTIME_MODE
UIDartState* dart_state = new UIDartState(nullptr, nullptr);

bool is_running_from_kernel = GetKernelPlatformBinary() != nullptr;

Dart_Isolate isolate =
Dart_CreateIsolate(script_uri, "main", g_default_isolate_snapshot_data,
g_default_isolate_snapshot_instructions, nullptr,
static_cast<tonic::DartState*>(dart_state), error);
is_running_from_kernel
? Dart_CreateIsolateFromKernel(
script_uri, "main", kernel_platform, nullptr /* flags */,
static_cast<tonic::DartState*>(dart_state), error)
: Dart_CreateIsolate(
script_uri, "main", g_default_isolate_snapshot_data,
g_default_isolate_snapshot_instructions, nullptr,
static_cast<tonic::DartState*>(dart_state), error);

FXL_CHECK(isolate) << error;
dart_state->set_debug_name_prefix(script_uri);
dart_state->SetIsolate(isolate);
Expand All @@ -216,7 +233,8 @@ Dart_Isolate ServiceIsolateCreateCallback(const char* script_uri,
const bool disable_websocket_origin_check = false;
const bool service_isolate_booted = DartServiceIsolate::Startup(
ip, port, tonic::DartState::HandleLibraryTag,
IsRunningPrecompiledCode(), disable_websocket_origin_check, error);
!IsRunningPrecompiledCode() && !is_running_from_kernel,
disable_websocket_origin_check, error);
FXL_CHECK(service_isolate_booted) << error;
}

Expand Down Expand Up @@ -252,7 +270,6 @@ Dart_Isolate IsolateCreateCallback(const char* script_uri,
// Are we running from a Dart source file?
const bool running_from_source = StringEndsWith(entry_uri, ".dart");

void* kernel_platform = nullptr;
std::vector<uint8_t> kernel_data;
std::vector<uint8_t> snapshot_data;
std::string entry_path;
Expand All @@ -272,14 +289,6 @@ Dart_Isolate IsolateCreateCallback(const char* script_uri,
GetUnzipperProviderForPath(std::move(bundle_path)));
zip_asset_store->GetAsBuffer(kKernelAssetKey, &kernel_data);
zip_asset_store->GetAsBuffer(kSnapshotAssetKey, &snapshot_data);

std::vector<uint8_t> platform_data;
zip_asset_store->GetAsBuffer(kPlatformKernelAssetKey, &platform_data);
if (!platform_data.empty()) {
kernel_platform = Dart_ReadKernelBinary(
platform_data.data(), platform_data.size(), ReleaseFetchedBytes);
FXL_DCHECK(kernel_platform != NULL);
}
}
}

Expand Down Expand Up @@ -454,10 +463,15 @@ static void EmbedderInformationCallback(Dart_EmbedderInformation* info) {
info->name = "Flutter";
}

void* GetKernelPlatformBinary() {
return kernel_platform;
}

void InitDartVM(const uint8_t* vm_snapshot_data,
const uint8_t* vm_snapshot_instructions,
const uint8_t* default_isolate_snapshot_data,
const uint8_t* default_isolate_snapshot_instructions) {
const uint8_t* default_isolate_snapshot_instructions,
const std::string& bundle_path) {
TRACE_EVENT0("flutter", __func__);

g_default_isolate_snapshot_data = default_isolate_snapshot_data;
Expand Down Expand Up @@ -534,6 +548,17 @@ void InitDartVM(const uint8_t* vm_snapshot_data,
PushBackAll(&args, kDartFuchsiaTraceArgs, arraysize(kDartFuchsiaTraceArgs));
#endif

if (!bundle_path.empty()) {
auto zip_asset_store = fxl::MakeRefCounted<ZipAssetStore>(
GetUnzipperProviderForPath(std::move(bundle_path)));
zip_asset_store->GetAsBuffer(kPlatformKernelAssetKey, &platform_data);
if (!platform_data.empty()) {
kernel_platform = Dart_ReadKernelBinary(
platform_data.data(), platform_data.size(), ReleaseFetchedBytes);
FXL_DCHECK(kernel_platform != nullptr);
}
}

for (size_t i = 0; i < settings.dart_flags.size(); i++)
args.push_back(settings.dart_flags[i].c_str());

Expand Down
6 changes: 5 additions & 1 deletion runtime/dart_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <memory>
#include <string>
#include <vector>

namespace blink {

Expand Down Expand Up @@ -41,7 +42,10 @@ struct EmbedderTracingCallbacks {
void InitDartVM(const uint8_t* vm_snapshot_data,
const uint8_t* vm_snapshot_instructions,
const uint8_t* default_isolate_snapshot_data,
const uint8_t* default_isolate_snapshot_instructions);
const uint8_t* default_isolate_snapshot_instructions,
const std::string& bundle_path);

void* GetKernelPlatformBinary();

void SetEmbedderTracingCallbacks(
std::unique_ptr<EmbedderTracingCallbacks> callbacks);
Expand Down
20 changes: 10 additions & 10 deletions runtime/dart_service_isolate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ void DartServiceIsolate::Shutdown(Dart_NativeArguments args) {
bool DartServiceIsolate::Startup(std::string server_ip,
intptr_t server_port,
Dart_LibraryTagHandler embedder_tag_handler,
bool running_precompiled,
bool running_from_sources,
bool disable_origin_check,
char** error) {
Dart_Isolate isolate = Dart_CurrentIsolate();
Expand All @@ -110,15 +110,7 @@ bool DartServiceIsolate::Startup(std::string server_ip,

Dart_Handle result;

if (running_precompiled) {
Dart_Handle uri = Dart_NewStringFromCString("dart:vmservice_sky");
Dart_Handle library = Dart_LookupLibrary(uri);
SHUTDOWN_ON_ERROR(library);
result = Dart_SetRootLibrary(library);
SHUTDOWN_ON_ERROR(result);
result = Dart_SetNativeResolver(library, GetNativeFunction, GetSymbol);
SHUTDOWN_ON_ERROR(result);
} else {
if (running_from_sources) {
// Use our own library tag handler when loading service isolate sources.
Dart_SetLibraryTagHandler(DartServiceIsolate::LibraryTagHandler);
// Load main script.
Expand All @@ -132,6 +124,14 @@ bool DartServiceIsolate::Startup(std::string server_ip,
// Finalize loading.
result = Dart_FinalizeLoading(false);
SHUTDOWN_ON_ERROR(result);
} else {
Dart_Handle uri = Dart_NewStringFromCString("dart:vmservice_sky");
Dart_Handle library = Dart_LookupLibrary(uri);
SHUTDOWN_ON_ERROR(library);
result = Dart_SetRootLibrary(library);
SHUTDOWN_ON_ERROR(result);
result = Dart_SetNativeResolver(library, GetNativeFunction, GetSymbol);
SHUTDOWN_ON_ERROR(result);
}

// Make runnable.
Expand Down
2 changes: 1 addition & 1 deletion runtime/dart_service_isolate.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class DartServiceIsolate {
static bool Startup(std::string server_ip,
intptr_t server_port,
Dart_LibraryTagHandler embedder_tag_handler,
bool running_precompiled,
bool running_from_sources,
bool disable_origin_check,
char** error);

Expand Down
4 changes: 1 addition & 3 deletions runtime/runtime_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,12 @@ RuntimeController::~RuntimeController() {}
void RuntimeController::CreateDartController(
const std::string& script_uri,
const uint8_t* isolate_snapshot_data,
const uint8_t* isolate_snapshot_instr,
const std::vector<uint8_t>& platform_kernel) {
const uint8_t* isolate_snapshot_instr) {
FXL_DCHECK(!dart_controller_);

dart_controller_.reset(new DartController());
dart_controller_->CreateIsolateFor(
script_uri, isolate_snapshot_data, isolate_snapshot_instr,
platform_kernel,
std::make_unique<UIDartState>(this, std::make_unique<Window>(this)));

UIDartState* dart_state = dart_controller_->dart_state();
Expand Down
3 changes: 1 addition & 2 deletions runtime/runtime_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ class RuntimeController : public WindowClient, public IsolateClient {

void CreateDartController(const std::string& script_uri,
const uint8_t* isolate_snapshot_data,
const uint8_t* isolate_snapshot_instr,
const std::vector<uint8_t>& kernel_platform);
const uint8_t* isolate_snapshot_instr);
DartController* dart_controller() const { return dart_controller_.get(); }

void SetViewportMetrics(const ViewportMetrics& metrics);
Expand Down
5 changes: 3 additions & 2 deletions runtime/runtime_init.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@ PlatformImpl* g_platform_impl = nullptr;
void InitRuntime(const uint8_t* vm_snapshot_data,
const uint8_t* vm_snapshot_instructions,
const uint8_t* default_isolate_snapshot_data,
const uint8_t* default_isolate_snapshot_instructions) {
const uint8_t* default_isolate_snapshot_instructions,
const std::string& bundle_path) {
TRACE_EVENT0("flutter", "InitRuntime");

FXL_CHECK(!g_platform_impl);
g_platform_impl = new PlatformImpl();
InitEngine(g_platform_impl);
InitDartVM(vm_snapshot_data, vm_snapshot_instructions,
default_isolate_snapshot_data,
default_isolate_snapshot_instructions);
default_isolate_snapshot_instructions, bundle_path);
}

} // namespace blink
4 changes: 3 additions & 1 deletion runtime/runtime_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
#define FLUTTER_RUNTIME_RUNTIME_INIT_H_

#include <inttypes.h>
#include <string>

namespace blink {

void InitRuntime(const uint8_t* vm_snapshot_data,
const uint8_t* vm_snapshot_instructions,
const uint8_t* default_isolate_snapshot_data,
const uint8_t* default_isolate_snapshot_instructions);
const uint8_t* default_isolate_snapshot_instructions,
const std::string& bundle_path);

} // namespace blink

Expand Down
27 changes: 17 additions & 10 deletions shell/common/diagnostic/diagnostic_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "flutter/common/threads.h"
#include "flutter/flow/compositor_context.h"
#include "flutter/runtime/dart_init.h"
#include "flutter/runtime/embedder_resources.h"
#include "flutter/shell/common/engine.h"
#include "flutter/shell/common/picture_serializer.h"
Expand Down Expand Up @@ -72,16 +73,22 @@ void DiagnosticServer::Start(uint32_t port, bool ipv6) {
EmbedderResources resources(
&flutter::runtime::__sky_embedder_diagnostic_server_resources_[0]);

const char* source = nullptr;
int source_length =
resources.ResourceLookup(kDiagnosticServerScript, &source);
FXL_DCHECK(source_length != EmbedderResources::kNoSuchInstance);

Dart_Handle diagnostic_library = Dart_LoadLibrary(
Dart_NewStringFromCString("dart:diagnostic_server"), Dart_Null(),
Dart_NewStringFromUTF8(reinterpret_cast<const uint8_t*>(source),
source_length),
0, 0);
Dart_Handle diagnostic_library;
if (blink::GetKernelPlatformBinary() != nullptr) {
diagnostic_library =
Dart_LookupLibrary(Dart_NewStringFromCString("dart:diagnostic_server"));
} else {
const char* source = nullptr;
int source_length =
resources.ResourceLookup(kDiagnosticServerScript, &source);
FXL_DCHECK(source_length != EmbedderResources::kNoSuchInstance);

diagnostic_library = Dart_LoadLibrary(
Dart_NewStringFromCString("dart:diagnostic_server"), Dart_Null(),
Dart_NewStringFromUTF8(reinterpret_cast<const uint8_t*>(source),
source_length),
0, 0);
}

FXL_CHECK(!LogIfError(diagnostic_library));
FXL_CHECK(!LogIfError(Dart_SetNativeResolver(diagnostic_library,
Expand Down
Loading

0 comments on commit ec19da1

Please sign in to comment.