summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authoramit@chromium.org <amit@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-21 21:01:36 +0000
committeramit@chromium.org <amit@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-21 21:01:36 +0000
commit00b73410b463dc2fd920ebc11d4e47ad24bdd42e (patch)
tree0a9f2ebca7e9af85a41e1bc7ed4b8b22c326c174 /chrome
parenta43c5f32f2acced9804ec36773f9c57972e37e85 (diff)
downloadchromium_src-00b73410b463dc2fd920ebc11d4e47ad24bdd42e.zip
chromium_src-00b73410b463dc2fd920ebc11d4e47ad24bdd42e.tar.gz
chromium_src-00b73410b463dc2fd920ebc11d4e47ad24bdd42e.tar.bz2
Experimental pre-reading optimization to run on perf bots
Pre-reading chrome.dll prior to calling loadlibrary has shown significant improvement int he startup performance. Temporarily enabling this for headless mode so that we can try out the effect on the perf bots. Review URL: http://codereview.chromium.org/2814019 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@50386 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/app/client_util.cc57
1 files changed, 57 insertions, 0 deletions
diff --git a/chrome/app/client_util.cc b/chrome/app/client_util.cc
index e4b2b78..4730e53 100644
--- a/chrome/app/client_util.cc
+++ b/chrome/app/client_util.cc
@@ -81,6 +81,10 @@ bool EnvQueryStr(const wchar_t* key_name, std::wstring* value) {
return true;
}
+bool IsRunningHeadless() {
+ return (0 != ::GetEnvironmentVariableW(L"CHROME_HEADLESS", NULL, 0));
+}
+
// Expects that |dir| has a trailing backslash. |dir| is modified so it
// contains the full path that was tried. Caller must check for the return
// value not being null to dermine if this path contains a valid dll.
@@ -102,6 +106,59 @@ HMODULE LoadChromeWithDirectory(std::wstring* dir) {
#else
dir->append(installer_util::kChromeDll);
#endif
+
+ // Experimental pre-reading optimization
+ // The idea is to pre read significant portion of chrome.dll in advance
+ // so that subsequent hard page faults are avoided.
+ DWORD pre_read_size_mb = 0;
+ const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
+ if (!cmd_line.HasSwitch(switches::kProcessType) &&
+ (IsRunningHeadless() || InstallUtil::IsChromeFrameProcess())) {
+ HKEY key = NULL;
+ if (::RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Google\\ChromeFrame",
+ 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) {
+ DWORD unused = sizeof(pre_read_size_mb);
+ RegQueryValueEx(key, L"PreRead", NULL, NULL,
+ reinterpret_cast<LPBYTE>(&pre_read_size_mb), &unused);
+ RegCloseKey(key);
+ key = NULL;
+ } else {
+ pre_read_size_mb = 16; // Read in first 16 MB by default.
+ }
+ }
+
+ if (pre_read_size_mb) {
+ HANDLE chrome_dll = CreateFile(dir->c_str(),
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_SEQUENTIAL_SCAN,
+ NULL);
+ if (chrome_dll == INVALID_HANDLE_VALUE) {
+ DWORD error = GetLastError();
+ DLOG(ERROR) << __FUNCTION__ << " CreateFile( "
+ << dir->c_str() << " ) failed. Error: " << error;
+ } else {
+ const size_t kChunkSize = 1024 * 1024; // 1 MB
+ void* buffer = VirtualAlloc(NULL, kChunkSize, MEM_COMMIT, PAGE_READWRITE);
+ if (buffer) {
+ size_t read_size = pre_read_size_mb * kChunkSize;
+ DWORD read = 0;
+ while (::ReadFile(chrome_dll, buffer, kChunkSize, &read, NULL)) {
+ // nothing to do here...
+ read_size -= std::min(size_t(read), read_size);
+ if (!read || !read_size)
+ break;
+ }
+
+ VirtualFree(buffer, 0, MEM_RELEASE);
+ }
+
+ CloseHandle(chrome_dll);
+ }
+ }
+
return ::LoadLibraryExW(dir->c_str(), NULL,
LOAD_WITH_ALTERED_SEARCH_PATH);
}