diff options
19 files changed, 242 insertions, 458 deletions
diff --git a/ash/shell/content_client/shell_content_browser_client.cc b/ash/shell/content_client/shell_content_browser_client.cc index 5f2adc5..d75e759 100644 --- a/ash/shell/content_client/shell_content_browser_client.cc +++ b/ash/shell/content_client/shell_content_browser_client.cc @@ -6,22 +6,14 @@ #include "ash/shell/content_client/shell_browser_main_parts.h" #include "base/command_line.h" -#include "content/public/common/content_descriptors.h" -#include "content/public/common/content_switches.h" #include "content/shell/browser/shell_browser_context.h" -#include "gin/v8_initializer.h" #include "third_party/skia/include/core/SkBitmap.h" namespace ash { namespace shell { ShellContentBrowserClient::ShellContentBrowserClient() - : -#if defined(OS_POSIX) && !defined(OS_MACOSX) - v8_natives_fd_(-1), - v8_snapshot_fd_(-1), -#endif // OS_POSIX && !OS_MACOSX - shell_browser_main_parts_(nullptr) { + : shell_browser_main_parts_(nullptr) { } ShellContentBrowserClient::~ShellContentBrowserClient() { @@ -43,46 +35,6 @@ net::URLRequestContextGetter* ShellContentBrowserClient::CreateRequestContext( request_interceptors.Pass()); } -void ShellContentBrowserClient::AppendMappedFileCommandLineSwitches( - base::CommandLine* command_line) { -#if defined(OS_POSIX) && !defined(OS_MACOSX) -#if defined(V8_USE_EXTERNAL_STARTUP_DATA) - std::string process_type = - command_line->GetSwitchValueASCII(switches::kProcessType); - if (process_type != switches::kZygoteProcess) { - DCHECK(natives_fd_exists()); - command_line->AppendSwitch(::switches::kV8NativesPassedByFD); - if (snapshot_fd_exists()) - command_line->AppendSwitch(::switches::kV8SnapshotPassedByFD); - } -#endif // V8_USE_EXTERNAL_STARTUP_DATA -#endif // OS_POSIX && !OS_MACOSX -} - -#if defined(OS_POSIX) && !defined(OS_MACOSX) -void ShellContentBrowserClient::GetAdditionalMappedFilesForChildProcess( - const base::CommandLine& command_line, - int child_process_id, - content::FileDescriptorInfo* mappings) { -#if defined(V8_USE_EXTERNAL_STARTUP_DATA) - if (!natives_fd_exists()) { - int v8_natives_fd = -1; - int v8_snapshot_fd = -1; - if (gin::V8Initializer::OpenV8FilesForChildProcesses(&v8_natives_fd, - &v8_snapshot_fd)) { - v8_natives_fd_.reset(v8_natives_fd); - v8_snapshot_fd_.reset(v8_snapshot_fd); - } - } - // V8 can't start up without the source of the natives, but it can - // start up (slower) without the snapshot. - DCHECK(natives_fd_exists()); - mappings->Share(kV8NativesDataDescriptor, v8_natives_fd_.get()); - mappings->Share(kV8SnapshotDataDescriptor, v8_snapshot_fd_.get()); -#endif // V8_USE_EXTERNAL_STARTUP_DATA -} -#endif // OS_POSIX && !OS_MACOSX - content::ShellBrowserContext* ShellContentBrowserClient::browser_context() { return shell_browser_main_parts_->browser_context(); } diff --git a/ash/shell/content_client/shell_content_browser_client.h b/ash/shell/content_client/shell_content_browser_client.h index 432f45a..1a5eb44 100644 --- a/ash/shell/content_client/shell_content_browser_client.h +++ b/ash/shell/content_client/shell_content_browser_client.h @@ -33,26 +33,10 @@ class ShellContentBrowserClient : public content::ContentBrowserClient { content::BrowserContext* browser_context, content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors) override; - void AppendMappedFileCommandLineSwitches( - base::CommandLine* command_line) override; -#if defined(OS_POSIX) && !defined(OS_MACOSX) - void GetAdditionalMappedFilesForChildProcess( - const base::CommandLine& command_line, - int child_process_id, - content::FileDescriptorInfo* mappings) override; -#endif content::ShellBrowserContext* browser_context(); private: -#if defined(OS_POSIX) && !defined(OS_MACOSX) - bool natives_fd_exists() { return v8_natives_fd_.is_valid(); } - bool snapshot_fd_exists() { return v8_snapshot_fd_.is_valid(); } - - base::ScopedFD v8_natives_fd_; - base::ScopedFD v8_snapshot_fd_; -#endif - ShellBrowserMainParts* shell_browser_main_parts_; DISALLOW_COPY_AND_ASSIGN(ShellContentBrowserClient); diff --git a/base/i18n/icu_util.cc b/base/i18n/icu_util.cc index a9f0b12..cacc3df 100644 --- a/base/i18n/icu_util.cc +++ b/base/i18n/icu_util.cc @@ -34,11 +34,6 @@ namespace base { namespace i18n { -// Use an unversioned file name to simplify a icu version update down the road. -// No need to change the filename in multiple places (gyp files, windows -// build pkg configurations, etc). 'l' stands for Little Endian. -// This variable is exported through the header file. -const char kIcuDataFileName[] = "icudtl.dat"; #if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_SHARED #define ICU_UTIL_DATA_SYMBOL "icudt" U_ICU_VERSION_SHORT "_dat" #if defined(OS_WIN) @@ -47,44 +42,124 @@ const char kIcuDataFileName[] = "icudtl.dat"; #endif namespace { - +#if !defined(OS_NACL) #if !defined(NDEBUG) // Assert that we are not called more than once. Even though calling this // function isn't harmful (ICU can handle it), being called twice probably // indicates a programming error. -#if !defined(OS_NACL) +bool g_check_called_once = true; bool g_called_once = false; +#endif // !defined(NDEBUG) + +#if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE +// Use an unversioned file name to simplify a icu version update down the road. +// No need to change the filename in multiple places (gyp files, windows +// build pkg configurations, etc). 'l' stands for Little Endian. +// This variable is exported through the header file. +const char kIcuDataFileName[] = "icudtl.dat"; + +// File handle 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). +const PlatformFile kInvalidPlatformFile = +#if defined(OS_WIN) + INVALID_HANDLE_VALUE; +#else + -1; #endif -bool g_check_called_once = true; +PlatformFile g_icudtl_pf = kInvalidPlatformFile; +CR_DEFINE_STATIC_LOCAL(MemoryMappedFile, g_icudtl_mapped_file, ()); +MemoryMappedFile::Region g_icudtl_region; + +void LazyInitIcuDataFile() { + if (g_icudtl_pf != kInvalidPlatformFile) { + return; + } +#if !defined(OS_MACOSX) + FilePath data_path; +#if defined(OS_WIN) + // The data file will be in the same directory as the current module. + bool path_ok = PathService::Get(DIR_MODULE, &data_path); + wchar_t tmp_buffer[_MAX_PATH] = {0}; + wcscpy_s(tmp_buffer, data_path.value().c_str()); + debug::Alias(tmp_buffer); + CHECK(path_ok); // TODO(scottmg): http://crbug.com/445616 +#elif defined(OS_ANDROID) + bool path_ok = PathService::Get(DIR_ANDROID_APP_DATA, &data_path); +#else + // For now, expect the data file to be alongside the executable. + // This is sufficient while we work on unit tests, but will eventually + // likely live in a data directory. + bool path_ok = PathService::Get(DIR_EXE, &data_path); #endif + DCHECK(path_ok); + data_path = data_path.AppendASCII(kIcuDataFileName); + +#if defined(OS_WIN) + // TODO(scottmg): http://crbug.com/445616 + wchar_t tmp_buffer2[_MAX_PATH] = {0}; + wcscpy_s(tmp_buffer2, data_path.value().c_str()); + debug::Alias(tmp_buffer2); +#endif + +#else + // Assume it is in the framework bundle's Resources directory. + ScopedCFTypeRef<CFStringRef> data_file_name( + SysUTF8ToCFStringRef(kIcuDataFileName)); + FilePath data_path = mac::PathForFrameworkBundleResource(data_file_name); + if (data_path.empty()) { + LOG(ERROR) << kIcuDataFileName << " not found in bundle"; + return; + } +#endif // !defined(OS_MACOSX) + File file(data_path, File::FLAG_OPEN | File::FLAG_READ); + if (file.IsValid()) { + g_icudtl_pf = file.TakePlatformFile(); + g_icudtl_region = MemoryMappedFile::Region::kWholeFile; + } } +bool InitializeICUWithFileDescriptorInternal( + PlatformFile data_fd, + const MemoryMappedFile::Region& data_region) { + // This can be called multiple times in tests. + if (g_icudtl_mapped_file.IsValid()) { + return true; + } + if (data_fd < 0) { + return false; + } + if (!g_icudtl_mapped_file.Initialize(File(data_fd), data_region)) { + LOG(ERROR) << "Couldn't mmap icu data file"; + return false; + } + UErrorCode err = U_ZERO_ERROR; + udata_setCommonData(const_cast<uint8*>(g_icudtl_mapped_file.data()), &err); + return err == U_ZERO_ERROR; +} +#endif // ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE +#endif // !defined(OS_NACL) + +} // namespace + #if !defined(OS_NACL) +#if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE bool InitializeICUWithFileDescriptor( PlatformFile data_fd, - MemoryMappedFile::Region data_region) { + const MemoryMappedFile::Region& data_region) { #if !defined(NDEBUG) DCHECK(!g_check_called_once || !g_called_once); g_called_once = true; #endif - -#if (ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_STATIC) - // The ICU data is statically linked. - return true; -#elif (ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE) - CR_DEFINE_STATIC_LOCAL(MemoryMappedFile, mapped_file, ()); - if (!mapped_file.IsValid()) { - if (!mapped_file.Initialize(File(data_fd), data_region)) { - LOG(ERROR) << "Couldn't mmap icu data file"; - return false; - } - } - UErrorCode err = U_ZERO_ERROR; - udata_setCommonData(const_cast<uint8*>(mapped_file.data()), &err); - return err == U_ZERO_ERROR; -#endif // ICU_UTIL_DATA_FILE + return InitializeICUWithFileDescriptorInternal(data_fd, data_region); } +PlatformFile GetIcuDataFileHandle(MemoryMappedFile::Region* out_region) { + CHECK_NE(g_icudtl_pf, kInvalidPlatformFile); + *out_region = g_icudtl_region; + return g_icudtl_pf; +} +#endif // ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE bool InitializeICU() { #if !defined(NDEBUG) @@ -123,60 +198,9 @@ bool InitializeICU() { // it is needed. This can fail if the process is sandboxed at that time. // Instead, we map the file in and hand off the data so the sandbox won't // cause any problems. - - // Chrome doesn't normally shut down ICU, so the mapped data shouldn't ever - // be released. - CR_DEFINE_STATIC_LOCAL(MemoryMappedFile, mapped_file, ()); - if (!mapped_file.IsValid()) { -#if !defined(OS_MACOSX) - FilePath data_path; -#if defined(OS_WIN) - // The data file will be in the same directory as the current module. - bool path_ok = PathService::Get(DIR_MODULE, &data_path); - wchar_t tmp_buffer[_MAX_PATH] = {0}; - wcscpy_s(tmp_buffer, data_path.value().c_str()); - debug::Alias(tmp_buffer); - CHECK(path_ok); // TODO(scottmg): http://crbug.com/445616 -#elif defined(OS_ANDROID) - bool path_ok = PathService::Get(DIR_ANDROID_APP_DATA, &data_path); -#else - // For now, expect the data file to be alongside the executable. - // This is sufficient while we work on unit tests, but will eventually - // likely live in a data directory. - bool path_ok = PathService::Get(DIR_EXE, &data_path); -#endif - DCHECK(path_ok); - data_path = data_path.AppendASCII(kIcuDataFileName); - -#if defined(OS_WIN) - // TODO(scottmg): http://crbug.com/445616 - wchar_t tmp_buffer2[_MAX_PATH] = {0}; - wcscpy_s(tmp_buffer2, data_path.value().c_str()); - debug::Alias(tmp_buffer2); -#endif - -#else - // Assume it is in the framework bundle's Resources directory. - ScopedCFTypeRef<CFStringRef> data_file_name( - SysUTF8ToCFStringRef(kIcuDataFileName)); - FilePath data_path = - mac::PathForFrameworkBundleResource(data_file_name); - if (data_path.empty()) { - LOG(ERROR) << kIcuDataFileName << " not found in bundle"; - return false; - } -#endif // OS check - if (!mapped_file.Initialize(data_path)) { -#if defined(OS_WIN) - CHECK(false); // TODO(scottmg): http://crbug.com/445616 -#endif - LOG(ERROR) << "Couldn't mmap " << data_path.AsUTF8Unsafe(); - return false; - } - } - UErrorCode err = U_ZERO_ERROR; - udata_setCommonData(const_cast<uint8*>(mapped_file.data()), &err); - result = (err == U_ZERO_ERROR); + LazyInitIcuDataFile(); + result = InitializeICUWithFileDescriptorInternal( + g_icudtl_pf, g_icudtl_region); #if defined(OS_WIN) CHECK(result); // TODO(scottmg): http://crbug.com/445616 #endif @@ -193,10 +217,10 @@ bool InitializeICU() { #endif return result; } -#endif +#endif // !defined(OS_NACL) void AllowMultipleInitializeCallsForTesting() { -#if !defined(NDEBUG) +#if !defined(NDEBUG) && !defined(OS_NACL) g_check_called_once = false; #endif } diff --git a/base/i18n/icu_util.h b/base/i18n/icu_util.h index 65de0ad..d62f8bac 100644 --- a/base/i18n/icu_util.h +++ b/base/i18n/icu_util.h @@ -12,19 +12,24 @@ namespace base { namespace i18n { -BASE_I18N_EXPORT extern const char kIcuDataFileName[]; - #if !defined(OS_NACL) // Call this function to load ICU's data tables for the current process. This // function should be called before ICU is used. BASE_I18N_EXPORT bool InitializeICU(); +#if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE +// Returns the PlatformFile and Region that was initialized by InitializeICU(). +// Use with InitializeICUWithFileDescriptor(). +BASE_I18N_EXPORT PlatformFile GetIcuDataFileHandle( + MemoryMappedFile::Region* out_region); + // Android and html_viewer use a file descriptor passed by browser process to // initialize ICU in render processes. BASE_I18N_EXPORT bool InitializeICUWithFileDescriptor( PlatformFile data_fd, - MemoryMappedFile::Region data_region); -#endif + const MemoryMappedFile::Region& data_region); +#endif // ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE +#endif // !defined(OS_NACL) // In a test binary, the call above might occur twice. BASE_I18N_EXPORT void AllowMultipleInitializeCallsForTesting(); diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 6bc3356..70fff7c 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc @@ -12,7 +12,6 @@ #include "base/bind_helpers.h" #include "base/command_line.h" #include "base/files/scoped_file.h" -#include "base/i18n/icu_util.h" #include "base/lazy_instance.h" #include "base/path_service.h" #include "base/prefs/pref_service.h" @@ -125,7 +124,6 @@ #include "content/public/common/url_utils.h" #include "content/public/common/web_preferences.h" #include "device/devices_app/devices_app.h" -#include "gin/v8_initializer.h" #include "net/base/mime_util.h" #include "net/cookies/canonical_cookie.h" #include "net/cookies/cookie_options.h" @@ -610,10 +608,6 @@ namespace chrome { ChromeContentBrowserClient::ChromeContentBrowserClient() : -#if defined(OS_POSIX) && !defined(OS_MACOSX) - v8_natives_fd_(-1), - v8_snapshot_fd_(-1), -#endif // OS_POSIX && !OS_MACOSX weak_factory_(this) { #if defined(ENABLE_PLUGINS) for (size_t i = 0; i < arraysize(kPredefinedAllowedDevChannelOrigins); ++i) @@ -1175,32 +1169,6 @@ bool IsAutoReloadVisibleOnlyEnabled() { } // namespace -// When Chrome is updated on non-Windows platforms, the new files (like -// V8 natives and snapshot) can have the same names as the previous -// versions. Since the renderers for an existing Chrome browser process -// are likely not compatible with the new files, the browser keeps hold -// of the old files using an open fd. This fd is passed to subprocesses -// like renderers. Here we add the flag to tell the subprocesses where -// to find these file descriptors. -void ChromeContentBrowserClient::AppendMappedFileCommandLineSwitches( - base::CommandLine* command_line) { -#if defined(OS_POSIX) && !defined(OS_MACOSX) -#if defined(V8_USE_EXTERNAL_STARTUP_DATA) - std::string process_type = - command_line->GetSwitchValueASCII(switches::kProcessType); - if (process_type != switches::kZygoteProcess) { - // We want to pass the natives by fd because after an update the file may - // be updated, but we want the newly launched renderers to get the old one, - // opened by the browser when it started. - DCHECK(natives_fd_exists()); - command_line->AppendSwitch(::switches::kV8NativesPassedByFD); - if (snapshot_fd_exists()) - command_line->AppendSwitch(::switches::kV8SnapshotPassedByFD); - } -#endif // V8_USE_EXTERNAL_STARTUP_DATA -#endif // OS_POSIX && !OS_MACOSX -} - void ChromeContentBrowserClient::AppendExtraCommandLineSwitches( base::CommandLine* command_line, int child_process_id) { @@ -2246,24 +2214,6 @@ void ChromeContentBrowserClient::GetAdditionalMappedFilesForChildProcess( const base::CommandLine& command_line, int child_process_id, FileDescriptorInfo* mappings) { -#if defined(V8_USE_EXTERNAL_STARTUP_DATA) - if (!natives_fd_exists()) { - int v8_natives_fd = -1; - int v8_snapshot_fd = -1; - if (gin::V8Initializer::OpenV8FilesForChildProcesses(&v8_natives_fd, - &v8_snapshot_fd)) { - v8_natives_fd_.reset(v8_natives_fd); - v8_snapshot_fd_.reset(v8_snapshot_fd); - } - } - // V8 can't start up without the source of the natives, but it can - // start up (slower) without the snapshot. - DCHECK(natives_fd_exists()); - mappings->Share(kV8NativesDataDescriptor, v8_natives_fd_.get()); - if (snapshot_fd_exists()) - mappings->Share(kV8SnapshotDataDescriptor, v8_snapshot_fd_.get()); -#endif // V8_USE_EXTERNAL_STARTUP_DATA - #if defined(OS_ANDROID) base::FilePath data_path; PathService::Get(ui::DIR_RESOURCE_PAKS_ANDROID, &data_path); @@ -2307,14 +2257,6 @@ void ChromeContentBrowserClient::GetAdditionalMappedFilesForChildProcess( base::FilePath app_data_path; PathService::Get(base::DIR_ANDROID_APP_DATA, &app_data_path); DCHECK(!app_data_path.empty()); - - flags = base::File::FLAG_OPEN | base::File::FLAG_READ; - base::FilePath icudata_path = - app_data_path.AppendASCII(base::i18n::kIcuDataFileName); - base::File icudata_file(icudata_path, flags); - DCHECK(icudata_file.IsValid()); - mappings->Transfer(kAndroidICUDataDescriptor, - base::ScopedFD(icudata_file.TakePlatformFile())); #else int crash_signal_fd = GetCrashSignalFD(command_line); if (crash_signal_fd >= 0) { diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 9edd155..d618af52 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h @@ -112,8 +112,6 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient { const std::string& alias_name) override; void AppendExtraCommandLineSwitches(base::CommandLine* command_line, int child_process_id) override; - void AppendMappedFileCommandLineSwitches( - base::CommandLine* command_line) override; std::string GetApplicationLocale() override; std::string GetAcceptLangs(content::BrowserContext* context) override; const gfx::ImageSkia* GetDefaultFavicon() override; @@ -307,13 +305,6 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient { std::set<std::string> allowed_dev_channel_origins_; #endif -#if defined(OS_POSIX) && !defined(OS_MACOSX) - base::ScopedFD v8_natives_fd_; - base::ScopedFD v8_snapshot_fd_; - bool natives_fd_exists() { return v8_natives_fd_ != -1; } - bool snapshot_fd_exists() { return v8_snapshot_fd_ != -1; } -#endif // OS_POSIX && !OS_MACOSX - // Vector of additional ChromeContentBrowserClientParts. // Parts are deleted in the reverse order they are added. std::vector<ChromeContentBrowserClientParts*> extra_parts_; diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc index de1abe0..f141c2a 100644 --- a/chromecast/browser/cast_content_browser_client.cc +++ b/chromecast/browser/cast_content_browser_client.cc @@ -9,7 +9,6 @@ #include "base/base_switches.h" #include "base/command_line.h" #include "base/files/scoped_file.h" -#include "base/i18n/icu_util.h" #include "base/i18n/rtl.h" #include "base/path_service.h" #include "chromecast/base/cast_paths.h" @@ -39,7 +38,6 @@ #include "content/public/common/content_switches.h" #include "content/public/common/url_constants.h" #include "content/public/common/web_preferences.h" -#include "gin/v8_initializer.h" #include "media/audio/audio_manager_factory.h" #include "net/ssl/ssl_cert_request_info.h" #include "net/url_request/url_request_context_getter.h" @@ -54,9 +52,7 @@ namespace chromecast { namespace shell { CastContentBrowserClient::CastContentBrowserClient() - : v8_natives_fd_(-1), - v8_snapshot_fd_(-1), - url_request_context_factory_(new URLRequestContextFactory()) { + : url_request_context_factory_(new URLRequestContextFactory()) { } CastContentBrowserClient::~CastContentBrowserClient() { @@ -178,21 +174,6 @@ bool CastContentBrowserClient::IsHandledURL(const GURL& url) { return false; } -void CastContentBrowserClient::AppendMappedFileCommandLineSwitches( - base::CommandLine* command_line) { - std::string process_type = - command_line->GetSwitchValueNative(switches::kProcessType); - -#if defined(V8_USE_EXTERNAL_STARTUP_DATA) - if (process_type != switches::kZygoteProcess) { - DCHECK(natives_fd_exists()); - command_line->AppendSwitch(::switches::kV8NativesPassedByFD); - if (snapshot_fd_exists()) - command_line->AppendSwitch(::switches::kV8SnapshotPassedByFD); - } -} - -#endif // V8_USE_EXTERNAL_STARTUP_DATA void CastContentBrowserClient::AppendExtraCommandLineSwitches( base::CommandLine* command_line, int child_process_id) { @@ -355,22 +336,6 @@ void CastContentBrowserClient::GetAdditionalMappedFilesForChildProcess( const base::CommandLine& command_line, int child_process_id, content::FileDescriptorInfo* mappings) { -#if defined(V8_USE_EXTERNAL_STARTUP_DATA) - if (!natives_fd_exists()) { - int v8_natives_fd = -1; - int v8_snapshot_fd = -1; - if (gin::V8Initializer::OpenV8FilesForChildProcesses(&v8_natives_fd, - &v8_snapshot_fd)) { - v8_natives_fd_.reset(v8_natives_fd); - v8_snapshot_fd_.reset(v8_snapshot_fd); - } - } - // V8 can't start up without the source of the natives, but it can - // start up (slower) without the snapshot. - DCHECK(natives_fd_exists()); - mappings->Share(kV8NativesDataDescriptor, v8_natives_fd_.get()); - mappings->Share(kV8SnapshotDataDescriptor, v8_snapshot_fd_.get()); -#endif // V8_USE_EXTERNAL_STARTUP_DATA #if defined(OS_ANDROID) const int flags_open_read = base::File::FLAG_OPEN | base::File::FLAG_READ; base::FilePath pak_file_path; @@ -395,16 +360,6 @@ void CastContentBrowserClient::GetAdditionalMappedFilesForChildProcess( base::ScopedFD(minidump_file.TakePlatformFile())); } } - - base::FilePath app_data_path; - CHECK(PathService::Get(base::DIR_ANDROID_APP_DATA, &app_data_path)); - base::FilePath icudata_path = - app_data_path.AppendASCII(base::i18n::kIcuDataFileName); - base::File icudata_file(icudata_path, flags_open_read); - if (!icudata_file.IsValid()) - NOTREACHED() << "Failed to open ICU file when creating renderer process"; - mappings->Transfer(kAndroidICUDataDescriptor, - base::ScopedFD(icudata_file.TakePlatformFile())); #else int crash_signal_fd = GetCrashSignalFD(command_line); if (crash_signal_fd >= 0) { diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h index 092d0a7..942a4c0 100644 --- a/chromecast/browser/cast_content_browser_client.h +++ b/chromecast/browser/cast_content_browser_client.h @@ -78,8 +78,6 @@ class CastContentBrowserClient: public content::ContentBrowserClient { bool IsHandledURL(const GURL& url) override; void AppendExtraCommandLineSwitches(base::CommandLine* command_line, int child_process_id) override; - void AppendMappedFileCommandLineSwitches( - base::CommandLine* command_line) override; content::AccessTokenStore* CreateAccessTokenStore() override; void OverrideWebkitPrefs(content::RenderViewHost* render_view_host, content::WebPreferences* prefs) override; @@ -151,11 +149,6 @@ class CastContentBrowserClient: public content::ContentBrowserClient { std::map<std::string, breakpad::CrashHandlerHostLinux*> crash_handlers_; #endif - base::ScopedFD v8_natives_fd_; - base::ScopedFD v8_snapshot_fd_; - bool natives_fd_exists() { return v8_natives_fd_ != -1; } - bool snapshot_fd_exists() { return v8_snapshot_fd_ != -1; } - scoped_ptr<URLRequestContextFactory> url_request_context_factory_; DISALLOW_COPY_AND_ASSIGN(CastContentBrowserClient); diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 3cdfc88..74638ee 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn @@ -114,6 +114,7 @@ source_set("browser") { "//content/common:mojo_bindings", "//content/public/common:mojo_bindings", "//device/bluetooth", + "//gin", "//mojo/application/public/interfaces", "//storage/browser", "//storage/common", diff --git a/content/browser/DEPS b/content/browser/DEPS index 2ed7e5c..f6b6865 100644 --- a/content/browser/DEPS +++ b/content/browser/DEPS @@ -9,6 +9,7 @@ include_rules = [ "+content/public/browser", "+device/battery", # For battery status service. "+device/vibration", # For Vibration API + "+gin/v8_initializer.h", "+media/audio", # For audio input for speech input feature. "+media/base", # For Android JNI registration. "+media/filters", # For reporting GPU decoding UMA. diff --git a/content/browser/child_process_launcher.cc b/content/browser/child_process_launcher.cc index 48c5e94..4f8e190 100644 --- a/content/browser/child_process_launcher.cc +++ b/content/browser/child_process_launcher.cc @@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/files/file_util.h" +#include "base/i18n/icu_util.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/metrics/histogram.h" @@ -43,6 +44,7 @@ #if defined(OS_POSIX) #include "base/posix/global_descriptors.h" #include "content/browser/file_descriptor_info_impl.h" +#include "gin/v8_initializer.h" #endif namespace content { @@ -141,15 +143,45 @@ void LaunchOnLauncherThread(const NotifyCallback& callback, #endif #endif -#if defined(OS_ANDROID) - // Android WebView runs in single process, ensure that we never get here - // when running in single process mode. - CHECK(!cmd_line->HasSwitch(switches::kSingleProcess)); +#if defined(OS_POSIX) && !defined(OS_MACOSX) std::map<int, base::MemoryMappedFile::Region> regions; GetContentClient()->browser()->GetAdditionalMappedFilesForChildProcess( *cmd_line, child_process_id, files_to_register.get()); +#if defined(V8_USE_EXTERNAL_STARTUP_DATA) + base::PlatformFile natives_pf = + gin::V8Initializer::GetOpenNativesFileForChildProcesses( + ®ions[kV8NativesDataDescriptor]); + DCHECK_GE(natives_pf, 0); + files_to_register->Share(kV8NativesDataDescriptor, natives_pf); + + base::MemoryMappedFile::Region snapshot_region; + base::PlatformFile snapshot_pf = + gin::V8Initializer::GetOpenSnapshotFileForChildProcesses( + &snapshot_region); + // Failure to load the V8 snapshot is not necessarily an error. V8 can start + // up (slower) without the snapshot. + if (snapshot_pf != -1) { + files_to_register->Share(kV8SnapshotDataDescriptor, snapshot_pf); + regions.insert(std::make_pair(kV8SnapshotDataDescriptor, snapshot_region)); + } - GetContentClient()->browser()->AppendMappedFileCommandLineSwitches(cmd_line); + if (process_type != switches::kZygoteProcess) { + cmd_line->AppendSwitch(::switches::kV8NativesPassedByFD); + if (snapshot_pf != -1) { + cmd_line->AppendSwitch(::switches::kV8SnapshotPassedByFD); + } + } +#endif // defined(V8_USE_EXTERNAL_STARTUP_DATA) +#endif // defined(OS_POSIX) && !defined(OS_MACOSX) + +#if defined(OS_ANDROID) + files_to_register->Share( + kAndroidICUDataDescriptor, + base::i18n::GetIcuDataFileHandle(®ions[kAndroidICUDataDescriptor])); + + // Android WebView runs in single process, ensure that we never get here + // when running in single process mode. + CHECK(!cmd_line->HasSwitch(switches::kSingleProcess)); StartChildProcess( cmd_line->argv(), child_process_id, files_to_register.Pass(), regions, @@ -161,11 +193,6 @@ void LaunchOnLauncherThread(const NotifyCallback& callback, // child termination. #if !defined(OS_MACOSX) - GetContentClient()->browser()->GetAdditionalMappedFilesForChildProcess( - *cmd_line, child_process_id, files_to_register.get()); - - GetContentClient()->browser()->AppendMappedFileCommandLineSwitches(cmd_line); - if (use_zygote) { base::ProcessHandle handle = ZygoteHostImpl::GetInstance()->ForkRequest( cmd_line->argv(), files_to_register.Pass(), process_type); diff --git a/content/content_browser.gypi b/content/content_browser.gypi index bcf4a1b..bd9dd98 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -1795,6 +1795,7 @@ '../components/mime_util/mime_util.gyp:mime_util', '../components/scheduler/scheduler.gyp:scheduler_common', '../device/bluetooth/bluetooth.gyp:device_bluetooth', + '../gin/gin.gyp:gin', '../net/net.gyp:http_server', '../storage/storage_browser.gyp:storage', '../storage/storage_common.gyp:storage_common', diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 0a97ef2..acd568b 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h @@ -274,12 +274,6 @@ class CONTENT_EXPORT ContentBrowserClient { virtual void AppendExtraCommandLineSwitches(base::CommandLine* command_line, int child_process_id) {} - // This is called on the process launching thread, when files that should be - // passed to the client have been opened. It allows command line switches to - // be added to tell the client where to find its files. - virtual void AppendMappedFileCommandLineSwitches( - base::CommandLine* command_line) {} - // Returns the locale used by the application. // This is called on the UI and IO threads. virtual std::string GetApplicationLocale(); diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc index a73cfdb..a48c008 100644 --- a/content/shell/browser/shell_content_browser_client.cc +++ b/content/shell/browser/shell_content_browser_client.cc @@ -34,7 +34,6 @@ #include "content/shell/common/shell_messages.h" #include "content/shell/common/shell_switches.h" #include "content/shell/renderer/layout_test/blink_test_helpers.h" -#include "gin/v8_initializer.h" #include "net/url_request/url_request_context_getter.h" #include "url/gurl.h" @@ -129,12 +128,7 @@ void ShellContentBrowserClient::SetSwapProcessesForRedirect(bool swap) { } ShellContentBrowserClient::ShellContentBrowserClient() - : -#if defined(OS_POSIX) && !defined(OS_MACOSX) - v8_natives_fd_(-1), - v8_snapshot_fd_(-1), -#endif // OS_POSIX && !OS_MACOSX - shell_browser_main_parts_(NULL) { + : shell_browser_main_parts_(NULL) { DCHECK(!g_browser_client); g_browser_client = this; } @@ -206,22 +200,6 @@ bool ShellContentBrowserClient::IsHandledURL(const GURL& url) { return false; } -void ShellContentBrowserClient::AppendMappedFileCommandLineSwitches( - base::CommandLine* command_line) { -#if defined(OS_POSIX) && !defined(OS_MACOSX) -#if defined(V8_USE_EXTERNAL_STARTUP_DATA) - std::string process_type = - command_line->GetSwitchValueASCII(switches::kProcessType); - if (process_type != switches::kZygoteProcess) { - DCHECK(natives_fd_exists()); - command_line->AppendSwitch(::switches::kV8NativesPassedByFD); - if (snapshot_fd_exists()) - command_line->AppendSwitch(::switches::kV8SnapshotPassedByFD); - } -#endif // V8_USE_EXTERNAL_STARTUP_DATA -#endif // OS_POSIX && !OS_MACOSX -} - void ShellContentBrowserClient::AppendExtraCommandLineSwitches( base::CommandLine* command_line, int child_process_id) { @@ -357,23 +335,6 @@ void ShellContentBrowserClient::GetAdditionalMappedFilesForChildProcess( const base::CommandLine& command_line, int child_process_id, FileDescriptorInfo* mappings) { -#if defined(V8_USE_EXTERNAL_STARTUP_DATA) - if (!natives_fd_exists()) { - int v8_natives_fd = -1; - int v8_snapshot_fd = -1; - if (gin::V8Initializer::OpenV8FilesForChildProcesses(&v8_natives_fd, - &v8_snapshot_fd)) { - v8_natives_fd_.reset(v8_natives_fd); - v8_snapshot_fd_.reset(v8_snapshot_fd); - } - } - // V8 can't start up without the source of the natives, but it can - // start up (slower) without the snapshot. - DCHECK(natives_fd_exists()); - mappings->Share(kV8NativesDataDescriptor, v8_natives_fd_.get()); - mappings->Share(kV8SnapshotDataDescriptor, v8_snapshot_fd_.get()); -#endif // V8_USE_EXTERNAL_STARTUP_DATA - #if defined(OS_ANDROID) int flags = base::File::FLAG_OPEN | base::File::FLAG_READ; base::FilePath pak_file; diff --git a/content/shell/browser/shell_content_browser_client.h b/content/shell/browser/shell_content_browser_client.h index fe843a6..0568691 100644 --- a/content/shell/browser/shell_content_browser_client.h +++ b/content/shell/browser/shell_content_browser_client.h @@ -46,8 +46,6 @@ class ShellContentBrowserClient : public ContentBrowserClient { bool IsHandledURL(const GURL& url) override; void AppendExtraCommandLineSwitches(base::CommandLine* command_line, int child_process_id) override; - void AppendMappedFileCommandLineSwitches( - base::CommandLine* command_line) override; void OverrideWebkitPrefs(RenderViewHost* render_view_host, WebPreferences* prefs) override; void ResourceDispatcherHostCreated() override; @@ -105,13 +103,6 @@ class ShellContentBrowserClient : public ContentBrowserClient { scoped_ptr<ShellResourceDispatcherHostDelegate> resource_dispatcher_host_delegate_; -#if defined(OS_POSIX) && !defined(OS_MACOSX) - base::ScopedFD v8_natives_fd_; - base::ScopedFD v8_snapshot_fd_; - bool natives_fd_exists() { return v8_natives_fd_ != -1; } - bool snapshot_fd_exists() { return v8_snapshot_fd_ != -1; } -#endif - base::Closure select_client_certificate_callback_; ShellBrowserMainParts* shell_browser_main_parts_; diff --git a/extensions/shell/browser/shell_content_browser_client.cc b/extensions/shell/browser/shell_content_browser_client.cc index 957b830..c9314ad 100644 --- a/extensions/shell/browser/shell_content_browser_client.cc +++ b/extensions/shell/browser/shell_content_browser_client.cc @@ -28,7 +28,6 @@ #include "extensions/shell/browser/shell_browser_main_parts.h" #include "extensions/shell/browser/shell_extension_system.h" #include "extensions/shell/browser/shell_speech_recognition_manager_delegate.h" -#include "gin/v8_initializer.h" #include "url/gurl.h" #if !defined(DISABLE_NACL) @@ -54,12 +53,7 @@ ShellContentBrowserClient* g_instance = nullptr; ShellContentBrowserClient::ShellContentBrowserClient( ShellBrowserMainDelegate* browser_main_delegate) - : -#if defined(OS_POSIX) && !defined(OS_MACOSX) - v8_natives_fd_(-1), - v8_snapshot_fd_(-1), -#endif // OS_POSIX && !OS_MACOSX - browser_main_parts_(nullptr), + : browser_main_parts_(nullptr), browser_main_delegate_(browser_main_delegate) { DCHECK(!g_instance); g_instance = this; @@ -200,21 +194,6 @@ void ShellContentBrowserClient::SiteInstanceDeleting( site_instance->GetId())); } -void ShellContentBrowserClient::AppendMappedFileCommandLineSwitches( - base::CommandLine* command_line) { - std::string process_type = - command_line->GetSwitchValueASCII(::switches::kProcessType); - -#if defined(OS_POSIX) && !defined(OS_MACOSX) -#if defined(V8_USE_EXTERNAL_STARTUP_DATA) - DCHECK(natives_fd_exists()); - command_line->AppendSwitch(::switches::kV8NativesPassedByFD); - if (snapshot_fd_exists()) - command_line->AppendSwitch(::switches::kV8SnapshotPassedByFD); -#endif // V8_USE_EXTERNAL_STARTUP_DATA -#endif // OS_POSIX && !OS_MACOSX -} - void ShellContentBrowserClient::AppendExtraCommandLineSwitches( base::CommandLine* command_line, int child_process_id) { @@ -254,30 +233,6 @@ void ShellContentBrowserClient::GetAdditionalAllowedSchemesForFileSystem( additional_allowed_schemes->push_back(kExtensionScheme); } -#if defined(OS_POSIX) && !defined(OS_MACOSX) -void ShellContentBrowserClient::GetAdditionalMappedFilesForChildProcess( - const base::CommandLine& command_line, - int child_process_id, - content::FileDescriptorInfo* mappings) { -#if defined(V8_USE_EXTERNAL_STARTUP_DATA) - if (!natives_fd_exists()) { - int v8_natives_fd = -1; - int v8_snapshot_fd = -1; - if (gin::V8Initializer::OpenV8FilesForChildProcesses(&v8_natives_fd, - &v8_snapshot_fd)) { - v8_natives_fd_.reset(v8_natives_fd); - v8_snapshot_fd_.reset(v8_snapshot_fd); - } - } - // V8 can't start up without the source of the natives, but it can - // start up (slower) without the snapshot. - DCHECK(natives_fd_exists()); - mappings->Share(kV8NativesDataDescriptor, v8_natives_fd_.get()); - mappings->Share(kV8SnapshotDataDescriptor, v8_snapshot_fd_.get()); -#endif // V8_USE_EXTERNAL_STARTUP_DATA -} -#endif // OS_POSIX && !OS_MACOSX - content::DevToolsManagerDelegate* ShellContentBrowserClient::GetDevToolsManagerDelegate() { return new content::ShellDevToolsManagerDelegate(GetBrowserContext()); diff --git a/extensions/shell/browser/shell_content_browser_client.h b/extensions/shell/browser/shell_content_browser_client.h index d282397..16e51ca 100644 --- a/extensions/shell/browser/shell_content_browser_client.h +++ b/extensions/shell/browser/shell_content_browser_client.h @@ -52,21 +52,12 @@ class ShellContentBrowserClient : public content::ContentBrowserClient { void SiteInstanceDeleting(content::SiteInstance* site_instance) override; void AppendExtraCommandLineSwitches(base::CommandLine* command_line, int child_process_id) override; - void AppendMappedFileCommandLineSwitches( - base::CommandLine* command_line) override; content::SpeechRecognitionManagerDelegate* CreateSpeechRecognitionManagerDelegate() override; content::BrowserPpapiHost* GetExternalBrowserPpapiHost( int plugin_process_id) override; void GetAdditionalAllowedSchemesForFileSystem( std::vector<std::string>* additional_schemes) override; -#if defined(OS_POSIX) && !defined(OS_MACOSX) - void GetAdditionalMappedFilesForChildProcess( - const base::CommandLine& command_line, - int child_process_id, - content::FileDescriptorInfo* mappings) override; -#endif - content::DevToolsManagerDelegate* GetDevToolsManagerDelegate() override; protected: @@ -82,13 +73,6 @@ class ShellContentBrowserClient : public content::ContentBrowserClient { // Returns the extension or app associated with |site_instance| or NULL. const Extension* GetExtension(content::SiteInstance* site_instance); -#if defined(OS_POSIX) && !defined(OS_MACOSX) - base::ScopedFD v8_natives_fd_; - base::ScopedFD v8_snapshot_fd_; - bool natives_fd_exists() { return v8_natives_fd_ != -1; } - bool snapshot_fd_exists() { return v8_snapshot_fd_ != -1; } -#endif - // Owned by content::BrowserMainLoop. ShellBrowserMainParts* browser_main_parts_; diff --git a/gin/v8_initializer.cc b/gin/v8_initializer.cc index 0568fe7..2ba5106 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) { diff --git a/gin/v8_initializer.h b/gin/v8_initializer.h index 1e05fd0..e181436 100644 --- a/gin/v8_initializer.h +++ b/gin/v8_initializer.h @@ -6,6 +6,7 @@ #define GIN_V8_INITIALIZER_H_ #include "base/files/file.h" +#include "base/files/memory_mapped_file.h" #include "gin/array_buffer.h" #include "gin/gin_export.h" #include "gin/public/isolate_holder.h" @@ -50,12 +51,17 @@ class GIN_EXPORT V8Initializer { // so that it will not return if natives cannot be loaded. static void LoadV8Natives(); - // Opens the V8 snapshot data files and returns open file descriptors to these - // files in |natives_fd_out| and |snapshot_fd_out|, which can be passed to - // child processes. - static bool OpenV8FilesForChildProcesses(base::PlatformFile* natives_fd_out, - base::PlatformFile* snapshot_fd_out) - WARN_UNUSED_RESULT; + // Opens (unless already cached) and returns the V8 natives file. + // Use with LoadV8NativesFromFD(). + // Asserts if the file does not exist. + static base::PlatformFile GetOpenNativesFileForChildProcesses( + base::MemoryMappedFile::Region* region_out); + + // Opens (unless already cached) and returns the V8 snapshot file. + // Use with LoadV8SnapshotFromFD(). + // Will return -1 if the file does not exist. + static base::PlatformFile GetOpenSnapshotFileForChildProcesses( + base::MemoryMappedFile::Region* region_out); #endif // V8_USE_EXTERNAL_STARTUP_DATA }; |