summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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(