summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ash/shell/content_client/shell_content_browser_client.cc50
-rw-r--r--ash/shell/content_client/shell_content_browser_client.h16
-rw-r--r--base/i18n/icu_util.cc186
-rw-r--r--base/i18n/icu_util.h13
-rw-r--r--chrome/browser/chrome_content_browser_client.cc58
-rw-r--r--chrome/browser/chrome_content_browser_client.h9
-rw-r--r--chromecast/browser/cast_content_browser_client.cc47
-rw-r--r--chromecast/browser/cast_content_browser_client.h7
-rw-r--r--content/browser/BUILD.gn1
-rw-r--r--content/browser/DEPS1
-rw-r--r--content/browser/child_process_launcher.cc47
-rw-r--r--content/content_browser.gypi1
-rw-r--r--content/public/browser/content_browser_client.h6
-rw-r--r--content/shell/browser/shell_content_browser_client.cc41
-rw-r--r--content/shell/browser/shell_content_browser_client.h9
-rw-r--r--extensions/shell/browser/shell_content_browser_client.cc47
-rw-r--r--extensions/shell/browser/shell_content_browser_client.h16
-rw-r--r--gin/v8_initializer.cc127
-rw-r--r--gin/v8_initializer.h18
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(
+ &regions[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(&regions[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
};