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

Side by Side Diff: gin/v8_initializer.cc

Issue 1665513002: Pass both 32 and 64 bit snapshot and natives fds to child processes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: avoid non-POD global Created 4 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 | « gin/v8_initializer.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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "gin/v8_initializer.h" 5 #include "gin/v8_initializer.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include "base/debug/alias.h" 10 #include "base/debug/alias.h"
11 #include "base/files/file.h" 11 #include "base/files/file.h"
12 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
13 #include "base/files/memory_mapped_file.h" 13 #include "base/files/memory_mapped_file.h"
14 #include "base/lazy_instance.h"
14 #include "base/logging.h" 15 #include "base/logging.h"
15 #include "base/memory/scoped_ptr.h" 16 #include "base/memory/scoped_ptr.h"
16 #include "base/metrics/histogram.h" 17 #include "base/metrics/histogram.h"
17 #include "base/rand_util.h" 18 #include "base/rand_util.h"
18 #include "base/strings/sys_string_conversions.h" 19 #include "base/strings/sys_string_conversions.h"
19 #include "base/threading/platform_thread.h" 20 #include "base/threading/platform_thread.h"
20 #include "base/time/time.h" 21 #include "base/time/time.h"
21 #include "crypto/sha2.h" 22 #include "crypto/sha2.h"
22 23
23 #if defined(V8_USE_EXTERNAL_STARTUP_DATA) 24 #if defined(V8_USE_EXTERNAL_STARTUP_DATA)
(...skipping 19 matching lines...) Expand all
43 const base::PlatformFile kInvalidPlatformFile = 44 const base::PlatformFile kInvalidPlatformFile =
44 #if defined(OS_WIN) 45 #if defined(OS_WIN)
45 INVALID_HANDLE_VALUE; 46 INVALID_HANDLE_VALUE;
46 #else 47 #else
47 -1; 48 -1;
48 #endif 49 #endif
49 50
50 // File handles intentionally never closed. Not using File here because its 51 // File handles intentionally never closed. Not using File here because its
51 // Windows implementation guards against two instances owning the same 52 // Windows implementation guards against two instances owning the same
52 // PlatformFile (which we allow since we know it is never freed). 53 // PlatformFile (which we allow since we know it is never freed).
53 base::PlatformFile g_natives_pf = kInvalidPlatformFile; 54 typedef std::map<const char*,
54 base::PlatformFile g_snapshot_pf = kInvalidPlatformFile; 55 std::pair<base::PlatformFile, base::MemoryMappedFile::Region>>
55 base::MemoryMappedFile::Region g_natives_region; 56 OpenedFileMap;
56 base::MemoryMappedFile::Region g_snapshot_region; 57 static base::LazyInstance<OpenedFileMap>::Leaky g_opened_files =
58 LAZY_INSTANCE_INITIALIZER;
59
60 OpenedFileMap::mapped_type& GetOpenedFile(const char* file) {
61 OpenedFileMap& opened_files(g_opened_files.Get());
62 if (opened_files.find(file) == opened_files.end()) {
63 opened_files[file] =
64 std::make_pair(kInvalidPlatformFile, base::MemoryMappedFile::Region());
65 }
66 return opened_files[file];
67 }
57 68
58 #if defined(OS_ANDROID) 69 #if defined(OS_ANDROID)
59 #ifdef __LP64__ 70 const char kNativesFileName64[] = "natives_blob_64.bin";
60 const char kNativesFileName[] = "natives_blob_64.bin"; 71 const char kSnapshotFileName64[] = "snapshot_blob_64.bin";
61 const char kSnapshotFileName[] = "snapshot_blob_64.bin"; 72 const char kNativesFileName32[] = "natives_blob_32.bin";
73 const char kSnapshotFileName32[] = "snapshot_blob_32.bin";
74
75 #if defined(__LP64__)
76 #define kNativesFileName kNativesFileName64
77 #define kSnapshotFileName kSnapshotFileName64
62 #else 78 #else
63 const char kNativesFileName[] = "natives_blob_32.bin"; 79 #define kNativesFileName kNativesFileName32
64 const char kSnapshotFileName[] = "snapshot_blob_32.bin"; 80 #define kSnapshotFileName kSnapshotFileName32
65 #endif // __LP64__ 81 #endif
66 82
67 #else // defined(OS_ANDROID) 83 #else // defined(OS_ANDROID)
68 const char kNativesFileName[] = "natives_blob.bin"; 84 const char kNativesFileName[] = "natives_blob.bin";
69 const char kSnapshotFileName[] = "snapshot_blob.bin"; 85 const char kSnapshotFileName[] = "snapshot_blob.bin";
70 #endif // defined(OS_ANDROID) 86 #endif // defined(OS_ANDROID)
71 87
72 void GetV8FilePath(const char* file_name, base::FilePath* path_out) { 88 void GetV8FilePath(const char* file_name, base::FilePath* path_out) {
73 #if !defined(OS_MACOSX) 89 #if !defined(OS_MACOSX)
74 base::FilePath data_path; 90 base::FilePath data_path;
75 #if defined(OS_ANDROID) 91 #if defined(OS_ANDROID)
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 } 179 }
164 } 180 }
165 #endif // defined(OS_ANDROID) 181 #endif // defined(OS_ANDROID)
166 182
167 UMA_HISTOGRAM_ENUMERATION("V8.Initializer.OpenV8File.Result", 183 UMA_HISTOGRAM_ENUMERATION("V8.Initializer.OpenV8File.Result",
168 result, 184 result,
169 OpenV8FileResult::MAX_VALUE); 185 OpenV8FileResult::MAX_VALUE);
170 return file.TakePlatformFile(); 186 return file.TakePlatformFile();
171 } 187 }
172 188
173 void OpenNativesFileIfNecessary() { 189 static const OpenedFileMap::mapped_type OpenFileIfNecessary(
174 if (g_natives_pf == kInvalidPlatformFile) { 190 const char* file_name) {
175 g_natives_pf = OpenV8File(kNativesFileName, &g_natives_region); 191 OpenedFileMap::mapped_type& opened = GetOpenedFile(file_name);
192 if (opened.first == kInvalidPlatformFile) {
193 opened.first = OpenV8File(file_name, &opened.second);
176 } 194 }
177 } 195 return opened;
178
179 void OpenSnapshotFileIfNecessary() {
180 if (g_snapshot_pf == kInvalidPlatformFile) {
181 g_snapshot_pf = OpenV8File(kSnapshotFileName, &g_snapshot_region);
182 }
183 } 196 }
184 197
185 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA) 198 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
186 bool VerifyV8StartupFile(base::MemoryMappedFile** file, 199 bool VerifyV8StartupFile(base::MemoryMappedFile** file,
187 const unsigned char* fingerprint) { 200 const unsigned char* fingerprint) {
188 unsigned char output[crypto::kSHA256Length]; 201 unsigned char output[crypto::kSHA256Length];
189 crypto::SHA256HashString( 202 crypto::SHA256HashString(
190 base::StringPiece(reinterpret_cast<const char*>((*file)->data()), 203 base::StringPiece(reinterpret_cast<const char*>((*file)->data()),
191 (*file)->length()), 204 (*file)->length()),
192 output, sizeof(output)); 205 output, sizeof(output));
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 #endif // V8_VERIFY_EXTERNAL_STARTUP_DATA 242 #endif // V8_VERIFY_EXTERNAL_STARTUP_DATA
230 243
231 enum LoadV8FileResult { 244 enum LoadV8FileResult {
232 V8_LOAD_SUCCESS = 0, 245 V8_LOAD_SUCCESS = 0,
233 V8_LOAD_FAILED_OPEN, 246 V8_LOAD_FAILED_OPEN,
234 V8_LOAD_FAILED_MAP, 247 V8_LOAD_FAILED_MAP,
235 V8_LOAD_FAILED_VERIFY, 248 V8_LOAD_FAILED_VERIFY,
236 V8_LOAD_MAX_VALUE 249 V8_LOAD_MAX_VALUE
237 }; 250 };
238 251
239 static LoadV8FileResult MapVerify(base::PlatformFile platform_file, 252 static LoadV8FileResult MapVerify(const OpenedFileMap::mapped_type& file_region,
240 const base::MemoryMappedFile::Region& region,
241 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA) 253 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
242 const unsigned char* fingerprint, 254 const unsigned char* fingerprint,
243 #endif 255 #endif
244 base::MemoryMappedFile** mmapped_file_out) { 256 base::MemoryMappedFile** mmapped_file_out) {
245 if (platform_file == kInvalidPlatformFile) 257 if (file_region.first == kInvalidPlatformFile)
246 return V8_LOAD_FAILED_OPEN; 258 return V8_LOAD_FAILED_OPEN;
247 if (!MapV8File(platform_file, region, mmapped_file_out)) 259 if (!MapV8File(file_region.first, file_region.second, mmapped_file_out))
248 return V8_LOAD_FAILED_MAP; 260 return V8_LOAD_FAILED_MAP;
249 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA) 261 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
250 if (!VerifyV8StartupFile(mmapped_file_out, fingerprint)) 262 if (!VerifyV8StartupFile(mmapped_file_out, fingerprint))
251 return V8_LOAD_FAILED_VERIFY; 263 return V8_LOAD_FAILED_VERIFY;
252 #endif // V8_VERIFY_EXTERNAL_STARTUP_DATA 264 #endif // V8_VERIFY_EXTERNAL_STARTUP_DATA
253 return V8_LOAD_SUCCESS; 265 return V8_LOAD_SUCCESS;
254 } 266 }
255 267
256 // static 268 // static
257 void V8Initializer::LoadV8Snapshot() { 269 void V8Initializer::LoadV8Snapshot() {
258 if (g_mapped_snapshot) 270 if (g_mapped_snapshot)
259 return; 271 return;
260 272
261 OpenSnapshotFileIfNecessary(); 273 OpenFileIfNecessary(kSnapshotFileName);
262 LoadV8FileResult result = MapVerify(g_snapshot_pf, g_snapshot_region, 274 LoadV8FileResult result = MapVerify(GetOpenedFile(kSnapshotFileName),
263 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA) 275 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
264 g_snapshot_fingerprint, 276 g_snapshot_fingerprint,
265 #endif 277 #endif
266 &g_mapped_snapshot); 278 &g_mapped_snapshot);
267 // V8 can't start up without the source of the natives, but it can 279 // V8 can't start up without the source of the natives, but it can
268 // start up (slower) without the snapshot. 280 // start up (slower) without the snapshot.
269 UMA_HISTOGRAM_ENUMERATION("V8.Initializer.LoadV8Snapshot.Result", result, 281 UMA_HISTOGRAM_ENUMERATION("V8.Initializer.LoadV8Snapshot.Result", result,
270 V8_LOAD_MAX_VALUE); 282 V8_LOAD_MAX_VALUE);
271 } 283 }
272 284
273 void V8Initializer::LoadV8Natives() { 285 void V8Initializer::LoadV8Natives() {
274 if (g_mapped_natives) 286 if (g_mapped_natives)
275 return; 287 return;
276 288
277 OpenNativesFileIfNecessary(); 289 OpenFileIfNecessary(kNativesFileName);
278 LoadV8FileResult result = MapVerify(g_natives_pf, g_natives_region, 290 LoadV8FileResult result = MapVerify(GetOpenedFile(kNativesFileName),
279 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA) 291 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
280 g_natives_fingerprint, 292 g_natives_fingerprint,
281 #endif 293 #endif
282 &g_mapped_natives); 294 &g_mapped_natives);
283 if (result != V8_LOAD_SUCCESS) { 295 if (result != V8_LOAD_SUCCESS) {
284 LOG(FATAL) << "Couldn't mmap v8 natives data file, status code is " 296 LOG(FATAL) << "Couldn't mmap v8 natives data file, status code is "
285 << static_cast<int>(result); 297 << static_cast<int>(result);
286 } 298 }
287 } 299 }
288 300
(...skipping 15 matching lines...) Expand all
304 } 316 }
305 317
306 LoadV8FileResult result = V8_LOAD_SUCCESS; 318 LoadV8FileResult result = V8_LOAD_SUCCESS;
307 if (!MapV8File(snapshot_pf, snapshot_region, &g_mapped_snapshot)) 319 if (!MapV8File(snapshot_pf, snapshot_region, &g_mapped_snapshot))
308 result = V8_LOAD_FAILED_MAP; 320 result = V8_LOAD_FAILED_MAP;
309 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA) 321 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
310 if (!VerifyV8StartupFile(&g_mapped_snapshot, g_snapshot_fingerprint)) 322 if (!VerifyV8StartupFile(&g_mapped_snapshot, g_snapshot_fingerprint))
311 result = V8_LOAD_FAILED_VERIFY; 323 result = V8_LOAD_FAILED_VERIFY;
312 #endif // V8_VERIFY_EXTERNAL_STARTUP_DATA 324 #endif // V8_VERIFY_EXTERNAL_STARTUP_DATA
313 if (result == V8_LOAD_SUCCESS) { 325 if (result == V8_LOAD_SUCCESS) {
314 g_snapshot_pf = snapshot_pf; 326 g_opened_files.Get()[kSnapshotFileName] =
315 g_snapshot_region = snapshot_region; 327 std::make_pair(snapshot_pf, snapshot_region);
316 } 328 }
317 UMA_HISTOGRAM_ENUMERATION("V8.Initializer.LoadV8Snapshot.Result", result, 329 UMA_HISTOGRAM_ENUMERATION("V8.Initializer.LoadV8Snapshot.Result", result,
318 V8_LOAD_MAX_VALUE); 330 V8_LOAD_MAX_VALUE);
319 } 331 }
320 332
321 // static 333 // static
322 void V8Initializer::LoadV8NativesFromFD(base::PlatformFile natives_pf, 334 void V8Initializer::LoadV8NativesFromFD(base::PlatformFile natives_pf,
323 int64_t natives_offset, 335 int64_t natives_offset,
324 int64_t natives_size) { 336 int64_t natives_size) {
325 if (g_mapped_natives) 337 if (g_mapped_natives)
326 return; 338 return;
327 339
328 CHECK_NE(natives_pf, kInvalidPlatformFile); 340 CHECK_NE(natives_pf, kInvalidPlatformFile);
329 341
330 base::MemoryMappedFile::Region natives_region = 342 base::MemoryMappedFile::Region natives_region =
331 base::MemoryMappedFile::Region::kWholeFile; 343 base::MemoryMappedFile::Region::kWholeFile;
332 if (natives_size != 0 || natives_offset != 0) { 344 if (natives_size != 0 || natives_offset != 0) {
333 natives_region.offset = natives_offset; 345 natives_region.offset = natives_offset;
334 natives_region.size = natives_size; 346 natives_region.size = natives_size;
335 } 347 }
336 348
337 if (!MapV8File(natives_pf, natives_region, &g_mapped_natives)) { 349 if (!MapV8File(natives_pf, natives_region, &g_mapped_natives)) {
338 LOG(FATAL) << "Couldn't mmap v8 natives data file"; 350 LOG(FATAL) << "Couldn't mmap v8 natives data file";
339 } 351 }
340 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA) 352 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
341 if (!VerifyV8StartupFile(&g_mapped_natives, g_natives_fingerprint)) { 353 if (!VerifyV8StartupFile(&g_mapped_natives, g_natives_fingerprint)) {
342 LOG(FATAL) << "Couldn't verify contents of v8 natives data file"; 354 LOG(FATAL) << "Couldn't verify contents of v8 natives data file";
343 } 355 }
344 #endif // V8_VERIFY_EXTERNAL_STARTUP_DATA 356 #endif // V8_VERIFY_EXTERNAL_STARTUP_DATA
345 g_natives_pf = natives_pf; 357 g_opened_files.Get()[kNativesFileName] =
346 g_natives_region = natives_region; 358 std::make_pair(natives_pf, natives_region);
347 } 359 }
348 360
349 // static 361 // static
350 base::PlatformFile V8Initializer::GetOpenNativesFileForChildProcesses( 362 base::PlatformFile V8Initializer::GetOpenNativesFileForChildProcesses(
351 base::MemoryMappedFile::Region* region_out) { 363 base::MemoryMappedFile::Region* region_out) {
352 OpenNativesFileIfNecessary(); 364 const OpenedFileMap::mapped_type& opened =
353 *region_out = g_natives_region; 365 OpenFileIfNecessary(kNativesFileName);
354 return g_natives_pf; 366 *region_out = opened.second;
367 return opened.first;
355 } 368 }
356 369
357 // static 370 // static
358 base::PlatformFile V8Initializer::GetOpenSnapshotFileForChildProcesses( 371 base::PlatformFile V8Initializer::GetOpenSnapshotFileForChildProcesses(
359 base::MemoryMappedFile::Region* region_out) { 372 base::MemoryMappedFile::Region* region_out) {
360 OpenSnapshotFileIfNecessary(); 373 const OpenedFileMap::mapped_type& opened =
361 *region_out = g_snapshot_region; 374 OpenFileIfNecessary(kSnapshotFileName);
362 return g_snapshot_pf; 375 *region_out = opened.second;
376 return opened.first;
363 } 377 }
378
379 #if defined(OS_ANDROID)
380 // static
381 base::PlatformFile V8Initializer::GetOpenNativesFileForChildProcesses(
382 base::MemoryMappedFile::Region* region_out,
383 bool abi_32_bit) {
384 const char* natives_file =
385 abi_32_bit ? kNativesFileName32 : kNativesFileName64;
386 const OpenedFileMap::mapped_type& opened = OpenFileIfNecessary(natives_file);
387 *region_out = opened.second;
388 return opened.first;
389 }
390
391 // static
392 base::PlatformFile V8Initializer::GetOpenSnapshotFileForChildProcesses(
393 base::MemoryMappedFile::Region* region_out,
394 bool abi_32_bit) {
395 const char* snapshot_file =
396 abi_32_bit ? kSnapshotFileName32 : kSnapshotFileName64;
397 const OpenedFileMap::mapped_type& opened = OpenFileIfNecessary(snapshot_file);
398 *region_out = opened.second;
399 return opened.first;
400 }
401 #endif // defined(OS_ANDROID)
364 #endif // defined(V8_USE_EXTERNAL_STARTUP_DATA) 402 #endif // defined(V8_USE_EXTERNAL_STARTUP_DATA)
365 403
366 // static 404 // static
367 void V8Initializer::Initialize(IsolateHolder::ScriptMode mode, 405 void V8Initializer::Initialize(IsolateHolder::ScriptMode mode,
368 IsolateHolder::V8ExtrasMode v8_extras_mode) { 406 IsolateHolder::V8ExtrasMode v8_extras_mode) {
369 static bool v8_is_initialized = false; 407 static bool v8_is_initialized = false;
370 if (v8_is_initialized) 408 if (v8_is_initialized)
371 return; 409 return;
372 410
373 v8::V8::InitializePlatform(V8Platform::Get()); 411 v8::V8::InitializePlatform(V8Platform::Get());
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 if (g_mapped_snapshot) { 454 if (g_mapped_snapshot) {
417 *snapshot_data_out = 455 *snapshot_data_out =
418 reinterpret_cast<const char*>(g_mapped_snapshot->data()); 456 reinterpret_cast<const char*>(g_mapped_snapshot->data());
419 *snapshot_size_out = static_cast<int>(g_mapped_snapshot->length()); 457 *snapshot_size_out = static_cast<int>(g_mapped_snapshot->length());
420 } else { 458 } else {
421 *snapshot_data_out = NULL; 459 *snapshot_data_out = NULL;
422 *snapshot_size_out = 0; 460 *snapshot_size_out = 0;
423 } 461 }
424 } 462 }
425 463
464 #if defined(OS_ANDROID)
465 // static
466 base::FilePath V8Initializer::GetNativesFilePath(bool abi_32_bit) {
467 base::FilePath path;
468 GetV8FilePath(abi_32_bit ? kNativesFileName32 : kNativesFileName64, &path);
469 return path;
470 }
471
472 // static
473 base::FilePath V8Initializer::GetSnapshotFilePath(bool abi_32_bit) {
474 base::FilePath path;
475 GetV8FilePath(abi_32_bit ? kSnapshotFileName32 : kSnapshotFileName64, &path);
476 return path;
477 }
478 #endif // defined(OS_ANDROID)
479
426 } // namespace gin 480 } // namespace gin
OLDNEW
« no previous file with comments | « gin/v8_initializer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698