Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
dart_snapshot.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include <sstream>
8
10#include "flutter/fml/paths.h"
14#include "third_party/dart/runtime/include/dart_api.h"
15
16namespace flutter {
17
18const char* DartSnapshot::kVMDataSymbol = "kDartSnapshotData";
19const char* DartSnapshot::kVMInstructionsSymbol = "kDartSnapshotText";
20const char* DartSnapshot::kIsolateDataSymbol = "kDartSnapshotData";
21const char* DartSnapshot::kIsolateInstructionsSymbol = "kDartSnapshotText";
22
23// On Windows and Android (in debug mode) the engine finds the Dart snapshot
24// data through symbols that are statically linked into the executable.
25// On other platforms this data is obtained by a dynamic symbol lookup.
26#define DART_SNAPSHOT_STATIC_LINK \
27 ((FML_OS_WIN || FML_OS_ANDROID) && FLUTTER_JIT_RUNTIME)
28
29#if !DART_SNAPSHOT_STATIC_LINK
30
31static std::unique_ptr<const fml::Mapping> GetFileMapping(
32 const std::string& path,
33 bool executable) {
34 if (executable) {
36 } else {
38 }
39}
40
41// The first party embedders don't yet use the stable embedder API and depend on
42// the engine figuring out the locations of the various heap and instructions
43// buffers. Consequently, the engine had baked in opinions about where these
44// buffers would reside and how they would be packaged (examples, in an external
45// dylib, in the same dylib, at a path, at a path relative to and FD, etc..). As
46// the needs of the platforms changed, the lack of an API meant that the engine
47// had to be patched to look for new fields in the settings object. This grew
48// untenable and with the addition of the new Fuchsia embedder and the generic C
49// embedder API, embedders could specify the mapping directly. Once everyone
50// moves to the embedder API, this method can effectively be reduced to just
51// invoking the embedder_mapping_callback directly.
52static std::shared_ptr<const fml::Mapping> SearchMapping(
53 const MappingCallback& embedder_mapping_callback,
54 const std::string& file_path,
55 const std::vector<std::string>& native_library_paths,
56 const char* native_library_symbol_name,
57 bool is_executable) {
58 // Ask the embedder. There is no fallback as we expect the embedders (via
59 // their embedding APIs) to just specify the mappings directly.
60 if (embedder_mapping_callback) {
61 // Note that mapping will be nullptr if the mapping callback returns an
62 // invalid mapping. If all the other methods for resolving the data also
63 // fail, the engine will stop with accompanying error logs.
64 if (auto mapping = embedder_mapping_callback()) {
65 return mapping;
66 }
67 }
68
69 // Attempt to open file at path specified.
70 if (!file_path.empty()) {
71 if (auto file_mapping = GetFileMapping(file_path, is_executable)) {
72 return file_mapping;
73 }
74 }
75
76 // Look in application specified native library if specified.
77 for (const std::string& path : native_library_paths) {
78 auto native_library = fml::NativeLibrary::Create(path.c_str());
79 auto symbol_mapping = std::make_unique<const fml::SymbolMapping>(
80 native_library, native_library_symbol_name);
81 if (symbol_mapping->GetMapping() != nullptr) {
82 return symbol_mapping;
83 }
84 }
85
86 // Look inside the currently loaded process.
87 {
88 auto loaded_process = fml::NativeLibrary::CreateForCurrentProcess();
89 auto symbol_mapping = std::make_unique<const fml::SymbolMapping>(
90 loaded_process, native_library_symbol_name);
91 if (symbol_mapping->GetMapping() != nullptr) {
92 return symbol_mapping;
93 }
94 }
95
96 return nullptr;
97}
98
99#endif // !DART_SNAPSHOT_STATIC_LINK
100
101static std::shared_ptr<const fml::Mapping> ResolveVMData(
102 const Settings& settings) {
103#if DART_SNAPSHOT_STATIC_LINK
104 return std::make_unique<fml::NonOwnedMapping>(kDartSnapshotData,
105 0, // size
106 nullptr, // release_func
107 true // dontneed_safe
108 );
109#else // DART_SNAPSHOT_STATIC_LINK
110 return SearchMapping(
111 settings.vm_snapshot_data, // embedder_mapping_callback
112 settings.vm_snapshot_data_path, // file_path
113 settings.application_library_paths, // native_library_paths
114 DartSnapshot::kVMDataSymbol, // native_library_symbol_name
115 false // is_executable
116 );
117#endif // DART_SNAPSHOT_STATIC_LINK
118}
119
120static std::shared_ptr<const fml::Mapping> ResolveVMInstructions(
121 const Settings& settings) {
122#if DART_SNAPSHOT_STATIC_LINK
123 return std::make_unique<fml::NonOwnedMapping>(kDartSnapshotText,
124 0, // size
125 nullptr, // release_func
126 true // dontneed_safe
127 );
128#else // DART_SNAPSHOT_STATIC_LINK
129 return SearchMapping(
130 settings.vm_snapshot_instr, // embedder_mapping_callback
131 settings.vm_snapshot_instr_path, // file_path
132 settings.application_library_paths, // native_library_paths
133 DartSnapshot::kVMInstructionsSymbol, // native_library_symbol_name
134 true // is_executable
135 );
136#endif // DART_SNAPSHOT_STATIC_LINK
137}
138
139static std::shared_ptr<const fml::Mapping> ResolveIsolateData(
140 const Settings& settings) {
141#if DART_SNAPSHOT_STATIC_LINK
142 return std::make_unique<fml::NonOwnedMapping>(kDartSnapshotData,
143 0, // size
144 nullptr, // release_func
145 true // dontneed_safe
146 );
147#else // DART_SNAPSHOT_STATIC_LINK
148 return SearchMapping(
149 settings.isolate_snapshot_data, // embedder_mapping_callback
150 settings.isolate_snapshot_data_path, // file_path
151 settings.application_library_paths, // native_library_paths
152 DartSnapshot::kIsolateDataSymbol, // native_library_symbol_name
153 false // is_executable
154 );
155#endif // DART_SNAPSHOT_STATIC_LINK
156}
157
158static std::shared_ptr<const fml::Mapping> ResolveIsolateInstructions(
159 const Settings& settings) {
160#if DART_SNAPSHOT_STATIC_LINK
161 return std::make_unique<fml::NonOwnedMapping>(kDartSnapshotText,
162 0, // size
163 nullptr, // release_func
164 true // dontneed_safe
165 );
166#else // DART_SNAPSHOT_STATIC_LINK
167 return SearchMapping(
168 settings.isolate_snapshot_instr, // embedder_mapping_callback
169 settings.isolate_snapshot_instr_path, // file_path
170 settings.application_library_paths, // native_library_paths
171 DartSnapshot::kIsolateInstructionsSymbol, // native_library_symbol_name
172 true // is_executable
173 );
174#endif // DART_SNAPSHOT_STATIC_LINK
175}
176
178 const Settings& settings) {
179 TRACE_EVENT0("flutter", "DartSnapshot::VMSnapshotFromSettings");
180 auto snapshot =
181 fml::MakeRefCounted<DartSnapshot>(ResolveVMData(settings), //
182 ResolveVMInstructions(settings) //
183 );
184 if (snapshot->IsValid()) {
185 return snapshot;
186 }
187 return nullptr;
188}
189
191 const Settings& settings) {
192 TRACE_EVENT0("flutter", "DartSnapshot::IsolateSnapshotFromSettings");
193 auto snapshot =
194 fml::MakeRefCounted<DartSnapshot>(ResolveIsolateData(settings), //
195 ResolveIsolateInstructions(settings) //
196 );
197 if (snapshot->IsValid()) {
198 return snapshot;
199 }
200 return nullptr;
201}
202
204 const std::shared_ptr<const fml::Mapping>& snapshot_data,
205 const std::shared_ptr<const fml::Mapping>& snapshot_instructions) {
206 auto snapshot =
207 fml::MakeRefCounted<DartSnapshot>(snapshot_data, snapshot_instructions);
208 if (snapshot->IsValid()) {
209 return snapshot;
210 }
211 return nullptr;
212 // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
213}
214
216 const Settings& settings) {
217#if DART_SNAPSHOT_STATIC_LINK
218 return nullptr;
219#else // DART_SNAPSHOT_STATIC_LINK
220 if (settings.vmservice_snapshot_library_path.empty()) {
221 return nullptr;
222 }
223
224 std::shared_ptr<const fml::Mapping> snapshot_data =
227 std::shared_ptr<const fml::Mapping> snapshot_instructions =
230 return IsolateSnapshotFromMappings(snapshot_data, snapshot_instructions);
231#endif // DART_SNAPSHOT_STATIC_LINK
232}
233
234DartSnapshot::DartSnapshot(std::shared_ptr<const fml::Mapping> data,
235 std::shared_ptr<const fml::Mapping> instructions)
236 : data_(std::move(data)), instructions_(std::move(instructions)) {}
237
238DartSnapshot::~DartSnapshot() = default;
239
241 return static_cast<bool>(data_);
242}
243
245 return data_ && instructions_;
246}
247
248const uint8_t* DartSnapshot::GetDataMapping() const {
249 return data_ ? data_->GetMapping() : nullptr;
250}
251
253 return instructions_ ? instructions_->GetMapping() : nullptr;
254}
255
257 if (data_ && !data_->IsDontNeedSafe()) {
258 return false;
259 }
260 if (instructions_ && !instructions_->IsDontNeedSafe()) {
261 return false;
262 }
263 return true;
264}
265
267 return ::Dart_DetectNullSafety(
268 nullptr, // script_uri (unsupported by Flutter)
269 nullptr, // package_config (package resolution of parent used)
270 nullptr, // original_working_directory (no package config)
271 GetDataMapping(), // snapshot_data
272 GetInstructionsMapping(), // snapshot_instructions
273 kernel ? kernel->GetMapping() : nullptr, // kernel_buffer
274 kernel ? kernel->GetSize() : 0u // kernel_buffer_size
275 );
276}
277
278} // namespace flutter
bool IsNullSafetyEnabled(const fml::Mapping *application_kernel_mapping) const
bool IsValidForAOT() const
Determines if this snapshot contains both the heap and instructions components. This is only useful w...
static fml::RefPtr< DartSnapshot > VMServiceIsolateSnapshotFromSettings(const Settings &settings)
Create an isolate snapshot specialized for launching the service isolate. Returns nullptr if no such ...
static fml::RefPtr< const DartSnapshot > VMSnapshotFromSettings(const Settings &settings)
From the fields present in the given settings object, infer the core snapshot.
static fml::RefPtr< DartSnapshot > IsolateSnapshotFromMappings(const std::shared_ptr< const fml::Mapping > &snapshot_data, const std::shared_ptr< const fml::Mapping > &snapshot_instructions)
Create an isolate snapshot from existing fml::Mappings.
bool IsValid() const
Determines if this snapshot contains a heap component. Since the instructions component is optional,...
const uint8_t * GetInstructionsMapping() const
Get a pointer to the read-execute mapping to the instructions snapshot.
static const char * kIsolateDataSymbol
static const char * kVMDataSymbol
const uint8_t * GetDataMapping() const
Get a pointer to the read-only mapping to the heap snapshot.
static const char * kIsolateInstructionsSymbol
bool IsDontNeedSafe() const
Returns whether both the data and instructions mappings are safe to use with madvise(DONTNEED).
static fml::RefPtr< const DartSnapshot > IsolateSnapshotFromSettings(const Settings &settings)
From the fields present in the given settings object, infer the isolate snapshot.
static const char * kVMInstructionsSymbol
static std::unique_ptr< FileMapping > CreateReadExecute(const std::string &path)
Definition mapping.cc:44
static std::unique_ptr< FileMapping > CreateReadOnly(const std::string &path)
Definition mapping.cc:20
virtual const uint8_t * GetMapping() const =0
virtual size_t GetSize() const =0
static fml::RefPtr< NativeLibrary > CreateForCurrentProcess()
static fml::RefPtr< NativeLibrary > Create(const char *path)
const uint8_t kDartSnapshotText[]
const uint8_t kDartSnapshotData[]
static std::shared_ptr< const fml::Mapping > ResolveIsolateData(const Settings &settings)
static std::shared_ptr< const fml::Mapping > SearchMapping(const MappingCallback &embedder_mapping_callback, const std::string &file_path, const std::vector< std::string > &native_library_paths, const char *native_library_symbol_name, bool is_executable)
static std::shared_ptr< const fml::Mapping > ResolveVMInstructions(const Settings &settings)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switch_defs.h:52
static std::shared_ptr< const fml::Mapping > ResolveVMData(const Settings &settings)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switch_defs.h:36
std::function< std::unique_ptr< fml::Mapping >(void)> MappingCallback
Definition settings.h:87
static std::unique_ptr< const fml::Mapping > GetFileMapping(const std::string &path, bool executable)
static std::shared_ptr< const fml::Mapping > ResolveIsolateInstructions(const Settings &settings)
Definition ref_ptr.h:261
std::vector< std::string > vmservice_snapshot_library_path
Definition settings.h:138
std::string vm_snapshot_instr_path
Definition settings.h:117
MappingCallback isolate_snapshot_instr
Definition settings.h:123
MappingCallback isolate_snapshot_data
Definition settings.h:121
MappingCallback vm_snapshot_data
Definition settings.h:116
std::string isolate_snapshot_data_path
Definition settings.h:120
MappingCallback vm_snapshot_instr
Definition settings.h:118
std::string vm_snapshot_data_path
Definition settings.h:115
std::string isolate_snapshot_instr_path
Definition settings.h:122
std::vector< std::string > application_library_paths
Definition settings.h:134
#define TRACE_EVENT0(category_group, name)