summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/BUILD.gn2
-rw-r--r--chrome/browser/BUILD.gn3
-rw-r--r--chrome/browser/chrome_content_browser_client.cc2
-rw-r--r--chrome/chrome_browser.gypi1
-rw-r--r--components/BUILD.gn1
-rw-r--r--components/html_viewer/BUILD.gn2
-rw-r--r--components/startup_metric_utils.gypi40
-rw-r--r--components/startup_metric_utils/browser/BUILD.gn29
-rw-r--r--components/startup_metric_utils/browser/DEPS3
-rw-r--r--components/startup_metric_utils/browser/OWNERS13
-rw-r--r--components/startup_metric_utils/browser/startup_metric_message_filter.cc31
-rw-r--r--components/startup_metric_utils/browser/startup_metric_message_filter.h31
-rw-r--r--components/startup_metric_utils/browser/startup_metric_utils.cc62
-rw-r--r--components/startup_metric_utils/browser/startup_metric_utils.h6
-rw-r--r--components/startup_metric_utils/common/BUILD.gn16
-rw-r--r--components/startup_metric_utils/common/DEPS3
-rw-r--r--components/startup_metric_utils/common/startup_metric_message_generator.cc33
-rw-r--r--components/startup_metric_utils/common/startup_metric_message_generator.h7
-rw-r--r--components/startup_metric_utils/common/startup_metric_messages.h13
-rw-r--r--content/content_renderer.gypi1
-rw-r--r--content/renderer/BUILD.gn1
-rw-r--r--content/renderer/DEPS1
-rw-r--r--content/renderer/renderer_main.cc8
-rw-r--r--ipc/ipc_message_start.h1
-rw-r--r--tools/metrics/histograms/histograms.xml9
25 files changed, 300 insertions, 19 deletions
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index ab96da6..075f5b7 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -236,7 +236,7 @@ if (!is_android) {
":packed_resources",
]
deps += [
- "//components/startup_metric_utils/browser",
+ "//components/startup_metric_utils/browser:lib",
# Precompiled plugins that need to get copied to the output directory.
# On Mac, internal plugins go inside the framework, so these
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 13075b3..ed49486 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -160,7 +160,8 @@ source_set("browser") {
"//components/security_interstitials/core",
"//components/signin/core/browser",
"//components/ssl_errors",
- "//components/startup_metric_utils/browser",
+ "//components/startup_metric_utils/browser:lib",
+ "//components/startup_metric_utils/browser:message_filter_lib",
"//components/strings",
"//components/suggestions",
"//components/sync_bookmarks",
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 2cd5a26..7035fee 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -117,6 +117,7 @@
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/rappor/rappor_utils.h"
#include "components/signin/core/common/profile_management_switches.h"
+#include "components/startup_metric_utils/browser/startup_metric_message_filter.h"
#include "components/translate/core/common/translate_switches.h"
#include "components/url_formatter/url_fixer.h"
#include "components/variations/variations_associated_data.h"
@@ -907,6 +908,7 @@ void ChromeContentBrowserClient::RenderProcessWillLaunch(
DataReductionProxyChromeSettingsFactory::GetForBrowserContext(profile);
host->AddFilter(new data_reduction_proxy::DataReductionProxyMessageFilter(
data_reduction_proxy_settings));
+ host->AddFilter(new startup_metric_utils::StartupMetricMessageFilter());
host->Send(new ChromeViewMsg_SetIsIncognitoProcess(
profile->IsOffTheRecord()));
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 57e5b8e..583eb16 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -3135,6 +3135,7 @@
'../components/components.gyp:suggestions',
'../components/components.gyp:signin_core_browser',
'../components/components.gyp:startup_metric_utils_browser',
+ '../components/components.gyp:startup_metric_utils_browser_message_filter',
'../components/components.gyp:sync_bookmarks',
'../components/components.gyp:sync_driver',
'../components/components.gyp:sync_sessions',
diff --git a/components/BUILD.gn b/components/BUILD.gn
index 166563f..a1ec4d7 100644
--- a/components/BUILD.gn
+++ b/components/BUILD.gn
@@ -132,6 +132,7 @@ group("all_components") {
"//components/security_interstitials/core",
"//components/signin/core/browser",
"//components/ssl_config",
+ "//components/startup_metric_utils/common",
"//components/startup_metric_utils/browser",
"//components/sync_driver",
"//components/sync_sessions",
diff --git a/components/html_viewer/BUILD.gn b/components/html_viewer/BUILD.gn
index acbcbe9..95d6539 100644
--- a/components/html_viewer/BUILD.gn
+++ b/components/html_viewer/BUILD.gn
@@ -163,7 +163,7 @@ source_set("lib") {
"//components/resource_provider/public/cpp",
"//components/resource_provider/public/interfaces",
"//components/scheduler:scheduler",
- "//components/startup_metric_utils/browser",
+ "//components/startup_metric_utils/browser:lib",
"//components/webcrypto",
"//components/web_view:switches",
"//components/web_view/public/interfaces",
diff --git a/components/startup_metric_utils.gypi b/components/startup_metric_utils.gypi
index f70e7a0..c93819a 100644
--- a/components/startup_metric_utils.gypi
+++ b/components/startup_metric_utils.gypi
@@ -2,9 +2,14 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+# We have 2 separate browser targets because //components/html_viewer requires
+# startup_metric_utils_browser, but has symbols that conflict with mojo symbols
+# that startup_metric_utils_browser_message_filter indirectly depends on.
+
{
'targets': [
{
+ # GN version: //components/startup_metric_utils/browser:lib
'target_name': 'startup_metric_utils_browser',
'type': 'static_library',
'dependencies': [
@@ -18,5 +23,40 @@
'startup_metric_utils/browser/startup_metric_utils.h',
],
},
+ {
+ # GN version: //components/startup_metric_utils/browser:message_filter_lib
+ 'target_name': 'startup_metric_utils_browser_message_filter',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../content/content.gyp:content_browser',
+ 'startup_metric_utils_browser',
+ 'startup_metric_utils_common',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ 'startup_metric_utils/browser/startup_metric_message_filter.cc',
+ 'startup_metric_utils/browser/startup_metric_message_filter.h',
+ ],
+ },
+ {
+ # GN version: //components/startup_metric_utils/common
+ 'target_name': 'startup_metric_utils_common',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../ipc/ipc.gyp:ipc',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ 'startup_metric_utils/common/startup_metric_message_generator.cc',
+ 'startup_metric_utils/common/startup_metric_message_generator.h',
+ 'startup_metric_utils/common/startup_metric_messages.h',
+ ],
+ },
],
}
diff --git a/components/startup_metric_utils/browser/BUILD.gn b/components/startup_metric_utils/browser/BUILD.gn
index 258e210..8f44817 100644
--- a/components/startup_metric_utils/browser/BUILD.gn
+++ b/components/startup_metric_utils/browser/BUILD.gn
@@ -2,7 +2,20 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-source_set("browser") {
+# We have 2 separate targets because //components/html_viewer requires :lib,
+# but has symbols that conflict with mojo symbols that :message_filter_lib
+# indirectly depends on.
+
+group("browser") {
+ testonly = true
+
+ deps = [
+ ":lib",
+ ":message_filter_lib",
+ ]
+}
+
+source_set("lib") {
sources = [
"startup_metric_utils.cc",
"startup_metric_utils.h",
@@ -12,3 +25,17 @@ source_set("browser") {
"//base",
]
}
+
+source_set("message_filter_lib") {
+ sources = [
+ "startup_metric_message_filter.cc",
+ "startup_metric_message_filter.h",
+ ]
+
+ deps = [
+ ":lib",
+ "//base",
+ "//components/startup_metric_utils/common",
+ "//content/public/browser",
+ ]
+}
diff --git a/components/startup_metric_utils/browser/DEPS b/components/startup_metric_utils/browser/DEPS
new file mode 100644
index 0000000..1c35d9c
--- /dev/null
+++ b/components/startup_metric_utils/browser/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+content/public/browser",
+]
diff --git a/components/startup_metric_utils/browser/OWNERS b/components/startup_metric_utils/browser/OWNERS
new file mode 100644
index 0000000..ba38e27
--- /dev/null
+++ b/components/startup_metric_utils/browser/OWNERS
@@ -0,0 +1,13 @@
+# Changes to IPC messages require a security review to avoid introducing
+# new sandbox escapes.
+per-file *_message*.h=set noparent
+per-file *_message*.h=dcheng@chromium.org
+per-file *_message*.h=inferno@chromium.org
+per-file *_message*.h=jln@chromium.org
+per-file *_message*.h=jschuh@chromium.org
+per-file *_message*.h=kenrb@chromium.org
+per-file *_message*.h=mkwst@chromium.org
+per-file *_message*.h=nasko@chromium.org
+per-file *_message*.h=palmer@chromium.org
+per-file *_message*.h=tsepez@chromium.org
+per-file *_message*.h=wfh@chromium.org
diff --git a/components/startup_metric_utils/browser/startup_metric_message_filter.cc b/components/startup_metric_utils/browser/startup_metric_message_filter.cc
new file mode 100644
index 0000000..556d045
--- /dev/null
+++ b/components/startup_metric_utils/browser/startup_metric_message_filter.cc
@@ -0,0 +1,31 @@
+// Copyright 2015 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.
+
+#include "components/startup_metric_utils/browser/startup_metric_message_filter.h"
+
+#include "components/startup_metric_utils/browser/startup_metric_utils.h"
+#include "components/startup_metric_utils/common/startup_metric_messages.h"
+
+namespace startup_metric_utils {
+
+StartupMetricMessageFilter::StartupMetricMessageFilter()
+ : content::BrowserMessageFilter(StartupMetricMsgStart) {}
+
+bool StartupMetricMessageFilter::OnMessageReceived(
+ const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(StartupMetricMessageFilter, message)
+ IPC_MESSAGE_HANDLER(StartupMetricHostMsg_RecordRendererMainEntryTime,
+ OnRecordRendererMainEntryTime)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void StartupMetricMessageFilter::OnRecordRendererMainEntryTime(
+ const base::TimeTicks& renderer_main_entry_time) {
+ RecordRendererMainEntryTime(renderer_main_entry_time);
+}
+
+} // namespace startup_metric_utils
diff --git a/components/startup_metric_utils/browser/startup_metric_message_filter.h b/components/startup_metric_utils/browser/startup_metric_message_filter.h
new file mode 100644
index 0000000..ffac9c8
--- /dev/null
+++ b/components/startup_metric_utils/browser/startup_metric_message_filter.h
@@ -0,0 +1,31 @@
+// Copyright 2015 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.
+
+#ifndef COMPONENTS_STARTUP_METRIC_UTILS_BROWSER_STARTUP_METRIC_MESSAGE_FILTER_H_
+#define COMPONENTS_STARTUP_METRIC_UTILS_BROWSER_STARTUP_METRIC_MESSAGE_FILTER_H_
+
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "base/time/time.h"
+#include "content/public/browser/browser_message_filter.h"
+
+namespace startup_metric_utils {
+
+class StartupMetricMessageFilter : public content::BrowserMessageFilter {
+ public:
+ StartupMetricMessageFilter();
+ bool OnMessageReceived(const IPC::Message& message) override;
+
+ private:
+ ~StartupMetricMessageFilter() override = default;
+ void OnRecordRendererMainEntryTime(
+ const base::TimeTicks& renderer_main_entry_time);
+
+ DISALLOW_COPY_AND_ASSIGN(StartupMetricMessageFilter);
+};
+
+} // namespace startup_metric_utils
+
+#endif // COMPONENTS_STARTUP_METRIC_UTILS_BROWSER_STARTUP_METRIC_MESSAGE_FILTER_H_
diff --git a/components/startup_metric_utils/browser/startup_metric_utils.cc b/components/startup_metric_utils/browser/startup_metric_utils.cc
index 3f41447..626079e 100644
--- a/components/startup_metric_utils/browser/startup_metric_utils.cc
+++ b/components/startup_metric_utils/browser/startup_metric_utils.cc
@@ -30,13 +30,16 @@ volatile bool g_non_browser_ui_displayed = false;
base::LazyInstance<base::TimeTicks>::Leaky g_process_creation_ticks =
LAZY_INSTANCE_INITIALIZER;
-base::LazyInstance<base::TimeTicks>::Leaky g_main_entry_point_ticks =
+base::LazyInstance<base::TimeTicks>::Leaky g_browser_main_entry_point_ticks =
+ LAZY_INSTANCE_INITIALIZER;
+
+base::LazyInstance<base::TimeTicks>::Leaky g_renderer_main_entry_point_ticks =
LAZY_INSTANCE_INITIALIZER;
// Only used by RecordMainEntryTimeHistogram(), should go away with it (do not
// add new uses of this), see crbug.com/317481 for discussion on why it was kept
// as-is for now.
-base::LazyInstance<base::Time>::Leaky g_main_entry_point_time =
+base::LazyInstance<base::Time>::Leaky g_browser_main_entry_point_time =
LAZY_INSTANCE_INITIALIZER;
StartupTemperature g_startup_temperature = UNCERTAIN_STARTUP_TEMPERATURE;
@@ -170,6 +173,8 @@ bool GetHardFaultCountForCurrentProcess(uint32_t* hard_fault_count,
// ".ColdStart" or ".WarmStart", as appropriate.
// |value_expr| is an expression evaluating to the value to be recorded. This
// will be evaluated exactly once and cached, so side effects are not an issue.
+// A metric logged using this macro must have an affected-histogram entry in the
+// definition of the StartupTemperature suffix in histograms.xml.
#define UMA_HISTOGRAM_WITH_STARTUP_TEMPERATURE(type, basename, value_expr) \
{ \
const auto kValue = value_expr; \
@@ -298,9 +303,9 @@ base::TimeTicks StartupTimeToTimeTicks(const base::Time& time) {
void RecordMainEntryTimeHistogram() {
const int kLowWordMask = 0xFFFFFFFF;
const int kLower31BitsMask = 0x7FFFFFFF;
- DCHECK(!g_main_entry_point_time.Get().is_null());
+ DCHECK(!g_browser_main_entry_point_time.Get().is_null());
const base::TimeDelta browser_main_entry_time_absolute =
- g_main_entry_point_time.Get() - base::Time::UnixEpoch();
+ g_browser_main_entry_point_time.Get() - base::Time::UnixEpoch();
const uint64 browser_main_entry_time_raw_ms =
browser_main_entry_time_absolute.InMilliseconds();
@@ -320,6 +325,21 @@ void RecordMainEntryTimeHistogram() {
browser_main_entry_time_raw_ms_low_word);
}
+// Record renderer main entry time histogram.
+void RecordRendererMainEntryHistogram() {
+ const base::TimeTicks& browser_main_entry_point_ticks =
+ g_browser_main_entry_point_ticks.Get();
+ const base::TimeTicks& renderer_main_entry_point_ticks =
+ g_renderer_main_entry_point_ticks.Get();
+
+ if (!browser_main_entry_point_ticks.is_null() &&
+ !renderer_main_entry_point_ticks.is_null()) {
+ UMA_HISTOGRAM_AND_TRACE_WITH_STARTUP_TEMPERATURE(
+ UMA_HISTOGRAM_LONG_TIMES_100, "Startup.BrowserMainToRendererMain",
+ browser_main_entry_point_ticks, renderer_main_entry_point_ticks);
+ }
+}
+
// Environment variable that stores the timestamp when the executable's main()
// function was entered in TimeTicks. This is required because chrome.exe and
// chrome.dll don't share the same static storage.
@@ -354,15 +374,15 @@ void RecordStartupProcessCreationTime(const base::Time& time) {
}
void RecordMainEntryPointTime(const base::Time& time) {
- DCHECK(g_main_entry_point_ticks.Get().is_null());
- g_main_entry_point_ticks.Get() = StartupTimeToTimeTicks(time);
- DCHECK(!g_main_entry_point_ticks.Get().is_null());
+ DCHECK(g_browser_main_entry_point_ticks.Get().is_null());
+ g_browser_main_entry_point_ticks.Get() = StartupTimeToTimeTicks(time);
+ DCHECK(!g_browser_main_entry_point_ticks.Get().is_null());
// TODO(jeremy): Remove this with RecordMainEntryTimeHistogram() when
// resolving crbug.com/317481.
- DCHECK(g_main_entry_point_time.Get().is_null());
- g_main_entry_point_time.Get() = time;
- DCHECK(!g_main_entry_point_time.Get().is_null());
+ DCHECK(g_browser_main_entry_point_time.Get().is_null());
+ g_browser_main_entry_point_time.Get() = time;
+ DCHECK(!g_browser_main_entry_point_time.Get().is_null());
}
void RecordExeMainEntryPointTime(const base::Time& time) {
@@ -400,12 +420,12 @@ void RecordBrowserMainMessageLoopStart(const base::TimeTicks& ticks,
UMA_HISTOGRAM_AND_TRACE_WITH_STARTUP_TEMPERATURE(
UMA_HISTOGRAM_LONG_TIMES,
"Startup.BrowserMessageLoopStartTimeFromMainEntry.FirstRun",
- g_main_entry_point_ticks.Get(), ticks);
+ g_browser_main_entry_point_ticks.Get(), ticks);
} else {
UMA_HISTOGRAM_AND_TRACE_WITH_STARTUP_TEMPERATURE(
UMA_HISTOGRAM_LONG_TIMES,
"Startup.BrowserMessageLoopStartTimeFromMainEntry",
- g_main_entry_point_ticks.Get(), ticks);
+ g_browser_main_entry_point_ticks.Get(), ticks);
}
// Record timings between process creation, the main() in the executable being
@@ -421,13 +441,13 @@ void RecordBrowserMainMessageLoopStart(const base::TimeTicks& ticks,
// chrome.exe:main() to chrome.dll:main().
UMA_HISTOGRAM_AND_TRACE_WITH_STARTUP_TEMPERATURE(
UMA_HISTOGRAM_LONG_TIMES, "Startup.LoadTime.ExeMainToDllMain",
- exe_main_ticks, g_main_entry_point_ticks.Get());
+ exe_main_ticks, g_browser_main_entry_point_ticks.Get());
// Process create to chrome.dll:main(). Reported as a histogram only as
// the other two events above are sufficient for tracing purposes.
UMA_HISTOGRAM_WITH_STARTUP_TEMPERATURE(
UMA_HISTOGRAM_LONG_TIMES, "Startup.LoadTime.ProcessCreateToDllMain",
- g_main_entry_point_ticks.Get() - process_creation_ticks);
+ g_browser_main_entry_point_ticks.Get() - process_creation_ticks);
}
}
}
@@ -455,6 +475,13 @@ void RecordBrowserOpenTabsDelta(const base::TimeDelta& delta) {
"Startup.BrowserOpenTabs", delta);
}
+void RecordRendererMainEntryTime(const base::TimeTicks& ticks) {
+ // Record the renderer main entry time, but don't log the UMA metric
+ // immediately because the startup temperature is not known yet.
+ if (g_renderer_main_entry_point_ticks.Get().is_null())
+ g_renderer_main_entry_point_ticks.Get() = ticks;
+}
+
void RecordFirstWebContentsMainFrameLoad(const base::TimeTicks& ticks) {
static bool is_first_call = true;
if (!is_first_call || ticks.is_null())
@@ -487,6 +514,11 @@ void RecordFirstWebContentsNonEmptyPaint(const base::TimeTicks& ticks) {
if (!is_first_call || ticks.is_null())
return;
is_first_call = false;
+
+ // Log Startup.BrowserMainToRendererMain now that the first renderer main
+ // entry time and the startup temperature are known.
+ RecordRendererMainEntryHistogram();
+
if (WasNonBrowserUIDisplayed() || g_process_creation_ticks.Get().is_null())
return;
@@ -539,7 +571,7 @@ void RecordFirstWebContentsMainNavigationFinished(
}
base::TimeTicks MainEntryPointTicks() {
- return g_main_entry_point_ticks.Get();
+ return g_browser_main_entry_point_ticks.Get();
}
StartupTemperature GetStartupTemperature() {
diff --git a/components/startup_metric_utils/browser/startup_metric_utils.h b/components/startup_metric_utils/browser/startup_metric_utils.h
index 2b2885f..0422f4f 100644
--- a/components/startup_metric_utils/browser/startup_metric_utils.h
+++ b/components/startup_metric_utils/browser/startup_metric_utils.h
@@ -72,6 +72,12 @@ void RecordBrowserWindowDisplay(const base::TimeTicks& ticks);
// Call this with the time delta that the browser spent opening its tabs.
void RecordBrowserOpenTabsDelta(const base::TimeDelta& delta);
+// Call this with a renderer main entry time. The value provided for the first
+// call to this function is used to compute
+// Startup.LoadTime.BrowserMainToRendererMain. Further calls to this
+// function are ignored.
+void RecordRendererMainEntryTime(const base::TimeTicks& ticks);
+
// Call this with the time when the first web contents loaded its main frame,
// only if the first web contents was unimpended in its attempt to do so.
void RecordFirstWebContentsMainFrameLoad(const base::TimeTicks& ticks);
diff --git a/components/startup_metric_utils/common/BUILD.gn b/components/startup_metric_utils/common/BUILD.gn
new file mode 100644
index 0000000..bfcb358
--- /dev/null
+++ b/components/startup_metric_utils/common/BUILD.gn
@@ -0,0 +1,16 @@
+# Copyright 2015 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.
+
+source_set("common") {
+ sources = [
+ "startup_metric_message_generator.cc",
+ "startup_metric_message_generator.h",
+ "startup_metric_messages.h",
+ ]
+
+ deps = [
+ "//base",
+ "//ipc",
+ ]
+}
diff --git a/components/startup_metric_utils/common/DEPS b/components/startup_metric_utils/common/DEPS
new file mode 100644
index 0000000..1c40d98
--- /dev/null
+++ b/components/startup_metric_utils/common/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+ipc",
+]
diff --git a/components/startup_metric_utils/common/startup_metric_message_generator.cc b/components/startup_metric_utils/common/startup_metric_message_generator.cc
new file mode 100644
index 0000000..dbd429c
--- /dev/null
+++ b/components/startup_metric_utils/common/startup_metric_message_generator.cc
@@ -0,0 +1,33 @@
+// Copyright 2015 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.
+
+// Get basic type definitions.
+#define IPC_MESSAGE_IMPL
+#include "components/startup_metric_utils/common/startup_metric_message_generator.h"
+
+// Generate constructors.
+#include "ipc/struct_constructor_macros.h"
+#include "components/startup_metric_utils/common/startup_metric_message_generator.h"
+
+// Generate destructors.
+#include "ipc/struct_destructor_macros.h"
+#include "components/startup_metric_utils/common/startup_metric_message_generator.h"
+
+// Generate param traits write methods.
+#include "ipc/param_traits_write_macros.h"
+namespace IPC {
+#include "components/startup_metric_utils/common/startup_metric_message_generator.h"
+} // namespace IPC
+
+// Generate param traits read methods.
+#include "ipc/param_traits_read_macros.h"
+namespace IPC {
+#include "components/startup_metric_utils/common/startup_metric_message_generator.h"
+} // namespace IPC
+
+// Generate param traits log methods.
+#include "ipc/param_traits_log_macros.h"
+namespace IPC {
+#include "components/startup_metric_utils/common/startup_metric_message_generator.h"
+} // namespace IPC
diff --git a/components/startup_metric_utils/common/startup_metric_message_generator.h b/components/startup_metric_utils/common/startup_metric_message_generator.h
new file mode 100644
index 0000000..090e3b0
--- /dev/null
+++ b/components/startup_metric_utils/common/startup_metric_message_generator.h
@@ -0,0 +1,7 @@
+// Copyright 2015 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.
+
+// Multiply-included file, hence no include guard.
+
+#include "components/startup_metric_utils/common/startup_metric_messages.h"
diff --git a/components/startup_metric_utils/common/startup_metric_messages.h b/components/startup_metric_utils/common/startup_metric_messages.h
new file mode 100644
index 0000000..a8e4548
--- /dev/null
+++ b/components/startup_metric_utils/common/startup_metric_messages.h
@@ -0,0 +1,13 @@
+// Copyright 2015 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.
+
+#include <stdint.h>
+
+#include "base/time/time.h"
+#include "ipc/ipc_message_macros.h"
+
+#define IPC_MESSAGE_START StartupMetricMsgStart
+
+IPC_MESSAGE_CONTROL1(StartupMetricHostMsg_RecordRendererMainEntryTime,
+ base::TimeTicks /* renderer_main_entry_time */)
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi
index 47448c2..6fc80be 100644
--- a/content/content_renderer.gypi
+++ b/content/content_renderer.gypi
@@ -8,6 +8,7 @@
'../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
'../cc/cc.gyp:cc',
'../cc/blink/cc_blink.gyp:cc_blink',
+ '../components/components.gyp:startup_metric_utils_common',
'../components/components.gyp:webusb',
'../components/scheduler/scheduler.gyp:scheduler',
'../components/url_formatter/url_formatter.gyp:url_formatter',
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index 7f56efb..42da81ac 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -29,6 +29,7 @@ source_set("renderer") {
"//cc",
"//cc/blink",
"//components/scheduler:scheduler",
+ "//components/startup_metric_utils/common",
"//components/url_formatter",
"//components/webusb",
"//content:resources",
diff --git a/content/renderer/DEPS b/content/renderer/DEPS
index 06e9940..e5367fc 100644
--- a/content/renderer/DEPS
+++ b/content/renderer/DEPS
@@ -5,6 +5,7 @@ include_rules = [
"+components/url_formatter",
"+cc/blink",
+ "+components/startup_metric_utils/common",
"+content/public/child",
"+content/public/renderer",
"+content/child",
diff --git a/content/renderer/renderer_main.cc b/content/renderer/renderer_main.cc
index 0f44527..ea7c913 100644
--- a/content/renderer/renderer_main.cc
+++ b/content/renderer/renderer_main.cc
@@ -16,9 +16,11 @@
#include "base/strings/string_util.h"
#include "base/sys_info.h"
#include "base/threading/platform_thread.h"
+#include "base/time/time.h"
#include "base/timer/hi_res_timer_manager.h"
#include "base/trace_event/trace_event.h"
#include "components/scheduler/renderer/renderer_scheduler.h"
+#include "components/startup_metric_utils/common/startup_metric_messages.h"
#include "content/child/child_process.h"
#include "content/common/content_constants_internal.h"
#include "content/public/common/content_switches.h"
@@ -82,6 +84,8 @@ int RendererMain(const MainFunctionParams& parameters) {
// expect synchronous events around the main loop of a thread.
TRACE_EVENT_ASYNC_BEGIN0("startup", "RendererMain", 0);
+ const base::TimeTicks renderer_main_entry_time = base::TimeTicks::Now();
+
base::trace_event::TraceLog::GetInstance()->SetProcessName("Renderer");
base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex(
kTraceEventRendererProcessSortIndex);
@@ -200,6 +204,10 @@ int RendererMain(const MainFunctionParams& parameters) {
RenderThreadImpl::Create(main_message_loop.Pass(),
renderer_scheduler.Pass());
#endif
+ RenderThreadImpl::current()->Send(
+ new StartupMetricHostMsg_RecordRendererMainEntryTime(
+ renderer_main_entry_time));
+
base::HighResolutionTimerManager hi_res_timer_manager;
if (run_loop) {
diff --git a/ipc/ipc_message_start.h b/ipc/ipc_message_start.h
index c151c547..82786b5 100644
--- a/ipc/ipc_message_start.h
+++ b/ipc/ipc_message_start.h
@@ -132,6 +132,7 @@ enum IPCMessageStart {
ArcInstanceMsgStart,
ArcInstanceHostMsgStart,
DistillerMsgStart,
+ StartupMetricMsgStart,
LastIPCMsgStart // Must come last.
};
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 83f6ec7..9880e2d 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -45069,6 +45069,14 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries.
</summary>
</histogram>
+<histogram name="Startup.BrowserMainToRendererMain" units="milliseconds">
+ <owner>fdoray@chromium.org</owner>
+ <summary>
+ Time from the ChromeMain() entry in the browser process to the first
+ RendererMain() entry.
+ </summary>
+</histogram>
+
<histogram name="Startup.BrowserMessageLoopStartHardFaultCount" units="faults">
<owner>chrisha@chromium.org</owner>
<summary>
@@ -82082,6 +82090,7 @@ To add a new entry, add it with any value and run test to compute valid value.
<histogram_suffixes name="StartupTemperature" separator=".">
<suffix name="ColdStartup" label="Startup was cold (mostly hard faults)."/>
<suffix name="WarmStartup" label="Startup was warm (almost no hard faults)."/>
+ <affected-histogram name="Startup.BrowserMainToRendererMain"/>
<affected-histogram name="Startup.BrowserMessageLoopStartTime"/>
<affected-histogram name="Startup.BrowserMessageLoopStartTimeFromMainEntry"/>
<affected-histogram