[fuchsia] Teach engine how to set up an isolate from a list of kernel files. (flutter/engine#5210)

This commit is contained in:
Ryan Macnak
2018-05-16 10:09:53 -07:00
committed by GitHub
parent 118335c206
commit aab4242b2c
5 changed files with 108 additions and 10 deletions

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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,

View 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

View File

@@ -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();