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

Update Flutter engine kernel-loading logic. (#3886)

* Fix Flutter loading from dill files.

* Remove disable of causal async stacks.

* Include mirrors patch files as they are needed for release/profile gen_snapshot

* Free the bytes

* Add FTL_DCHECK
上级 f56d6781
......@@ -364,6 +364,11 @@ generate_vm_patched_sdk("flutter_patched_sdk") {
processed_gypis.math_runtime_sources,
"//dart/runtime/lib",
],
[
"mirrors",
processed_gypis.mirrors_runtime_sources,
"//dart/runtime/lib",
],
[
"typed_data",
processed_gypis.typed_data_runtime_sources,
......
......@@ -44,7 +44,8 @@ std::string ResolvePath(std::string path) {
} // namespace
DartController::DartController() : ui_dart_state_(nullptr) {}
DartController::DartController() : ui_dart_state_(nullptr),
kernel_bytes(nullptr), platform_kernel_bytes(nullptr) {}
DartController::~DartController() {
if (ui_dart_state_) {
......@@ -55,6 +56,12 @@ DartController::~DartController() {
Dart_ShutdownIsolate(); // deletes ui_dart_state_
ui_dart_state_ = nullptr;
}
if (kernel_bytes) {
free(kernel_bytes);
}
if (platform_kernel_bytes) {
free(platform_kernel_bytes);
}
}
bool DartController::SendStartMessage(Dart_Handle root_library) {
......@@ -94,10 +101,25 @@ bool DartController::SendStartMessage(Dart_Handle root_library) {
return LogIfError(result);
}
static void CopyVectorBytes(const std::vector<uint8_t>& vector,
uint8_t*& bytes) {
if (bytes) {
free(bytes);
}
bytes = (uint8_t*) malloc(vector.size());
memcpy(bytes, vector.data(), vector.size());
}
tonic::DartErrorHandleType DartController::RunFromKernel(
const uint8_t* buffer, size_t size) {
const std::vector<uint8_t>& kernel) {
tonic::DartState::Scope scope(dart_state());
Dart_Handle result = Dart_LoadKernel(Dart_ReadKernelBinary(buffer, size));
// 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(kernel, kernel_bytes);
Dart_Handle result = Dart_LoadKernel(
Dart_ReadKernelBinary(kernel_bytes, kernel.size()));
LogIfError(result);
tonic::DartErrorHandleType error = tonic::GetErrorHandleType(result);
if (SendStartMessage(Dart_RootLibrary())) {
......@@ -146,11 +168,28 @@ tonic::DartErrorHandleType DartController::RunFromSource(
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) {
char* error = nullptr;
Dart_Isolate isolate = Dart_CreateIsolate(
script_uri.c_str(), "main", isolate_snapshot_data, isolate_snapshot_instr,
nullptr, static_cast<tonic::DartState*>(state.get()), &error);
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);
isolate = Dart_CreateIsolateFromKernel(
script_uri.c_str(), "main",
Dart_ReadKernelBinary(platform_kernel_bytes, platform_kernel.size()),
nullptr /* flags */,
static_cast<tonic::DartState*>(state.get()), &error);
} else {
isolate = Dart_CreateIsolate(
script_uri.c_str(), "main", isolate_snapshot_data,
isolate_snapshot_instr, nullptr,
static_cast<tonic::DartState*>(state.get()), &error);
}
FTL_CHECK(isolate) << error;
ui_dart_state_ = state.release();
dart_state()->message_handler().Initialize(blink::Threads::UI());
......
......@@ -6,6 +6,7 @@
#define FLUTTER_RUNTIME_DART_CONTROLLER_H_
#include <memory>
#include <vector>
#include "dart/runtime/include/dart_api.h"
#include "lib/ftl/macros.h"
......@@ -19,7 +20,7 @@ class DartController {
DartController();
~DartController();
tonic::DartErrorHandleType RunFromKernel(const uint8_t* buffer, size_t size);
tonic::DartErrorHandleType RunFromKernel(const std::vector<uint8_t>& kernel);
tonic::DartErrorHandleType RunFromPrecompiledSnapshot();
tonic::DartErrorHandleType RunFromScriptSnapshot(const uint8_t* buffer,
size_t size);
......@@ -29,6 +30,7 @@ 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_; }
......@@ -40,6 +42,15 @@ class DartController {
// during isolate shutdown.
UIDartState* ui_dart_state_;
// Kernel binary image of dart script. This is copied and maintained
// for dart script lifespan, so that kernel loading mechanism can
// incrementally build the dart objects from it.
uint8_t* kernel_bytes;
// 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;
FTL_DISALLOW_COPY_AND_ASSIGN(DartController);
};
}
......
......@@ -67,6 +67,7 @@ namespace blink {
const char kKernelAssetKey[] = "kernel_blob.bin";
const char kSnapshotAssetKey[] = "snapshot_blob.bin";
const char kPlatformKernelAssetKey[] = "platform.dill";
namespace {
......@@ -243,6 +244,7 @@ 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;
......@@ -262,15 +264,25 @@ 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());
FTL_DCHECK(kernel_platform != NULL);
}
}
}
UIDartState* parent_dart_state = static_cast<UIDartState*>(callback_data);
UIDartState* dart_state = parent_dart_state->CreateForChildIsolate();
Dart_Isolate isolate = Dart_CreateIsolate(
script_uri, main, g_default_isolate_snapshot_data,
g_default_isolate_snapshot_instructions, nullptr, dart_state, error);
Dart_Isolate isolate = kernel_platform != nullptr
? Dart_CreateIsolateFromKernel(script_uri, main, kernel_platform,
nullptr /* flags */, dart_state, error)
: Dart_CreateIsolate(script_uri, main, g_default_isolate_snapshot_data,
g_default_isolate_snapshot_instructions, nullptr, dart_state, error);
FTL_CHECK(isolate) << error;
dart_state->SetIsolate(isolate);
FTL_CHECK(!LogIfError(
......
......@@ -20,6 +20,9 @@ extern const char kKernelAssetKey[];
// Name of the snapshot blob asset within the FLX bundle.
extern const char kSnapshotAssetKey[];
// Name of the platform kernel blob asset within the FLX bundle.
extern const char kPlatformKernelAssetKey[];
bool IsRunningPrecompiledCode();
using EmbedderTracingCallback = ftl::Closure;
......
......@@ -28,12 +28,14 @@ RuntimeController::~RuntimeController() {}
void RuntimeController::CreateDartController(
const std::string& script_uri, const uint8_t* isolate_snapshot_data,
const uint8_t* isolate_snapshot_instr) {
const uint8_t* isolate_snapshot_instr,
const std::vector<uint8_t>& platform_kernel) {
FTL_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,7 +28,8 @@ 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 uint8_t* isolate_snapshot_instr,
const std::vector<uint8_t>& kernel_platform);
DartController* dart_controller() const { return dart_controller_.get(); }
void SetViewportMetrics(const ViewportMetrics& metrics);
......
......@@ -181,13 +181,16 @@ void Engine::Init() {
void Engine::RunBundle(const std::string& bundle_path) {
TRACE_EVENT0("flutter", "Engine::RunBundle");
ConfigureAssetBundle(bundle_path);
ConfigureRuntime(GetScriptUriFromPath(bundle_path));
std::vector<uint8_t> platform_kernel;
GetAssetAsBuffer(blink::kPlatformKernelAssetKey, &platform_kernel);
ConfigureRuntime(GetScriptUriFromPath(bundle_path), platform_kernel);
if (blink::IsRunningPrecompiledCode()) {
runtime_->dart_controller()->RunFromPrecompiledSnapshot();
} else {
std::vector<uint8_t> kernel;
if (GetAssetAsBuffer(blink::kKernelAssetKey, &kernel)) {
runtime_->dart_controller()->RunFromKernel(kernel.data(), kernel.size());
runtime_->dart_controller()->RunFromKernel(kernel);
return;
}
std::vector<uint8_t> snapshot;
......@@ -425,11 +428,13 @@ void Engine::ConfigureAssetBundle(const std::string& path) {
}
}
void Engine::ConfigureRuntime(const std::string& script_uri) {
void Engine::ConfigureRuntime(const std::string& script_uri,
const std::vector<uint8_t>& platform_kernel) {
runtime_ = blink::RuntimeController::Create(this);
runtime_->CreateDartController(std::move(script_uri),
default_isolate_snapshot_data,
default_isolate_snapshot_instr);
default_isolate_snapshot_instr,
platform_kernel);
runtime_->SetViewportMetrics(viewport_metrics_);
runtime_->SetLocale(language_code_, country_code_);
runtime_->SetSemanticsEnabled(semantics_enabled_);
......
......@@ -84,7 +84,8 @@ class Engine : public blink::RuntimeDelegate {
void StartAnimatorIfPossible();
void ConfigureAssetBundle(const std::string& path);
void ConfigureRuntime(const std::string& script_uri);
void ConfigureRuntime(const std::string& script_uri,
const std::vector<uint8_t>& platform_kernel = std::vector<uint8_t>());
bool HandleLifecyclePlatformMessage(blink::PlatformMessage* message);
bool HandleNavigationPlatformMessage(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册