| Index: gin/v8_initializer.cc
|
| diff --git a/gin/v8_initializer.cc b/gin/v8_initializer.cc
|
| index 0568fe77db9300785c3830a0461028d93e89b47c..2ba5106de2c61949702f516e9cbc09f7c07546b3 100644
|
| --- a/gin/v8_initializer.cc
|
| +++ b/gin/v8_initializer.cc
|
| @@ -27,10 +27,27 @@ namespace gin {
|
|
|
| namespace {
|
|
|
| +// None of these globals are ever freed nor closed.
|
| base::MemoryMappedFile* g_mapped_natives = nullptr;
|
| base::MemoryMappedFile* g_mapped_snapshot = nullptr;
|
|
|
| #if defined(V8_USE_EXTERNAL_STARTUP_DATA)
|
| +
|
| +const base::PlatformFile kInvalidPlatformFile =
|
| +#if defined(OS_WIN)
|
| + INVALID_HANDLE_VALUE;
|
| +#else
|
| + -1;
|
| +#endif
|
| +
|
| +// File handles intentionally never closed. Not using File here because its
|
| +// Windows implementation guards against two instances owning the same
|
| +// PlatformFile (which we allow since we know it is never freed).
|
| +base::PlatformFile g_natives_pf = kInvalidPlatformFile;
|
| +base::PlatformFile g_snapshot_pf = kInvalidPlatformFile;
|
| +base::MemoryMappedFile::Region g_natives_region;
|
| +base::MemoryMappedFile::Region g_snapshot_region;
|
| +
|
| #if !defined(OS_MACOSX)
|
| const int kV8SnapshotBasePathKey =
|
| #if defined(OS_ANDROID)
|
| @@ -65,13 +82,13 @@ void GetV8FilePath(const char* file_name, base::FilePath* path_out) {
|
| DCHECK(!path_out->empty());
|
| }
|
|
|
| -static bool MapV8File(base::File file,
|
| +static bool MapV8File(base::PlatformFile platform_file,
|
| base::MemoryMappedFile::Region region,
|
| base::MemoryMappedFile** mmapped_file_out) {
|
| DCHECK(*mmapped_file_out == NULL);
|
| base::MemoryMappedFile* mmapped_file = *mmapped_file_out =
|
| new base::MemoryMappedFile;
|
| - if (!mmapped_file->Initialize(file.Pass(), region)) {
|
| + if (!mmapped_file->Initialize(base::File(platform_file), region)) {
|
| delete mmapped_file;
|
| *mmapped_file_out = NULL;
|
| return false;
|
| @@ -80,9 +97,8 @@ static bool MapV8File(base::File file,
|
| return true;
|
| }
|
|
|
| -static bool OpenV8File(const base::FilePath& path,
|
| - int flags,
|
| - base::File& file) {
|
| +base::PlatformFile OpenV8File(const char* file_name,
|
| + base::MemoryMappedFile::Region* region_out) {
|
| // Re-try logic here is motivated by http://crbug.com/479537
|
| // for A/V on Windows (https://support.microsoft.com/en-us/kb/316609).
|
|
|
| @@ -95,10 +111,16 @@ static bool OpenV8File(const base::FilePath& path,
|
| MAX_VALUE
|
| };
|
|
|
| + base::FilePath path;
|
| + GetV8FilePath(file_name, &path);
|
| +
|
| OpenV8FileResult result = OpenV8FileResult::FAILED_IN_USE;
|
| + int flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
|
| + base::File file;
|
| for (int attempt = 0; attempt < kMaxOpenAttempts; attempt++) {
|
| file.Initialize(path, flags);
|
| if (file.IsValid()) {
|
| + *region_out = base::MemoryMappedFile::Region::kWholeFile;
|
| if (attempt == 0) {
|
| result = OpenV8FileResult::OPENED;
|
| break;
|
| @@ -118,9 +140,19 @@ static bool OpenV8File(const base::FilePath& path,
|
| UMA_HISTOGRAM_ENUMERATION("V8.Initializer.OpenV8File.Result",
|
| result,
|
| OpenV8FileResult::MAX_VALUE);
|
| + return file.TakePlatformFile();
|
| +}
|
|
|
| - return result == OpenV8FileResult::OPENED
|
| - || result == OpenV8FileResult::OPENED_RETRY;
|
| +void OpenNativesFileIfNecessary() {
|
| + if (g_natives_pf == kInvalidPlatformFile) {
|
| + g_natives_pf = OpenV8File(kNativesFileName, &g_natives_region);
|
| + }
|
| +}
|
| +
|
| +void OpenSnapshotFileIfNecessary() {
|
| + if (g_snapshot_pf == kInvalidPlatformFile) {
|
| + g_snapshot_pf = OpenV8File(kSnapshotFileName, &g_snapshot_region);
|
| + }
|
| }
|
|
|
| #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
|
| @@ -163,22 +195,15 @@ enum LoadV8FileResult {
|
| V8_LOAD_MAX_VALUE
|
| };
|
|
|
| -static LoadV8FileResult OpenMapVerify(
|
| - const char* file_name,
|
| +static LoadV8FileResult MapVerify(base::PlatformFile platform_file,
|
| + const base::MemoryMappedFile::Region& region,
|
| #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
|
| - const unsigned char* fingerprint,
|
| + const unsigned char* fingerprint,
|
| #endif
|
| - base::MemoryMappedFile** mmapped_file_out) {
|
| - base::FilePath path;
|
| - GetV8FilePath(file_name, &path);
|
| -
|
| - base::File file;
|
| - int flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
|
| -
|
| - if (!OpenV8File(path, flags, file))
|
| + base::MemoryMappedFile** mmapped_file_out) {
|
| + if (platform_file == kInvalidPlatformFile)
|
| return V8_LOAD_FAILED_OPEN;
|
| - if (!MapV8File(file.Pass(), base::MemoryMappedFile::Region::kWholeFile,
|
| - mmapped_file_out))
|
| + if (!MapV8File(platform_file, region, mmapped_file_out))
|
| return V8_LOAD_FAILED_MAP;
|
| #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
|
| if (!VerifyV8StartupFile(mmapped_file_out, fingerprint))
|
| @@ -192,11 +217,14 @@ void V8Initializer::LoadV8Snapshot() {
|
| if (g_mapped_snapshot)
|
| return;
|
|
|
| - LoadV8FileResult result = OpenMapVerify(kSnapshotFileName,
|
| + OpenSnapshotFileIfNecessary();
|
| + LoadV8FileResult result = MapVerify(g_snapshot_pf, g_snapshot_region,
|
| #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
|
| - g_snapshot_fingerprint,
|
| + g_snapshot_fingerprint,
|
| #endif
|
| - &g_mapped_snapshot);
|
| + &g_mapped_snapshot);
|
| + // V8 can't start up without the source of the natives, but it can
|
| + // start up (slower) without the snapshot.
|
| UMA_HISTOGRAM_ENUMERATION("V8.Initializer.LoadV8Snapshot.Result", result,
|
| V8_LOAD_MAX_VALUE);
|
| }
|
| @@ -205,11 +233,12 @@ void V8Initializer::LoadV8Natives() {
|
| if (g_mapped_natives)
|
| return;
|
|
|
| - LoadV8FileResult result = OpenMapVerify(kNativesFileName,
|
| + OpenNativesFileIfNecessary();
|
| + LoadV8FileResult result = MapVerify(g_natives_pf, g_natives_region,
|
| #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
|
| - g_natives_fingerprint,
|
| + g_natives_fingerprint,
|
| #endif
|
| - &g_mapped_natives);
|
| + &g_mapped_natives);
|
| if (result != V8_LOAD_SUCCESS) {
|
| LOG(FATAL) << "Couldn't mmap v8 natives data file, status code is "
|
| << static_cast<int>(result);
|
| @@ -223,7 +252,7 @@ void V8Initializer::LoadV8SnapshotFromFD(base::PlatformFile snapshot_pf,
|
| if (g_mapped_snapshot)
|
| return;
|
|
|
| - if (snapshot_pf == reinterpret_cast<base::PlatformFile>(-1))
|
| + if (snapshot_pf == kInvalidPlatformFile)
|
| return;
|
|
|
| base::MemoryMappedFile::Region snapshot_region =
|
| @@ -234,7 +263,7 @@ void V8Initializer::LoadV8SnapshotFromFD(base::PlatformFile snapshot_pf,
|
| }
|
|
|
| LoadV8FileResult result = V8_LOAD_SUCCESS;
|
| - if (!MapV8File(base::File(snapshot_pf), snapshot_region, &g_mapped_snapshot))
|
| + if (!MapV8File(snapshot_pf, snapshot_region, &g_mapped_snapshot))
|
| result = V8_LOAD_FAILED_MAP;
|
| #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
|
| if (!VerifyV8StartupFile(&g_mapped_snapshot, g_snapshot_fingerprint))
|
| @@ -251,7 +280,7 @@ void V8Initializer::LoadV8NativesFromFD(base::PlatformFile natives_pf,
|
| if (g_mapped_natives)
|
| return;
|
|
|
| - CHECK_NE(natives_pf, reinterpret_cast<base::PlatformFile>(-1));
|
| + CHECK_NE(natives_pf, kInvalidPlatformFile);
|
|
|
| base::MemoryMappedFile::Region natives_region =
|
| base::MemoryMappedFile::Region::kWholeFile;
|
| @@ -260,7 +289,7 @@ void V8Initializer::LoadV8NativesFromFD(base::PlatformFile natives_pf,
|
| base::MemoryMappedFile::Region(natives_offset, natives_size);
|
| }
|
|
|
| - if (!MapV8File(base::File(natives_pf), natives_region, &g_mapped_natives)) {
|
| + if (!MapV8File(natives_pf, natives_region, &g_mapped_natives)) {
|
| LOG(FATAL) << "Couldn't mmap v8 natives data file";
|
| }
|
| #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
|
| @@ -271,33 +300,21 @@ void V8Initializer::LoadV8NativesFromFD(base::PlatformFile natives_pf,
|
| }
|
|
|
| // static
|
| -bool V8Initializer::OpenV8FilesForChildProcesses(
|
| - base::PlatformFile* natives_fd_out,
|
| - base::PlatformFile* snapshot_fd_out) {
|
| - base::FilePath natives_data_path;
|
| - base::FilePath snapshot_data_path;
|
| - GetV8FilePath(kNativesFileName, &natives_data_path);
|
| - GetV8FilePath(kSnapshotFileName, &snapshot_data_path);
|
| -
|
| - base::File natives_data_file;
|
| - base::File snapshot_data_file;
|
| - int file_flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
|
| -
|
| - 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();
|
| - }
|
| - // We can start up without the snapshot file, but not without the natives.
|
| - return natives_success;
|
| +base::PlatformFile V8Initializer::GetOpenNativesFileForChildProcesses(
|
| + base::MemoryMappedFile::Region* region_out) {
|
| + OpenNativesFileIfNecessary();
|
| + *region_out = g_natives_region;
|
| + return g_natives_pf;
|
| }
|
|
|
| -#endif // V8_USE_EXTERNAL_STARTUP_DATA
|
| +// static
|
| +base::PlatformFile V8Initializer::GetOpenSnapshotFileForChildProcesses(
|
| + base::MemoryMappedFile::Region* region_out) {
|
| + OpenSnapshotFileIfNecessary();
|
| + *region_out = g_snapshot_region;
|
| + return g_snapshot_pf;
|
| +}
|
| +#endif // defined(V8_USE_EXTERNAL_STARTUP_DATA)
|
|
|
| // static
|
| void V8Initializer::Initialize(gin::IsolateHolder::ScriptMode mode) {
|
|
|