Skip to content

Commit

Permalink
Allow embedders to specify AOT snapshot buffers. (#7538)
Browse files Browse the repository at this point in the history
  • Loading branch information
chinmaygarde committed Jan 19, 2019
1 parent 75cfebd commit 898b4f8
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 19 deletions.
19 changes: 15 additions & 4 deletions common/settings.h
Expand Up @@ -13,6 +13,7 @@
#include <vector>

#include "flutter/fml/closure.h"
#include "flutter/fml/mapping.h"
#include "flutter/fml/unique_fd.h"

namespace blink {
Expand All @@ -21,6 +22,11 @@ using TaskObserverAdd =
std::function<void(intptr_t /* key */, fml::closure /* callback */)>;
using TaskObserverRemove = std::function<void(intptr_t /* key */)>;

// TODO(chinmaygarde): Deprecate all the "path" struct members in favor of the
// callback that generates the mapping from these paths.
// https://github.com/flutter/flutter/issues/26783
using MappingCallback = std::function<std::unique_ptr<fml::Mapping>(void)>;

struct Settings {
Settings();

Expand All @@ -29,10 +35,15 @@ struct Settings {
~Settings();

// VM settings
std::string vm_snapshot_data_path;
std::string vm_snapshot_instr_path;
std::string isolate_snapshot_data_path;
std::string isolate_snapshot_instr_path;
std::string vm_snapshot_data_path; // deprecated
MappingCallback vm_snapshot_data;
std::string vm_snapshot_instr_path; // deprecated
MappingCallback vm_snapshot_instr;

std::string isolate_snapshot_data_path; // deprecated
MappingCallback isolate_snapshot_data;
std::string isolate_snapshot_instr_path; // deprecated
MappingCallback isolate_snapshot_instr;

std::string application_library_path;
std::string application_kernel_asset;
Expand Down
18 changes: 18 additions & 0 deletions runtime/dart_snapshot.cc
Expand Up @@ -41,6 +41,10 @@ static const char* kIsolateInstructionsSymbolSo =
SYMBOL_PREFIX "kDartIsolateSnapshotInstructions";

std::unique_ptr<DartSnapshotBuffer> ResolveVMData(const Settings& settings) {
if (settings.vm_snapshot_data) {
return DartSnapshotBuffer::CreateWithMapping(settings.vm_snapshot_data());
}

if (settings.vm_snapshot_data_path.size() > 0) {
if (auto source = DartSnapshotBuffer::CreateWithContentsOfFile(
fml::OpenFile(settings.vm_snapshot_data_path.c_str(), false,
Expand All @@ -66,6 +70,10 @@ std::unique_ptr<DartSnapshotBuffer> ResolveVMData(const Settings& settings) {

std::unique_ptr<DartSnapshotBuffer> ResolveVMInstructions(
const Settings& settings) {
if (settings.vm_snapshot_instr) {
return DartSnapshotBuffer::CreateWithMapping(settings.vm_snapshot_instr());
}

if (settings.vm_snapshot_instr_path.size() > 0) {
if (auto source = DartSnapshotBuffer::CreateWithContentsOfFile(
fml::OpenFile(settings.vm_snapshot_instr_path.c_str(), false,
Expand All @@ -91,6 +99,11 @@ std::unique_ptr<DartSnapshotBuffer> ResolveVMInstructions(

std::unique_ptr<DartSnapshotBuffer> ResolveIsolateData(
const Settings& settings) {
if (settings.isolate_snapshot_data) {
return DartSnapshotBuffer::CreateWithMapping(
settings.isolate_snapshot_data());
}

if (settings.isolate_snapshot_data_path.size() > 0) {
if (auto source = DartSnapshotBuffer::CreateWithContentsOfFile(
fml::OpenFile(settings.isolate_snapshot_data_path.c_str(), false,
Expand All @@ -116,6 +129,11 @@ std::unique_ptr<DartSnapshotBuffer> ResolveIsolateData(

std::unique_ptr<DartSnapshotBuffer> ResolveIsolateInstructions(
const Settings& settings) {
if (settings.isolate_snapshot_data) {
return DartSnapshotBuffer::CreateWithMapping(
settings.isolate_snapshot_instr());
}

if (settings.isolate_snapshot_instr_path.size() > 0) {
if (auto source = DartSnapshotBuffer::CreateWithContentsOfFile(
fml::OpenFile(settings.isolate_snapshot_instr_path.c_str(), false,
Expand Down
35 changes: 20 additions & 15 deletions runtime/dart_snapshot_buffer.cc
Expand Up @@ -31,26 +31,23 @@ class NativeLibrarySnapshotBuffer final : public DartSnapshotBuffer {
FML_DISALLOW_COPY_AND_ASSIGN(NativeLibrarySnapshotBuffer);
};

class FileSnapshotBuffer final : public DartSnapshotBuffer {
class MappingBuffer final : public DartSnapshotBuffer {
public:
FileSnapshotBuffer(
const fml::UniqueFD& fd,
std::initializer_list<fml::FileMapping::Protection> protection)
: mapping_(fd, protection) {
if (mapping_.GetSize() > 0) {
symbol_ = mapping_.GetMapping();
}
MappingBuffer(std::unique_ptr<fml::Mapping> mapping)
: mapping_(std::move(mapping)) {
FML_DCHECK(mapping_);
}

const uint8_t* GetSnapshotPointer() const override { return symbol_; }
const uint8_t* GetSnapshotPointer() const override {
return mapping_->GetMapping();
}

size_t GetSnapshotSize() const override { return mapping_.GetSize(); }
size_t GetSnapshotSize() const override { return mapping_->GetSize(); }

private:
fml::FileMapping mapping_;
const uint8_t* symbol_ = nullptr;
std::unique_ptr<fml::Mapping> mapping_;

FML_DISALLOW_COPY_AND_ASSIGN(FileSnapshotBuffer);
FML_DISALLOW_COPY_AND_ASSIGN(MappingBuffer);
};

class UnmanagedAllocation final : public DartSnapshotBuffer {
Expand Down Expand Up @@ -80,8 +77,16 @@ std::unique_ptr<DartSnapshotBuffer>
DartSnapshotBuffer::CreateWithContentsOfFile(
const fml::UniqueFD& fd,
std::initializer_list<fml::FileMapping::Protection> protection) {
auto source = std::make_unique<FileSnapshotBuffer>(fd, protection);
return source->GetSnapshotPointer() == nullptr ? nullptr : std::move(source);
return CreateWithMapping(std::make_unique<fml::FileMapping>(fd, protection));
}

std::unique_ptr<DartSnapshotBuffer> DartSnapshotBuffer::CreateWithMapping(
std::unique_ptr<fml::Mapping> mapping) {
if (mapping == nullptr || mapping->GetSize() == 0 ||
mapping->GetMapping() == nullptr) {
return nullptr;
}
return std::make_unique<MappingBuffer>(std::move(mapping));
}

std::unique_ptr<DartSnapshotBuffer>
Expand Down
5 changes: 5 additions & 0 deletions runtime/dart_snapshot_buffer.h
Expand Up @@ -15,6 +15,8 @@

namespace blink {

// TODO(chinmaygarde): Replace this with just |fml::Mapping|.
// https://github.com/flutter/flutter/issues/26782
class DartSnapshotBuffer {
public:
static std::unique_ptr<DartSnapshotBuffer> CreateWithSymbolInLibrary(
Expand All @@ -28,6 +30,9 @@ class DartSnapshotBuffer {
static std::unique_ptr<DartSnapshotBuffer> CreateWithUnmanagedAllocation(
const uint8_t* allocation);

static std::unique_ptr<DartSnapshotBuffer> CreateWithMapping(
std::unique_ptr<fml::Mapping> mapping);

virtual ~DartSnapshotBuffer();

virtual const uint8_t* GetSnapshotPointer() const = 0;
Expand Down
41 changes: 41 additions & 0 deletions shell/platform/embedder/embedder.cc
Expand Up @@ -248,6 +248,44 @@ struct _FlutterPlatformMessageResponseHandle {
fml::RefPtr<blink::PlatformMessage> message;
};

void PopulateSnapshotMappingCallbacks(const FlutterProjectArgs* args,
blink::Settings& settings) {
// There are no ownership concerns here as all mappings are owned by the
// embedder and not the engine.
auto make_mapping_callback = [](const uint8_t* mapping, size_t size) {
return [mapping, size]() {
return std::make_unique<fml::NonOwnedMapping>(mapping, size);
};
};

if (blink::DartVM::IsRunningPrecompiledCode()) {
if (SAFE_ACCESS(args, vm_snapshot_data_size, 0) != 0 &&
SAFE_ACCESS(args, vm_snapshot_data, nullptr) != nullptr) {
settings.vm_snapshot_data = make_mapping_callback(
args->vm_snapshot_data, args->vm_snapshot_data_size);
}

if (SAFE_ACCESS(args, vm_snapshot_instructions_size, 0) != 0 &&
SAFE_ACCESS(args, vm_snapshot_instructions, nullptr) != nullptr) {
settings.vm_snapshot_instr = make_mapping_callback(
args->vm_snapshot_instructions, args->vm_snapshot_instructions_size);
}

if (SAFE_ACCESS(args, isolate_snapshot_data_size, 0) != 0 &&
SAFE_ACCESS(args, isolate_snapshot_data, nullptr) != nullptr) {
settings.isolate_snapshot_data = make_mapping_callback(
args->isolate_snapshot_data, args->isolate_snapshot_data_size);
}

if (SAFE_ACCESS(args, isolate_snapshot_instructions_size, 0) != 0 &&
SAFE_ACCESS(args, isolate_snapshot_instructions, nullptr) != nullptr) {
settings.isolate_snapshot_instr =
make_mapping_callback(args->isolate_snapshot_instructions,
args->isolate_snapshot_instructions_size);
}
}
}

FlutterResult FlutterEngineRun(size_t version,
const FlutterRendererConfig* config,
const FlutterProjectArgs* args,
Expand Down Expand Up @@ -298,6 +336,9 @@ FlutterResult FlutterEngineRun(size_t version,
}

blink::Settings settings = shell::SettingsFromCommandLine(command_line);

PopulateSnapshotMappingCallbacks(args, settings);

settings.icu_data_path = icu_data_path;
settings.assets_path = args->assets_path;

Expand Down
28 changes: 28 additions & 0 deletions shell/platform/embedder/embedder.h
Expand Up @@ -217,6 +217,34 @@ typedef struct {
// to respond to platform messages from the Dart application. The callback
// will be invoked on the thread on which the |FlutterEngineRun| call is made.
FlutterPlatformMessageCallback platform_message_callback;
// The VM snapshot data buffer used in AOT operation. This buffer must be
// mapped in as read-only. For more information refer to the documentation on
// the Wiki at
// https://github.com/flutter/flutter/wiki/Flutter-engine-operation-in-AOT-Mode
const uint8_t* vm_snapshot_data;
// The size of the VM snapshot data buffer.
size_t vm_snapshot_data_size;
// The VM snapshot instructions buffer used in AOT operation. This buffer must
// be mapped in as read-execute. For more information refer to the
// documentation on the Wiki at
// https://github.com/flutter/flutter/wiki/Flutter-engine-operation-in-AOT-Mode
const uint8_t* vm_snapshot_instructions;
// The size of the VM snapshot instructions buffer.
size_t vm_snapshot_instructions_size;
// The isolate snapshot data buffer used in AOT operation. This buffer must be
// mapped in as read-only. For more information refer to the documentation on
// the Wiki at
// https://github.com/flutter/flutter/wiki/Flutter-engine-operation-in-AOT-Mode
const uint8_t* isolate_snapshot_data;
// The size of the isolate snapshot data buffer.
size_t isolate_snapshot_data_size;
// The isolate snapshot instructions buffer used in AOT operation. This buffer
// must be mapped in as read-execute. For more information refer to the
// documentation on the Wiki at
// https://github.com/flutter/flutter/wiki/Flutter-engine-operation-in-AOT-Mode
const uint8_t* isolate_snapshot_instructions;
// The size of the isoalte snapshot instructions buffer.
size_t isolate_snapshot_instructions_size;
} FlutterProjectArgs;

FLUTTER_EXPORT
Expand Down

0 comments on commit 898b4f8

Please sign in to comment.