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

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

Issue 2694103004: Cleanup app snapshots on isolate/vm exit. (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/isolate_data.h ('K') | « 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 Log::PrintErr("Failed to memory map snapshot\n");
zra 2017/02/15 04:41:40 Why not: FATAL1("Failed to memory map snapshot: %
rmacnak 2017/02/16 03:05:30 Done.
76 Platform::Exit(kErrorExitCode); 121 Platform::Exit(kErrorExitCode);
77 } 122 }
78 } 123 }
79 124
125 MappedMemory* vm_instr_mapping = NULL;
80 if (vm_instructions_size != 0) { 126 if (vm_instructions_size != 0) {
81 *vm_instructions_buffer = reinterpret_cast<const uint8_t*>(file->Map( 127 vm_instr_mapping = file->Map(File::kReadExecute, vm_instructions_position,
82 File::kReadExecute, vm_instructions_position, vm_instructions_size)); 128 vm_instructions_size);
83 if (*vm_instructions_buffer == NULL) { 129 if (vm_instr_mapping == NULL) {
84 Log::PrintErr("Failed to memory map snapshot\n"); 130 Log::PrintErr("Failed to memory map snapshot\n");
85 Platform::Exit(kErrorExitCode); 131 Platform::Exit(kErrorExitCode);
86 } 132 }
87 } 133 }
88 134
89 *isolate_data_buffer = reinterpret_cast<const uint8_t*>( 135 MappedMemory* isolate_data_mapping = NULL;
90 file->Map(File::kReadOnly, isolate_data_position, isolate_data_size)); 136 if (isolate_data_size != 0) {
91 if (isolate_data_buffer == NULL) { 137 isolate_data_mapping =
92 Log::PrintErr("Failed to memory map snapshot\n"); 138 file->Map(File::kReadOnly, isolate_data_position, isolate_data_size);
93 Platform::Exit(kErrorExitCode); 139 if (isolate_data_mapping == NULL) {
140 Log::PrintErr("Failed to memory map snapshot\n");
141 Platform::Exit(kErrorExitCode);
142 }
94 } 143 }
95 144
96 if (isolate_instructions_size == 0) { 145 MappedMemory* isolate_instr_mapping = NULL;
97 *isolate_instructions_buffer = NULL; 146 if (isolate_instructions_size != 0) {
98 } else { 147 isolate_instr_mapping =
99 *isolate_instructions_buffer = reinterpret_cast<const uint8_t*>(
100 file->Map(File::kReadExecute, isolate_instructions_position, 148 file->Map(File::kReadExecute, isolate_instructions_position,
101 isolate_instructions_size)); 149 isolate_instructions_size);
102 if (*isolate_instructions_buffer == NULL) { 150 if (isolate_instr_mapping == NULL) {
103 Log::PrintErr("Failed to memory map snapshot\n"); 151 Log::PrintErr("Failed to memory map snapshot\n");
104 Platform::Exit(kErrorExitCode); 152 Platform::Exit(kErrorExitCode);
105 } 153 }
106 } 154 }
107 155
108 file->Release(); 156 file->Release();
109 return true; 157 return new MappedAppSnapshot(vm_data_mapping, vm_instr_mapping,
158 isolate_data_mapping, isolate_instr_mapping);
110 } 159 }
111 160
112 161
113 #if defined(DART_PRECOMPILED_RUNTIME) 162 #if defined(DART_PRECOMPILED_RUNTIME)
114 static bool ReadAppSnapshotDynamicLibrary( 163 class DylibAppSnapshot : public AppSnapshot {
115 const char* script_name, 164 public:
116 const uint8_t** vm_data_buffer, 165 DylibAppSnapshot(void* library,
117 const uint8_t** vm_instructions_buffer, 166 const uint8_t* vm_snapshot_data,
118 const uint8_t** isolate_data_buffer, 167 const uint8_t* vm_snapshot_instructions,
119 const uint8_t** isolate_instructions_buffer) { 168 const uint8_t* isolate_snapshot_data,
120 void* library = Extensions::LoadExtensionLibrary(script_name); 169 const uint8_t* isolate_snapshot_instructions)
121 if (library == NULL) { 170 : library_(library),
122 return false; 171 vm_snapshot_data_(vm_snapshot_data),
172 vm_snapshot_instructions_(vm_snapshot_instructions),
173 isolate_snapshot_data_(isolate_snapshot_data),
174 isolate_snapshot_instructions_(isolate_snapshot_instructions) {}
175
176 ~DylibAppSnapshot() { Extensions::UnloadLibrary(library_); }
177
178 void SetBuffers(const uint8_t** vm_data_buffer,
179 const uint8_t** vm_instructions_buffer,
180 const uint8_t** isolate_data_buffer,
181 const uint8_t** isolate_instructions_buffer) {
182 *vm_data_buffer = vm_snapshot_data_;
183 *vm_instructions_buffer = vm_snapshot_instructions_;
184 *isolate_data_buffer = isolate_snapshot_data_;
185 *isolate_instructions_buffer = isolate_snapshot_instructions_;
123 } 186 }
124 187
125 *vm_data_buffer = reinterpret_cast<const uint8_t*>( 188 private:
189 void* library_;
190 const uint8_t* vm_snapshot_data_;
191 const uint8_t* vm_snapshot_instructions_;
192 const uint8_t* isolate_snapshot_data_;
193 const uint8_t* isolate_snapshot_instructions_;
194 };
195
196
197 static AppSnapshot* TryReadAppSnapshotDynamicLibrary(const char* script_name) {
198 void* library = Extensions::LoadLibrary(script_name);
199 if (library == NULL) {
200 return NULL;
201 }
202
203 const uint8_t* vm_data_buffer = reinterpret_cast<const uint8_t*>(
126 Extensions::ResolveSymbol(library, kVmSnapshotDataSymbolName)); 204 Extensions::ResolveSymbol(library, kVmSnapshotDataSymbolName));
127 if (*vm_data_buffer == NULL) { 205 if (vm_data_buffer == NULL) {
128 Log::PrintErr("Failed to resolve symbol '%s'\n", kVmSnapshotDataSymbolName); 206 Log::PrintErr("Failed to resolve symbol '%s'\n", kVmSnapshotDataSymbolName);
129 Platform::Exit(kErrorExitCode); 207 Platform::Exit(kErrorExitCode);
130 } 208 }
131 209
132 *vm_instructions_buffer = reinterpret_cast<const uint8_t*>( 210 const uint8_t* vm_instructions_buffer = reinterpret_cast<const uint8_t*>(
133 Extensions::ResolveSymbol(library, kVmSnapshotInstructionsSymbolName)); 211 Extensions::ResolveSymbol(library, kVmSnapshotInstructionsSymbolName));
134 if (*vm_instructions_buffer == NULL) { 212 if (vm_instructions_buffer == NULL) {
135 Log::PrintErr("Failed to resolve symbol '%s'\n", 213 Log::PrintErr("Failed to resolve symbol '%s'\n",
136 kVmSnapshotInstructionsSymbolName); 214 kVmSnapshotInstructionsSymbolName);
137 Platform::Exit(kErrorExitCode); 215 Platform::Exit(kErrorExitCode);
138 } 216 }
139 217
140 *isolate_data_buffer = reinterpret_cast<const uint8_t*>( 218 const uint8_t* isolate_data_buffer = reinterpret_cast<const uint8_t*>(
141 Extensions::ResolveSymbol(library, kIsolateSnapshotDataSymbolName)); 219 Extensions::ResolveSymbol(library, kIsolateSnapshotDataSymbolName));
142 if (*isolate_data_buffer == NULL) { 220 if (isolate_data_buffer == NULL) {
143 Log::PrintErr("Failed to resolve symbol '%s'\n", 221 Log::PrintErr("Failed to resolve symbol '%s'\n",
144 kIsolateSnapshotDataSymbolName); 222 kIsolateSnapshotDataSymbolName);
145 Platform::Exit(kErrorExitCode); 223 Platform::Exit(kErrorExitCode);
146 } 224 }
147 225
148 *isolate_instructions_buffer = 226 const uint8_t* isolate_instructions_buffer =
149 reinterpret_cast<const uint8_t*>(Extensions::ResolveSymbol( 227 reinterpret_cast<const uint8_t*>(Extensions::ResolveSymbol(
150 library, kIsolateSnapshotInstructionsSymbolName)); 228 library, kIsolateSnapshotInstructionsSymbolName));
151 if (*isolate_instructions_buffer == NULL) { 229 if (isolate_instructions_buffer == NULL) {
152 Log::PrintErr("Failed to resolve symbol '%s'\n", 230 Log::PrintErr("Failed to resolve symbol '%s'\n",
153 kIsolateSnapshotInstructionsSymbolName); 231 kIsolateSnapshotInstructionsSymbolName);
154 Platform::Exit(kErrorExitCode); 232 Platform::Exit(kErrorExitCode);
155 } 233 }
156 234
157 return true; 235 return new DylibAppSnapshot(library, vm_data_buffer, vm_instructions_buffer,
236 isolate_data_buffer, isolate_instructions_buffer);
158 } 237 }
159 #endif // defined(DART_PRECOMPILED_RUNTIME) 238 #endif // defined(DART_PRECOMPILED_RUNTIME)
160 239
161 240
162 bool Snapshot::ReadAppSnapshot(const char* script_name, 241 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) { 242 if (File::GetType(script_name, true) != File::kIsFile) {
168 // If 'script_name' refers to a pipe, don't read to check for an app 243 // 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 244 // snapshot since we cannot rewind if it isn't (and couldn't mmap it in
170 // anyway if it was). 245 // anyway if it was).
171 return false; 246 return NULL;
172 } 247 }
173 if (ReadAppSnapshotBlobs(script_name, vm_data_buffer, vm_instructions_buffer, 248 AppSnapshot* snapshot = TryReadAppSnapshotBlobs(script_name);
174 isolate_data_buffer, isolate_instructions_buffer)) { 249 if (snapshot != NULL) {
175 return true; 250 return snapshot;
176 } 251 }
177 #if defined(DART_PRECOMPILED_RUNTIME) 252 #if defined(DART_PRECOMPILED_RUNTIME)
178 // For testing AOT with the standalone embedder, we also support loading 253 // For testing AOT with the standalone embedder, we also support loading
179 // from a dynamic library to simulate what happens on iOS. 254 // from a dynamic library to simulate what happens on iOS.
180 return ReadAppSnapshotDynamicLibrary( 255 snapshot = TryReadAppSnapshotDynamicLibrary(script_name);
181 script_name, vm_data_buffer, vm_instructions_buffer, isolate_data_buffer, 256 if (snapshot != NULL) {
182 isolate_instructions_buffer); 257 return snapshot;
183 #else 258 }
184 return false;
185 #endif // defined(DART_PRECOMPILED_RUNTIME) 259 #endif // defined(DART_PRECOMPILED_RUNTIME)
260 return NULL;
186 } 261 }
187 262
188 263
189 static void WriteSnapshotFile(const char* filename, 264 static void WriteSnapshotFile(const char* filename,
190 bool write_magic_number, 265 bool write_magic_number,
191 const uint8_t* buffer, 266 const uint8_t* buffer,
192 const intptr_t size) { 267 const intptr_t size) {
193 File* file = File::Open(filename, File::kWriteTruncate); 268 File* file = File::Open(filename, File::kWriteTruncate);
194 if (file == NULL) { 269 if (file == NULL) {
195 ErrorExit(kErrorExitCode, "Unable to open file %s for writing snapshot\n", 270 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 = 415 Dart_Handle result =
341 Dart_CreateAppAOTSnapshotAsAssembly(&assembly_buffer, &assembly_size); 416 Dart_CreateAppAOTSnapshotAsAssembly(&assembly_buffer, &assembly_size);
342 if (Dart_IsError(result)) { 417 if (Dart_IsError(result)) {
343 ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result)); 418 ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
344 } 419 }
345 WriteSnapshotFile(snapshot_filename, false, assembly_buffer, assembly_size); 420 WriteSnapshotFile(snapshot_filename, false, assembly_buffer, assembly_size);
346 } 421 }
347 422
348 } // namespace bin 423 } // namespace bin
349 } // namespace dart 424 } // namespace dart
OLDNEW
« runtime/bin/isolate_data.h ('K') | « runtime/bin/snapshot_utils.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698