提交 ec19da1c 编写于 作者: A Alexander Aprelev 提交者: GitHub

Initialize service isolate from kernel file, rather than from embedded sources. (#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.
上级 28e08053
......@@ -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_);
......
......@@ -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_) {
......@@ -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";
......@@ -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,
......
......@@ -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_; }
......@@ -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
......
......@@ -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;
......@@ -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);
......@@ -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;
}
......@@ -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;
......@@ -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);
}
}
}
......@@ -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;
......@@ -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());
......
......@@ -11,6 +11,7 @@
#include <memory>
#include <string>
#include <vector>
namespace blink {
......@@ -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);
......
......@@ -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();
......@@ -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.
......@@ -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.
......
......@@ -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);
......
......@@ -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();
......
......@@ -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);
......
......@@ -20,7 +20,8 @@ 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);
......@@ -28,7 +29,7 @@ void InitRuntime(const uint8_t* vm_snapshot_data,
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
......@@ -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
......
......@@ -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"
......@@ -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,
......
......@@ -130,7 +130,7 @@ static const uint8_t* MemMapSnapshot(const std::string& aot_snapshot_path,
static const uint8_t* default_isolate_snapshot_data = nullptr;
static const uint8_t* default_isolate_snapshot_instr = nullptr;
void Engine::Init() {
void Engine::Init(const std::string& bundle_path) {
const uint8_t* vm_snapshot_data;
const uint8_t* vm_snapshot_instr;
#if !FLUTTER_AOT
......@@ -183,7 +183,7 @@ void Engine::Init() {
blink::InitRuntime(vm_snapshot_data, vm_snapshot_instr,
default_isolate_snapshot_data,
default_isolate_snapshot_instr);
default_isolate_snapshot_instr, bundle_path);
}
const std::string Engine::main_entrypoint_ = "main";
......@@ -193,10 +193,7 @@ void Engine::RunBundle(const std::string& bundle_path,
bool reuse_runtime_controller) {
TRACE_EVENT0("flutter", "Engine::RunBundle");
ConfigureAssetBundle(bundle_path);
std::vector<uint8_t> platform_kernel;
GetAssetAsBuffer(blink::kPlatformKernelAssetKey, &platform_kernel);
ConfigureRuntime(GetScriptUriFromPath(bundle_path), platform_kernel,
reuse_runtime_controller);
ConfigureRuntime(GetScriptUriFromPath(bundle_path), reuse_runtime_controller);
if (blink::IsRunningPrecompiledCode()) {
runtime_->dart_controller()->RunFromPrecompiledSnapshot(entrypoint);
......@@ -224,8 +221,7 @@ void Engine::RunBundleAndSnapshot(const std::string& bundle_path,
return;
}
ConfigureAssetBundle(bundle_path);
ConfigureRuntime(GetScriptUriFromPath(bundle_path), std::vector<uint8_t>(),
reuse_runtime_controller);
ConfigureRuntime(GetScriptUriFromPath(bundle_path), reuse_runtime_controller);
if (blink::IsRunningPrecompiledCode()) {
runtime_->dart_controller()->RunFromPrecompiledSnapshot(entrypoint);
} else {
......@@ -248,15 +244,9 @@ void Engine::RunBundleAndSource(const std::string& bundle_path,
if (packages_path.empty())
packages_path = FindPackagesPath(main);
std::vector<uint8_t> platform_kernel;
if (!bundle_path.empty()) {
ConfigureAssetBundle(bundle_path);
GetAssetAsBuffer(blink::kPlatformKernelAssetKey, &platform_kernel);
}
ConfigureRuntime(GetScriptUriFromPath(bundle_path), platform_kernel,
reuse_runtime_controller);
ConfigureRuntime(GetScriptUriFromPath(bundle_path), reuse_runtime_controller);
if (!platform_kernel.empty()) {
if (blink::GetKernelPlatformBinary() != nullptr) {
std::vector<uint8_t> kernel;
if (!files::ReadFileToVector(main, &kernel)) {
load_script_error_ = tonic::kUnknownErrorType;
......@@ -483,15 +473,14 @@ void Engine::ConfigureAssetBundle(const std::string& path) {
}
void Engine::ConfigureRuntime(const std::string& script_uri,
const std::vector<uint8_t>& platform_kernel,
bool reuse_runtime_controller) {
if (runtime_ && reuse_runtime_controller) {
return;
}
runtime_ = blink::RuntimeController::Create(this);
runtime_->CreateDartController(
std::move(script_uri), default_isolate_snapshot_data,
default_isolate_snapshot_instr, platform_kernel);
runtime_->CreateDartController(std::move(script_uri),
default_isolate_snapshot_data,
default_isolate_snapshot_instr);
runtime_->SetViewportMetrics(viewport_metrics_);
runtime_->SetLocale(language_code_, country_code_);
runtime_->SetUserSettingsData(user_settings_data_);
......
......@@ -33,7 +33,7 @@ class Engine : public blink::RuntimeDelegate {
fxl::WeakPtr<Engine> GetWeakPtr();
static void Init();
static void Init(const std::string& bundle_path);
void RunBundle(const std::string& bundle_path,
const std::string& entrypoint = main_entrypoint_,
......@@ -92,10 +92,8 @@ class Engine : public blink::RuntimeDelegate {
void StartAnimatorIfPossible();
void ConfigureAssetBundle(const std::string& path);
void ConfigureRuntime(
const std::string& script_uri,
const std::vector<uint8_t>& platform_kernel = std::vector<uint8_t>(),
bool reuse_runtime_controller = false);
void ConfigureRuntime(const std::string& script_uri,
bool reuse_runtime_controller = false);
bool HandleLifecyclePlatformMessage(blink::PlatformMessage* message);
bool HandleNavigationPlatformMessage(
......
......@@ -96,7 +96,8 @@ Shell::~Shell() {}
void Shell::InitStandalone(fxl::CommandLine command_line,
std::string icu_data_path,
std::string application_library_path) {
std::string application_library_path,
std::string bundle_path) {
TRACE_EVENT0("flutter", "Shell::InitStandalone");
fml::icu::InitializeICU(icu_data_path);
......@@ -191,10 +192,11 @@ void Shell::InitStandalone(fxl::CommandLine command_line,
blink::Settings::Set(settings);
Init(std::move(command_line));
Init(std::move(command_line), bundle_path);
}
void Shell::Init(fxl::CommandLine command_line) {
void Shell::Init(fxl::CommandLine command_line,
const std::string& bundle_path) {
#if FLUTTER_RUNTIME_MODE != FLUTTER_RUNTIME_MODE_RELEASE
bool trace_skia = command_line.HasOption(FlagForSwitch(Switch::TraceSkia));
InitSkiaEventTracer(trace_skia);
......@@ -202,7 +204,8 @@ void Shell::Init(fxl::CommandLine command_line) {
FXL_DCHECK(!g_shell);
g_shell = new Shell(std::move(command_line));
blink::Threads::UI()->PostTask(Engine::Init);
blink::Threads::UI()->PostTask(
[bundle_path]() { Engine::Init(bundle_path); });
}
Shell& Shell::Shared() {
......
......@@ -28,7 +28,8 @@ class Shell {
static void InitStandalone(fxl::CommandLine command_line,
std::string icu_data_path = "",
std::string application_library_path = "");
std::string application_library_path = "",
std::string bundle_path = "");
static Shell& Shared();
......@@ -71,7 +72,8 @@ class Shell {
std::string* isolate_name);
private:
static void Init(fxl::CommandLine command_line);
static void Init(fxl::CommandLine command_line,
const std::string& bundle_path);
Shell(fxl::CommandLine command_line);
......
......@@ -19,7 +19,8 @@ namespace shell {
static void Init(JNIEnv* env,
jclass clazz,
jobject context,
jobjectArray jargs) {
jobjectArray jargs,
jstring bundlePath) {
// Prepare command line arguments and initialize the shell.
std::vector<std::string> args;
args.push_back("flutter_tester");
......@@ -30,7 +31,9 @@ static void Init(JNIEnv* env,
auto command_line = fxl::CommandLineFromIterators(args.begin(), args.end());
std::string icu_data_path =
command_line.GetOptionValueWithDefault("icu-data-file-path", "");
Shell::InitStandalone(std::move(command_line), std::move(icu_data_path));
Shell::InitStandalone(std::move(command_line), std::move(icu_data_path),
/* application_library_path= */ "",
fml::jni::JavaStringToString(env, bundlePath));
}
static void RecordStartTimestamp(JNIEnv* env,
......@@ -45,7 +48,8 @@ bool RegisterFlutterMain(JNIEnv* env) {
static const JNINativeMethod methods[] = {
{
.name = "nativeInit",
.signature = "(Landroid/content/Context;[Ljava/lang/String;)V",
.signature = "(Landroid/content/Context;[Ljava/lang/String;Ljava/"
"lang/String;)V",
.fnPtr = reinterpret_cast<void*>(&Init),
},
{
......
......@@ -188,7 +188,9 @@ public class FlutterMain {
shellArgs.add("--log-tag=" + sSettings.getLogTag());
}
nativeInit(applicationContext, shellArgs.toArray(new String[0]));
String appBundlePath = findAppBundlePath(applicationContext);
nativeInit(applicationContext, shellArgs.toArray(new String[0]),
appBundlePath);
sInitialized = true;
} catch (Exception e) {
......@@ -197,7 +199,7 @@ public class FlutterMain {
}
}
private static native void nativeInit(Context context, String[] args);
private static native void nativeInit(Context context, String[] args, String bundlePath);
private static native void nativeRecordStartTimestamp(long initTimeMillis);
/**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册