diff options
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 |