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