mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Update Flutter engine kernel-loading logic. (flutter/engine#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
This commit is contained in:
parent
b355dec44a
commit
5bc3ac48a3
@ -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(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user