<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[210964] branches/safari-603-branch/Source</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/210964">210964</a></dd>
<dt>Author</dt> <dd>matthew_hanson@apple.com</dd>
<dt>Date</dt> <dd>2017-01-20 08:56:17 -0800 (Fri, 20 Jan 2017)</dd>
</dl>
<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/210936">r210936</a>. rdar://problem/30058349</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#branchessafari603branchSourceWebCoreCMakeListstxt">branches/safari-603-branch/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#branchessafari603branchSourceWebCoreChangeLog">branches/safari-603-branch/Source/WebCore/ChangeLog</a></li>
<li><a href="#branchessafari603branchSourceWebCoreWebCorexcodeprojprojectpbxproj">branches/safari-603-branch/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#branchessafari603branchSourceWebCorepageActivityStateh">branches/safari-603-branch/Source/WebCore/page/ActivityState.h</a></li>
<li><a href="#branchessafari603branchSourceWebCorepageChromeClienth">branches/safari-603-branch/Source/WebCore/page/ChromeClient.h</a></li>
<li><a href="#branchessafari603branchSourceWebCorepageDiagnosticLoggingKeyscpp">branches/safari-603-branch/Source/WebCore/page/DiagnosticLoggingKeys.cpp</a></li>
<li><a href="#branchessafari603branchSourceWebCorepageDiagnosticLoggingKeysh">branches/safari-603-branch/Source/WebCore/page/DiagnosticLoggingKeys.h</a></li>
<li><a href="#branchessafari603branchSourceWebCorepagePagecpp">branches/safari-603-branch/Source/WebCore/page/Page.cpp</a></li>
<li><a href="#branchessafari603branchSourceWebCorepagePageh">branches/safari-603-branch/Source/WebCore/page/Page.h</a></li>
<li><a href="#branchessafari603branchSourceWebCorepageSettingscpp">branches/safari-603-branch/Source/WebCore/page/Settings.cpp</a></li>
<li><a href="#branchessafari603branchSourceWebCorepageSettingsh">branches/safari-603-branch/Source/WebCore/page/Settings.h</a></li>
<li><a href="#branchessafari603branchSourceWebKit2ChangeLog">branches/safari-603-branch/Source/WebKit2/ChangeLog</a></li>
<li><a href="#branchessafari603branchSourceWebKit2PlatformLoggingh">branches/safari-603-branch/Source/WebKit2/Platform/Logging.h</a></li>
<li><a href="#branchessafari603branchSourceWebKit2UIProcessWebProcessPoolcpp">branches/safari-603-branch/Source/WebKit2/UIProcess/WebProcessPool.cpp</a></li>
<li><a href="#branchessafari603branchSourceWebKit2UIProcessWebProcessPoolh">branches/safari-603-branch/Source/WebKit2/UIProcess/WebProcessPool.h</a></li>
<li><a href="#branchessafari603branchSourceWebKit2UIProcessWebProcessPoolmessagesin">branches/safari-603-branch/Source/WebKit2/UIProcess/WebProcessPool.messages.in</a></li>
<li><a href="#branchessafari603branchSourceWebKit2WebKit2xcodeprojprojectpbxproj">branches/safari-603-branch/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj</a></li>
<li><a href="#branchessafari603branchSourceWebKit2WebProcessWebCoreSupportWebChromeClientcpp">branches/safari-603-branch/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp</a></li>
<li><a href="#branchessafari603branchSourceWebKit2WebProcessWebCoreSupportWebChromeClienth">branches/safari-603-branch/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#branchessafari603branchSourceWebCorepagePerformanceMonitorcpp">branches/safari-603-branch/Source/WebCore/page/PerformanceMonitor.cpp</a></li>
<li><a href="#branchessafari603branchSourceWebCorepagePerformanceMonitorh">branches/safari-603-branch/Source/WebCore/page/PerformanceMonitor.h</a></li>
<li><a href="#branchessafari603branchSourceWebKit2UIProcessPerActivityStateCPUUsageSamplercpp">branches/safari-603-branch/Source/WebKit2/UIProcess/PerActivityStateCPUUsageSampler.cpp</a></li>
<li><a href="#branchessafari603branchSourceWebKit2UIProcessPerActivityStateCPUUsageSamplerh">branches/safari-603-branch/Source/WebKit2/UIProcess/PerActivityStateCPUUsageSampler.h</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchessafari603branchSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/CMakeLists.txt (210963 => 210964)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/CMakeLists.txt        2017-01-20 16:25:55 UTC (rev 210963)
+++ branches/safari-603-branch/Source/WebCore/CMakeLists.txt        2017-01-20 16:56:17 UTC (rev 210964)
</span><span class="lines">@@ -2059,6 +2059,7 @@
</span><span class="cx"> page/Performance.cpp
</span><span class="cx"> page/PerformanceEntry.cpp
</span><span class="cx"> page/PerformanceLogging.cpp
</span><ins>+ page/PerformanceMonitor.cpp
</ins><span class="cx"> page/PerformanceNavigation.cpp
</span><span class="cx"> page/PerformanceResourceTiming.cpp
</span><span class="cx"> page/PerformanceTiming.cpp
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/ChangeLog (210963 => 210964)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/ChangeLog        2017-01-20 16:25:55 UTC (rev 210963)
+++ branches/safari-603-branch/Source/WebCore/ChangeLog        2017-01-20 16:56:17 UTC (rev 210964)
</span><span class="lines">@@ -1,5 +1,59 @@
</span><span class="cx"> 2017-01-20 Matthew Hanson <matthew_hanson@apple.com>
</span><span class="cx">
</span><ins>+ Merge r210936. rdar://problem/30058349
+
+ 2017-01-19 Chris Dumez <cdumez@apple.com>
+
+ Implement per activity state CPU usage reporting using diagnostic logging
+ https://bugs.webkit.org/show_bug.cgi?id=167163
+ <rdar://problem/30058349>
+
+ Reviewed by Andreas Kling.
+
+ Implement per activity state CPU usage reporting using diagnostic logging.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * page/ActivityState.h:
+ * page/ChromeClient.h:
+ * page/DiagnosticLoggingKeys.cpp:
+ (WebCore::DiagnosticLoggingKeys::nonVisibleStateKey):
+ (WebCore::DiagnosticLoggingKeys::visibleNonActiveStateKey):
+ (WebCore::DiagnosticLoggingKeys::visibleAndActiveStateKey):
+ (WebCore::DiagnosticLoggingKeys::foregroundCPUUsageToDiagnosticLogginKey):
+ (WebCore::DiagnosticLoggingKeys::backgroundCPUUsageToDiagnosticLogginKey):
+ * page/DiagnosticLoggingKeys.h:
+ * page/Page.cpp:
+ (WebCore::isUtilityPageChromeClient):
+ (WebCore::Page::Page):
+ (WebCore::Page::~Page):
+ (WebCore::Page::didStartProvisionalLoad):
+ (WebCore::Page::didFinishLoad):
+ (WebCore::Page::isUtilityPage):
+ (WebCore::Page::setActivityState):
+ (WebCore::Page::setIsVisibleInternal):
+ * page/Page.h:
+ (WebCore::Page::activityState):
+ (WebCore::Page::isUtilityPage):
+ * page/PerformanceMonitor.cpp: Added.
+ (WebCore::activityStateForCPUSampling):
+ (WebCore::PerformanceMonitor::PerformanceMonitor):
+ (WebCore::PerformanceMonitor::didStartProvisionalLoad):
+ (WebCore::PerformanceMonitor::didFinishLoad):
+ (WebCore::PerformanceMonitor::activityStateChanged):
+ (WebCore::PerformanceMonitor::measurePostLoadCPUUsage):
+ (WebCore::PerformanceMonitor::measurePostBackgroundingCPUUsage):
+ (WebCore::PerformanceMonitor::measurePerActivityStateCPUUsage):
+ (WebCore::stringForCPUSamplingActivityState):
+ (WebCore::PerformanceMonitor::measureCPUUsageInActivityState):
+ * page/PerformanceMonitor.h: Copied from Source/WebCore/page/ActivityState.h.
+ * page/Settings.cpp:
+ * page/Settings.h:
+ (WebCore::Settings::isPostLoadCPUUsageMeasurementEnabled):
+ (WebCore::Settings::isPostBackgroundingCPUUsageMeasurementEnabled):
+ (WebCore::Settings::isPerActivityStateCPUUsageMeasurementEnabled):
+
+2017-01-20 Matthew Hanson <matthew_hanson@apple.com>
+
</ins><span class="cx"> Merge r210473. rdar://problem/29204422
</span><span class="cx">
</span><span class="cx"> 2017-01-06 Jer Noble <jer.noble@apple.com>
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/WebCore.xcodeproj/project.pbxproj (210963 => 210964)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2017-01-20 16:25:55 UTC (rev 210963)
+++ branches/safari-603-branch/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2017-01-20 16:56:17 UTC (rev 210964)
</span><span class="lines">@@ -3073,6 +3073,8 @@
</span><span class="cx">                 83F1206B1B8C104700D75F63 /* JSNodeFilterCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83F1206A1B8C103600D75F63 /* JSNodeFilterCustom.cpp */; };
</span><span class="cx">                 83FE7CA71DA9F1A70037237C /* UIEventInit.h in Headers */ = {isa = PBXBuildFile; fileRef = 83FE7CA41DA9F1660037237C /* UIEventInit.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 83FE7CA81DA9F1B60037237C /* EventModifierInit.h in Headers */ = {isa = PBXBuildFile; fileRef = 83FE7CA31DA9F1650037237C /* EventModifierInit.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                83FE90271E307C30003E9199 /* PerformanceMonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 83FE90261E307C1C003E9199 /* PerformanceMonitor.h */; };
+                83FE90281E307C33003E9199 /* PerformanceMonitor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83FE90251E307C1C003E9199 /* PerformanceMonitor.cpp */; };
</ins><span class="cx">                 8419D2A7120D92D000141F8F /* SVGPathByteStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 8419D2A4120D92D000141F8F /* SVGPathByteStream.h */; };
</span><span class="cx">                 8419D2A8120D92D000141F8F /* SVGPathByteStreamBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8419D2A5120D92D000141F8F /* SVGPathByteStreamBuilder.cpp */; };
</span><span class="cx">                 8419D2A9120D92D000141F8F /* SVGPathByteStreamBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 8419D2A6120D92D000141F8F /* SVGPathByteStreamBuilder.h */; };
</span><span class="lines">@@ -10626,6 +10628,8 @@
</span><span class="cx">                 83FE7CA41DA9F1660037237C /* UIEventInit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIEventInit.h; sourceTree = "<group>"; };
</span><span class="cx">                 83FE7CA51DA9F1660037237C /* UIEventInit.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = UIEventInit.idl; sourceTree = "<group>"; };
</span><span class="cx">                 83FE7CA61DA9F1660037237C /* EventModifierInit.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = EventModifierInit.idl; sourceTree = "<group>"; };
</span><ins>+                83FE90251E307C1C003E9199 /* PerformanceMonitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PerformanceMonitor.cpp; sourceTree = "<group>"; };
+                83FE90261E307C1C003E9199 /* PerformanceMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PerformanceMonitor.h; sourceTree = "<group>"; };
</ins><span class="cx">                 8419D2A4120D92D000141F8F /* SVGPathByteStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGPathByteStream.h; sourceTree = "<group>"; };
</span><span class="cx">                 8419D2A5120D92D000141F8F /* SVGPathByteStreamBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGPathByteStreamBuilder.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 8419D2A6120D92D000141F8F /* SVGPathByteStreamBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGPathByteStreamBuilder.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -18057,6 +18061,8 @@
</span><span class="cx">                                 86BE33FC15058CB200CE0FD8 /* PerformanceEntry.idl */,
</span><span class="cx">                                 AD5A0C211DECA10100707054 /* PerformanceLogging.cpp */,
</span><span class="cx">                                 AD5A0C201DECA0B500707054 /* PerformanceLogging.h */,
</span><ins>+                                83FE90251E307C1C003E9199 /* PerformanceMonitor.cpp */,
+                                83FE90261E307C1C003E9199 /* PerformanceMonitor.h */,
</ins><span class="cx">                                 8AF4E55211DC5A36000ED3DE /* PerformanceNavigation.cpp */,
</span><span class="cx">                                 8AF4E55311DC5A36000ED3DE /* PerformanceNavigation.h */,
</span><span class="cx">                                 8AF4E55411DC5A36000ED3DE /* PerformanceNavigation.idl */,
</span><span class="lines">@@ -26752,6 +26758,7 @@
</span><span class="cx">                                 85031B440A44EFC700F992E0 /* KeyboardEvent.h in Headers */,
</span><span class="cx">                                 1AE00D59182DAC8D00087DD7 /* KeyedCoding.h in Headers */,
</span><span class="cx">                                 517A63C51B74318F00E7DCDC /* KeyedDecoderCF.h in Headers */,
</span><ins>+                                83FE90271E307C30003E9199 /* PerformanceMonitor.h in Headers */,
</ins><span class="cx">                                 517A63C61B74319200E7DCDC /* KeyedEncoderCF.h in Headers */,
</span><span class="cx">                                 A513B3D7114B1666001C429B /* KeyEventCocoa.h in Headers */,
</span><span class="cx">                                 265541391489811C000DFC5D /* KeyEventCodesIOS.h in Headers */,
</span><span class="lines">@@ -31178,6 +31185,7 @@
</span><span class="cx">                                 073BE34E17D180B2002BD431 /* RTCSessionDescriptionDescriptor.cpp in Sources */,
</span><span class="cx">                                 078E090E17D14CEE00420AA1 /* RTCStatsReport.cpp in Sources */,
</span><span class="cx">                                 078E091017D14CEE00420AA1 /* RTCStatsResponse.cpp in Sources */,
</span><ins>+                                83FE90281E307C33003E9199 /* PerformanceMonitor.cpp in Sources */,
</ins><span class="cx">                                 5E2C43671BCEE3770001E2BC /* RTCTrackEvent.cpp in Sources */,
</span><span class="cx">                                 5824ABA21AE81116009074B7 /* RubyElement.cpp in Sources */,
</span><span class="cx">                                 5824ABA61AE81384009074B7 /* RubyTextElement.cpp in Sources */,
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCorepageActivityStateh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/page/ActivityState.h (210963 => 210964)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/page/ActivityState.h        2017-01-20 16:25:55 UTC (rev 210963)
+++ branches/safari-603-branch/Source/WebCore/page/ActivityState.h        2017-01-20 16:56:17 UTC (rev 210964)
</span><span class="lines">@@ -45,4 +45,10 @@
</span><span class="cx"> static const Flags AllFlags = WindowIsActive | IsFocused | IsVisible | IsVisibleOrOccluded | IsInWindow | IsVisuallyIdle | IsAudible | IsLoading;
</span><span class="cx"> };
</span><span class="cx">
</span><ins>+enum class ActivityStateForCPUSampling {
+ NonVisible,
+ VisibleNonActive,
+ VisibleAndActive
+};
+
</ins><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCorepageChromeClienth"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/page/ChromeClient.h (210963 => 210964)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/page/ChromeClient.h        2017-01-20 16:25:55 UTC (rev 210963)
+++ branches/safari-603-branch/Source/WebCore/page/ChromeClient.h        2017-01-20 16:56:17 UTC (rev 210964)
</span><span class="lines">@@ -21,6 +21,7 @@
</span><span class="cx">
</span><span class="cx"> #pragma once
</span><span class="cx">
</span><ins>+#include "ActivityState.h"
</ins><span class="cx"> #include "AXObjectCache.h"
</span><span class="cx"> #include "Cursor.h"
</span><span class="cx"> #include "DatabaseDetails.h"
</span><span class="lines">@@ -460,6 +461,8 @@
</span><span class="cx">
</span><span class="cx"> virtual void didInvalidateDocumentMarkerRects() { }
</span><span class="cx">
</span><ins>+ virtual void reportProcessCPUTime(int64_t, ActivityStateForCPUSampling) { }
+
</ins><span class="cx"> protected:
</span><span class="cx"> virtual ~ChromeClient() { }
</span><span class="cx"> };
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCorepageDiagnosticLoggingKeyscpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/page/DiagnosticLoggingKeys.cpp (210963 => 210964)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/page/DiagnosticLoggingKeys.cpp        2017-01-20 16:25:55 UTC (rev 210963)
+++ branches/safari-603-branch/Source/WebCore/page/DiagnosticLoggingKeys.cpp        2017-01-20 16:56:17 UTC (rev 210964)
</span><span class="lines">@@ -163,6 +163,11 @@
</span><span class="cx"> return ASCIILiteral("noStore");
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+String DiagnosticLoggingKeys::nonVisibleStateKey()
+{
+ return ASCIILiteral("nonVisibleState");
+}
+
</ins><span class="cx"> String DiagnosticLoggingKeys::notInMemoryCacheKey()
</span><span class="cx"> {
</span><span class="cx"> return ASCIILiteral("notInMemoryCache");
</span><span class="lines">@@ -598,6 +603,16 @@
</span><span class="cx"> return ASCIILiteral("video");
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+String DiagnosticLoggingKeys::visibleNonActiveStateKey()
+{
+ return ASCIILiteral("visibleNonActiveState");
+}
+
+String DiagnosticLoggingKeys::visibleAndActiveStateKey()
+{
+ return ASCIILiteral("visibleAndActiveState");
+}
+
</ins><span class="cx"> String DiagnosticLoggingKeys::wastedSpeculativeWarmupWithRevalidationKey()
</span><span class="cx"> {
</span><span class="cx"> return ASCIILiteral("wastedSpeculativeWarmupWithRevalidation");
</span><span class="lines">@@ -658,5 +673,37 @@
</span><span class="cx"> return ASCIILiteral("webGL");
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+String DiagnosticLoggingKeys::foregroundCPUUsageToDiagnosticLoggingKey(double cpuUsage)
+{
+ if (cpuUsage < 10)
+ return ASCIILiteral("Below10");
+ if (cpuUsage < 20)
+ return ASCIILiteral("10to20");
+ if (cpuUsage < 40)
+ return ASCIILiteral("20to40");
+ if (cpuUsage < 60)
+ return ASCIILiteral("40to60");
+ if (cpuUsage < 80)
+ return ASCIILiteral("60to80");
+ return ASCIILiteral("over80");
+}
+
+String DiagnosticLoggingKeys::backgroundCPUUsageToDiagnosticLoggingKey(double cpuUsage)
+{
+ if (cpuUsage < 1)
+ return ASCIILiteral("Below1");
+ if (cpuUsage < 5)
+ return ASCIILiteral("1to5");
+ if (cpuUsage < 10)
+ return ASCIILiteral("5to10");
+ if (cpuUsage < 30)
+ return ASCIILiteral("10to30");
+ if (cpuUsage < 50)
+ return ASCIILiteral("30to50");
+ if (cpuUsage < 70)
+ return ASCIILiteral("50to70");
+ return ASCIILiteral("over70");
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx">
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCorepageDiagnosticLoggingKeysh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/page/DiagnosticLoggingKeys.h (210963 => 210964)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/page/DiagnosticLoggingKeys.h        2017-01-20 16:25:55 UTC (rev 210963)
+++ branches/safari-603-branch/Source/WebCore/page/DiagnosticLoggingKeys.h        2017-01-20 16:56:17 UTC (rev 210964)
</span><span class="lines">@@ -40,7 +40,7 @@
</span><span class="cx"> static String cachedResourceRevalidationKey();
</span><span class="cx"> static String canCacheKey();
</span><span class="cx"> static String cannotSuspendActiveDOMObjectsKey();
</span><del>- static String cpuUsageKey();
</del><ins>+ WEBCORE_EXPORT static String cpuUsageKey();
</ins><span class="cx"> WEBCORE_EXPORT static String createSharedBufferFailedKey();
</span><span class="cx"> WEBCORE_EXPORT static String deltaKey();
</span><span class="cx"> static String deniedByClientKey();
</span><span class="lines">@@ -88,6 +88,7 @@
</span><span class="cx"> static String noDocumentLoaderKey();
</span><span class="cx"> WEBCORE_EXPORT static String noLongerInCacheKey();
</span><span class="cx"> static String noStoreKey();
</span><ins>+ WEBCORE_EXPORT static String nonVisibleStateKey();
</ins><span class="cx"> WEBCORE_EXPORT static String notHTTPFamilyKey();
</span><span class="cx"> WEBCORE_EXPORT static String notInCacheKey();
</span><span class="cx"> static String notInMemoryCacheKey();
</span><span class="lines">@@ -150,6 +151,8 @@
</span><span class="cx"> WEBCORE_EXPORT static String userKey();
</span><span class="cx"> WEBCORE_EXPORT static String varyingHeaderMismatchKey();
</span><span class="cx"> static String videoKey();
</span><ins>+ WEBCORE_EXPORT static String visibleNonActiveStateKey();
+ WEBCORE_EXPORT static String visibleAndActiveStateKey();
</ins><span class="cx"> WEBCORE_EXPORT static String wastedSpeculativeWarmupWithRevalidationKey();
</span><span class="cx"> WEBCORE_EXPORT static String wastedSpeculativeWarmupWithoutRevalidationKey();
</span><span class="cx"> WEBCORE_EXPORT static String webGLKey();
</span><span class="lines">@@ -156,6 +159,9 @@
</span><span class="cx"> WEBCORE_EXPORT static String webViewKey();
</span><span class="cx"> WEBCORE_EXPORT static String zoomedKey();
</span><span class="cx">
</span><ins>+ WEBCORE_EXPORT static String foregroundCPUUsageToDiagnosticLoggingKey(double cpuUsage);
+ WEBCORE_EXPORT static String backgroundCPUUsageToDiagnosticLoggingKey(double cpuUsage);
+
</ins><span class="cx"> // Success / Failure keys.
</span><span class="cx"> static String successKey();
</span><span class="cx"> static String failureKey();
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCorepagePagecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/page/Page.cpp (210963 => 210964)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/page/Page.cpp        2017-01-20 16:25:55 UTC (rev 210963)
+++ branches/safari-603-branch/Source/WebCore/page/Page.cpp        2017-01-20 16:56:17 UTC (rev 210964)
</span><span class="lines">@@ -66,6 +66,7 @@
</span><span class="cx"> #include "PageDebuggable.h"
</span><span class="cx"> #include "PageGroup.h"
</span><span class="cx"> #include "PageOverlayController.h"
</span><ins>+#include "PerformanceMonitor.h"
</ins><span class="cx"> #include "PlatformMediaSessionManager.h"
</span><span class="cx"> #include "PlugInClient.h"
</span><span class="cx"> #include "PluginData.h"
</span><span class="lines">@@ -126,13 +127,13 @@
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><del>-#define RELEASE_LOG_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_IF(isAlwaysOnLoggingAllowed(), channel, "%p - Page::" fmt, this, ##__VA_ARGS__)
-
</del><span class="cx"> static HashSet<Page*>* allPages;
</span><ins>+static unsigned nonUtilityPageCount { 0 };
</ins><span class="cx">
</span><del>-static const std::chrono::seconds cpuUsageMeasurementDelay { 5 };
-static const std::chrono::seconds postLoadCPUUsageMeasurementDuration { 10 };
-static const std::chrono::minutes backgroundCPUUsageMeasurementDuration { 5 };
</del><ins>+static inline bool isUtilityPageChromeClient(ChromeClient& chromeClient)
+{
+ return chromeClient.isEmptyChromeClient() || chromeClient.isSVGImageChromeClient();
+}
</ins><span class="cx">
</span><span class="cx"> DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, pageCounter, ("Page"));
</span><span class="cx">
</span><span class="lines">@@ -252,8 +253,8 @@
</span><span class="cx"> , m_visitedLinkStore(*WTFMove(pageConfiguration.visitedLinkStore))
</span><span class="cx"> , m_sessionID(SessionID::defaultSessionID())
</span><span class="cx"> , m_isClosing(false)
</span><del>- , m_postPageLoadCPUUsageTimer(*this, &Page::measurePostLoadCPUUsage)
- , m_postBackgroundingCPUUsageTimer(*this, &Page::measurePostBackgroundingCPUUsage)
</del><ins>+ , m_isUtilityPage(isUtilityPageChromeClient(chrome().client()))
+ , m_performanceMonitor(isUtilityPage() ? nullptr : std::make_unique<PerformanceMonitor>(*this))
</ins><span class="cx"> {
</span><span class="cx"> updateTimerThrottlingState();
</span><span class="cx">
</span><span class="lines">@@ -270,6 +271,8 @@
</span><span class="cx">
</span><span class="cx"> ASSERT(!allPages->contains(this));
</span><span class="cx"> allPages->add(this);
</span><ins>+ if (!isUtilityPage())
+ ++nonUtilityPageCount;
</ins><span class="cx">
</span><span class="cx"> #ifndef NDEBUG
</span><span class="cx"> pageCounter.increment();
</span><span class="lines">@@ -294,6 +297,8 @@
</span><span class="cx"> m_mainFrame->setView(nullptr);
</span><span class="cx"> setGroupName(String());
</span><span class="cx"> allPages->remove(this);
</span><ins>+ if (!isUtilityPage())
+ --nonUtilityPageCount;
</ins><span class="cx">
</span><span class="cx"> m_settings->pageDestroyed();
</span><span class="cx">
</span><span class="lines">@@ -937,8 +942,8 @@
</span><span class="cx">
</span><span class="cx"> void Page::didStartProvisionalLoad()
</span><span class="cx"> {
</span><del>- m_postLoadCPUTime = std::nullopt;
- m_postPageLoadCPUUsageTimer.stop();
</del><ins>+ if (m_performanceMonitor)
+ m_performanceMonitor->didStartProvisionalLoad();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void Page::didFinishLoad()
</span><span class="lines">@@ -945,85 +950,15 @@
</span><span class="cx"> {
</span><span class="cx"> resetRelevantPaintedObjectCounter();
</span><span class="cx">
</span><del>- // Only do post-load CPU usage measurement if there is a single Page in the process in order to reduce noise.
- if (Settings::isPostLoadCPUUsageMeasurementEnabled() && allPages->size() == 1) {
- m_postLoadCPUTime = std::nullopt;
- m_postPageLoadCPUUsageTimer.startOneShot(cpuUsageMeasurementDelay);
- }
</del><ins>+ if (m_performanceMonitor)
+ m_performanceMonitor->didFinishLoad();
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-static String foregroundCPUUsageToDiagnosticLogginKey(double cpuUsage)
</del><ins>+bool Page::isOnlyNonUtilityPage() const
</ins><span class="cx"> {
</span><del>- if (cpuUsage < 10)
- return ASCIILiteral("Below10");
- if (cpuUsage < 20)
- return ASCIILiteral("10to20");
- if (cpuUsage < 40)
- return ASCIILiteral("20to40");
- if (cpuUsage < 60)
- return ASCIILiteral("40to60");
- if (cpuUsage < 80)
- return ASCIILiteral("60to80");
- return ASCIILiteral("over80");
</del><ins>+ return !isUtilityPage() && nonUtilityPageCount == 1;
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-void Page::measurePostLoadCPUUsage()
-{
- if (allPages->size() != 1)
- return;
-
- if (!m_postLoadCPUTime) {
- m_postLoadCPUTime = getCPUTime();
- if (m_postLoadCPUTime)
- m_postPageLoadCPUUsageTimer.startOneShot(postLoadCPUUsageMeasurementDuration);
- return;
- }
- std::optional<CPUTime> cpuTime = getCPUTime();
- if (!cpuTime)
- return;
-
- double cpuUsage = cpuTime.value().percentageCPUUsageSince(*m_postLoadCPUTime);
- RELEASE_LOG_IF_ALLOWED(PerformanceLogging, "measurePostLoadCPUUsage: Process was using %.1f%% percent CPU after the page load.", cpuUsage);
- diagnosticLoggingClient().logDiagnosticMessageWithValue(DiagnosticLoggingKeys::postPageLoadKey(), DiagnosticLoggingKeys::cpuUsageKey(), foregroundCPUUsageToDiagnosticLogginKey(cpuUsage), ShouldSample::No);
-}
-
-static String backgroundCPUUsageToDiagnosticLogginKey(double cpuUsage)
-{
- if (cpuUsage < 1)
- return ASCIILiteral("Below1");
- if (cpuUsage < 5)
- return ASCIILiteral("1to5");
- if (cpuUsage < 10)
- return ASCIILiteral("5to10");
- if (cpuUsage < 30)
- return ASCIILiteral("10to30");
- if (cpuUsage < 50)
- return ASCIILiteral("30to50");
- if (cpuUsage < 70)
- return ASCIILiteral("50to70");
- return ASCIILiteral("over70");
-}
-
-void Page::measurePostBackgroundingCPUUsage()
-{
- if (allPages->size() != 1)
- return;
-
- if (!m_postBackgroundingCPUTime) {
- m_postBackgroundingCPUTime = getCPUTime();
- if (m_postBackgroundingCPUTime)
- m_postBackgroundingCPUUsageTimer.startOneShot(backgroundCPUUsageMeasurementDuration);
- return;
- }
- std::optional<CPUTime> cpuTime = getCPUTime();
- if (!cpuTime)
- return;
-
- double cpuUsage = cpuTime.value().percentageCPUUsageSince(*m_postBackgroundingCPUTime);
- RELEASE_LOG_IF_ALLOWED(PerformanceLogging, "measurePostBackgroundingCPUUsage: Process was using %.1f%% percent CPU after becoming non visible.", cpuUsage);
- diagnosticLoggingClient().logDiagnosticMessageWithValue(DiagnosticLoggingKeys::postPageBackgroundingKey(), DiagnosticLoggingKeys::cpuUsageKey(), backgroundCPUUsageToDiagnosticLogginKey(cpuUsage), ShouldSample::No);
-}
-
</del><span class="cx"> void Page::setTopContentInset(float contentInset)
</span><span class="cx"> {
</span><span class="cx"> if (m_topContentInset == contentInset)
</span><span class="lines">@@ -1576,6 +1511,9 @@
</span><span class="cx">
</span><span class="cx"> if (wasVisibleAndActive != isVisibleAndActive())
</span><span class="cx"> PlatformMediaSessionManager::updateNowPlayingInfoIfNecessary();
</span><ins>+
+ if (m_performanceMonitor)
+ m_performanceMonitor->activityStateChanged(oldActivityState, activityState);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> bool Page::isVisibleAndActive() const
</span><span class="lines">@@ -1632,13 +1570,6 @@
</span><span class="cx"> if (FrameView* view = mainFrame().view())
</span><span class="cx"> view->hide();
</span><span class="cx"> }
</span><del>-
- // Measure CPU usage of pages when they are no longer visible.
- m_postBackgroundingCPUTime = std::nullopt;
- if (isVisible)
- m_postBackgroundingCPUUsageTimer.stop();
- else if (Settings::isPostBackgroundingCPUUsageMeasurementEnabled() && allPages->size() == 1)
- m_postBackgroundingCPUUsageTimer.startOneShot(cpuUsageMeasurementDelay);
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void Page::setIsPrerender()
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCorepagePageh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/page/Page.h (210963 => 210964)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/page/Page.h        2017-01-20 16:25:55 UTC (rev 210963)
+++ branches/safari-603-branch/Source/WebCore/page/Page.h        2017-01-20 16:56:17 UTC (rev 210964)
</span><span class="lines">@@ -21,7 +21,6 @@
</span><span class="cx"> #pragma once
</span><span class="cx">
</span><span class="cx"> #include "ActivityState.h"
</span><del>-#include "CPUTime.h"
</del><span class="cx"> #include "FindOptions.h"
</span><span class="cx"> #include "FrameLoaderTypes.h"
</span><span class="cx"> #include "LayoutMilestones.h"
</span><span class="lines">@@ -105,6 +104,7 @@
</span><span class="cx"> class PageConsoleClient;
</span><span class="cx"> class PageDebuggable;
</span><span class="cx"> class PageGroup;
</span><ins>+class PerformanceMonitor;
</ins><span class="cx"> class PlugInClient;
</span><span class="cx"> class PluginData;
</span><span class="cx"> class PluginInfoProvider;
</span><span class="lines">@@ -357,6 +357,8 @@
</span><span class="cx">
</span><span class="cx"> // Notifications when the Page starts and stops being presented via a native window.
</span><span class="cx"> WEBCORE_EXPORT void setActivityState(ActivityState::Flags);
</span><ins>+ ActivityState::Flags activityState() const { return m_activityState; }
+
</ins><span class="cx"> bool isVisibleAndActive() const;
</span><span class="cx"> WEBCORE_EXPORT void setIsVisible(bool);
</span><span class="cx"> WEBCORE_EXPORT void setIsPrerender();
</span><span class="lines">@@ -559,6 +561,10 @@
</span><span class="cx"> void setEventThrottlingBehaviorOverride(std::optional<EventThrottlingBehavior> throttling) { m_eventThrottlingBehaviorOverride = throttling; }
</span><span class="cx">
</span><span class="cx"> WebGLStateTracker* webGLStateTracker() const { return m_webGLStateTracker.get(); }
</span><ins>+
+ bool isOnlyNonUtilityPage() const;
+ bool isUtilityPage() const { return m_isUtilityPage; }
+
</ins><span class="cx"> private:
</span><span class="cx"> WEBCORE_EXPORT void initGroup();
</span><span class="cx">
</span><span class="lines">@@ -572,9 +578,6 @@
</span><span class="cx"> void checkSubframeCountConsistency() const;
</span><span class="cx"> #endif
</span><span class="cx">
</span><del>- void measurePostLoadCPUUsage();
- void measurePostBackgroundingCPUUsage();
-
</del><span class="cx"> enum ShouldHighlightMatches { DoNotHighlightMatches, HighlightMatches };
</span><span class="cx"> enum ShouldMarkMatches { DoNotMarkMatches, MarkMatches };
</span><span class="cx">
</span><span class="lines">@@ -756,15 +759,13 @@
</span><span class="cx"> bool m_showAllPlugins { false };
</span><span class="cx"> bool m_controlledByAutomation { false };
</span><span class="cx"> bool m_resourceCachingDisabled { false };
</span><ins>+ bool m_isUtilityPage;
</ins><span class="cx"> UserInterfaceLayoutDirection m_userInterfaceLayoutDirection { UserInterfaceLayoutDirection::LTR };
</span><span class="cx">
</span><span class="cx"> // For testing.
</span><span class="cx"> std::optional<EventThrottlingBehavior> m_eventThrottlingBehaviorOverride;
</span><span class="cx">
</span><del>- Timer m_postPageLoadCPUUsageTimer;
- std::optional<CPUTime> m_postLoadCPUTime;
- Timer m_postBackgroundingCPUUsageTimer;
- std::optional<CPUTime> m_postBackgroundingCPUTime;
</del><ins>+ std::unique_ptr<PerformanceMonitor> m_performanceMonitor;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> inline PageGroup& Page::group()
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCorepagePerformanceMonitorcpp"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/Source/WebCore/page/PerformanceMonitor.cpp (0 => 210964)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/page/PerformanceMonitor.cpp         (rev 0)
+++ branches/safari-603-branch/Source/WebCore/page/PerformanceMonitor.cpp        2017-01-20 16:56:17 UTC (rev 210964)
</span><span class="lines">@@ -0,0 +1,200 @@
</span><ins>+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PerformanceMonitor.h"
+
+#include "Chrome.h"
+#include "ChromeClient.h"
+#include "DiagnosticLoggingClient.h"
+#include "DiagnosticLoggingKeys.h"
+#include "Logging.h"
+#include "Page.h"
+#include "Settings.h"
+
+namespace WebCore {
+
+#define RELEASE_LOG_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_IF(m_page.isAlwaysOnLoggingAllowed(), channel, "%p - PerformanceMonitor::" fmt, this, ##__VA_ARGS__)
+
+static const std::chrono::seconds cpuUsageMeasurementDelay { 5 };
+static const std::chrono::seconds postLoadCPUUsageMeasurementDuration { 10 };
+static const std::chrono::minutes backgroundCPUUsageMeasurementDuration { 5 };
+static const std::chrono::minutes cpuUsageSamplingInterval { 10 };
+
+static inline ActivityStateForCPUSampling activityStateForCPUSampling(ActivityState::Flags state)
+{
+ if (!(state & ActivityState::IsVisible))
+ return ActivityStateForCPUSampling::NonVisible;
+ if (state & ActivityState::WindowIsActive)
+ return ActivityStateForCPUSampling::VisibleAndActive;
+ return ActivityStateForCPUSampling::VisibleNonActive;
+}
+
+PerformanceMonitor::PerformanceMonitor(Page& page)
+ : m_page(page)
+ , m_postPageLoadCPUUsageTimer(*this, &PerformanceMonitor::measurePostLoadCPUUsage)
+ , m_postBackgroundingCPUUsageTimer(*this, &PerformanceMonitor::measurePostBackgroundingCPUUsage)
+ , m_perActivityStateCPUUsageTimer(*this, &PerformanceMonitor::measurePerActivityStateCPUUsage)
+{
+ ASSERT(!page.isUtilityPage());
+
+ if (Settings::isPerActivityStateCPUUsageMeasurementEnabled()) {
+ m_perActivityStateCPUTime = getCPUTime();
+ m_perActivityStateCPUUsageTimer.startRepeating(cpuUsageSamplingInterval);
+ }
+}
+
+void PerformanceMonitor::didStartProvisionalLoad()
+{
+ m_postLoadCPUTime = std::nullopt;
+ m_postPageLoadCPUUsageTimer.stop();
+}
+
+void PerformanceMonitor::didFinishLoad()
+{
+ // Only do post-load CPU usage measurement if there is a single Page in the process in order to reduce noise.
+ if (Settings::isPostLoadCPUUsageMeasurementEnabled() && m_page.isOnlyNonUtilityPage()) {
+ m_postLoadCPUTime = std::nullopt;
+ m_postPageLoadCPUUsageTimer.startOneShot(cpuUsageMeasurementDelay);
+ }
+}
+
+void PerformanceMonitor::activityStateChanged(ActivityState::Flags oldState, ActivityState::Flags newState)
+{
+ ActivityState::Flags changed = oldState ^ newState;
+ bool visibilityChanged = changed & ActivityState::IsVisible;
+
+ // Measure CPU usage of pages when they are no longer visible.
+ if (Settings::isPostBackgroundingCPUUsageMeasurementEnabled() && visibilityChanged) {
+ m_postBackgroundingCPUTime = std::nullopt;
+ if (newState & ActivityState::IsVisible)
+ m_postBackgroundingCPUUsageTimer.stop();
+ else if (m_page.isOnlyNonUtilityPage())
+ m_postBackgroundingCPUUsageTimer.startOneShot(cpuUsageMeasurementDelay);
+ }
+
+ if (Settings::isPerActivityStateCPUUsageMeasurementEnabled()) {
+ // If visibility changed then report CPU usage right away because CPU usage is connected to visibility state.
+ auto oldActivityStateForCPUSampling = activityStateForCPUSampling(oldState);
+ if (oldActivityStateForCPUSampling != activityStateForCPUSampling(newState)) {
+ measureCPUUsageInActivityState(oldActivityStateForCPUSampling);
+ m_perActivityStateCPUUsageTimer.startRepeating(cpuUsageSamplingInterval);
+ }
+ }
+}
+
+void PerformanceMonitor::measurePostLoadCPUUsage()
+{
+ if (!m_page.isOnlyNonUtilityPage()) {
+ m_postLoadCPUTime = std::nullopt;
+ return;
+ }
+
+ if (!m_postLoadCPUTime) {
+ m_postLoadCPUTime = getCPUTime();
+ if (m_postLoadCPUTime)
+ m_postPageLoadCPUUsageTimer.startOneShot(postLoadCPUUsageMeasurementDuration);
+ return;
+ }
+ std::optional<CPUTime> cpuTime = getCPUTime();
+ if (!cpuTime)
+ return;
+
+ double cpuUsage = cpuTime.value().percentageCPUUsageSince(*m_postLoadCPUTime);
+ RELEASE_LOG_IF_ALLOWED(PerformanceLogging, "measurePostLoadCPUUsage: Process was using %.1f%% CPU after the page load.", cpuUsage);
+ m_page.diagnosticLoggingClient().logDiagnosticMessageWithValue(DiagnosticLoggingKeys::postPageLoadKey(), DiagnosticLoggingKeys::cpuUsageKey(), DiagnosticLoggingKeys::foregroundCPUUsageToDiagnosticLoggingKey(cpuUsage), ShouldSample::No);
+}
+
+void PerformanceMonitor::measurePostBackgroundingCPUUsage()
+{
+ if (!m_page.isOnlyNonUtilityPage()) {
+ m_postBackgroundingCPUTime = std::nullopt;
+ return;
+ }
+
+ if (!m_postBackgroundingCPUTime) {
+ m_postBackgroundingCPUTime = getCPUTime();
+ if (m_postBackgroundingCPUTime)
+ m_postBackgroundingCPUUsageTimer.startOneShot(backgroundCPUUsageMeasurementDuration);
+ return;
+ }
+ std::optional<CPUTime> cpuTime = getCPUTime();
+ if (!cpuTime)
+ return;
+
+ double cpuUsage = cpuTime.value().percentageCPUUsageSince(*m_postBackgroundingCPUTime);
+ RELEASE_LOG_IF_ALLOWED(PerformanceLogging, "measurePostBackgroundingCPUUsage: Process was using %.1f%% CPU after becoming non visible.", cpuUsage);
+ m_page.diagnosticLoggingClient().logDiagnosticMessageWithValue(DiagnosticLoggingKeys::postPageBackgroundingKey(), DiagnosticLoggingKeys::cpuUsageKey(), DiagnosticLoggingKeys::backgroundCPUUsageToDiagnosticLoggingKey(cpuUsage), ShouldSample::No);
+}
+
+void PerformanceMonitor::measurePerActivityStateCPUUsage()
+{
+ measureCPUUsageInActivityState(activityStateForCPUSampling(m_page.activityState()));
+}
+
+#if !RELEASE_LOG_DISABLED
+
+static inline const char* stringForCPUSamplingActivityState(ActivityStateForCPUSampling activityState)
+{
+ switch (activityState) {
+ case ActivityStateForCPUSampling::NonVisible:
+ return "NonVisible";
+ case ActivityStateForCPUSampling::VisibleNonActive:
+ return "VisibleNonActive";
+ case ActivityStateForCPUSampling::VisibleAndActive:
+ return "VisibleAndActive";
+ }
+}
+
+#endif
+
+void PerformanceMonitor::measureCPUUsageInActivityState(ActivityStateForCPUSampling activityState)
+{
+ if (!m_page.isOnlyNonUtilityPage()) {
+ m_perActivityStateCPUTime = std::nullopt;
+ return;
+ }
+
+ if (!m_perActivityStateCPUTime) {
+ m_perActivityStateCPUTime = getCPUTime();
+ return;
+ }
+
+ std::optional<CPUTime> cpuTime = getCPUTime();
+ if (!cpuTime) {
+ m_perActivityStateCPUTime = std::nullopt;
+ return;
+ }
+
+#if !RELEASE_LOG_DISABLED
+ double cpuUsage = cpuTime.value().percentageCPUUsageSince(*m_perActivityStateCPUTime);
+ RELEASE_LOG_IF_ALLOWED(PerformanceLogging, "measureCPUUsageInActivityState: Process is using %.1f%% CPU in state: %s", cpuUsage, stringForCPUSamplingActivityState(activityState));
+#endif
+ m_page.chrome().client().reportProcessCPUTime((cpuTime.value().systemTime + cpuTime.value().userTime) - (m_perActivityStateCPUTime.value().systemTime + m_perActivityStateCPUTime.value().userTime), activityState);
+
+ m_perActivityStateCPUTime = WTFMove(cpuTime);
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="branchessafari603branchSourceWebCorepagePerformanceMonitorhfromrev210963branchessafari603branchSourceWebCorepageActivityStateh"></a>
<div class="copfile"><h4>Copied: branches/safari-603-branch/Source/WebCore/page/PerformanceMonitor.h (from rev 210963, branches/safari-603-branch/Source/WebCore/page/ActivityState.h) (0 => 210964)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/page/PerformanceMonitor.h         (rev 0)
+++ branches/safari-603-branch/Source/WebCore/page/PerformanceMonitor.h        2017-01-20 16:56:17 UTC (rev 210964)
</span><span class="lines">@@ -0,0 +1,61 @@
</span><ins>+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "ActivityState.h"
+#include "CPUTime.h"
+#include "Timer.h"
+#include <wtf/Optional.h>
+
+namespace WebCore {
+
+class Page;
+
+class PerformanceMonitor {
+public:
+ explicit PerformanceMonitor(Page&);
+
+ void didStartProvisionalLoad();
+ void didFinishLoad();
+ void activityStateChanged(ActivityState::Flags oldState, ActivityState::Flags newState);
+
+private:
+ void measurePostLoadCPUUsage();
+ void measurePostBackgroundingCPUUsage();
+ void measurePerActivityStateCPUUsage();
+ void measureCPUUsageInActivityState(ActivityStateForCPUSampling);
+
+ Page& m_page;
+
+ Timer m_postPageLoadCPUUsageTimer;
+ std::optional<CPUTime> m_postLoadCPUTime;
+ Timer m_postBackgroundingCPUUsageTimer;
+ std::optional<CPUTime> m_postBackgroundingCPUTime;
+ Timer m_perActivityStateCPUUsageTimer;
+ std::optional<CPUTime> m_perActivityStateCPUTime;
+};
+
+}
</ins></span></pre></div>
<a id="branchessafari603branchSourceWebCorepageSettingscpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/page/Settings.cpp (210963 => 210964)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/page/Settings.cpp        2017-01-20 16:25:55 UTC (rev 210963)
+++ branches/safari-603-branch/Source/WebCore/page/Settings.cpp        2017-01-20 16:56:17 UTC (rev 210964)
</span><span class="lines">@@ -778,24 +778,6 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx">
</span><del>-bool Settings::isPostLoadCPUUsageMeasurementEnabled()
-{
-#if PLATFORM(COCOA)
- return true;
-#else
- return false;
-#endif
-}
-
-bool Settings::isPostBackgroundingCPUUsageMeasurementEnabled()
-{
-#if PLATFORM(MAC)
- return true;
-#else
- return false;
-#endif
-}
-
</del><span class="cx"> void Settings::setAllowsAnySSLCertificate(bool allowAnySSLCertificate)
</span><span class="cx"> {
</span><span class="cx"> gAllowsAnySSLCertificate = allowAnySSLCertificate;
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCorepageSettingsh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/page/Settings.h (210963 => 210964)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/page/Settings.h        2017-01-20 16:25:55 UTC (rev 210963)
+++ branches/safari-603-branch/Source/WebCore/page/Settings.h        2017-01-20 16:56:17 UTC (rev 210964)
</span><span class="lines">@@ -201,6 +201,7 @@
</span><span class="cx">
</span><span class="cx"> static bool isPostLoadCPUUsageMeasurementEnabled();
</span><span class="cx"> static bool isPostBackgroundingCPUUsageMeasurementEnabled();
</span><ins>+ static bool isPerActivityStateCPUUsageMeasurementEnabled();
</ins><span class="cx">
</span><span class="cx"> static bool globalConstRedeclarationShouldThrow();
</span><span class="cx">
</span><span class="lines">@@ -423,4 +424,31 @@
</span><span class="cx"> static bool gAllowsAnySSLCertificate;
</span><span class="cx"> };
</span><span class="cx">
</span><ins>+inline bool Settings::isPostLoadCPUUsageMeasurementEnabled()
+{
+#if PLATFORM(COCOA)
+ return true;
+#else
+ return false;
+#endif
+}
+
+inline bool Settings::isPostBackgroundingCPUUsageMeasurementEnabled()
+{
+#if PLATFORM(MAC)
+ return true;
+#else
+ return false;
+#endif
+}
+
+inline bool Settings::isPerActivityStateCPUUsageMeasurementEnabled()
+{
+#if PLATFORM(MAC)
+ return true;
+#else
+ return false;
+#endif
+}
+
</ins><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="branchessafari603branchSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebKit2/ChangeLog (210963 => 210964)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebKit2/ChangeLog        2017-01-20 16:25:55 UTC (rev 210963)
+++ branches/safari-603-branch/Source/WebKit2/ChangeLog        2017-01-20 16:56:17 UTC (rev 210964)
</span><span class="lines">@@ -1,5 +1,39 @@
</span><span class="cx"> 2017-01-20 Matthew Hanson <matthew_hanson@apple.com>
</span><span class="cx">
</span><ins>+ Merge r210936. rdar://problem/30058349
+
+ 2017-01-19 Chris Dumez <cdumez@apple.com>
+
+ Implement per activity state CPU usage reporting using diagnostic logging
+ https://bugs.webkit.org/show_bug.cgi?id=167163
+ <rdar://problem/30058349>
+
+ Reviewed by Andreas Kling.
+
+ Implement per activity state CPU usage reporting using diagnostic logging.
+
+ * Platform/Logging.h:
+ * UIProcess/PerActivityStateCPUUsageSampler.cpp: Added.
+ (WebKit::PerActivityStateCPUUsageSampler::PerActivityStateCPUUsageSampler):
+ (WebKit::PerActivityStateCPUUsageSampler::~PerActivityStateCPUUsageSampler):
+ (WebKit::PerActivityStateCPUUsageSampler::reportWebContentCPUTime):
+ (WebKit::loggingKeyForActivityState):
+ (WebKit::loggingKeyForCPUUsage):
+ (WebKit::PerActivityStateCPUUsageSampler::loggingTimerFired):
+ (WebKit::PerActivityStateCPUUsageSampler::pageForLogging):
+ * UIProcess/PerActivityStateCPUUsageSampler.h: Copied from Source/WebCore/page/ActivityState.h.
+ * UIProcess/WebProcessPool.cpp:
+ (WebKit::WebProcessPool::WebProcessPool):
+ (WebKit::WebProcessPool::reportWebContentCPUTime):
+ * UIProcess/WebProcessPool.h:
+ * UIProcess/WebProcessPool.messages.in:
+ * WebKit2.xcodeproj/project.pbxproj:
+ * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+ (WebKit::WebChromeClient::reportProcessCPUTime):
+ * WebProcess/WebCoreSupport/WebChromeClient.h:
+
+2017-01-20 Matthew Hanson <matthew_hanson@apple.com>
+
</ins><span class="cx"> Merge r210913. rdar://problem/30086738
</span><span class="cx">
</span><span class="cx"> 2017-01-18 Said Abou-Hallawa <sabouhallawa@apple.com>
</span></span></pre></div>
<a id="branchessafari603branchSourceWebKit2PlatformLoggingh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebKit2/Platform/Logging.h (210963 => 210964)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebKit2/Platform/Logging.h        2017-01-20 16:25:55 UTC (rev 210963)
+++ branches/safari-603-branch/Source/WebKit2/Platform/Logging.h        2017-01-20 16:56:17 UTC (rev 210964)
</span><span class="lines">@@ -57,6 +57,7 @@
</span><span class="cx"> M(NetworkCacheStorage) \
</span><span class="cx"> M(NetworkScheduling) \
</span><span class="cx"> M(NetworkSession) \
</span><ins>+ M(PerformanceLogging) \
</ins><span class="cx"> M(Plugins) \
</span><span class="cx"> M(Printing) \
</span><span class="cx"> M(ProcessSuspension) \
</span></span></pre></div>
<a id="branchessafari603branchSourceWebKit2UIProcessPerActivityStateCPUUsageSamplercpp"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/Source/WebKit2/UIProcess/PerActivityStateCPUUsageSampler.cpp (0 => 210964)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebKit2/UIProcess/PerActivityStateCPUUsageSampler.cpp         (rev 0)
+++ branches/safari-603-branch/Source/WebKit2/UIProcess/PerActivityStateCPUUsageSampler.cpp        2017-01-20 16:56:17 UTC (rev 210964)
</span><span class="lines">@@ -0,0 +1,116 @@
</span><ins>+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PerActivityStateCPUUsageSampler.h"
+
+#include "Logging.h"
+#include "WebProcessPool.h"
+#include "WebProcessProxy.h"
+#include <WebCore/DiagnosticLoggingKeys.h>
+
+namespace WebKit {
+
+static const int64_t microsecondsPerSecond = 1000000;
+
+using namespace WebCore;
+
+static const std::chrono::minutes loggingInterval { 60 };
+
+PerActivityStateCPUUsageSampler::PerActivityStateCPUUsageSampler(WebProcessPool& processPool)
+ : m_processPool(processPool)
+ , m_loggingTimer(RunLoop::main(), this, &PerActivityStateCPUUsageSampler::loggingTimerFired)
+{
+ m_lastCPUTime = monotonicallyIncreasingTime();
+ m_loggingTimer.startRepeating(loggingInterval);
+}
+
+PerActivityStateCPUUsageSampler::~PerActivityStateCPUUsageSampler()
+{
+}
+
+void PerActivityStateCPUUsageSampler::reportWebContentCPUTime(int64_t cpuTime, ActivityStateForCPUSampling activityState)
+{
+ auto result = m_cpuTimeInActivityState.add(activityState, cpuTime);
+ if (!result.isNewEntry)
+ result.iterator->value += cpuTime;
+}
+
+static inline String loggingKeyForActivityState(ActivityStateForCPUSampling state)
+{
+ switch (state) {
+ case ActivityStateForCPUSampling::NonVisible:
+ return DiagnosticLoggingKeys::nonVisibleStateKey();
+ case ActivityStateForCPUSampling::VisibleNonActive:
+ return DiagnosticLoggingKeys::visibleNonActiveStateKey();
+ case ActivityStateForCPUSampling::VisibleAndActive:
+ return DiagnosticLoggingKeys::visibleAndActiveStateKey();
+ }
+}
+
+static inline String loggingKeyForCPUUsage(ActivityStateForCPUSampling state, double cpuUsage)
+{
+ switch (state) {
+ case ActivityStateForCPUSampling::NonVisible:
+ return DiagnosticLoggingKeys::backgroundCPUUsageToDiagnosticLoggingKey(cpuUsage);
+ case ActivityStateForCPUSampling::VisibleNonActive:
+ case ActivityStateForCPUSampling::VisibleAndActive:
+ return DiagnosticLoggingKeys::foregroundCPUUsageToDiagnosticLoggingKey(cpuUsage);
+ }
+}
+
+void PerActivityStateCPUUsageSampler::loggingTimerFired()
+{
+ auto* page = pageForLogging();
+ if (!page) {
+ m_cpuTimeInActivityState.clear();
+ return;
+ }
+
+ double currentCPUTime = monotonicallyIncreasingTime();
+ int64_t cpuTimeDelta = (currentCPUTime - m_lastCPUTime) * microsecondsPerSecond;
+
+ for (auto& pair : m_cpuTimeInActivityState) {
+ double cpuUsage = static_cast<double>(pair.value * 100.) / cpuTimeDelta;
+ String loggingKey = loggingKeyForActivityState(pair.key);
+ page->logDiagnosticMessageWithValue(DiagnosticLoggingKeys::cpuUsageKey(), loggingKey, loggingKeyForCPUUsage(pair.key, cpuUsage), false);
+ RELEASE_LOG(PerformanceLogging, "WebContent processes used %.1f%% CPU in %s state", cpuUsage, loggingKey.utf8().data());
+ }
+
+ m_cpuTimeInActivityState.clear();
+ m_lastCPUTime = currentCPUTime;
+}
+
+WebPageProxy* PerActivityStateCPUUsageSampler::pageForLogging() const
+{
+ for (auto& webProcess : m_processPool.processes()) {
+ if (!webProcess->pageCount())
+ continue;
+ return *webProcess->pages().begin();
+ }
+ return nullptr;
+}
+
+} // namespace WebKit
</ins></span></pre></div>
<a id="branchessafari603branchSourceWebKit2UIProcessPerActivityStateCPUUsageSamplerhfromrev210963branchessafari603branchSourceWebCorepageActivityStateh"></a>
<div class="copfile"><h4>Copied: branches/safari-603-branch/Source/WebKit2/UIProcess/PerActivityStateCPUUsageSampler.h (from rev 210963, branches/safari-603-branch/Source/WebCore/page/ActivityState.h) (0 => 210964)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebKit2/UIProcess/PerActivityStateCPUUsageSampler.h         (rev 0)
+++ branches/safari-603-branch/Source/WebKit2/UIProcess/PerActivityStateCPUUsageSampler.h        2017-01-20 16:56:17 UTC (rev 210964)
</span><span class="lines">@@ -0,0 +1,55 @@
</span><ins>+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <WebCore/Page.h>
+#include <wtf/HashMap.h>
+#include <wtf/RunLoop.h>
+
+namespace WebKit {
+
+class WebPageProxy;
+class WebProcessPool;
+
+class PerActivityStateCPUUsageSampler {
+public:
+ explicit PerActivityStateCPUUsageSampler(WebProcessPool&);
+ ~PerActivityStateCPUUsageSampler();
+
+ void reportWebContentCPUTime(int64_t cpuTime, WebCore::ActivityStateForCPUSampling);
+
+private:
+ void loggingTimerFired();
+ WebPageProxy* pageForLogging() const;
+
+ WebProcessPool& m_processPool;
+ RunLoop::Timer<PerActivityStateCPUUsageSampler> m_loggingTimer;
+ typedef HashMap<WebCore::ActivityStateForCPUSampling, int64_t, WTF::IntHash<WebCore::ActivityStateForCPUSampling>, WTF::StrongEnumHashTraits<WebCore::ActivityStateForCPUSampling>> CPUTimeInActivityStateMap;
+ CPUTimeInActivityStateMap m_cpuTimeInActivityState;
+ double m_lastCPUTime;
+};
+
+} // namespace WebKit
</ins></span></pre></div>
<a id="branchessafari603branchSourceWebKit2UIProcessWebProcessPoolcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebKit2/UIProcess/WebProcessPool.cpp (210963 => 210964)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebKit2/UIProcess/WebProcessPool.cpp        2017-01-20 16:25:55 UTC (rev 210963)
+++ branches/safari-603-branch/Source/WebKit2/UIProcess/WebProcessPool.cpp        2017-01-20 16:56:17 UTC (rev 210964)
</span><span class="lines">@@ -42,6 +42,7 @@
</span><span class="cx"> #include "NetworkProcessCreationParameters.h"
</span><span class="cx"> #include "NetworkProcessMessages.h"
</span><span class="cx"> #include "NetworkProcessProxy.h"
</span><ins>+#include "PerActivityStateCPUUsageSampler.h"
</ins><span class="cx"> #include "SandboxExtension.h"
</span><span class="cx"> #include "StatisticsData.h"
</span><span class="cx"> #include "TextChecker.h"
</span><span class="lines">@@ -168,6 +169,7 @@
</span><span class="cx"> , m_websiteDataStore(m_configuration->shouldHaveLegacyDataStore() ? API::WebsiteDataStore::create(legacyWebsiteDataStoreConfiguration(m_configuration)).ptr() : nullptr)
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="cx"> , m_highPerformanceGraphicsUsageSampler(std::make_unique<HighPerformanceGraphicsUsageSampler>(*this))
</span><ins>+ , m_perActivityStateCPUUsageSampler(std::make_unique<PerActivityStateCPUUsageSampler>(*this))
</ins><span class="cx"> #endif
</span><span class="cx"> , m_shouldUseTestingNetworkSession(false)
</span><span class="cx"> , m_processTerminationEnabled(true)
</span><span class="lines">@@ -1435,4 +1437,15 @@
</span><span class="cx"> sendToAllProcesses(Messages::WebProcess::SetHiddenPageTimerThrottlingIncreaseLimit(limitInMilliseconds));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void WebProcessPool::reportWebContentCPUTime(int64_t cpuTime, uint64_t activityState)
+{
+#if PLATFORM(MAC)
+ if (m_perActivityStateCPUUsageSampler)
+ m_perActivityStateCPUUsageSampler->reportWebContentCPUTime(cpuTime, static_cast<WebCore::ActivityStateForCPUSampling>(activityState));
+#else
+ UNUSED_PARAM(cpuTime);
+ UNUSED_PARAM(activityState);
+#endif
+}
+
</ins><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="branchessafari603branchSourceWebKit2UIProcessWebProcessPoolh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebKit2/UIProcess/WebProcessPool.h (210963 => 210964)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebKit2/UIProcess/WebProcessPool.h        2017-01-20 16:25:55 UTC (rev 210963)
+++ branches/safari-603-branch/Source/WebKit2/UIProcess/WebProcessPool.h        2017-01-20 16:56:17 UTC (rev 210964)
</span><span class="lines">@@ -81,6 +81,7 @@
</span><span class="cx"> class DownloadProxy;
</span><span class="cx"> class HighPerformanceGraphicsUsageSampler;
</span><span class="cx"> class UIGamepad;
</span><ins>+class PerActivityStateCPUUsageSampler;
</ins><span class="cx"> class WebAutomationSession;
</span><span class="cx"> class WebContextSupplement;
</span><span class="cx"> class WebIconDatabase;
</span><span class="lines">@@ -254,6 +255,8 @@
</span><span class="cx"> void clearCachedCredentials();
</span><span class="cx"> void terminateDatabaseProcess();
</span><span class="cx">
</span><ins>+ void reportWebContentCPUTime(int64_t cpuTime, uint64_t activityState);
+
</ins><span class="cx"> void allowSpecificHTTPSCertificateForHost(const WebCertificateInfo*, const String& host);
</span><span class="cx">
</span><span class="cx"> WebProcessProxy& createNewWebProcessRespectingProcessCountLimit(); // Will return an existing one if limit is met.
</span><span class="lines">@@ -526,6 +529,7 @@
</span><span class="cx"> RetainPtr<NSObject> m_automaticDashSubstitutionNotificationObserver;
</span><span class="cx">
</span><span class="cx"> std::unique_ptr<HighPerformanceGraphicsUsageSampler> m_highPerformanceGraphicsUsageSampler;
</span><ins>+ std::unique_ptr<PerActivityStateCPUUsageSampler> m_perActivityStateCPUUsageSampler;
</ins><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> String m_overrideIconDatabasePath;
</span></span></pre></div>
<a id="branchessafari603branchSourceWebKit2UIProcessWebProcessPoolmessagesin"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebKit2/UIProcess/WebProcessPool.messages.in (210963 => 210964)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebKit2/UIProcess/WebProcessPool.messages.in        2017-01-20 16:25:55 UTC (rev 210963)
+++ branches/safari-603-branch/Source/WebKit2/UIProcess/WebProcessPool.messages.in        2017-01-20 16:56:17 UTC (rev 210964)
</span><span class="lines">@@ -34,4 +34,6 @@
</span><span class="cx"> # Plug-in messages.
</span><span class="cx"> void AddPlugInAutoStartOriginHash(String pageOrigin, uint32_t hash, WebCore::SessionID sessionID)
</span><span class="cx"> void PlugInDidReceiveUserInteraction(uint32_t hash, WebCore::SessionID sessionID)
</span><ins>+
+ ReportWebContentCPUTime(int64_t cpuTime, uint64_t activityState)
</ins><span class="cx"> }
</span></span></pre></div>
<a id="branchessafari603branchSourceWebKit2WebKit2xcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj (210963 => 210964)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2017-01-20 16:25:55 UTC (rev 210963)
+++ branches/safari-603-branch/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2017-01-20 16:56:17 UTC (rev 210964)
</span><span class="lines">@@ -1236,6 +1236,8 @@
</span><span class="cx">                 831EEBBE1BD85C4300BB64C3 /* NetworkCacheSpeculativeLoad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 831EEBBC1BD85C4300BB64C3 /* NetworkCacheSpeculativeLoad.cpp */; };
</span><span class="cx">                 832AE2521BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 832AE2501BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.h */; };
</span><span class="cx">                 832AE2531BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 832AE2511BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.cpp */; };
</span><ins>+                832ED18B1E2FE157006BA64A /* PerActivityStateCPUUsageSampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 832ED1891E2FE13B006BA64A /* PerActivityStateCPUUsageSampler.cpp */; };
+                832ED18C1E2FE157006BA64A /* PerActivityStateCPUUsageSampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 832ED18A1E2FE13B006BA64A /* PerActivityStateCPUUsageSampler.h */; };
</ins><span class="cx">                 834B250F1A831A8D00CFB150 /* NetworkCacheFileSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 834B250E1A831A8D00CFB150 /* NetworkCacheFileSystem.h */; };
</span><span class="cx">                 834B25121A842C8700CFB150 /* NetworkCacheStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 834B25101A842C8700CFB150 /* NetworkCacheStatistics.h */; };
</span><span class="cx">                 8360349F1ACB34D600626549 /* WebSQLiteDatabaseTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8360349D1ACB34D600626549 /* WebSQLiteDatabaseTracker.cpp */; };
</span><span class="lines">@@ -3390,6 +3392,8 @@
</span><span class="cx">                 831EEBBC1BD85C4300BB64C3 /* NetworkCacheSpeculativeLoad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkCacheSpeculativeLoad.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 832AE2501BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCacheSpeculativeLoadManager.h; sourceTree = "<group>"; };
</span><span class="cx">                 832AE2511BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkCacheSpeculativeLoadManager.cpp; sourceTree = "<group>"; };
</span><ins>+                832ED1891E2FE13B006BA64A /* PerActivityStateCPUUsageSampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PerActivityStateCPUUsageSampler.cpp; sourceTree = "<group>"; };
+                832ED18A1E2FE13B006BA64A /* PerActivityStateCPUUsageSampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PerActivityStateCPUUsageSampler.h; sourceTree = "<group>"; };
</ins><span class="cx">                 834B250E1A831A8D00CFB150 /* NetworkCacheFileSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCacheFileSystem.h; sourceTree = "<group>"; };
</span><span class="cx">                 834B25101A842C8700CFB150 /* NetworkCacheStatistics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCacheStatistics.h; sourceTree = "<group>"; };
</span><span class="cx">                 8360349D1ACB34D600626549 /* WebSQLiteDatabaseTracker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSQLiteDatabaseTracker.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -6274,6 +6278,8 @@
</span><span class="cx">                                 BC6EDAA5111271C600E7678B /* PageClient.h */,
</span><span class="cx">                                 1AC75379183A9FDA0072CB15 /* PageLoadState.cpp */,
</span><span class="cx">                                 1AC7537A183A9FDB0072CB15 /* PageLoadState.h */,
</span><ins>+                                832ED1891E2FE13B006BA64A /* PerActivityStateCPUUsageSampler.cpp */,
+                                832ED18A1E2FE13B006BA64A /* PerActivityStateCPUUsageSampler.h */,
</ins><span class="cx">                                 37716A59195B910500EE8B1B /* ProcessAssertion.cpp */,
</span><span class="cx">                                 86F9536018FF4FD4001DB2EF /* ProcessAssertion.h */,
</span><span class="cx">                                 86E67A22190F411800004AB7 /* ProcessThrottler.cpp */,
</span><span class="lines">@@ -8070,6 +8076,7 @@
</span><span class="cx">                                 CE1A0BD71A48E6C60054EF74 /* TextInputSPI.h in Headers */,
</span><span class="cx">                                 1AAF263914687C39004A1E8A /* TiledCoreAnimationDrawingArea.h in Headers */,
</span><span class="cx">                                 1AF05D8714688348008B1E81 /* TiledCoreAnimationDrawingAreaProxy.h in Headers */,
</span><ins>+                                832ED18C1E2FE157006BA64A /* PerActivityStateCPUUsageSampler.h in Headers */,
</ins><span class="cx">                                 1AFE436618B6C081009C7A48 /* UIDelegate.h in Headers */,
</span><span class="cx">                                 515BE1B51D5917FF00DD7C68 /* UIGamepad.h in Headers */,
</span><span class="cx">                                 515BE1A91D55293400DD7C68 /* UIGamepadProvider.h in Headers */,
</span><span class="lines">@@ -9233,6 +9240,7 @@
</span><span class="cx">                                 93A88B471BC8829700ABA5C2 /* APIHitTestResult.cpp in Sources */,
</span><span class="cx">                                 7CD3A4821A5D02FA009623B8 /* APINavigation.cpp in Sources */,
</span><span class="cx">                                 BCF69FA31176D01400471A52 /* APINavigationData.cpp in Sources */,
</span><ins>+                                832ED18B1E2FE157006BA64A /* PerActivityStateCPUUsageSampler.cpp in Sources */,
</ins><span class="cx">                                 B63403F914910D57001070B5 /* APIObject.cpp in Sources */,
</span><span class="cx">                                 378E1A3D181ED6FF0031007A /* APIObject.mm in Sources */,
</span><span class="cx">                                 BC857FB612B830E600EDEB2E /* APIOpenPanelParameters.cpp in Sources */,
</span></span></pre></div>
<a id="branchessafari603branchSourceWebKit2WebProcessWebCoreSupportWebChromeClientcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp (210963 => 210964)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp        2017-01-20 16:25:55 UTC (rev 210963)
+++ branches/safari-603-branch/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp        2017-01-20 16:56:17 UTC (rev 210964)
</span><span class="lines">@@ -49,6 +49,7 @@
</span><span class="cx"> #include "WebPageProxyMessages.h"
</span><span class="cx"> #include "WebPopupMenu.h"
</span><span class="cx"> #include "WebProcess.h"
</span><ins>+#include "WebProcessPoolMessages.h"
</ins><span class="cx"> #include "WebProcessProxyMessages.h"
</span><span class="cx"> #include "WebSearchPopupMenu.h"
</span><span class="cx"> #include <WebCore/ApplicationCacheStorage.h>
</span><span class="lines">@@ -265,6 +266,11 @@
</span><span class="cx"> m_page->runModal();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void WebChromeClient::reportProcessCPUTime(int64_t cpuTime, ActivityStateForCPUSampling activityState)
+{
+ WebProcess::singleton().send(Messages::WebProcessPool::ReportWebContentCPUTime(cpuTime, static_cast<uint64_t>(activityState)), 0);
+}
+
</ins><span class="cx"> void WebChromeClient::setToolbarsVisible(bool toolbarsAreVisible)
</span><span class="cx"> {
</span><span class="cx"> m_page->send(Messages::WebPageProxy::SetToolbarsAreVisible(toolbarsAreVisible));
</span></span></pre></div>
<a id="branchessafari603branchSourceWebKit2WebProcessWebCoreSupportWebChromeClienth"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h (210963 => 210964)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h        2017-01-20 16:25:55 UTC (rev 210963)
+++ branches/safari-603-branch/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h        2017-01-20 16:56:17 UTC (rev 210964)
</span><span class="lines">@@ -74,6 +74,8 @@
</span><span class="cx">
</span><span class="cx"> bool canRunModal() override;
</span><span class="cx"> void runModal() override;
</span><ins>+
+ void reportProcessCPUTime(int64_t, WebCore::ActivityStateForCPUSampling) final;
</ins><span class="cx">
</span><span class="cx"> void setToolbarsVisible(bool) override;
</span><span class="cx"> bool toolbarsVisible() override;
</span></span></pre>
</div>
</div>
</body>
</html>