[fuchsia] Teach engine how to set up an isolate from a list of kernel files. (flutter/engine#5210)
This commit is contained in:
@@ -33,6 +33,7 @@ struct Settings {
|
||||
|
||||
std::string application_library_path;
|
||||
std::string application_kernel_asset;
|
||||
std::string application_kernel_list_asset;
|
||||
|
||||
std::string main_dart_file_path;
|
||||
std::string packages_file_path;
|
||||
|
||||
@@ -273,7 +273,9 @@ bool DartIsolate::PrepareForRunningFromPrecompiledCode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool LoadScriptSnapshot(std::shared_ptr<const fml::Mapping> mapping) {
|
||||
static bool LoadScriptSnapshot(std::shared_ptr<const fml::Mapping> mapping,
|
||||
bool last_piece) {
|
||||
FXL_CHECK(last_piece) << "Script snapshots cannot be divided";
|
||||
if (tonic::LogIfError(Dart_LoadScriptFromSnapshot(mapping->GetMapping(),
|
||||
mapping->GetSize()))) {
|
||||
return false;
|
||||
@@ -281,27 +283,40 @@ static bool LoadScriptSnapshot(std::shared_ptr<const fml::Mapping> mapping) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool LoadKernelSnapshot(std::shared_ptr<const fml::Mapping> mapping) {
|
||||
if (tonic::LogIfError(Dart_LoadScriptFromKernel(mapping->GetMapping(),
|
||||
mapping->GetSize()))) {
|
||||
static bool LoadKernelSnapshot(std::shared_ptr<const fml::Mapping> mapping,
|
||||
bool last_piece) {
|
||||
Dart_Handle library = Dart_LoadLibraryFromKernel(mapping->GetMapping(),
|
||||
mapping->GetSize());
|
||||
if (tonic::LogIfError(library)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!last_piece) {
|
||||
// More to come.
|
||||
return true;
|
||||
}
|
||||
|
||||
Dart_SetRootLibrary(library);
|
||||
if (tonic::LogIfError(Dart_FinalizeLoading(false))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool LoadSnapshot(std::shared_ptr<const fml::Mapping> mapping) {
|
||||
static bool LoadSnapshot(std::shared_ptr<const fml::Mapping> mapping,
|
||||
bool last_piece) {
|
||||
if (Dart_IsKernel(mapping->GetMapping(), mapping->GetSize())) {
|
||||
return LoadKernelSnapshot(std::move(mapping));
|
||||
return LoadKernelSnapshot(std::move(mapping), last_piece);
|
||||
} else {
|
||||
return LoadScriptSnapshot(std::move(mapping));
|
||||
return LoadScriptSnapshot(std::move(mapping), last_piece);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FXL_WARN_UNUSED_RESULT
|
||||
bool DartIsolate::PrepareForRunningFromSnapshot(
|
||||
std::shared_ptr<const fml::Mapping> mapping) {
|
||||
std::shared_ptr<const fml::Mapping> mapping,
|
||||
bool last_piece) {
|
||||
TRACE_EVENT0("flutter", "DartIsolate::PrepareForRunningFromSnapshot");
|
||||
if (phase_ != Phase::LibrariesSetup) {
|
||||
return false;
|
||||
@@ -321,10 +336,15 @@ bool DartIsolate::PrepareForRunningFromSnapshot(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!LoadSnapshot(mapping)) {
|
||||
if (!LoadSnapshot(mapping, last_piece)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!last_piece) {
|
||||
// More to come.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Dart_IsNull(Dart_RootLibrary())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -67,7 +67,8 @@ class DartIsolate : public UIDartState {
|
||||
|
||||
FXL_WARN_UNUSED_RESULT
|
||||
bool PrepareForRunningFromSnapshot(
|
||||
std::shared_ptr<const fml::Mapping> snapshot);
|
||||
std::shared_ptr<const fml::Mapping> snapshot,
|
||||
bool last_piece = true);
|
||||
|
||||
FXL_WARN_UNUSED_RESULT
|
||||
bool PrepareForRunningFromSource(const std::string& main_source_file,
|
||||
|
||||
@@ -88,6 +88,35 @@ class SourceIsolateConfiguration final : public IsolateConfiguration {
|
||||
FXL_DISALLOW_COPY_AND_ASSIGN(SourceIsolateConfiguration);
|
||||
};
|
||||
|
||||
class KernelListIsolateConfiguration final : public IsolateConfiguration {
|
||||
public:
|
||||
KernelListIsolateConfiguration(
|
||||
std::vector<std::unique_ptr<fml::Mapping>> kernel_pieces)
|
||||
: kernel_pieces_(std::move(kernel_pieces)) {}
|
||||
|
||||
// |shell::IsolateConfiguration|
|
||||
bool DoPrepareIsolate(blink::DartIsolate& isolate) override {
|
||||
if (blink::DartVM::IsRunningPrecompiledCode()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < kernel_pieces_.size(); i++) {
|
||||
bool last_piece = i + 1 == kernel_pieces_.size();
|
||||
if (!isolate.PrepareForRunningFromSnapshot(std::move(kernel_pieces_[i]),
|
||||
last_piece)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<fml::Mapping>> kernel_pieces_;
|
||||
|
||||
FXL_DISALLOW_COPY_AND_ASSIGN(KernelListIsolateConfiguration);
|
||||
};
|
||||
|
||||
std::unique_ptr<IsolateConfiguration> IsolateConfiguration::InferFromSettings(
|
||||
const blink::Settings& settings,
|
||||
fxl::RefPtr<blink::AssetManager> asset_manager) {
|
||||
@@ -107,6 +136,7 @@ std::unique_ptr<IsolateConfiguration> IsolateConfiguration::InferFromSettings(
|
||||
|
||||
// Running from kernel snapshot.
|
||||
{
|
||||
// TODO(engine): Add AssetManager::GetAsMapping or such to avoid the copy.
|
||||
std::vector<uint8_t> kernel;
|
||||
if (asset_manager && asset_manager->GetAsBuffer(
|
||||
settings.application_kernel_asset, &kernel)) {
|
||||
@@ -117,6 +147,7 @@ std::unique_ptr<IsolateConfiguration> IsolateConfiguration::InferFromSettings(
|
||||
|
||||
// Running from script snapshot.
|
||||
{
|
||||
// TODO(engine): Add AssetManager::GetAsMapping or such to avoid the copy.
|
||||
std::vector<uint8_t> script_snapshot;
|
||||
if (asset_manager && asset_manager->GetAsBuffer(
|
||||
settings.script_snapshot_path, &script_snapshot)) {
|
||||
@@ -125,6 +156,42 @@ std::unique_ptr<IsolateConfiguration> IsolateConfiguration::InferFromSettings(
|
||||
}
|
||||
}
|
||||
|
||||
// Running from kernel divided into several pieces (for sharing).
|
||||
{
|
||||
// TODO(fuchsia): Add AssetManager::GetAsMapping or such to avoid the copy.
|
||||
// TODO(fuchsia): Use async blobfs API once it becomes available.
|
||||
std::vector<uint8_t> kernel_list;
|
||||
if (asset_manager &&
|
||||
asset_manager->GetAsBuffer(settings.application_kernel_list_asset,
|
||||
&kernel_list)) {
|
||||
std::vector<std::unique_ptr<fml::Mapping>> kernel_pieces;
|
||||
|
||||
size_t piece_path_start = 0;
|
||||
while (piece_path_start < kernel_list.size()) {
|
||||
size_t piece_path_end = piece_path_start;
|
||||
while ((piece_path_end < kernel_list.size()) &&
|
||||
(kernel_list[piece_path_end] != '\n')) {
|
||||
piece_path_end++;
|
||||
}
|
||||
|
||||
std::string piece_path(reinterpret_cast<const char*>(&kernel_list[piece_path_start]),
|
||||
piece_path_end - piece_path_start);
|
||||
std::vector<uint8_t> piece;
|
||||
if (!asset_manager->GetAsBuffer(piece_path, &piece)) {
|
||||
FXL_LOG(ERROR) << "Failed to load: " << piece_path;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
kernel_pieces.emplace_back(
|
||||
std::make_unique<fml::DataMapping>(std::move(piece)));
|
||||
|
||||
piece_path_start = piece_path_end + 1;
|
||||
}
|
||||
|
||||
return CreateForKernelList(std::move(kernel_pieces));
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -145,4 +212,10 @@ std::unique_ptr<IsolateConfiguration> IsolateConfiguration::CreateForSource(
|
||||
std::move(packages_path));
|
||||
}
|
||||
|
||||
std::unique_ptr<IsolateConfiguration> IsolateConfiguration::CreateForKernelList(
|
||||
std::vector<std::unique_ptr<fml::Mapping>> kernel_pieces) {
|
||||
return std::make_unique<KernelListIsolateConfiguration>(
|
||||
std::move(kernel_pieces));
|
||||
}
|
||||
|
||||
} // namespace shell
|
||||
|
||||
@@ -33,6 +33,9 @@ class IsolateConfiguration {
|
||||
std::string main_path,
|
||||
std::string packages_path);
|
||||
|
||||
static std::unique_ptr<IsolateConfiguration> CreateForKernelList(
|
||||
std::vector<std::unique_ptr<fml::Mapping>> kernel_pieces);
|
||||
|
||||
IsolateConfiguration();
|
||||
|
||||
virtual ~IsolateConfiguration();
|
||||
|
||||
Reference in New Issue
Block a user