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

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

Issue 2694103004: Cleanup app snapshots on isolate/vm exit. (Closed)
Patch Set: merge 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
« no previous file with comments | « runtime/bin/snapshot_utils.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
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "bin/snapshot_utils.h" 5 #include "bin/snapshot_utils.h"
6 6
7 #include "bin/dartutils.h" 7 #include "bin/dartutils.h"
8 #include "bin/error_exit.h" 8 #include "bin/error_exit.h"
9 #include "bin/extensions.h" 9 #include "bin/extensions.h"
10 #include "bin/file.h" 10 #include "bin/file.h"
11 #include "bin/platform.h" 11 #include "bin/platform.h"
12 #include "include/dart_api.h" 12 #include "include/dart_api.h"
13 #include "platform/utils.h" 13 #include "platform/utils.h"
14 14
15 namespace dart { 15 namespace dart {
16 namespace bin { 16 namespace bin {
17 17
18 extern const char* kVmSnapshotDataSymbolName; 18 extern const char* kVmSnapshotDataSymbolName;
19 extern const char* kVmSnapshotInstructionsSymbolName; 19 extern const char* kVmSnapshotInstructionsSymbolName;
20 extern const char* kIsolateSnapshotDataSymbolName; 20 extern const char* kIsolateSnapshotDataSymbolName;
21 extern const char* kIsolateSnapshotInstructionsSymbolName; 21 extern const char* kIsolateSnapshotInstructionsSymbolName;
22 22
23 static const int64_t kAppSnapshotHeaderSize = 5 * kInt64Size; 23 static const int64_t kAppSnapshotHeaderSize = 5 * kInt64Size;
24 static const int64_t kAppSnapshotMagicNumber = 0xf6f6dcdc; 24 static const int64_t kAppSnapshotMagicNumber = 0xf6f6dcdc;
25 static const int64_t kAppSnapshotPageSize = 4 * KB; 25 static const int64_t kAppSnapshotPageSize = 4 * KB;
26 26
27 static bool ReadAppSnapshotBlobs(const char* script_name, 27 class MappedAppSnapshot : public AppSnapshot {
28 const uint8_t** vm_data_buffer, 28 public:
29 const uint8_t** vm_instructions_buffer, 29 MappedAppSnapshot(MappedMemory* vm_snapshot_data,
30 const uint8_t** isolate_data_buffer, 30 MappedMemory* vm_snapshot_instructions,
31 const uint8_t** isolate_instructions_buffer) { 31 MappedMemory* isolate_snapshot_data,
32 MappedMemory* isolate_snapshot_instructions)
33 : vm_data_mapping_(vm_snapshot_data),
34 vm_instructions_mapping_(vm_snapshot_instructions),
35 isolate_data_mapping_(isolate_snapshot_data),
36 isolate_instructions_mapping_(isolate_snapshot_instructions) {}
37
38 ~MappedAppSnapshot() {
39 delete vm_data_mapping_;
40 delete vm_instructions_mapping_;
41 delete isolate_data_mapping_;
42 delete isolate_instructions_mapping_;
43 }
44
45 void SetBuffers(const uint8_t** vm_data_buffer,
46 const uint8_t** vm_instructions_buffer,
47 const uint8_t** isolate_data_buffer,
48 const uint8_t** isolate_instructions_buffer) {
49 if (vm_data_mapping_ != NULL) {
50 *vm_data_buffer =
51 reinterpret_cast<const uint8_t*>(vm_data_mapping_->address());
52 }
53 if (vm_instructions_mapping_ != NULL) {
54 *vm_instructions_buffer =
55 reinterpret_cast<const uint8_t*>(vm_instructions_mapping_->address());
56 }
57 if (isolate_data_mapping_ != NULL) {
58 *isolate_data_buffer =
59 reinterpret_cast<const uint8_t*>(isolate_data_mapping_->address());
60 }
61 if (isolate_instructions_mapping_ != NULL) {
62 *isolate_instructions_buffer = reinterpret_cast<const uint8_t*>(
63 isolate_instructions_mapping_->address());
64 }
65 }
66
67 private:
68 MappedMemory* vm_data_mapping_;
69 MappedMemory* vm_instructions_mapping_;
70 MappedMemory* isolate_data_mapping_;
71 MappedMemory* isolate_instructions_mapping_;
72 };
73
74
75 static AppSnapshot* TryReadAppSnapshotBlobs(const char* script_name) {
32 File* file = File::Open(script_name, File::kRead); 76 File* file = File::Open(script_name, File::kRead);
33 if (file == NULL) { 77 if (file == NULL) {
34 return false; 78 return NULL;
35 } 79 }
36 if (file->Length() < kAppSnapshotHeaderSize) { 80 if (file->Length() < kAppSnapshotHeaderSize) {
37 file->Release(); 81 file->Release();
38 return false; 82 return NULL;
39 } 83 }
40 int64_t header[5]; 84 int64_t header[5];
41 ASSERT(sizeof(header) == kAppSnapshotHeaderSize); 85 ASSERT(sizeof(header) == kAppSnapshotHeaderSize);
42 if (!file->ReadFully(&header, kAppSnapshotHeaderSize)) { 86 if (!file->ReadFully(&header, kAppSnapshotHeaderSize)) {
43 file->Release(); 87 file->Release();
44 return false; 88 return NULL;
45 } 89 }
46 if (header[0] != kAppSnapshotMagicNumber) { 90 if (header[0] != kAppSnapshotMagicNumber) {
47 file->Release(); 91 file->Release();
48 return false; 92 return NULL;
49 } 93 }
50 94
51 int64_t vm_data_size = header[1]; 95 int64_t vm_data_size = header[1];
52 int64_t vm_data_position = 96 int64_t vm_data_position =
53 Utils::RoundUp(file->Position(), kAppSnapshotPageSize); 97 Utils::RoundUp(file->Position(), kAppSnapshotPageSize);
54 int64_t vm_instructions_size = header[2]; 98 int64_t vm_instructions_size = header[2];
55 int64_t vm_instructions_position = vm_data_position + vm_data_size; 99 int64_t vm_instructions_position = vm_data_position + vm_data_size;
56 if (vm_instructions_size != 0) { 100 if (vm_instructions_size != 0) {
57 vm_instructions_position = 101 vm_instructions_position =
58 Utils::RoundUp(vm_instructions_position, kAppSnapshotPageSize); 102 Utils::RoundUp(vm_instructions_position, kAppSnapshotPageSize);
59 } 103 }
60 int64_t isolate_data_size = header[3]; 104 int64_t isolate_data_size = header[3];
61 int64_t isolate_data_position = Utils::RoundUp( 105 int64_t isolate_data_position = Utils::RoundUp(
62 vm_instructions_position + vm_instructions_size, kAppSnapshotPageSize); 106 vm_instructions_position + vm_instructions_size, kAppSnapshotPageSize);
63 int64_t isolate_instructions_size = header[4]; 107 int64_t isolate_instructions_size = header[4];
64 int64_t isolate_instructions_position = 108 int64_t isolate_instructions_position =
65 isolate_data_position + isolate_data_size; 109 isolate_data_position + isolate_data_size;
66 if (isolate_instructions_size != 0) { 110 if (isolate_instructions_size != 0) {
67 isolate_instructions_position = 111 isolate_instructions_position =
68 Utils::RoundUp(isolate_instructions_position, kAppSnapshotPageSize); 112 Utils::RoundUp(isolate_instructions_position, kAppSnapshotPageSize);
69 } 113 }
70 114
115 MappedMemory* vm_data_mapping = NULL;
71 if (vm_data_size != 0) { 116 if (vm_data_size != 0) {
72 *vm_data_buffer = reinterpret_cast<const uint8_t*>( 117 vm_data_mapping =
73 file->Map(File::kReadOnly, vm_data_position, vm_data_size)); 118 file->Map(File::kReadOnly, vm_data_position, vm_data_size);
74 if (vm_data_buffer == NULL) { 119 if (vm_data_mapping == NULL) {
75 Log::PrintErr("Failed to memory map snapshot\n"); 120 FATAL1("Failed to memory map snapshot: %s\n", script_name);
76 Platform::Exit(kErrorExitCode);
77 } 121 }
78 } 122 }
79 123
124 MappedMemory* vm_instr_mapping = NULL;
80 if (vm_instructions_size != 0) { 125 if (vm_instructions_size != 0) {
81 *vm_instructions_buffer = reinterpret_cast<const uint8_t*>(file->Map( 126 vm_instr_mapping = file->Map(File::kReadExecute, vm_instructions_position,
82 File::kReadExecute, vm_instructions_position, vm_instructions_size)); 127 vm_instructions_size);
83 if (*vm_instructions_buffer == NULL) { 128 if (vm_instr_mapping == NULL) {
84 Log::PrintErr("Failed to memory map snapshot\n"); 129 FATAL1("Failed to memory map snapshot: %s\n", script_name);
85 Platform::Exit(kErrorExitCode);
86 } 130 }
87 } 131 }
88 132
89 *isolate_data_buffer = reinterpret_cast<const uint8_t*>( 133 MappedMemory* isolate_data_mapping = NULL;
90 file->Map(File::kReadOnly, isolate_data_position, isolate_data_size)); 134 if (isolate_data_size != 0) {
91 if (isolate_data_buffer == NULL) { 135 isolate_data_mapping =
92 Log::PrintErr("Failed to memory map snapshot\n"); 136 file->Map(File::kReadOnly, isolate_data_position, isolate_data_size);
93 Platform::Exit(kErrorExitCode); 137 if (isolate_data_mapping == NULL) {
138 FATAL1("Failed to memory map snapshot: %s\n", script_name);
139 }
94 } 140 }
95 141
96 if (isolate_instructions_size == 0) { 142 MappedMemory* isolate_instr_mapping = NULL;
97 *isolate_instructions_buffer = NULL; 143 if (isolate_instructions_size != 0) {
98 } else { 144 isolate_instr_mapping =
99 *isolate_instructions_buffer = reinterpret_cast<const uint8_t*>(
100 file->Map(File::kReadExecute, isolate_instructions_position, 145 file->Map(File::kReadExecute, isolate_instructions_position,
101 isolate_instructions_size)); 146 isolate_instructions_size);
102 if (*isolate_instructions_buffer == NULL) { 147 if (isolate_instr_mapping == NULL) {
103 Log::PrintErr("Failed to memory map snapshot\n"); 148 FATAL1("Failed to memory map snapshot: %s\n", script_name);
104 Platform::Exit(kErrorExitCode);
105 } 149 }
106 } 150 }
107 151
108 file->Release(); 152 file->Release();
109 return true; 153 return new MappedAppSnapshot(vm_data_mapping, vm_instr_mapping,
154 isolate_data_mapping, isolate_instr_mapping);
110 } 155 }
111 156
112 157
113 #if defined(DART_PRECOMPILED_RUNTIME) 158 #if defined(DART_PRECOMPILED_RUNTIME)
114 static bool ReadAppSnapshotDynamicLibrary( 159 class DylibAppSnapshot : public AppSnapshot {
115 const char* script_name, 160 public:
116 const uint8_t** vm_data_buffer, 161 DylibAppSnapshot(void* library,
117 const uint8_t** vm_instructions_buffer, 162 const uint8_t* vm_snapshot_data,
118 const uint8_t** isolate_data_buffer, 163 const uint8_t* vm_snapshot_instructions,
119 const uint8_t** isolate_instructions_buffer) { 164 const uint8_t* isolate_snapshot_data,
120 void* library = Extensions::LoadExtensionLibrary(script_name); 165 const uint8_t* isolate_snapshot_instructions)
121 if (library == NULL) { 166 : library_(library),
122 return false; 167 vm_snapshot_data_(vm_snapshot_data),
168 vm_snapshot_instructions_(vm_snapshot_instructions),
169 isolate_snapshot_data_(isolate_snapshot_data),
170 isolate_snapshot_instructions_(isolate_snapshot_instructions) {}
171
172 ~DylibAppSnapshot() { Extensions::UnloadLibrary(library_); }
173
174 void SetBuffers(const uint8_t** vm_data_buffer,
175 const uint8_t** vm_instructions_buffer,
176 const uint8_t** isolate_data_buffer,
177 const uint8_t** isolate_instructions_buffer) {
178 *vm_data_buffer = vm_snapshot_data_;
179 *vm_instructions_buffer = vm_snapshot_instructions_;
180 *isolate_data_buffer = isolate_snapshot_data_;
181 *isolate_instructions_buffer = isolate_snapshot_instructions_;
123 } 182 }
124 183
125 *vm_data_buffer = reinterpret_cast<const uint8_t*>( 184 private:
126 Extensions::ResolveSymbol(library, kVmSnapshotDataSymbolName)); 185 void* library_;
127 if (*vm_data_buffer == NULL) { 186 const uint8_t* vm_snapshot_data_;
128 Log::PrintErr("Failed to resolve symbol '%s'\n", kVmSnapshotDataSymbolName); 187 const uint8_t* vm_snapshot_instructions_;
129 Platform::Exit(kErrorExitCode); 188 const uint8_t* isolate_snapshot_data_;
189 const uint8_t* isolate_snapshot_instructions_;
190 };
191
192
193 static AppSnapshot* TryReadAppSnapshotDynamicLibrary(const char* script_name) {
194 void* library = Extensions::LoadLibrary(script_name);
195 if (library == NULL) {
196 return NULL;
130 } 197 }
131 198
132 *vm_instructions_buffer = reinterpret_cast<const uint8_t*>( 199 const uint8_t* vm_data_buffer = reinterpret_cast<const uint8_t*>(
133 Extensions::ResolveSymbol(library, kVmSnapshotInstructionsSymbolName)); 200 Extensions::ResolveSymbol(library, kVmSnapshotDataSymbolName));
134 if (*vm_instructions_buffer == NULL) { 201 if (vm_data_buffer == NULL) {
135 Log::PrintErr("Failed to resolve symbol '%s'\n", 202 FATAL1("Failed to resolve symbol '%s'\n", kVmSnapshotDataSymbolName);
136 kVmSnapshotInstructionsSymbolName);
137 Platform::Exit(kErrorExitCode);
138 } 203 }
139 204
140 *isolate_data_buffer = reinterpret_cast<const uint8_t*>( 205 const uint8_t* vm_instructions_buffer = reinterpret_cast<const uint8_t*>(
141 Extensions::ResolveSymbol(library, kIsolateSnapshotDataSymbolName)); 206 Extensions::ResolveSymbol(library, kVmSnapshotInstructionsSymbolName));
142 if (*isolate_data_buffer == NULL) { 207 if (vm_instructions_buffer == NULL) {
143 Log::PrintErr("Failed to resolve symbol '%s'\n", 208 FATAL1("Failed to resolve symbol '%s'\n",
144 kIsolateSnapshotDataSymbolName); 209 kVmSnapshotInstructionsSymbolName);
145 Platform::Exit(kErrorExitCode);
146 } 210 }
147 211
148 *isolate_instructions_buffer = 212 const uint8_t* isolate_data_buffer = reinterpret_cast<const uint8_t*>(
213 Extensions::ResolveSymbol(library, kIsolateSnapshotDataSymbolName));
214 if (isolate_data_buffer == NULL) {
215 FATAL1("Failed to resolve symbol '%s'\n", kIsolateSnapshotDataSymbolName);
216 }
217
218 const uint8_t* isolate_instructions_buffer =
149 reinterpret_cast<const uint8_t*>(Extensions::ResolveSymbol( 219 reinterpret_cast<const uint8_t*>(Extensions::ResolveSymbol(
150 library, kIsolateSnapshotInstructionsSymbolName)); 220 library, kIsolateSnapshotInstructionsSymbolName));
151 if (*isolate_instructions_buffer == NULL) { 221 if (isolate_instructions_buffer == NULL) {
152 Log::PrintErr("Failed to resolve symbol '%s'\n", 222 FATAL1("Failed to resolve symbol '%s'\n",
153 kIsolateSnapshotInstructionsSymbolName); 223 kIsolateSnapshotInstructionsSymbolName);
154 Platform::Exit(kErrorExitCode);
155 } 224 }
156 225
157 return true; 226 return new DylibAppSnapshot(library, vm_data_buffer, vm_instructions_buffer,
227 isolate_data_buffer, isolate_instructions_buffer);
158 } 228 }
159 #endif // defined(DART_PRECOMPILED_RUNTIME) 229 #endif // defined(DART_PRECOMPILED_RUNTIME)
160 230
161 231
162 bool Snapshot::ReadAppSnapshot(const char* script_name, 232 AppSnapshot* Snapshot::TryReadAppSnapshot(const char* script_name) {
163 const uint8_t** vm_data_buffer,
164 const uint8_t** vm_instructions_buffer,
165 const uint8_t** isolate_data_buffer,
166 const uint8_t** isolate_instructions_buffer) {
167 if (File::GetType(script_name, true) != File::kIsFile) { 233 if (File::GetType(script_name, true) != File::kIsFile) {
168 // If 'script_name' refers to a pipe, don't read to check for an app 234 // If 'script_name' refers to a pipe, don't read to check for an app
169 // snapshot since we cannot rewind if it isn't (and couldn't mmap it in 235 // snapshot since we cannot rewind if it isn't (and couldn't mmap it in
170 // anyway if it was). 236 // anyway if it was).
171 return false; 237 return NULL;
172 } 238 }
173 if (ReadAppSnapshotBlobs(script_name, vm_data_buffer, vm_instructions_buffer, 239 AppSnapshot* snapshot = TryReadAppSnapshotBlobs(script_name);
174 isolate_data_buffer, isolate_instructions_buffer)) { 240 if (snapshot != NULL) {
175 return true; 241 return snapshot;
176 } 242 }
177 #if defined(DART_PRECOMPILED_RUNTIME) 243 #if defined(DART_PRECOMPILED_RUNTIME)
178 // For testing AOT with the standalone embedder, we also support loading 244 // For testing AOT with the standalone embedder, we also support loading
179 // from a dynamic library to simulate what happens on iOS. 245 // from a dynamic library to simulate what happens on iOS.
180 return ReadAppSnapshotDynamicLibrary( 246 snapshot = TryReadAppSnapshotDynamicLibrary(script_name);
181 script_name, vm_data_buffer, vm_instructions_buffer, isolate_data_buffer, 247 if (snapshot != NULL) {
182 isolate_instructions_buffer); 248 return snapshot;
183 #else 249 }
184 return false;
185 #endif // defined(DART_PRECOMPILED_RUNTIME) 250 #endif // defined(DART_PRECOMPILED_RUNTIME)
251 return NULL;
186 } 252 }
187 253
188 254
189 static void WriteSnapshotFile(const char* filename, 255 static void WriteSnapshotFile(const char* filename,
190 bool write_magic_number, 256 bool write_magic_number,
191 const uint8_t* buffer, 257 const uint8_t* buffer,
192 const intptr_t size) { 258 const intptr_t size) {
193 File* file = File::Open(filename, File::kWriteTruncate); 259 File* file = File::Open(filename, File::kWriteTruncate);
194 if (file == NULL) { 260 if (file == NULL) {
195 ErrorExit(kErrorExitCode, "Unable to open file %s for writing snapshot\n", 261 ErrorExit(kErrorExitCode, "Unable to open file %s for writing snapshot\n",
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 Dart_Handle result = 406 Dart_Handle result =
341 Dart_CreateAppAOTSnapshotAsAssembly(&assembly_buffer, &assembly_size); 407 Dart_CreateAppAOTSnapshotAsAssembly(&assembly_buffer, &assembly_size);
342 if (Dart_IsError(result)) { 408 if (Dart_IsError(result)) {
343 ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result)); 409 ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
344 } 410 }
345 WriteSnapshotFile(snapshot_filename, false, assembly_buffer, assembly_size); 411 WriteSnapshotFile(snapshot_filename, false, assembly_buffer, assembly_size);
346 } 412 }
347 413
348 } // namespace bin 414 } // namespace bin
349 } // namespace dart 415 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/bin/snapshot_utils.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698