Chromium Code Reviews| Index: gin/v8_initializer.cc |
| diff --git a/gin/v8_initializer.cc b/gin/v8_initializer.cc |
| index 8f79d0d8693b23b01820e9906dad5da48a64bb77..e5a36e88283b5d24c5a7c96b688240a05f55573f 100644 |
| --- a/gin/v8_initializer.cc |
| +++ b/gin/v8_initializer.cc |
| @@ -73,28 +73,16 @@ void GetV8FilePaths(base::FilePath* natives_path_out, |
| #endif // !defined(OS_MACOSX) |
| } |
| -static bool MapV8Files(base::File natives_file, |
| - base::File snapshot_file, |
| - base::MemoryMappedFile::Region natives_region = |
| - base::MemoryMappedFile::Region::kWholeFile, |
| - base::MemoryMappedFile::Region snapshot_region = |
| - base::MemoryMappedFile::Region::kWholeFile) { |
| - g_mapped_natives = new base::MemoryMappedFile; |
| - if (!g_mapped_natives->IsValid()) { |
| - if (!g_mapped_natives->Initialize(natives_file.Pass(), natives_region)) { |
| - delete g_mapped_natives; |
| - g_mapped_natives = NULL; |
| - LOG(FATAL) << "Couldn't mmap v8 natives data file"; |
| - return false; |
| - } |
| - } |
| - |
| - g_mapped_snapshot = new base::MemoryMappedFile; |
| - if (!g_mapped_snapshot->IsValid()) { |
| - if (!g_mapped_snapshot->Initialize(snapshot_file.Pass(), snapshot_region)) { |
| - delete g_mapped_snapshot; |
| - g_mapped_snapshot = NULL; |
| - LOG(ERROR) << "Couldn't mmap v8 snapshot data file"; |
| +bool MapV8File(base::MemoryMappedFile** mmapped_file_return, |
| + base::File file, |
| + base::MemoryMappedFile::Region region = |
| + base::MemoryMappedFile::Region::kWholeFile) { |
| + base::MemoryMappedFile* mmapped_file = *mmapped_file_return = |
| + new base::MemoryMappedFile; |
| + if (!mmapped_file->IsValid()) { |
| + if (!mmapped_file->Initialize(file.Pass(), region)) { |
| + delete mmapped_file; |
| + *mmapped_file_return = NULL; |
| return false; |
| } |
| } |
| @@ -146,12 +134,12 @@ static bool OpenV8File(const base::FilePath& path, |
| } |
| #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA) |
| -bool VerifyV8SnapshotFile(base::MemoryMappedFile* snapshot_file, |
| - const unsigned char* fingerprint) { |
| +bool VerifyV8StartupFile(base::MemoryMappedFile* file, |
| + const unsigned char* fingerprint) { |
| unsigned char output[crypto::kSHA256Length]; |
| crypto::SHA256HashString( |
| - base::StringPiece(reinterpret_cast<const char*>(snapshot_file->data()), |
| - snapshot_file->length()), |
| + base::StringPiece(reinterpret_cast<const char*>(file->data()), |
| + file->length()), |
| output, sizeof(output)); |
| return !memcmp(fingerprint, output, sizeof(output)); |
| } |
| @@ -172,18 +160,45 @@ extern const unsigned char g_natives_fingerprint[]; |
| extern const unsigned char g_snapshot_fingerprint[]; |
| #endif // V8_VERIFY_EXTERNAL_STARTUP_DATA |
| +enum LoadV8FileResult { |
| + V8_LOAD_SUCCESS = 0, |
| + V8_LOAD_FAILED_OPEN, |
| + V8_LOAD_FAILED_MAP, |
| + V8_LOAD_FAILED_VERIFY, |
| + V8_LOAD_MAX_VALUE |
| +}; |
| + |
| // static |
| bool V8Initializer::LoadV8Snapshot() { |
| + if (g_mapped_snapshot) |
| + return true; |
| - enum LoadV8SnapshotResult { |
| - SUCCESS = 0, |
| - FAILED_OPEN, |
| - FAILED_MAP, |
| - FAILED_VERIFY, |
| - MAX_VALUE |
| - }; |
| + base::FilePath natives_data_path; |
| + base::FilePath snapshot_data_path; |
| + GetV8FilePaths(&natives_data_path, &snapshot_data_path); |
|
rmcilroy
2015/06/01 14:06:31
Maybe create seperate functions for natives and sn
Erik Corry Chromium.org
2015/06/02 11:18:52
Done.
|
| - if (g_mapped_natives && g_mapped_snapshot) |
| + base::File snapshot_file; |
| + int flags = base::File::FLAG_OPEN | base::File::FLAG_READ; |
| + |
| + LoadV8FileResult result; |
| + if (!OpenV8File(snapshot_data_path, flags, snapshot_file)) { |
| + result = V8_LOAD_FAILED_OPEN; |
| + } else if (!MapV8File(&g_mapped_snapshot, snapshot_file.Pass())) { |
| + result = V8_LOAD_FAILED_MAP; |
| +#if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA) |
| + } else if (!VerifyV8StartupFile(g_mapped_snapshot, g_snapshot_fingerprint)) { |
| + result = V8_LOAD_FAILED_VERIFY; |
| +#endif // V8_VERIFY_EXTERNAL_STARTUP_DATA |
| + } else { |
| + result = V8_LOAD_SUCCESS; |
| + } |
| + return result == V8_LOAD_SUCCESS; |
| + UMA_HISTOGRAM_ENUMERATION("V8.Initializer.LoadV8Snapshot.Result", result, |
| + V8_LOAD_MAX_VALUE); |
| +} |
| + |
| +bool V8Initializer::LoadV8Natives() { |
| + if (g_mapped_natives) |
| return true; |
| base::FilePath natives_data_path; |
| @@ -191,56 +206,66 @@ bool V8Initializer::LoadV8Snapshot() { |
| GetV8FilePaths(&natives_data_path, &snapshot_data_path); |
| base::File natives_file; |
| - base::File snapshot_file; |
| int flags = base::File::FLAG_OPEN | base::File::FLAG_READ; |
| - LoadV8SnapshotResult result; |
| - if (!OpenV8File(natives_data_path, flags, natives_file) || |
| - !OpenV8File(snapshot_data_path, flags, snapshot_file)) { |
| - result = LoadV8SnapshotResult::FAILED_OPEN; |
| - } else if (!MapV8Files(natives_file.Pass(), snapshot_file.Pass())) { |
| - result = LoadV8SnapshotResult::FAILED_MAP; |
| + LoadV8FileResult result; |
| + if (!OpenV8File(natives_data_path, flags, natives_file)) { |
| + result = V8_LOAD_FAILED_OPEN; |
| + } else if (!MapV8File(&g_mapped_natives, natives_file.Pass())) { |
| + result = V8_LOAD_FAILED_MAP; |
| #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA) |
| - } else if (!VerifyV8SnapshotFile(g_mapped_natives, g_natives_fingerprint) || |
| - !VerifyV8SnapshotFile(g_mapped_snapshot, g_snapshot_fingerprint)) { |
| - result = LoadV8SnapshotResult::FAILED_VERIFY; |
| + } else if (!VerifyV8StartupFile(g_mapped_natives, g_natives_fingerprint)) { |
| + result = V8_LOAD_FAILED_VERIFY; |
| #endif // V8_VERIFY_EXTERNAL_STARTUP_DATA |
| } else { |
| - result = LoadV8SnapshotResult::SUCCESS; |
| + result = V8_LOAD_SUCCESS; |
| } |
| - |
| - UMA_HISTOGRAM_ENUMERATION("V8.Initializer.LoadV8Snapshot.Result", |
| - result, |
| - LoadV8SnapshotResult::MAX_VALUE); |
| - return result == LoadV8SnapshotResult::SUCCESS; |
| + UMA_HISTOGRAM_ENUMERATION("V8.Initializer.LoadV8Natives.Result", result, |
| + V8_LOAD_MAX_VALUE); |
| + if (result != V8_LOAD_SUCCESS) { |
| + LOG(FATAL) << "Couldn't mmap v8 natives data file"; |
| + } |
| + return result == V8_LOAD_SUCCESS; |
| } |
| // static |
| -bool V8Initializer::LoadV8SnapshotFromFD(base::PlatformFile natives_pf, |
| - int64 natives_offset, |
| - int64 natives_size, |
| - base::PlatformFile snapshot_pf, |
| +bool V8Initializer::LoadV8SnapshotFromFD(base::PlatformFile snapshot_pf, |
| int64 snapshot_offset, |
| int64 snapshot_size) { |
| - if (g_mapped_natives && g_mapped_snapshot) |
| + if (g_mapped_snapshot) |
| return true; |
| - base::MemoryMappedFile::Region natives_region = |
| - base::MemoryMappedFile::Region::kWholeFile; |
| - if (natives_size != 0 || natives_offset != 0) { |
| - natives_region = |
| - base::MemoryMappedFile::Region(natives_offset, natives_size); |
| - } |
| + if (snapshot_pf == -1) |
| + return false; |
| base::MemoryMappedFile::Region snapshot_region = |
| base::MemoryMappedFile::Region::kWholeFile; |
| - if (natives_size != 0 || natives_offset != 0) { |
| + if (snapshot_size != 0 || snapshot_offset != 0) { |
| snapshot_region = |
| base::MemoryMappedFile::Region(snapshot_offset, snapshot_size); |
| } |
| - return MapV8Files(base::File(natives_pf), base::File(snapshot_pf), |
| - natives_region, snapshot_region); |
| + return MapV8File(&g_mapped_snapshot, base::File(snapshot_pf), |
| + snapshot_region); |
| +} |
| + |
| +bool V8Initializer::LoadV8NativesFromFD(base::PlatformFile natives_pf, |
| + int64 natives_offset, |
| + int64 natives_size) { |
| + if (g_mapped_natives) |
| + return true; |
| + |
| + if (natives_pf == -1) |
| + return false; |
| + |
| + base::MemoryMappedFile::Region natives_region = |
| + base::MemoryMappedFile::Region::kWholeFile; |
| + if (natives_size != 0 || natives_offset != 0) { |
| + natives_region = |
| + base::MemoryMappedFile::Region(natives_offset, natives_size); |
| + } |
| + |
| + return MapV8File(&g_mapped_natives, base::File(natives_pf), natives_region); |
| } |
| // static |
| @@ -255,13 +280,18 @@ bool V8Initializer::OpenV8FilesForChildProcesses( |
| base::File snapshot_data_file; |
| int file_flags = base::File::FLAG_OPEN | base::File::FLAG_READ; |
| - bool success = OpenV8File(natives_data_path, file_flags, natives_data_file) && |
| - OpenV8File(snapshot_data_path, file_flags, snapshot_data_file); |
| - if (success) { |
| + bool natives_success = |
| + OpenV8File(natives_data_path, file_flags, natives_data_file); |
| + if (natives_success) { |
| *natives_fd_out = natives_data_file.TakePlatformFile(); |
| + } |
| + bool snapshot_success = |
| + OpenV8File(snapshot_data_path, file_flags, snapshot_data_file); |
| + if (snapshot_success) { |
| *snapshot_fd_out = snapshot_data_file.TakePlatformFile(); |
| } |
| - return success; |
| + // We can start up without the snapshot file, but not without the natives. |
| + return natives_success; |
| } |
| #endif // V8_USE_EXTERNAL_STARTUP_DATA |
| @@ -285,10 +315,12 @@ void V8Initializer::Initialize(gin::IsolateHolder::ScriptMode mode) { |
| natives.raw_size = static_cast<int>(g_mapped_natives->length()); |
| v8::V8::SetNativesDataBlob(&natives); |
| - v8::StartupData snapshot; |
| - snapshot.data = reinterpret_cast<const char*>(g_mapped_snapshot->data()); |
| - snapshot.raw_size = static_cast<int>(g_mapped_snapshot->length()); |
| - v8::V8::SetSnapshotDataBlob(&snapshot); |
| + if (g_mapped_snapshot != NULL) { |
| + v8::StartupData snapshot; |
| + snapshot.data = reinterpret_cast<const char*>(g_mapped_snapshot->data()); |
| + snapshot.raw_size = static_cast<int>(g_mapped_snapshot->length()); |
| + v8::V8::SetSnapshotDataBlob(&snapshot); |
| + } |
| #endif // V8_USE_EXTERNAL_STARTUP_DATA |
| v8::V8::SetEntropySource(&GenerateEntropy); |
| @@ -302,15 +334,21 @@ void V8Initializer::GetV8ExternalSnapshotData(const char** natives_data_out, |
| int* natives_size_out, |
| const char** snapshot_data_out, |
| int* snapshot_size_out) { |
| - if (!g_mapped_natives || !g_mapped_snapshot) { |
| - *natives_data_out = *snapshot_data_out = NULL; |
| - *natives_size_out = *snapshot_size_out = 0; |
| - return; |
| + if (!g_mapped_natives) { |
| + *natives_data_out = NULL; |
| + *natives_size_out = 0; |
| + } else { |
| + *natives_data_out = reinterpret_cast<const char*>(g_mapped_natives->data()); |
| + *natives_size_out = static_cast<int>(g_mapped_natives->length()); |
| + } |
| + if (!g_mapped_snapshot) { |
| + *snapshot_data_out = NULL; |
| + *snapshot_size_out = 0; |
| + } else { |
| + *snapshot_data_out = |
| + reinterpret_cast<const char*>(g_mapped_snapshot->data()); |
| + *snapshot_size_out = static_cast<int>(g_mapped_snapshot->length()); |
| } |
| - *natives_data_out = reinterpret_cast<const char*>(g_mapped_natives->data()); |
| - *snapshot_data_out = reinterpret_cast<const char*>(g_mapped_snapshot->data()); |
| - *natives_size_out = static_cast<int>(g_mapped_natives->length()); |
| - *snapshot_size_out = static_cast<int>(g_mapped_snapshot->length()); |
| } |
| } // namespace gin |