summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authornasko@chromium.org <nasko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-13 22:39:34 +0000
committernasko@chromium.org <nasko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-13 22:39:34 +0000
commita6381cb574d7e48fd577aab1270d5298a16af6bc (patch)
treece8ebd0925be0bc5f8aaee6aba58aadc426c464f /content
parent5bf2f31639b75587926422d4c3f0a0d523d13cf8 (diff)
downloadchromium_src-a6381cb574d7e48fd577aab1270d5298a16af6bc.zip
chromium_src-a6381cb574d7e48fd577aab1270d5298a16af6bc.tar.gz
chromium_src-a6381cb574d7e48fd577aab1270d5298a16af6bc.tar.bz2
Adding a command line flag to specify renderer process limit
BUG=111498 TEST=Run chrome with --renderer-process-limit=X where X is the maximum number of renderer processes. Review URL: http://codereview.chromium.org/9328011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@121744 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/browser/browser_main_loop.cc11
-rw-r--r--content/browser/renderer_host/render_process_host_browsertest.cc191
-rw-r--r--content/browser/renderer_host/render_process_host_browsertest.h10
-rw-r--r--content/browser/renderer_host/render_process_host_impl.cc28
-rw-r--r--content/public/browser/render_process_host.h10
-rw-r--r--content/public/common/content_switches.cc5
-rw-r--r--content/public/common/content_switches.h1
7 files changed, 152 insertions, 104 deletions
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index c953db0..4096821 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -11,6 +11,7 @@
#include "base/message_loop.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
+#include "base/string_number_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "content/browser/browser_thread_impl.h"
#include "content/browser/download/download_file_manager.h"
@@ -26,6 +27,7 @@
#include "content/public/browser/browser_main_parts.h"
#include "content/public/browser/browser_shutdown.h"
#include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
#include "content/public/common/result_codes.h"
@@ -271,6 +273,15 @@ void BrowserMainLoop::EarlyInitialization() {
if (parsed_command_line_.HasSwitch(switches::kEnableTcpFastOpen))
net::set_tcp_fastopen_enabled(true);
+ if (parsed_command_line_.HasSwitch(switches::kRendererProcessLimit)) {
+ std::string limit_string = parsed_command_line_.GetSwitchValueASCII(
+ switches::kRendererProcessLimit);
+ size_t process_limit;
+ if (base::StringToSizeT(limit_string, &process_limit)) {
+ content::RenderProcessHost::SetMaxRendererProcessCount(process_limit);
+ }
+ }
+
if (parts_.get())
parts_->PostEarlyInitialization();
}
diff --git a/content/browser/renderer_host/render_process_host_browsertest.cc b/content/browser/renderer_host/render_process_host_browsertest.cc
index 4d4676d..50de340 100644
--- a/content/browser/renderer_host/render_process_host_browsertest.cc
+++ b/content/browser/renderer_host/render_process_host_browsertest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -55,9 +55,103 @@ base::ProcessHandle RenderProcessHostTest::ShowSingletonTab(const GURL& page) {
return wc->GetRenderProcessHost()->GetHandle();
}
+void RenderProcessHostTestWithCommandLine::SetUpCommandLine(
+ CommandLine* command_line) {
+ InProcessBrowserTest::SetUpCommandLine(command_line);
+ command_line->AppendSwitchASCII(switches::kRendererProcessLimit, "1");
+}
+
+// When we hit the max number of renderers, verify that the way we do process
+// sharing behaves correctly. In particular, this test is verifying that even
+// when we hit the max process limit, that renderers of each type will wind up
+// in a process of that type, even if that means creating a new process.
+void RenderProcessHostTest::TestProcessOverflow() {
+ int tab_count = 1;
+ int host_count = 1;
+ WebContents* tab1 = NULL;
+ WebContents* tab2 = NULL;
+ content::RenderProcessHost* rph1 = NULL;
+ content::RenderProcessHost* rph2 = NULL;
+ content::RenderProcessHost* rph3 = NULL;
+
+#if defined(USE_VIRTUAL_KEYBOARD)
+ ++host_count; // For the virtual keyboard.
+#endif
+
+ // Change the first tab to be the new tab page (TYPE_WEBUI).
+ GURL newtab(chrome::kTestNewTabURL);
+ ui_test_utils::NavigateToURL(browser(), newtab);
+ EXPECT_EQ(tab_count, browser()->tab_count());
+ tab1 = browser()->GetWebContentsAt(tab_count - 1);
+ rph1 = tab1->GetRenderProcessHost();
+ EXPECT_EQ(tab1->GetURL(), newtab);
+ EXPECT_EQ(host_count, RenderProcessHostCount());
+
+ // Create a new TYPE_TABBED tab. It should be in its own process.
+ GURL page1("data:text/html,hello world1");
+ browser()->ShowSingletonTab(page1);
+ if (browser()->tab_count() == tab_count)
+ ui_test_utils::WaitForNewTab(browser());
+ tab_count++;
+ host_count++;
+ EXPECT_EQ(tab_count, browser()->tab_count());
+ tab1 = browser()->GetWebContentsAt(tab_count - 1);
+ rph2 = tab1->GetRenderProcessHost();
+ EXPECT_EQ(tab1->GetURL(), page1);
+ EXPECT_EQ(host_count, RenderProcessHostCount());
+ EXPECT_NE(rph1, rph2);
+
+ // Create another TYPE_TABBED tab. It should share the previous process.
+ GURL page2("data:text/html,hello world2");
+ browser()->ShowSingletonTab(page2);
+ if (browser()->tab_count() == tab_count)
+ ui_test_utils::WaitForNewTab(browser());
+ tab_count++;
+ EXPECT_EQ(tab_count, browser()->tab_count());
+ tab2 = browser()->GetWebContentsAt(tab_count - 1);
+ EXPECT_EQ(tab2->GetURL(), page2);
+ EXPECT_EQ(host_count, RenderProcessHostCount());
+ EXPECT_EQ(tab2->GetRenderProcessHost(), rph2);
+
+ // Create another TYPE_WEBUI tab. It should share the process with newtab.
+ // Note: intentionally create this tab after the TYPE_TABBED tabs to exercise
+ // bug 43448 where extension and WebUI tabs could get combined into normal
+ // renderers.
+ GURL history(chrome::kTestHistoryURL);
+ browser()->ShowSingletonTab(history);
+ if (browser()->tab_count() == tab_count)
+ ui_test_utils::WaitForNewTab(browser());
+ tab_count++;
+ EXPECT_EQ(tab_count, browser()->tab_count());
+ tab2 = browser()->GetWebContentsAt(tab_count - 1);
+ EXPECT_EQ(tab2->GetURL(), history);
+ EXPECT_EQ(host_count, RenderProcessHostCount());
+ EXPECT_EQ(tab2->GetRenderProcessHost(), rph1);
+
+ // Create a TYPE_EXTENSION tab. It should be in its own process.
+ // (the bookmark manager is implemented as an extension)
+ GURL bookmarks(chrome::kTestBookmarksURL);
+ browser()->ShowSingletonTab(bookmarks);
+ if (browser()->tab_count() == tab_count)
+ ui_test_utils::WaitForNewTab(browser());
+ tab_count++;
+#if !defined(USE_VIRTUAL_KEYBOARD)
+ // The virtual keyboard already creates an extension process. So this
+ // should not increase the process count.
+ host_count++;
+#endif
+ EXPECT_EQ(tab_count, browser()->tab_count());
+ tab1 = browser()->GetWebContentsAt(tab_count - 1);
+ rph3 = tab1->GetRenderProcessHost();
+ EXPECT_EQ(tab1->GetURL(), bookmarks);
+ EXPECT_EQ(host_count, RenderProcessHostCount());
+ EXPECT_NE(rph1, rph3);
+ EXPECT_NE(rph2, rph3);
+}
+
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, ProcessPerTab) {
// Set max renderers to 1 to force running out of processes.
- content::RenderProcessHost::SetMaxRendererProcessCountForTest(1);
+ content::RenderProcessHost::SetMaxRendererProcessCount(1);
CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
parsed_command_line.AppendSwitch(switches::kProcessPerTab);
@@ -147,93 +241,14 @@ IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, Backgrounding) {
}
#endif
-// When we hit the max number of renderers, verify that the way we do process
-// sharing behaves correctly. In particular, this test is verifying that even
-// when we hit the max process limit, that renderers of each type will wind up
-// in a process of that type, even if that means creating a new process.
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, ProcessOverflow) {
// Set max renderers to 1 to force running out of processes.
- content::RenderProcessHost::SetMaxRendererProcessCountForTest(1);
-
- int tab_count = 1;
- int host_count = 1;
- WebContents* tab1 = NULL;
- WebContents* tab2 = NULL;
- content::RenderProcessHost* rph1 = NULL;
- content::RenderProcessHost* rph2 = NULL;
- content::RenderProcessHost* rph3 = NULL;
-
-#if defined(USE_VIRTUAL_KEYBOARD)
- ++host_count; // For the virtual keyboard.
-#endif
-
- // Change the first tab to be the new tab page (TYPE_WEBUI).
- GURL newtab(chrome::kTestNewTabURL);
- ui_test_utils::NavigateToURL(browser(), newtab);
- EXPECT_EQ(tab_count, browser()->tab_count());
- tab1 = browser()->GetWebContentsAt(tab_count - 1);
- rph1 = tab1->GetRenderProcessHost();
- EXPECT_EQ(tab1->GetURL(), newtab);
- EXPECT_EQ(host_count, RenderProcessHostCount());
-
- // Create a new TYPE_TABBED tab. It should be in its own process.
- GURL page1("data:text/html,hello world1");
- browser()->ShowSingletonTab(page1);
- if (browser()->tab_count() == tab_count)
- ui_test_utils::WaitForNewTab(browser());
- tab_count++;
- host_count++;
- EXPECT_EQ(tab_count, browser()->tab_count());
- tab1 = browser()->GetWebContentsAt(tab_count - 1);
- rph2 = tab1->GetRenderProcessHost();
- EXPECT_EQ(tab1->GetURL(), page1);
- EXPECT_EQ(host_count, RenderProcessHostCount());
- EXPECT_NE(rph1, rph2);
-
- // Create another TYPE_TABBED tab. It should share the previous process.
- GURL page2("data:text/html,hello world2");
- browser()->ShowSingletonTab(page2);
- if (browser()->tab_count() == tab_count)
- ui_test_utils::WaitForNewTab(browser());
- tab_count++;
- EXPECT_EQ(tab_count, browser()->tab_count());
- tab2 = browser()->GetWebContentsAt(tab_count - 1);
- EXPECT_EQ(tab2->GetURL(), page2);
- EXPECT_EQ(host_count, RenderProcessHostCount());
- EXPECT_EQ(tab2->GetRenderProcessHost(), rph2);
-
- // Create another TYPE_WEBUI tab. It should share the process with newtab.
- // Note: intentionally create this tab after the TYPE_TABBED tabs to exercise
- // bug 43448 where extension and WebUI tabs could get combined into normal
- // renderers.
- GURL history(chrome::kTestHistoryURL);
- browser()->ShowSingletonTab(history);
- if (browser()->tab_count() == tab_count)
- ui_test_utils::WaitForNewTab(browser());
- tab_count++;
- EXPECT_EQ(tab_count, browser()->tab_count());
- tab2 = browser()->GetWebContentsAt(tab_count - 1);
- EXPECT_EQ(tab2->GetURL(), history);
- EXPECT_EQ(host_count, RenderProcessHostCount());
- EXPECT_EQ(tab2->GetRenderProcessHost(), rph1);
+ content::RenderProcessHost::SetMaxRendererProcessCount(1);
+ TestProcessOverflow();
+}
- // Create a TYPE_EXTENSION tab. It should be in its own process.
- // (the bookmark manager is implemented as an extension)
- GURL bookmarks(chrome::kTestBookmarksURL);
- browser()->ShowSingletonTab(bookmarks);
- if (browser()->tab_count() == tab_count)
- ui_test_utils::WaitForNewTab(browser());
- tab_count++;
-#if !defined(USE_VIRTUAL_KEYBOARD)
- // The virtual keyboard already creates an extension process. So this
- // should not increase the process count.
- host_count++;
-#endif
- EXPECT_EQ(tab_count, browser()->tab_count());
- tab1 = browser()->GetWebContentsAt(tab_count - 1);
- rph3 = tab1->GetRenderProcessHost();
- EXPECT_EQ(tab1->GetURL(), bookmarks);
- EXPECT_EQ(host_count, RenderProcessHostCount());
- EXPECT_NE(rph1, rph3);
- EXPECT_NE(rph2, rph3);
+// Variation of the ProcessOverflow test, which is driven through command line
+// parameter instead of direct function call into the class.
+IN_PROC_BROWSER_TEST_F(RenderProcessHostTestWithCommandLine, ProcessOverflow) {
+ TestProcessOverflow();
}
diff --git a/content/browser/renderer_host/render_process_host_browsertest.h b/content/browser/renderer_host/render_process_host_browsertest.h
index 58d9f51..13cd7c7 100644
--- a/content/browser/renderer_host/render_process_host_browsertest.h
+++ b/content/browser/renderer_host/render_process_host_browsertest.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,8 +6,10 @@
#define CONTENT_BROWSER_RENDERER_HOST_RENDER_PROCESS_HOST_BROWSERTEST_H_
#pragma once
+#include "base/command_line.h"
#include "base/process.h"
#include "chrome/test/base/in_process_browser_test.h"
+#include "content/public/common/content_switches.h"
class GURL;
@@ -18,6 +20,12 @@ class RenderProcessHostTest : public InProcessBrowserTest {
int RenderProcessHostCount();
base::ProcessHandle ShowSingletonTab(const GURL& page);
+ void TestProcessOverflow();
+};
+
+class RenderProcessHostTestWithCommandLine : public RenderProcessHostTest {
+ protected:
+ virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE;
};
#endif // CONTENT_BROWSER_RENDERER_HOST_RENDER_PROCESS_HOST_BROWSERTEST_H_
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index f4682e1..55f6313 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -202,11 +202,20 @@ class RendererURLRequestContextSelector
scoped_refptr<net::URLRequestContextGetter> media_request_context_;
};
-size_t max_renderer_count_override = 0;
+// the global list of all renderer processes
+base::LazyInstance<IDMap<content::RenderProcessHost> >::Leaky
+ g_all_hosts = LAZY_INSTANCE_INITIALIZER;
-size_t GetMaxRendererProcessCount() {
- if (max_renderer_count_override)
- return max_renderer_count_override;
+} // namespace
+
+// Stores the maximum number of renderer processes the content module can
+// create.
+static size_t g_max_renderer_count_override = 0;
+
+// static
+size_t content::RenderProcessHost::GetMaxRendererProcessCount() {
+ if (g_max_renderer_count_override)
+ return g_max_renderer_count_override;
// Defines the maximum number of renderer processes according to the
// amount of installed memory as reported by the OS. The table
@@ -246,19 +255,12 @@ size_t GetMaxRendererProcessCount() {
return max_count;
}
-// the global list of all renderer processes
-base::LazyInstance<IDMap<content::RenderProcessHost> >::Leaky
- g_all_hosts = LAZY_INSTANCE_INITIALIZER;
-
-} // namespace
-
// static
bool g_run_renderer_in_process_ = false;
// static
-void content::RenderProcessHost::SetMaxRendererProcessCountForTest(
- size_t count) {
- max_renderer_count_override = count;
+void content::RenderProcessHost::SetMaxRendererProcessCount(size_t count) {
+ g_max_renderer_count_override = count;
}
RenderProcessHostImpl::RenderProcessHostImpl(
diff --git a/content/public/browser/render_process_host.h b/content/public/browser/render_process_host.h
index 785a484..adb08728 100644
--- a/content/public/browser/render_process_host.h
+++ b/content/public/browser/render_process_host.h
@@ -220,9 +220,15 @@ class CONTENT_EXPORT RenderProcessHost : public IPC::Message::Sender,
content::BrowserContext* browser_context, const GURL& site_url);
// Overrides the default heuristic for limiting the max renderer process
- // count. This is useful for unit testing process limit behaviors.
+ // count. This is useful for unit testing process limit behaviors. It is
+ // also used to allow a command line parameter to configure the max number of
+ // renderer processes and should only be called once during startup.
// A value of zero means to use the default heuristic.
- static void SetMaxRendererProcessCountForTest(size_t count);
+ static void SetMaxRendererProcessCount(size_t count);
+
+ // Returns the current max number of renderer processes used by the content
+ // module.
+ static size_t GetMaxRendererProcessCount();
};
} // namespace content.
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc
index 0bec7fa..bcbdf11 100644
--- a/content/public/common/content_switches.cc
+++ b/content/public/common/content_switches.cc
@@ -495,6 +495,11 @@ const char kRendererCrashTest[] = "renderer-crash-test";
// Causes the process to run as renderer instead of as browser.
const char kRendererProcess[] = "renderer";
+// Overrides the default/calculated limit to the number of renderer processes.
+// Very high values for this setting can lead to high memory/resource usage
+// or instability.
+const char kRendererProcessLimit[] = "renderer-process-limit";
+
// Causes the renderer process to display a dialog on launch.
const char kRendererStartupDialog[] = "renderer-startup-dialog";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h
index f271ebd..0937325 100644
--- a/content/public/common/content_switches.h
+++ b/content/public/common/content_switches.h
@@ -151,6 +151,7 @@ CONTENT_EXPORT extern const char kRendererAssertTest[];
extern const char kRendererCmdPrefix[];
CONTENT_EXPORT extern const char kRendererCrashTest[];
CONTENT_EXPORT extern const char kRendererProcess[];
+extern const char kRendererProcessLimit[];
extern const char kRendererStartupDialog[];
// TODO(jam): this doesn't belong in content.
CONTENT_EXPORT extern const char kServiceProcess[];