summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorerikcorry <erikcorry@chromium.org>2015-06-08 04:29:16 -0700
committerCommit bot <commit-bot@chromium.org>2015-06-08 11:30:00 +0000
commitc94eff1e7e8b2bd5973d7211c320d9f025c980c1 (patch)
treeb74c21bb58fadc70af46c76fb43d214c494c3766
parent878d687f2f9ff7d9f6424309d216ee2459886b68 (diff)
downloadchromium_src-c94eff1e7e8b2bd5973d7211c320d9f025c980c1.zip
chromium_src-c94eff1e7e8b2bd5973d7211c320d9f025c980c1.tar.gz
chromium_src-c94eff1e7e8b2bd5973d7211c320d9f025c980c1.tar.bz2
Allow startup with missing V8 snapshot file.
We want to stop shipping the snapshot file, and instead we want to generate it on the client. This will reduce the download size. But since snapshot generation will be asynchronous in a utility process, it might not be present on the first few runs of the browser. This means we have to be able to start up without the snapshot file (just with the natives source file). This CL fixes Blink to cope with a missing snapshot file (V8 could already cope). R=rmcilroy@chromium.org, sky@chromium.org BUG= Review URL: https://codereview.chromium.org/1164483003 Cr-Commit-Position: refs/heads/master@{#333258}
-rw-r--r--ash/shell/content_client/shell_content_browser_client.cc15
-rw-r--r--ash/shell/content_client/shell_content_browser_client.h7
-rw-r--r--chrome/browser/chrome_content_browser_client.cc44
-rw-r--r--chrome/browser/chrome_content_browser_client.h4
-rw-r--r--chrome/plugin/chrome_content_plugin_client.cc1
-rw-r--r--chromecast/browser/cast_content_browser_client.cc27
-rw-r--r--chromecast/browser/cast_content_browser_client.h4
-rw-r--r--components/html_viewer/ax_provider_impl_unittest.cc1
-rw-r--r--components/html_viewer/setup.cc9
-rw-r--r--content/app/content_main_runner.cc20
-rw-r--r--content/browser/child_process_launcher.cc5
-rw-r--r--content/public/browser/content_browser_client.h6
-rw-r--r--content/public/test/content_test_suite_base.cc1
-rw-r--r--content/shell/browser/shell_content_browser_client.cc20
-rw-r--r--content/shell/browser/shell_content_browser_client.h4
-rw-r--r--content/test/content_test_launcher.cc1
-rw-r--r--content/test/test_blink_web_unit_test_support.cc1
-rw-r--r--extensions/shell/browser/shell_content_browser_client.cc23
-rw-r--r--extensions/shell/browser/shell_content_browser_client.h4
-rw-r--r--gin/public/isolate_holder.h5
-rw-r--r--gin/shell/gin_main.cc1
-rw-r--r--gin/shell_runner_unittest.cc1
-rw-r--r--gin/test/file_runner.cc1
-rw-r--r--gin/test/v8_test.cc1
-rw-r--r--gin/v8_initializer.cc255
-rw-r--r--gin/v8_initializer.h28
-rw-r--r--media/blink/run_all_unittests.cc1
-rw-r--r--net/proxy/proxy_resolver_v8.cc1
28 files changed, 318 insertions, 173 deletions
diff --git a/ash/shell/content_client/shell_content_browser_client.cc b/ash/shell/content_client/shell_content_browser_client.cc
index 51b0107..5f2adc5 100644
--- a/ash/shell/content_client/shell_content_browser_client.cc
+++ b/ash/shell/content_client/shell_content_browser_client.cc
@@ -43,16 +43,17 @@ net::URLRequestContextGetter* ShellContentBrowserClient::CreateRequestContext(
request_interceptors.Pass());
}
-void ShellContentBrowserClient::AppendExtraCommandLineSwitches(
- base::CommandLine* command_line,
- int child_process_id) {
+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);
- command_line->AppendSwitch(::switches::kV8SnapshotPassedByFD);
+ if (snapshot_fd_exists())
+ command_line->AppendSwitch(::switches::kV8SnapshotPassedByFD);
}
#endif // V8_USE_EXTERNAL_STARTUP_DATA
#endif // OS_POSIX && !OS_MACOSX
@@ -64,7 +65,7 @@ void ShellContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
int child_process_id,
content::FileDescriptorInfo* mappings) {
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
- if (v8_natives_fd_.get() == -1 || v8_snapshot_fd_.get() == -1) {
+ if (!natives_fd_exists()) {
int v8_natives_fd = -1;
int v8_snapshot_fd = -1;
if (gin::V8Initializer::OpenV8FilesForChildProcesses(&v8_natives_fd,
@@ -73,7 +74,9 @@ void ShellContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
v8_snapshot_fd_.reset(v8_snapshot_fd);
}
}
- DCHECK(v8_natives_fd_.get() != -1 && v8_snapshot_fd_.get() != -1);
+ // 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
diff --git a/ash/shell/content_client/shell_content_browser_client.h b/ash/shell/content_client/shell_content_browser_client.h
index 9ee3373..432f45a 100644
--- a/ash/shell/content_client/shell_content_browser_client.h
+++ b/ash/shell/content_client/shell_content_browser_client.h
@@ -33,8 +33,8 @@ class ShellContentBrowserClient : public content::ContentBrowserClient {
content::BrowserContext* browser_context,
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors) override;
- void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
- int child_process_id) override;
+ void AppendMappedFileCommandLineSwitches(
+ base::CommandLine* command_line) override;
#if defined(OS_POSIX) && !defined(OS_MACOSX)
void GetAdditionalMappedFilesForChildProcess(
const base::CommandLine& command_line,
@@ -46,6 +46,9 @@ class ShellContentBrowserClient : public content::ContentBrowserClient {
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
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index a4004ca..78664bf 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -1172,6 +1172,32 @@ 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) {
@@ -1230,15 +1256,6 @@ void ChromeContentBrowserClient::AppendExtraCommandLineSwitches(
homedir.value().c_str());
#endif
-#if defined(OS_POSIX) && !defined(OS_MACOSX)
-#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
- if (process_type != switches::kZygoteProcess) {
- command_line->AppendSwitch(::switches::kV8NativesPassedByFD);
- command_line->AppendSwitch(::switches::kV8SnapshotPassedByFD);
- }
-#endif // V8_USE_EXTERNAL_STARTUP_DATA
-#endif // OS_POSIX && !OS_MACOSX
-
if (process_type == switches::kRendererProcess) {
content::RenderProcessHost* process =
content::RenderProcessHost::FromID(child_process_id);
@@ -2225,7 +2242,7 @@ void ChromeContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
int child_process_id,
FileDescriptorInfo* mappings) {
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
- if (v8_natives_fd_.get() == -1 || v8_snapshot_fd_.get() == -1) {
+ if (!natives_fd_exists()) {
int v8_natives_fd = -1;
int v8_snapshot_fd = -1;
if (gin::V8Initializer::OpenV8FilesForChildProcesses(&v8_natives_fd,
@@ -2234,9 +2251,12 @@ void ChromeContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
v8_snapshot_fd_.reset(v8_snapshot_fd);
}
}
- DCHECK(v8_natives_fd_.get() != -1 && v8_snapshot_fd_.get() != -1);
+ // 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());
+ if (snapshot_fd_exists())
+ mappings->Share(kV8SnapshotDataDescriptor, v8_snapshot_fd_.get());
#endif // V8_USE_EXTERNAL_STARTUP_DATA
#if defined(OS_ANDROID)
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index 9ddc184..b998246 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -112,6 +112,8 @@ 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;
@@ -306,6 +308,8 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient {
#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.
diff --git a/chrome/plugin/chrome_content_plugin_client.cc b/chrome/plugin/chrome_content_plugin_client.cc
index 3cfce28..d54e0c4 100644
--- a/chrome/plugin/chrome_content_plugin_client.cc
+++ b/chrome/plugin/chrome_content_plugin_client.cc
@@ -26,6 +26,7 @@ namespace chrome {
void ChromeContentPluginClient::PreSandboxInitialization() {
#ifdef V8_USE_EXTERNAL_STARTUP_DATA
gin::V8Initializer::LoadV8Snapshot();
+ gin::V8Initializer::LoadV8Natives();
#endif
#if defined(ENABLE_REMOTING)
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc
index 3ee657b..9e265ae 100644
--- a/chromecast/browser/cast_content_browser_client.cc
+++ b/chromecast/browser/cast_content_browser_client.cc
@@ -151,21 +151,28 @@ bool CastContentBrowserClient::IsHandledURL(const GURL& url) {
return false;
}
-void CastContentBrowserClient::AppendExtraCommandLineSwitches(
- base::CommandLine* command_line,
- int child_process_id) {
-
+void CastContentBrowserClient::AppendMappedFileCommandLineSwitches(
+ base::CommandLine* command_line) {
std::string process_type =
command_line->GetSwitchValueNative(switches::kProcessType);
- base::CommandLine* browser_command_line =
- base::CommandLine::ForCurrentProcess();
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
if (process_type != switches::kZygoteProcess) {
+ DCHECK(natives_fd_exists());
command_line->AppendSwitch(::switches::kV8NativesPassedByFD);
- command_line->AppendSwitch(::switches::kV8SnapshotPassedByFD);
+ 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) {
+ std::string process_type =
+ command_line->GetSwitchValueNative(switches::kProcessType);
+ base::CommandLine* browser_command_line =
+ base::CommandLine::ForCurrentProcess();
// IsCrashReporterEnabled() is set when InitCrashReporter() is called, and
// controlled by GetBreakpadClient()->EnableBreakpadForProcess(), therefore
@@ -321,7 +328,7 @@ void CastContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
int child_process_id,
content::FileDescriptorInfo* mappings) {
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
- if (v8_natives_fd_.get() == -1 || v8_snapshot_fd_.get() == -1) {
+ if (!natives_fd_exists()) {
int v8_natives_fd = -1;
int v8_snapshot_fd = -1;
if (gin::V8Initializer::OpenV8FilesForChildProcesses(&v8_natives_fd,
@@ -330,7 +337,9 @@ void CastContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
v8_snapshot_fd_.reset(v8_snapshot_fd);
}
}
- DCHECK(v8_natives_fd_.get() != -1 && v8_snapshot_fd_.get() != -1);
+ // 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
diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h
index e1bbe683..fa71076 100644
--- a/chromecast/browser/cast_content_browser_client.h
+++ b/chromecast/browser/cast_content_browser_client.h
@@ -75,6 +75,8 @@ 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;
@@ -149,6 +151,8 @@ class CastContentBrowserClient: public content::ContentBrowserClient {
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_;
diff --git a/components/html_viewer/ax_provider_impl_unittest.cc b/components/html_viewer/ax_provider_impl_unittest.cc
index bfbd9a7..7f9736a 100644
--- a/components/html_viewer/ax_provider_impl_unittest.cc
+++ b/components/html_viewer/ax_provider_impl_unittest.cc
@@ -51,6 +51,7 @@ class AxProviderImplTest : public testing::Test {
renderer_scheduler_(scheduler::RendererScheduler::Create()) {
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
gin::V8Initializer::LoadV8Snapshot();
+ gin::V8Initializer::LoadV8Natives();
#endif
blink::initialize(
new html_viewer::BlinkPlatformImpl(nullptr, renderer_scheduler_.get()));
diff --git a/components/html_viewer/setup.cc b/components/html_viewer/setup.cc
index cdbf7323..76a6614 100644
--- a/components/html_viewer/setup.cc
+++ b/components/html_viewer/setup.cc
@@ -114,11 +114,12 @@ void Setup::InitIfNecessary(const gfx::Size& screen_size_in_pixels,
renderer_scheduler_ = scheduler::RendererScheduler::Create();
blink_platform_.reset(new BlinkPlatformImpl(app_, renderer_scheduler_.get()));
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
- CHECK(gin::V8Initializer::LoadV8SnapshotFromFD(
- resource_loader_.ReleaseFile(kResourceNativesBlob).TakePlatformFile(), 0u,
- 0u,
+ gin::V8Initializer::LoadV8SnapshotFromFD(
resource_loader_.ReleaseFile(kResourceSnapshotBlob).TakePlatformFile(),
- 0u, 0u));
+ 0u, 0u);
+ gin::V8Initializer::LoadV8NativesFromFD(
+ resource_loader_.ReleaseFile(kResourceNativesBlob).TakePlatformFile(), 0u,
+ 0u);
#endif
blink::initialize(blink_platform_.get());
base::i18n::InitializeICUWithFileDescriptor(
diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc
index e4f8812..1a39863 100644
--- a/content/app/content_main_runner.cc
+++ b/content/app/content_main_runner.cc
@@ -741,17 +741,23 @@ class ContentMainRunnerImpl : public ContentMainRunner {
#endif // !OS_ANDROID
int v8_natives_fd = g_fds->MaybeGet(kV8NativesDataDescriptor);
int v8_snapshot_fd = g_fds->MaybeGet(kV8SnapshotDataDescriptor);
- if (v8_natives_fd != -1 && v8_snapshot_fd != -1) {
- auto v8_natives_region = g_fds->GetRegion(kV8NativesDataDescriptor);
+ if (v8_snapshot_fd != -1) {
auto v8_snapshot_region = g_fds->GetRegion(kV8SnapshotDataDescriptor);
- CHECK(gin::V8Initializer::LoadV8SnapshotFromFD(
- v8_natives_fd, v8_natives_region.offset, v8_natives_region.size,
- v8_snapshot_fd, v8_snapshot_region.offset, v8_snapshot_region.size));
+ gin::V8Initializer::LoadV8SnapshotFromFD(
+ v8_snapshot_fd, v8_snapshot_region.offset, v8_snapshot_region.size);
+ } else {
+ gin::V8Initializer::LoadV8Snapshot();
+ }
+ if (v8_natives_fd != -1) {
+ auto v8_natives_region = g_fds->GetRegion(kV8NativesDataDescriptor);
+ gin::V8Initializer::LoadV8NativesFromFD(
+ v8_natives_fd, v8_natives_region.offset, v8_natives_region.size);
} else {
- CHECK(gin::V8Initializer::LoadV8Snapshot());
+ gin::V8Initializer::LoadV8Natives();
}
#else
- CHECK(gin::V8Initializer::LoadV8Snapshot());
+ gin::V8Initializer::LoadV8Snapshot();
+ gin::V8Initializer::LoadV8Natives();
#endif // OS_POSIX && !OS_MACOSX
#endif // V8_USE_EXTERNAL_STARTUP_DATA
diff --git a/content/browser/child_process_launcher.cc b/content/browser/child_process_launcher.cc
index 0c461f4..48c5e94 100644
--- a/content/browser/child_process_launcher.cc
+++ b/content/browser/child_process_launcher.cc
@@ -149,6 +149,8 @@ void LaunchOnLauncherThread(const NotifyCallback& callback,
GetContentClient()->browser()->GetAdditionalMappedFilesForChildProcess(
*cmd_line, child_process_id, files_to_register.get());
+ GetContentClient()->browser()->AppendMappedFileCommandLineSwitches(cmd_line);
+
StartChildProcess(
cmd_line->argv(), child_process_id, files_to_register.Pass(), regions,
base::Bind(&OnChildProcessStartedAndroid, callback, client_thread_id,
@@ -161,6 +163,9 @@ void LaunchOnLauncherThread(const NotifyCallback& callback,
#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/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 579b9f8..3b050ff 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -274,6 +274,12 @@ 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/public/test/content_test_suite_base.cc b/content/public/test/content_test_suite_base.cc
index 7598b0d..6ced225 100644
--- a/content/public/test/content_test_suite_base.cc
+++ b/content/public/test/content_test_suite_base.cc
@@ -74,6 +74,7 @@ void ContentTestSuiteBase::Initialize() {
#if !defined(OS_IOS) && defined(V8_USE_EXTERNAL_STARTUP_DATA)
gin::V8Initializer::LoadV8Snapshot();
+ gin::V8Initializer::LoadV8Natives();
#endif
#if defined(OS_ANDROID)
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc
index 4a2e95c..ab722f4 100644
--- a/content/shell/browser/shell_content_browser_client.cc
+++ b/content/shell/browser/shell_content_browser_client.cc
@@ -206,19 +206,25 @@ bool ShellContentBrowserClient::IsHandledURL(const GURL& url) {
return false;
}
-void ShellContentBrowserClient::AppendExtraCommandLineSwitches(
- base::CommandLine* command_line,
- int child_process_id) {
+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);
- command_line->AppendSwitch(::switches::kV8SnapshotPassedByFD);
+ 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) {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kRunLayoutTest))
command_line->AppendSwitch(switches::kRunLayoutTest);
@@ -343,7 +349,7 @@ void ShellContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
int child_process_id,
FileDescriptorInfo* mappings) {
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
- if (v8_natives_fd_.get() == -1 || v8_snapshot_fd_.get() == -1) {
+ if (!natives_fd_exists()) {
int v8_natives_fd = -1;
int v8_snapshot_fd = -1;
if (gin::V8Initializer::OpenV8FilesForChildProcesses(&v8_natives_fd,
@@ -352,7 +358,9 @@ void ShellContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
v8_snapshot_fd_.reset(v8_snapshot_fd);
}
}
- DCHECK(v8_natives_fd_.get() != -1 && v8_snapshot_fd_.get() != -1);
+ // 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
diff --git a/content/shell/browser/shell_content_browser_client.h b/content/shell/browser/shell_content_browser_client.h
index 0dc59b2..fe843a6 100644
--- a/content/shell/browser/shell_content_browser_client.h
+++ b/content/shell/browser/shell_content_browser_client.h
@@ -46,6 +46,8 @@ 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;
@@ -106,6 +108,8 @@ class ShellContentBrowserClient : public ContentBrowserClient {
#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_;
diff --git a/content/test/content_test_launcher.cc b/content/test/content_test_launcher.cc
index 9b30fdb..46e6392 100644
--- a/content/test/content_test_launcher.cc
+++ b/content/test/content_test_launcher.cc
@@ -58,6 +58,7 @@ class ContentBrowserTestSuite : public ContentTestSuiteBase {
#ifdef V8_USE_EXTERNAL_STARTUP_DATA
gin::V8Initializer::LoadV8Snapshot();
+ gin::V8Initializer::LoadV8Natives();
#endif
// This needs to be done before base::TestSuite::Initialize() is called,
diff --git a/content/test/test_blink_web_unit_test_support.cc b/content/test/test_blink_web_unit_test_support.cc
index 599975c..0739137 100644
--- a/content/test/test_blink_web_unit_test_support.cc
+++ b/content/test/test_blink_web_unit_test_support.cc
@@ -92,6 +92,7 @@ TestBlinkWebUnitTestSupport::TestBlinkWebUnitTestSupport() {
#ifdef V8_USE_EXTERNAL_STARTUP_DATA
gin::V8Initializer::LoadV8Snapshot();
+ gin::V8Initializer::LoadV8Natives();
#endif
scoped_refptr<base::SingleThreadTaskRunner> dummy_task_runner;
diff --git a/extensions/shell/browser/shell_content_browser_client.cc b/extensions/shell/browser/shell_content_browser_client.cc
index 19f0547b..957b830 100644
--- a/extensions/shell/browser/shell_content_browser_client.cc
+++ b/extensions/shell/browser/shell_content_browser_client.cc
@@ -200,21 +200,26 @@ void ShellContentBrowserClient::SiteInstanceDeleting(
site_instance->GetId()));
}
-void ShellContentBrowserClient::AppendExtraCommandLineSwitches(
- base::CommandLine* command_line,
- int child_process_id) {
+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)
- if (process_type != ::switches::kZygoteProcess) {
- command_line->AppendSwitch(::switches::kV8NativesPassedByFD);
+ 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) {
+ std::string process_type =
+ command_line->GetSwitchValueASCII(::switches::kProcessType);
if (process_type == ::switches::kRendererProcess)
AppendRendererSwitches(command_line);
}
@@ -255,7 +260,7 @@ void ShellContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
int child_process_id,
content::FileDescriptorInfo* mappings) {
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
- if (v8_natives_fd_.get() == -1 || v8_snapshot_fd_.get() == -1) {
+ if (!natives_fd_exists()) {
int v8_natives_fd = -1;
int v8_snapshot_fd = -1;
if (gin::V8Initializer::OpenV8FilesForChildProcesses(&v8_natives_fd,
@@ -264,7 +269,9 @@ void ShellContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
v8_snapshot_fd_.reset(v8_snapshot_fd);
}
}
- DCHECK(v8_natives_fd_.get() != -1 && v8_snapshot_fd_.get() != -1);
+ // 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
diff --git a/extensions/shell/browser/shell_content_browser_client.h b/extensions/shell/browser/shell_content_browser_client.h
index f9d813f..d282397 100644
--- a/extensions/shell/browser/shell_content_browser_client.h
+++ b/extensions/shell/browser/shell_content_browser_client.h
@@ -52,6 +52,8 @@ 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(
@@ -83,6 +85,8 @@ class ShellContentBrowserClient : public content::ContentBrowserClient {
#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.
diff --git a/gin/public/isolate_holder.h b/gin/public/isolate_holder.h
index bf0db6c..1647293 100644
--- a/gin/public/isolate_holder.h
+++ b/gin/public/isolate_holder.h
@@ -40,7 +40,10 @@ class GIN_EXPORT IsolateHolder {
// Should be invoked once before creating IsolateHolder instances to
// initialize V8 and Gin. In case V8_USE_EXTERNAL_STARTUP_DATA is
- // defined, V8's initial snapshot should be loaded (by calling
+ // defined, V8's initial natives should be loaded (by calling
+ // V8Initializer::LoadV8NativesFromFD or
+ // V8Initializer::LoadV8Natives) before calling this method. If the
+ // snapshot file is available, it should also be loaded (by calling
// V8Initializer::LoadV8SnapshotFromFD or
// V8Initializer::LoadV8Snapshot) before calling this method.
static void Initialize(ScriptMode mode,
diff --git a/gin/shell/gin_main.cc b/gin/shell/gin_main.cc
index ceb4d64..0b461ee 100644
--- a/gin/shell/gin_main.cc
+++ b/gin/shell/gin_main.cc
@@ -62,6 +62,7 @@ int main(int argc, char** argv) {
base::i18n::InitializeICU();
#ifdef V8_USE_EXTERNAL_STARTUP_DATA
gin::V8Initializer::LoadV8Snapshot();
+ gin::V8Initializer::LoadV8Natives();
#endif
base::MessageLoop message_loop;
diff --git a/gin/shell_runner_unittest.cc b/gin/shell_runner_unittest.cc
index 4e4b9c2f..4c8b0f6 100644
--- a/gin/shell_runner_unittest.cc
+++ b/gin/shell_runner_unittest.cc
@@ -29,6 +29,7 @@ TEST(RunnerTest, Run) {
#ifdef V8_USE_EXTERNAL_STARTUP_DATA
gin::V8Initializer::LoadV8Snapshot();
+ gin::V8Initializer::LoadV8Natives();
#endif
gin::IsolateHolder::Initialize(gin::IsolateHolder::kStrictMode,
diff --git a/gin/test/file_runner.cc b/gin/test/file_runner.cc
index 8ed0f21..4e84b88 100644
--- a/gin/test/file_runner.cc
+++ b/gin/test/file_runner.cc
@@ -61,6 +61,7 @@ void RunTestFromFile(const base::FilePath& path, FileRunnerDelegate* delegate,
#ifdef V8_USE_EXTERNAL_STARTUP_DATA
gin::V8Initializer::LoadV8Snapshot();
+ gin::V8Initializer::LoadV8Natives();
#endif
gin::IsolateHolder::Initialize(gin::IsolateHolder::kStrictMode,
diff --git a/gin/test/v8_test.cc b/gin/test/v8_test.cc
index aad291d..cec4fc8 100644
--- a/gin/test/v8_test.cc
+++ b/gin/test/v8_test.cc
@@ -23,6 +23,7 @@ V8Test::~V8Test() {
void V8Test::SetUp() {
#ifdef V8_USE_EXTERNAL_STARTUP_DATA
gin::V8Initializer::LoadV8Snapshot();
+ gin::V8Initializer::LoadV8Natives();
#endif
gin::IsolateHolder::Initialize(gin::IsolateHolder::kStrictMode,
gin::ArrayBufferAllocator::SharedInstance());
diff --git a/gin/v8_initializer.cc b/gin/v8_initializer.cc
index 8f79d0d..0568fe7 100644
--- a/gin/v8_initializer.cc
+++ b/gin/v8_initializer.cc
@@ -50,53 +50,31 @@ const char kSnapshotFileName[] = "snapshot_blob.bin";
const int kMaxOpenAttempts = 5;
const int kOpenRetryDelayMillis = 250;
-void GetV8FilePaths(base::FilePath* natives_path_out,
- base::FilePath* snapshot_path_out) {
+void GetV8FilePath(const char* file_name, base::FilePath* path_out) {
#if !defined(OS_MACOSX)
base::FilePath data_path;
PathService::Get(kV8SnapshotBasePathKey, &data_path);
DCHECK(!data_path.empty());
- *natives_path_out = data_path.AppendASCII(kNativesFileName);
- *snapshot_path_out = data_path.AppendASCII(kSnapshotFileName);
+ *path_out = data_path.AppendASCII(file_name);
#else // !defined(OS_MACOSX)
base::ScopedCFTypeRef<CFStringRef> natives_file_name(
- base::SysUTF8ToCFStringRef(kNativesFileName));
- *natives_path_out =
- base::mac::PathForFrameworkBundleResource(natives_file_name);
- base::ScopedCFTypeRef<CFStringRef> snapshot_file_name(
- base::SysUTF8ToCFStringRef(kSnapshotFileName));
- *snapshot_path_out =
- base::mac::PathForFrameworkBundleResource(snapshot_file_name);
- DCHECK(!natives_path_out->empty());
- DCHECK(!snapshot_path_out->empty());
+ base::SysUTF8ToCFStringRef(file_name));
+ *path_out = base::mac::PathForFrameworkBundleResource(natives_file_name);
#endif // !defined(OS_MACOSX)
+ DCHECK(!path_out->empty());
}
-static bool MapV8Files(base::File natives_file,
- base::File snapshot_file,
- base::MemoryMappedFile::Region natives_region =
- base::MemoryMappedFile::Region::kWholeFile,
- base::MemoryMappedFile::Region snapshot_region =
- base::MemoryMappedFile::Region::kWholeFile) {
- g_mapped_natives = new base::MemoryMappedFile;
- if (!g_mapped_natives->IsValid()) {
- if (!g_mapped_natives->Initialize(natives_file.Pass(), natives_region)) {
- delete g_mapped_natives;
- g_mapped_natives = NULL;
- LOG(FATAL) << "Couldn't mmap v8 natives data file";
- return false;
- }
- }
-
- g_mapped_snapshot = new base::MemoryMappedFile;
- if (!g_mapped_snapshot->IsValid()) {
- if (!g_mapped_snapshot->Initialize(snapshot_file.Pass(), snapshot_region)) {
- delete g_mapped_snapshot;
- g_mapped_snapshot = NULL;
- LOG(ERROR) << "Couldn't mmap v8 snapshot data file";
- return false;
- }
+static bool MapV8File(base::File 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)) {
+ delete mmapped_file;
+ *mmapped_file_out = NULL;
+ return false;
}
return true;
@@ -146,14 +124,19 @@ static bool OpenV8File(const base::FilePath& path,
}
#if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
-bool VerifyV8SnapshotFile(base::MemoryMappedFile* snapshot_file,
- const unsigned char* fingerprint) {
+bool VerifyV8StartupFile(base::MemoryMappedFile** file,
+ const unsigned char* fingerprint) {
unsigned char output[crypto::kSHA256Length];
crypto::SHA256HashString(
- base::StringPiece(reinterpret_cast<const char*>(snapshot_file->data()),
- snapshot_file->length()),
+ base::StringPiece(reinterpret_cast<const char*>((*file)->data()),
+ (*file)->length()),
output, sizeof(output));
- return !memcmp(fingerprint, output, sizeof(output));
+ if (!memcmp(fingerprint, output, sizeof(output))) {
+ return true;
+ }
+ delete *file;
+ *file = NULL;
+ return false;
}
#endif // V8_VERIFY_EXTERNAL_STARTUP_DATA
#endif // V8_USE_EXTERNAL_STARTUP_DATA
@@ -172,58 +155,103 @@ extern const unsigned char g_natives_fingerprint[];
extern const unsigned char g_snapshot_fingerprint[];
#endif // V8_VERIFY_EXTERNAL_STARTUP_DATA
-// static
-bool V8Initializer::LoadV8Snapshot() {
-
- enum LoadV8SnapshotResult {
- SUCCESS = 0,
- FAILED_OPEN,
- FAILED_MAP,
- FAILED_VERIFY,
- MAX_VALUE
- };
-
- if (g_mapped_natives && g_mapped_snapshot)
- return true;
+enum LoadV8FileResult {
+ V8_LOAD_SUCCESS = 0,
+ V8_LOAD_FAILED_OPEN,
+ V8_LOAD_FAILED_MAP,
+ V8_LOAD_FAILED_VERIFY,
+ V8_LOAD_MAX_VALUE
+};
- base::FilePath natives_data_path;
- base::FilePath snapshot_data_path;
- GetV8FilePaths(&natives_data_path, &snapshot_data_path);
+static LoadV8FileResult OpenMapVerify(
+ const char* file_name,
+#if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
+ const unsigned char* fingerprint,
+#endif
+ base::MemoryMappedFile** mmapped_file_out) {
+ base::FilePath path;
+ GetV8FilePath(file_name, &path);
- base::File natives_file;
- base::File snapshot_file;
+ base::File file;
int flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
- LoadV8SnapshotResult result;
- if (!OpenV8File(natives_data_path, flags, natives_file) ||
- !OpenV8File(snapshot_data_path, flags, snapshot_file)) {
- result = LoadV8SnapshotResult::FAILED_OPEN;
- } else if (!MapV8Files(natives_file.Pass(), snapshot_file.Pass())) {
- result = LoadV8SnapshotResult::FAILED_MAP;
+ if (!OpenV8File(path, flags, file))
+ return V8_LOAD_FAILED_OPEN;
+ if (!MapV8File(file.Pass(), base::MemoryMappedFile::Region::kWholeFile,
+ mmapped_file_out))
+ return V8_LOAD_FAILED_MAP;
#if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
- } else if (!VerifyV8SnapshotFile(g_mapped_natives, g_natives_fingerprint) ||
- !VerifyV8SnapshotFile(g_mapped_snapshot, g_snapshot_fingerprint)) {
- result = LoadV8SnapshotResult::FAILED_VERIFY;
+ if (!VerifyV8StartupFile(mmapped_file_out, fingerprint))
+ return V8_LOAD_FAILED_VERIFY;
#endif // V8_VERIFY_EXTERNAL_STARTUP_DATA
- } else {
- result = LoadV8SnapshotResult::SUCCESS;
- }
+ return V8_LOAD_SUCCESS;
+}
- UMA_HISTOGRAM_ENUMERATION("V8.Initializer.LoadV8Snapshot.Result",
- result,
- LoadV8SnapshotResult::MAX_VALUE);
- return result == LoadV8SnapshotResult::SUCCESS;
+// static
+void V8Initializer::LoadV8Snapshot() {
+ if (g_mapped_snapshot)
+ return;
+
+ LoadV8FileResult result = OpenMapVerify(kSnapshotFileName,
+#if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
+ g_snapshot_fingerprint,
+#endif
+ &g_mapped_snapshot);
+ UMA_HISTOGRAM_ENUMERATION("V8.Initializer.LoadV8Snapshot.Result", result,
+ V8_LOAD_MAX_VALUE);
+}
+
+void V8Initializer::LoadV8Natives() {
+ if (g_mapped_natives)
+ return;
+
+ LoadV8FileResult result = OpenMapVerify(kNativesFileName,
+#if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
+ g_natives_fingerprint,
+#endif
+ &g_mapped_natives);
+ if (result != V8_LOAD_SUCCESS) {
+ LOG(FATAL) << "Couldn't mmap v8 natives data file, status code is "
+ << static_cast<int>(result);
+ }
}
// static
-bool V8Initializer::LoadV8SnapshotFromFD(base::PlatformFile natives_pf,
- int64 natives_offset,
- int64 natives_size,
- base::PlatformFile snapshot_pf,
+void V8Initializer::LoadV8SnapshotFromFD(base::PlatformFile snapshot_pf,
int64 snapshot_offset,
int64 snapshot_size) {
- if (g_mapped_natives && g_mapped_snapshot)
- return true;
+ if (g_mapped_snapshot)
+ return;
+
+ if (snapshot_pf == reinterpret_cast<base::PlatformFile>(-1))
+ return;
+
+ base::MemoryMappedFile::Region snapshot_region =
+ base::MemoryMappedFile::Region::kWholeFile;
+ if (snapshot_size != 0 || snapshot_offset != 0) {
+ snapshot_region =
+ base::MemoryMappedFile::Region(snapshot_offset, snapshot_size);
+ }
+
+ LoadV8FileResult result = V8_LOAD_SUCCESS;
+ if (!MapV8File(base::File(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))
+ result = V8_LOAD_FAILED_VERIFY;
+#endif // V8_VERIFY_EXTERNAL_STARTUP_DATA
+ UMA_HISTOGRAM_ENUMERATION("V8.Initializer.LoadV8Snapshot.Result", result,
+ V8_LOAD_MAX_VALUE);
+}
+
+// static
+void V8Initializer::LoadV8NativesFromFD(base::PlatformFile natives_pf,
+ int64 natives_offset,
+ int64 natives_size) {
+ if (g_mapped_natives)
+ return;
+
+ CHECK_NE(natives_pf, reinterpret_cast<base::PlatformFile>(-1));
base::MemoryMappedFile::Region natives_region =
base::MemoryMappedFile::Region::kWholeFile;
@@ -232,15 +260,14 @@ bool V8Initializer::LoadV8SnapshotFromFD(base::PlatformFile natives_pf,
base::MemoryMappedFile::Region(natives_offset, natives_size);
}
- base::MemoryMappedFile::Region snapshot_region =
- base::MemoryMappedFile::Region::kWholeFile;
- if (natives_size != 0 || natives_offset != 0) {
- snapshot_region =
- base::MemoryMappedFile::Region(snapshot_offset, snapshot_size);
+ if (!MapV8File(base::File(natives_pf), natives_region, &g_mapped_natives)) {
+ LOG(FATAL) << "Couldn't mmap v8 natives data file";
}
-
- return MapV8Files(base::File(natives_pf), base::File(snapshot_pf),
- natives_region, snapshot_region);
+#if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
+ if (!VerifyV8StartupFile(&g_mapped_natives, g_natives_fingerprint)) {
+ LOG(FATAL) << "Couldn't verify contents of v8 natives data file";
+ }
+#endif // V8_VERIFY_EXTERNAL_STARTUP_DATA
}
// static
@@ -249,19 +276,25 @@ bool V8Initializer::OpenV8FilesForChildProcesses(
base::PlatformFile* snapshot_fd_out) {
base::FilePath natives_data_path;
base::FilePath snapshot_data_path;
- GetV8FilePaths(&natives_data_path, &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 success = OpenV8File(natives_data_path, file_flags, natives_data_file) &&
- OpenV8File(snapshot_data_path, file_flags, snapshot_data_file);
- if (success) {
+ bool natives_success =
+ OpenV8File(natives_data_path, file_flags, natives_data_file);
+ if (natives_success) {
*natives_fd_out = natives_data_file.TakePlatformFile();
+ }
+ bool snapshot_success =
+ OpenV8File(snapshot_data_path, file_flags, snapshot_data_file);
+ if (snapshot_success) {
*snapshot_fd_out = snapshot_data_file.TakePlatformFile();
}
- return success;
+ // We can start up without the snapshot file, but not without the natives.
+ return natives_success;
}
#endif // V8_USE_EXTERNAL_STARTUP_DATA
@@ -285,10 +318,12 @@ void V8Initializer::Initialize(gin::IsolateHolder::ScriptMode mode) {
natives.raw_size = static_cast<int>(g_mapped_natives->length());
v8::V8::SetNativesDataBlob(&natives);
- v8::StartupData snapshot;
- snapshot.data = reinterpret_cast<const char*>(g_mapped_snapshot->data());
- snapshot.raw_size = static_cast<int>(g_mapped_snapshot->length());
- v8::V8::SetSnapshotDataBlob(&snapshot);
+ if (g_mapped_snapshot != NULL) {
+ v8::StartupData snapshot;
+ snapshot.data = reinterpret_cast<const char*>(g_mapped_snapshot->data());
+ snapshot.raw_size = static_cast<int>(g_mapped_snapshot->length());
+ v8::V8::SetSnapshotDataBlob(&snapshot);
+ }
#endif // V8_USE_EXTERNAL_STARTUP_DATA
v8::V8::SetEntropySource(&GenerateEntropy);
@@ -302,15 +337,21 @@ void V8Initializer::GetV8ExternalSnapshotData(const char** natives_data_out,
int* natives_size_out,
const char** snapshot_data_out,
int* snapshot_size_out) {
- if (!g_mapped_natives || !g_mapped_snapshot) {
- *natives_data_out = *snapshot_data_out = NULL;
- *natives_size_out = *snapshot_size_out = 0;
- return;
+ if (g_mapped_natives) {
+ *natives_data_out = reinterpret_cast<const char*>(g_mapped_natives->data());
+ *natives_size_out = static_cast<int>(g_mapped_natives->length());
+ } else {
+ *natives_data_out = NULL;
+ *natives_size_out = 0;
+ }
+ if (g_mapped_snapshot) {
+ *snapshot_data_out =
+ reinterpret_cast<const char*>(g_mapped_snapshot->data());
+ *snapshot_size_out = static_cast<int>(g_mapped_snapshot->length());
+ } else {
+ *snapshot_data_out = NULL;
+ *snapshot_size_out = 0;
}
- *natives_data_out = reinterpret_cast<const char*>(g_mapped_natives->data());
- *snapshot_data_out = reinterpret_cast<const char*>(g_mapped_snapshot->data());
- *natives_size_out = static_cast<int>(g_mapped_natives->length());
- *snapshot_size_out = static_cast<int>(g_mapped_snapshot->length());
}
} // namespace gin
diff --git a/gin/v8_initializer.h b/gin/v8_initializer.h
index 0189f59..1e05fd0 100644
--- a/gin/v8_initializer.h
+++ b/gin/v8_initializer.h
@@ -31,25 +31,31 @@ class GIN_EXPORT V8Initializer {
// Load V8 snapshot from user provided platform file descriptors.
// The offset and size arguments, if non-zero, specify the portions
- // of the files to be loaded. This methods returns true on success
- // (or if snapshot is already loaded), false otherwise.
- static bool LoadV8SnapshotFromFD(base::PlatformFile natives_fd,
- int64 natives_offset,
- int64 natives_size,
- base::PlatformFile snapshot_fd,
+ // of the files to be loaded. Since the VM can boot with or without
+ // the snapshot, this function does not return a status.
+ static void LoadV8SnapshotFromFD(base::PlatformFile snapshot_fd,
int64 snapshot_offset,
int64 snapshot_size);
+ // Similar to LoadV8SnapshotFromFD, but for the source of the natives.
+ // Without the natives we cannot continue, so this function contains
+ // release mode asserts and won't return if it fails.
+ static void LoadV8NativesFromFD(base::PlatformFile natives_fd,
+ int64 natives_offset,
+ int64 natives_size);
- // Load V8 snapshot from default resources. Returns true on success or
- // snapshot is already loaded, false otherwise.
- static bool LoadV8Snapshot();
+ // Load V8 snapshot from default resources, if they are available.
+ static void LoadV8Snapshot();
+
+ // Load V8 natives source from default resources. Contains asserts
+ // 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);
-
+ base::PlatformFile* snapshot_fd_out)
+ WARN_UNUSED_RESULT;
#endif // V8_USE_EXTERNAL_STARTUP_DATA
};
diff --git a/media/blink/run_all_unittests.cc b/media/blink/run_all_unittests.cc
index 0261dc2..e7b8b72 100644
--- a/media/blink/run_all_unittests.cc
+++ b/media/blink/run_all_unittests.cc
@@ -80,6 +80,7 @@ void BlinkMediaTestSuite::Initialize() {
#ifdef V8_USE_EXTERNAL_STARTUP_DATA
gin::V8Initializer::LoadV8Snapshot();
+ gin::V8Initializer::LoadV8Natives();
#endif
// Dummy task runner is initialized here because the blink::initialize creates
diff --git a/net/proxy/proxy_resolver_v8.cc b/net/proxy/proxy_resolver_v8.cc
index 8a15a69..206cd34 100644
--- a/net/proxy/proxy_resolver_v8.cc
+++ b/net/proxy/proxy_resolver_v8.cc
@@ -367,6 +367,7 @@ class SharedIsolateFactory {
if (!has_initialized_v8_) {
#ifdef V8_USE_EXTERNAL_STARTUP_DATA
gin::V8Initializer::LoadV8Snapshot();
+ gin::V8Initializer::LoadV8Natives();
#endif
gin::IsolateHolder::Initialize(