forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dart_snapshot.cc
199 lines (174 loc) · 7.13 KB
/
dart_snapshot.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/runtime/dart_snapshot.h"
#include <sstream>
#include "flutter/fml/native_library.h"
#include "flutter/fml/paths.h"
#include "flutter/fml/trace_event.h"
#include "flutter/lib/snapshot/snapshot.h"
#include "flutter/runtime/dart_vm.h"
namespace flutter {
const char* DartSnapshot::kVMDataSymbol = "kDartVmSnapshotData";
const char* DartSnapshot::kVMInstructionsSymbol = "kDartVmSnapshotInstructions";
const char* DartSnapshot::kIsolateDataSymbol = "kDartIsolateSnapshotData";
const char* DartSnapshot::kIsolateInstructionsSymbol =
"kDartIsolateSnapshotInstructions";
static std::unique_ptr<const fml::Mapping> GetFileMapping(
const std::string& path,
bool executable) {
if (executable) {
return fml::FileMapping::CreateReadExecute(path);
} else {
return fml::FileMapping::CreateReadOnly(path);
}
}
// The first party embedders don't yet use the stable embedder API and depend on
// the engine figuring out the locations of the various heap and instructions
// buffers. Consequently, the engine had baked in opinions about where these
// buffers would reside and how they would be packaged (examples, in an external
// dylib, in the same dylib, at a path, at a path relative to and FD, etc..). As
// the needs of the platforms changed, the lack of an API meant that the engine
// had to be patched to look for new fields in the settings object. This grew
// untenable and with the addition of the new Fuchsia embedder and the generic C
// embedder API, embedders could specify the mapping directly. Once everyone
// moves to the embedder API, this method can effectively be reduced to just
// invoking the embedder_mapping_callback directly.
static std::shared_ptr<const fml::Mapping> SearchMapping(
MappingCallback embedder_mapping_callback,
const std::string& file_path,
const std::vector<std::string>& native_library_path,
const char* native_library_symbol_name,
bool is_executable) {
// Ask the embedder. There is no fallback as we expect the embedders (via
// their embedding APIs) to just specify the mappings directly.
if (embedder_mapping_callback) {
return embedder_mapping_callback();
}
// Attempt to open file at path specified.
if (file_path.size() > 0) {
if (auto file_mapping = GetFileMapping(file_path, is_executable)) {
return file_mapping;
}
}
// Look in application specified native library if specified.
for (const std::string& path : native_library_path) {
auto native_library = fml::NativeLibrary::Create(path.c_str());
auto symbol_mapping = std::make_unique<const fml::SymbolMapping>(
native_library, native_library_symbol_name);
if (symbol_mapping->GetMapping() != nullptr) {
return symbol_mapping;
}
}
// Look inside the currently loaded process.
{
auto loaded_process = fml::NativeLibrary::CreateForCurrentProcess();
auto symbol_mapping = std::make_unique<const fml::SymbolMapping>(
loaded_process, native_library_symbol_name);
if (symbol_mapping->GetMapping() != nullptr) {
return symbol_mapping;
}
}
return nullptr;
}
static std::shared_ptr<const fml::Mapping> ResolveVMData(
const Settings& settings) {
#if OS_WIN
return std::make_unique<fml::NonOwnedMapping>(kDartVmSnapshotData, 0);
#else // OS_WIN
return SearchMapping(
settings.vm_snapshot_data, // embedder_mapping_callback
settings.vm_snapshot_data_path, // file_path
settings.application_library_path, // native_library_path
DartSnapshot::kVMDataSymbol, // native_library_symbol_name
false // is_executable
);
#endif // OS_WIN
}
static std::shared_ptr<const fml::Mapping> ResolveVMInstructions(
const Settings& settings) {
#if OS_WIN
return std::make_unique<fml::NonOwnedMapping>(kDartVmSnapshotInstructions, 0);
#else // OS_WIN
return SearchMapping(
settings.vm_snapshot_instr, // embedder_mapping_callback
settings.vm_snapshot_instr_path, // file_path
settings.application_library_path, // native_library_path
DartSnapshot::kVMInstructionsSymbol, // native_library_symbol_name
true // is_executable
);
#endif // OS_WIN
}
static std::shared_ptr<const fml::Mapping> ResolveIsolateData(
const Settings& settings) {
#if OS_WIN
return std::make_unique<fml::NonOwnedMapping>(kDartIsolateSnapshotData, 0);
#else // OS_WIN
return SearchMapping(
settings.isolate_snapshot_data, // embedder_mapping_callback
settings.isolate_snapshot_data_path, // file_path
settings.application_library_path, // native_library_path
DartSnapshot::kIsolateDataSymbol, // native_library_symbol_name
false // is_executable
);
#endif // OS_WIN
}
static std::shared_ptr<const fml::Mapping> ResolveIsolateInstructions(
const Settings& settings) {
#if OS_WIN
return std::make_unique<fml::NonOwnedMapping>(
kDartIsolateSnapshotInstructions, 0);
#else // OS_WIN
return SearchMapping(
settings.isolate_snapshot_instr, // embedder_mapping_callback
settings.isolate_snapshot_instr_path, // file_path
settings.application_library_path, // native_library_path
DartSnapshot::kIsolateInstructionsSymbol, // native_library_symbol_name
true // is_executable
);
#endif // OS_WIN
}
fml::RefPtr<DartSnapshot> DartSnapshot::VMSnapshotFromSettings(
const Settings& settings) {
TRACE_EVENT0("flutter", "DartSnapshot::VMSnapshotFromSettings");
auto snapshot =
fml::MakeRefCounted<DartSnapshot>(ResolveVMData(settings), //
ResolveVMInstructions(settings) //
);
if (snapshot->IsValid()) {
return snapshot;
}
return nullptr;
}
fml::RefPtr<DartSnapshot> DartSnapshot::IsolateSnapshotFromSettings(
const Settings& settings) {
TRACE_EVENT0("flutter", "DartSnapshot::IsolateSnapshotFromSettings");
auto snapshot =
fml::MakeRefCounted<DartSnapshot>(ResolveIsolateData(settings), //
ResolveIsolateInstructions(settings) //
);
if (snapshot->IsValid()) {
return snapshot;
}
return nullptr;
}
fml::RefPtr<DartSnapshot> DartSnapshot::Empty() {
return fml::MakeRefCounted<DartSnapshot>(nullptr, nullptr);
}
DartSnapshot::DartSnapshot(std::shared_ptr<const fml::Mapping> data,
std::shared_ptr<const fml::Mapping> instructions)
: data_(std::move(data)), instructions_(std::move(instructions)) {}
DartSnapshot::~DartSnapshot() = default;
bool DartSnapshot::IsValid() const {
return static_cast<bool>(data_);
}
bool DartSnapshot::IsValidForAOT() const {
return data_ && instructions_;
}
const uint8_t* DartSnapshot::GetDataMapping() const {
return data_ ? data_->GetMapping() : nullptr;
}
const uint8_t* DartSnapshot::GetInstructionsMapping() const {
return instructions_ ? instructions_->GetMapping() : nullptr;
}
} // namespace flutter