Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(180)

Side by Side Diff: runtime/bin/snapshot.cc

Issue 2681193002: Factor out snapshot helpers from main.cc. (Closed)
Patch Set: . Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« runtime/bin/snapshot.h ('K') | « runtime/bin/snapshot.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
zra 2017/02/09 16:15:38 Maybe snapshot_utils.cc? Worried that there will b
rmacnak 2017/02/10 02:11:56 Good point. Done.
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 #include "bin/snapshot.h"
6
7 #include "include/dart_api.h"
8 #include "bin/dartutils.h"
9 #include "bin/exit.h"
10 #include "bin/extensions.h"
11 #include "bin/file.h"
12
13 namespace dart {
14 namespace bin {
15
16 extern const char* kVmSnapshotDataSymbolName;
17 extern const char* kVmSnapshotInstructionsSymbolName;
18 extern const char* kIsolateSnapshotDataSymbolName;
19 extern const char* kIsolateSnapshotInstructionsSymbolName;
20
21 static const int64_t kAppSnapshotHeaderSize = 5 * kInt64Size;
22 static const int64_t kAppSnapshotMagicNumber = 0xf6f6dcdc;
23 static const int64_t kAppSnapshotPageSize = 4 * KB;
24
25 static bool ReadAppSnapshotBlobs(const char* script_name,
26 const uint8_t** vm_data_buffer,
27 const uint8_t** vm_instructions_buffer,
28 const uint8_t** isolate_data_buffer,
29 const uint8_t** isolate_instructions_buffer) {
30 File* file = File::Open(script_name, File::kRead);
31 if (file == NULL) {
32 return false;
33 }
34 if (file->Length() < kAppSnapshotHeaderSize) {
35 file->Release();
36 return false;
37 }
38 int64_t header[5];
39 ASSERT(sizeof(header) == kAppSnapshotHeaderSize);
40 if (!file->ReadFully(&header, kAppSnapshotHeaderSize)) {
41 file->Release();
42 return false;
43 }
44 if (header[0] != kAppSnapshotMagicNumber) {
45 file->Release();
46 return false;
47 }
48
49 int64_t vm_data_size = header[1];
50 int64_t vm_data_position =
51 Utils::RoundUp(file->Position(), kAppSnapshotPageSize);
52 int64_t vm_instructions_size = header[2];
53 int64_t vm_instructions_position = vm_data_position + vm_data_size;
54 if (vm_instructions_size != 0) {
55 vm_instructions_position =
56 Utils::RoundUp(vm_instructions_position, kAppSnapshotPageSize);
57 }
58 int64_t isolate_data_size = header[3];
59 int64_t isolate_data_position = Utils::RoundUp(
60 vm_instructions_position + vm_instructions_size, kAppSnapshotPageSize);
61 int64_t isolate_instructions_size = header[4];
62 int64_t isolate_instructions_position =
63 isolate_data_position + isolate_data_size;
64 if (isolate_instructions_size != 0) {
65 isolate_instructions_position =
66 Utils::RoundUp(isolate_instructions_position, kAppSnapshotPageSize);
67 }
68
69 if (vm_data_size != 0) {
70 *vm_data_buffer = reinterpret_cast<const uint8_t*>(
71 file->Map(File::kReadOnly, vm_data_position, vm_data_size));
72 if (vm_data_buffer == NULL) {
73 Log::PrintErr("Failed to memory map snapshot\n");
74 Platform::Exit(kErrorExitCode);
75 }
76 }
77
78 if (vm_instructions_size != 0) {
79 *vm_instructions_buffer = reinterpret_cast<const uint8_t*>(file->Map(
80 File::kReadExecute, vm_instructions_position, vm_instructions_size));
81 if (*vm_instructions_buffer == NULL) {
82 Log::PrintErr("Failed to memory map snapshot\n");
83 Platform::Exit(kErrorExitCode);
84 }
85 }
86
87 *isolate_data_buffer = reinterpret_cast<const uint8_t*>(
88 file->Map(File::kReadOnly, isolate_data_position, isolate_data_size));
89 if (isolate_data_buffer == NULL) {
90 Log::PrintErr("Failed to memory map snapshot\n");
91 Platform::Exit(kErrorExitCode);
92 }
93
94 if (isolate_instructions_size == 0) {
95 *isolate_instructions_buffer = NULL;
96 } else {
97 *isolate_instructions_buffer = reinterpret_cast<const uint8_t*>(
98 file->Map(File::kReadExecute, isolate_instructions_position,
99 isolate_instructions_size));
100 if (*isolate_instructions_buffer == NULL) {
101 Log::PrintErr("Failed to memory map snapshot\n");
102 Platform::Exit(kErrorExitCode);
103 }
104 }
105
106 file->Release();
107 return true;
108 }
109
110
111 #if defined(DART_PRECOMPILED_RUNTIME)
112 static bool ReadAppSnapshotDynamicLibrary(
113 const char* script_name,
114 const uint8_t** vm_data_buffer,
115 const uint8_t** vm_instructions_buffer,
116 const uint8_t** isolate_data_buffer,
117 const uint8_t** isolate_instructions_buffer) {
118 void* library = Extensions::LoadExtensionLibrary(script_name);
119 if (library == NULL) {
120 return false;
121 }
122
123 *vm_data_buffer = reinterpret_cast<const uint8_t*>(
124 Extensions::ResolveSymbol(library, kVmSnapshotDataSymbolName));
125 if (*vm_data_buffer == NULL) {
126 Log::PrintErr("Failed to resolve symbol '%s'\n", kVmSnapshotDataSymbolName);
127 Platform::Exit(kErrorExitCode);
128 }
129
130 *vm_instructions_buffer = reinterpret_cast<const uint8_t*>(
131 Extensions::ResolveSymbol(library, kVmSnapshotInstructionsSymbolName));
132 if (*vm_instructions_buffer == NULL) {
133 Log::PrintErr("Failed to resolve symbol '%s'\n",
134 kVmSnapshotInstructionsSymbolName);
135 Platform::Exit(kErrorExitCode);
136 }
137
138 *isolate_data_buffer = reinterpret_cast<const uint8_t*>(
139 Extensions::ResolveSymbol(library, kIsolateSnapshotDataSymbolName));
140 if (*isolate_data_buffer == NULL) {
141 Log::PrintErr("Failed to resolve symbol '%s'\n",
142 kIsolateSnapshotDataSymbolName);
143 Platform::Exit(kErrorExitCode);
144 }
145
146 *isolate_instructions_buffer =
147 reinterpret_cast<const uint8_t*>(Extensions::ResolveSymbol(
148 library, kIsolateSnapshotInstructionsSymbolName));
149 if (*isolate_instructions_buffer == NULL) {
150 Log::PrintErr("Failed to resolve symbol '%s'\n",
151 kIsolateSnapshotInstructionsSymbolName);
152 Platform::Exit(kErrorExitCode);
153 }
154
155 return true;
156 }
157 #endif // defined(DART_PRECOMPILED_RUNTIME)
158
159
160 bool Snapshot::ReadAppSnapshot(const char* script_name,
161 const uint8_t** vm_data_buffer,
162 const uint8_t** vm_instructions_buffer,
163 const uint8_t** isolate_data_buffer,
164 const uint8_t** isolate_instructions_buffer) {
165 if (File::GetType(script_name, true) != File::kIsFile) {
166 // If 'script_name' refers to a pipe, don't read to check for an app
167 // snapshot since we cannot rewind if it isn't (and couldn't mmap it in
168 // anyway if it was).
169 return false;
170 }
171 if (ReadAppSnapshotBlobs(script_name, vm_data_buffer, vm_instructions_buffer,
172 isolate_data_buffer, isolate_instructions_buffer)) {
173 return true;
174 }
175 #if defined(DART_PRECOMPILED_RUNTIME)
176 // For testing AOT with the standalone embedder, we also support loading
177 // from a dynamic library to simulate what happens on iOS.
178 return ReadAppSnapshotDynamicLibrary(
179 script_name, vm_data_buffer, vm_instructions_buffer, isolate_data_buffer,
180 isolate_instructions_buffer);
181 #else
182 return false;
183 #endif // defined(DART_PRECOMPILED_RUNTIME)
184 }
185
186
187 static void WriteSnapshotFile(const char* filename,
188 bool write_magic_number,
189 const uint8_t* buffer,
190 const intptr_t size) {
191 File* file = File::Open(filename, File::kWriteTruncate);
192 if (file == NULL) {
193 ErrorExit(kErrorExitCode, "Unable to open file %s for writing snapshot\n",
194 filename);
195 }
196
197 if (write_magic_number) {
198 // Write the magic number to indicate file is a script snapshot.
199 DartUtils::WriteMagicNumber(file);
200 }
201
202 if (!file->WriteFully(buffer, size)) {
203 ErrorExit(kErrorExitCode, "Unable to write file %s for writing snapshot\n",
204 filename);
205 }
206 file->Release();
207 }
208
209
210 static bool WriteInt64(File* file, int64_t size) {
211 return file->WriteFully(&size, sizeof(size));
212 }
213
214
215 static void WriteAppSnapshot(const char* filename,
216 uint8_t* vm_data_buffer,
217 intptr_t vm_data_size,
218 uint8_t* vm_instructions_buffer,
219 intptr_t vm_instructions_size,
220 uint8_t* isolate_data_buffer,
221 intptr_t isolate_data_size,
222 uint8_t* isolate_instructions_buffer,
223 intptr_t isolate_instructions_size) {
224 File* file = File::Open(filename, File::kWriteTruncate);
225 if (file == NULL) {
226 ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n", filename);
227 }
228
229 file->WriteFully(&kAppSnapshotMagicNumber, sizeof(kAppSnapshotMagicNumber));
230 WriteInt64(file, vm_data_size);
231 WriteInt64(file, vm_instructions_size);
232 WriteInt64(file, isolate_data_size);
233 WriteInt64(file, isolate_instructions_size);
234 ASSERT(file->Position() == kAppSnapshotHeaderSize);
235
236 file->SetPosition(Utils::RoundUp(file->Position(), kAppSnapshotPageSize));
237 if (!file->WriteFully(vm_data_buffer, vm_data_size)) {
238 ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n", filename);
239 }
240
241 if (vm_instructions_size != 0) {
242 file->SetPosition(Utils::RoundUp(file->Position(), kAppSnapshotPageSize));
243 if (!file->WriteFully(vm_instructions_buffer, vm_instructions_size)) {
244 ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n",
245 filename);
246 }
247 }
248
249 file->SetPosition(Utils::RoundUp(file->Position(), kAppSnapshotPageSize));
250 if (!file->WriteFully(isolate_data_buffer, isolate_data_size)) {
251 ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n", filename);
252 }
253
254 if (isolate_instructions_size != 0) {
255 file->SetPosition(Utils::RoundUp(file->Position(), kAppSnapshotPageSize));
256 if (!file->WriteFully(isolate_instructions_buffer,
257 isolate_instructions_size)) {
258 ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n",
259 filename);
260 }
261 }
262
263 file->Flush();
264 file->Release();
265 }
266
267
268 void Snapshot::GenerateScript(const char* snapshot_filename) {
269 // First create a snapshot.
270 uint8_t* buffer = NULL;
271 intptr_t size = 0;
272 Dart_Handle result = Dart_CreateScriptSnapshot(&buffer, &size);
273 if (Dart_IsError(result)) {
274 ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
275 }
276
277 WriteSnapshotFile(snapshot_filename, true, buffer, size);
278 }
279
280
281 void Snapshot::GenerateAppJIT(const char* snapshot_filename) {
282 #if defined(TARGET_ARCH_X64)
283 uint8_t* isolate_data_buffer = NULL;
284 intptr_t isolate_data_size = 0;
285 uint8_t* isolate_instructions_buffer = NULL;
286 intptr_t isolate_instructions_size = 0;
287 Dart_Handle result = Dart_CreateAppJITSnapshotAsBlobs(
288 &isolate_data_buffer, &isolate_data_size, &isolate_instructions_buffer,
289 &isolate_instructions_size);
290 if (Dart_IsError(result)) {
291 ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
292 }
293 WriteAppSnapshot(snapshot_filename, NULL, 0, NULL, 0, isolate_data_buffer,
294 isolate_data_size, isolate_instructions_buffer,
295 isolate_instructions_size);
296 #else
297 uint8_t* isolate_buffer = NULL;
298 intptr_t isolate_size = 0;
299
300 Dart_Handle result =
301 Dart_CreateSnapshot(NULL, NULL, &isolate_buffer, &isolate_size);
302 if (Dart_IsError(result)) {
303 ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
304 }
305
306 WriteAppSnapshot(snapshot_filename, NULL, 0, NULL, 0, isolate_buffer,
307 isolate_size, NULL, 0);
308 #endif // defined(TARGET_ARCH_X64)
309 }
310
311
312 void Snapshot::GenerateAppAOTAsBlobs(const char* snapshot_filename) {
313 uint8_t* vm_data_buffer = NULL;
314 intptr_t vm_data_size = 0;
315 uint8_t* vm_instructions_buffer = NULL;
316 intptr_t vm_instructions_size = 0;
317 uint8_t* isolate_data_buffer = NULL;
318 intptr_t isolate_data_size = 0;
319 uint8_t* isolate_instructions_buffer = NULL;
320 intptr_t isolate_instructions_size = 0;
321 Dart_Handle result = Dart_CreateAppAOTSnapshotAsBlobs(
322 &vm_data_buffer, &vm_data_size, &vm_instructions_buffer,
323 &vm_instructions_size, &isolate_data_buffer, &isolate_data_size,
324 &isolate_instructions_buffer, &isolate_instructions_size);
325 if (Dart_IsError(result)) {
326 ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
327 }
328 WriteAppSnapshot(snapshot_filename, vm_data_buffer, vm_data_size,
329 vm_instructions_buffer, vm_instructions_size,
330 isolate_data_buffer, isolate_data_size,
331 isolate_instructions_buffer, isolate_instructions_size);
332 }
333
334
335 void Snapshot::GenerateAppAOTAsAssembly(const char* snapshot_filename) {
336 uint8_t* assembly_buffer = NULL;
337 intptr_t assembly_size = 0;
338 Dart_Handle result =
339 Dart_CreateAppAOTSnapshotAsAssembly(&assembly_buffer, &assembly_size);
340 if (Dart_IsError(result)) {
341 ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
342 }
343 WriteSnapshotFile(snapshot_filename, false, assembly_buffer, assembly_size);
344 }
345
346 } // namespace bin
347 } // namespace dart
OLDNEW
« runtime/bin/snapshot.h ('K') | « runtime/bin/snapshot.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698