<!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  &lt;matthew_hanson@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Merge r210936. rdar://problem/30058349
+
+    2017-01-19  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+            Implement per activity state CPU usage reporting using diagnostic logging
+            https://bugs.webkit.org/show_bug.cgi?id=167163
+            &lt;rdar://problem/30058349&gt;
+
+            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  &lt;matthew_hanson@apple.com&gt;
+
</ins><span class="cx">         Merge r210473. rdar://problem/29204422
</span><span class="cx"> 
</span><span class="cx">     2017-01-06  Jer Noble  &lt;jer.noble@apple.com&gt;
</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 = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 83FE7CA51DA9F1660037237C /* UIEventInit.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = UIEventInit.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 83FE7CA61DA9F1660037237C /* EventModifierInit.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = EventModifierInit.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                83FE90251E307C1C003E9199 /* PerformanceMonitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PerformanceMonitor.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                83FE90261E307C1C003E9199 /* PerformanceMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PerformanceMonitor.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 8419D2A4120D92D000141F8F /* SVGPathByteStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGPathByteStream.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 8419D2A5120D92D000141F8F /* SVGPathByteStreamBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGPathByteStreamBuilder.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 8419D2A6120D92D000141F8F /* SVGPathByteStreamBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGPathByteStreamBuilder.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</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 &quot;ActivityState.h&quot;
</ins><span class="cx"> #include &quot;AXObjectCache.h&quot;
</span><span class="cx"> #include &quot;Cursor.h&quot;
</span><span class="cx"> #include &quot;DatabaseDetails.h&quot;
</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(&quot;noStore&quot;);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+String DiagnosticLoggingKeys::nonVisibleStateKey()
+{
+    return ASCIILiteral(&quot;nonVisibleState&quot;);
+}
+
</ins><span class="cx"> String DiagnosticLoggingKeys::notInMemoryCacheKey()
</span><span class="cx"> {
</span><span class="cx">     return ASCIILiteral(&quot;notInMemoryCache&quot;);
</span><span class="lines">@@ -598,6 +603,16 @@
</span><span class="cx">     return ASCIILiteral(&quot;video&quot;);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+String DiagnosticLoggingKeys::visibleNonActiveStateKey()
+{
+    return ASCIILiteral(&quot;visibleNonActiveState&quot;);
+}
+
+String DiagnosticLoggingKeys::visibleAndActiveStateKey()
+{
+    return ASCIILiteral(&quot;visibleAndActiveState&quot;);
+}
+
</ins><span class="cx"> String DiagnosticLoggingKeys::wastedSpeculativeWarmupWithRevalidationKey()
</span><span class="cx"> {
</span><span class="cx">     return ASCIILiteral(&quot;wastedSpeculativeWarmupWithRevalidation&quot;);
</span><span class="lines">@@ -658,5 +673,37 @@
</span><span class="cx">     return ASCIILiteral(&quot;webGL&quot;);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+String DiagnosticLoggingKeys::foregroundCPUUsageToDiagnosticLoggingKey(double cpuUsage)
+{
+    if (cpuUsage &lt; 10)
+        return ASCIILiteral(&quot;Below10&quot;);
+    if (cpuUsage &lt; 20)
+        return ASCIILiteral(&quot;10to20&quot;);
+    if (cpuUsage &lt; 40)
+        return ASCIILiteral(&quot;20to40&quot;);
+    if (cpuUsage &lt; 60)
+        return ASCIILiteral(&quot;40to60&quot;);
+    if (cpuUsage &lt; 80)
+        return ASCIILiteral(&quot;60to80&quot;);
+    return ASCIILiteral(&quot;over80&quot;);
+}
+
+String DiagnosticLoggingKeys::backgroundCPUUsageToDiagnosticLoggingKey(double cpuUsage)
+{
+    if (cpuUsage &lt; 1)
+        return ASCIILiteral(&quot;Below1&quot;);
+    if (cpuUsage &lt; 5)
+        return ASCIILiteral(&quot;1to5&quot;);
+    if (cpuUsage &lt; 10)
+        return ASCIILiteral(&quot;5to10&quot;);
+    if (cpuUsage &lt; 30)
+        return ASCIILiteral(&quot;10to30&quot;);
+    if (cpuUsage &lt; 50)
+        return ASCIILiteral(&quot;30to50&quot;);
+    if (cpuUsage &lt; 70)
+        return ASCIILiteral(&quot;50to70&quot;);
+    return ASCIILiteral(&quot;over70&quot;);
+}
+
</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 &quot;PageDebuggable.h&quot;
</span><span class="cx"> #include &quot;PageGroup.h&quot;
</span><span class="cx"> #include &quot;PageOverlayController.h&quot;
</span><ins>+#include &quot;PerformanceMonitor.h&quot;
</ins><span class="cx"> #include &quot;PlatformMediaSessionManager.h&quot;
</span><span class="cx"> #include &quot;PlugInClient.h&quot;
</span><span class="cx"> #include &quot;PluginData.h&quot;
</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, &quot;%p - Page::&quot; fmt, this, ##__VA_ARGS__)
-
</del><span class="cx"> static HashSet&lt;Page*&gt;* 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&amp; chromeClient)
+{
+    return chromeClient.isEmptyChromeClient() || chromeClient.isSVGImageChromeClient();
+}
</ins><span class="cx"> 
</span><span class="cx"> DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, pageCounter, (&quot;Page&quot;));
</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, &amp;Page::measurePostLoadCPUUsage)
-    , m_postBackgroundingCPUUsageTimer(*this, &amp;Page::measurePostBackgroundingCPUUsage)
</del><ins>+    , m_isUtilityPage(isUtilityPageChromeClient(chrome().client()))
+    , m_performanceMonitor(isUtilityPage() ? nullptr : std::make_unique&lt;PerformanceMonitor&gt;(*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-&gt;contains(this));
</span><span class="cx">     allPages-&gt;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-&gt;setView(nullptr);
</span><span class="cx">     setGroupName(String());
</span><span class="cx">     allPages-&gt;remove(this);
</span><ins>+    if (!isUtilityPage())
+        --nonUtilityPageCount;
</ins><span class="cx">     
</span><span class="cx">     m_settings-&gt;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-&gt;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() &amp;&amp; allPages-&gt;size() == 1) {
-        m_postLoadCPUTime = std::nullopt;
-        m_postPageLoadCPUUsageTimer.startOneShot(cpuUsageMeasurementDelay);
-    }
</del><ins>+    if (m_performanceMonitor)
+        m_performanceMonitor-&gt;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 &lt; 10)
-        return ASCIILiteral(&quot;Below10&quot;);
-    if (cpuUsage &lt; 20)
-        return ASCIILiteral(&quot;10to20&quot;);
-    if (cpuUsage &lt; 40)
-        return ASCIILiteral(&quot;20to40&quot;);
-    if (cpuUsage &lt; 60)
-        return ASCIILiteral(&quot;40to60&quot;);
-    if (cpuUsage &lt; 80)
-        return ASCIILiteral(&quot;60to80&quot;);
-    return ASCIILiteral(&quot;over80&quot;);
</del><ins>+    return !isUtilityPage() &amp;&amp; nonUtilityPageCount == 1;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Page::measurePostLoadCPUUsage()
-{
-    if (allPages-&gt;size() != 1)
-        return;
-
-    if (!m_postLoadCPUTime) {
-        m_postLoadCPUTime = getCPUTime();
-        if (m_postLoadCPUTime)
-            m_postPageLoadCPUUsageTimer.startOneShot(postLoadCPUUsageMeasurementDuration);
-        return;
-    }
-    std::optional&lt;CPUTime&gt; cpuTime = getCPUTime();
-    if (!cpuTime)
-        return;
-
-    double cpuUsage = cpuTime.value().percentageCPUUsageSince(*m_postLoadCPUTime);
-    RELEASE_LOG_IF_ALLOWED(PerformanceLogging, &quot;measurePostLoadCPUUsage: Process was using %.1f%% percent CPU after the page load.&quot;, cpuUsage);
-    diagnosticLoggingClient().logDiagnosticMessageWithValue(DiagnosticLoggingKeys::postPageLoadKey(), DiagnosticLoggingKeys::cpuUsageKey(), foregroundCPUUsageToDiagnosticLogginKey(cpuUsage), ShouldSample::No);
-}
-
-static String backgroundCPUUsageToDiagnosticLogginKey(double cpuUsage)
-{
-    if (cpuUsage &lt; 1)
-        return ASCIILiteral(&quot;Below1&quot;);
-    if (cpuUsage &lt; 5)
-        return ASCIILiteral(&quot;1to5&quot;);
-    if (cpuUsage &lt; 10)
-        return ASCIILiteral(&quot;5to10&quot;);
-    if (cpuUsage &lt; 30)
-        return ASCIILiteral(&quot;10to30&quot;);
-    if (cpuUsage &lt; 50)
-        return ASCIILiteral(&quot;30to50&quot;);
-    if (cpuUsage &lt; 70)
-        return ASCIILiteral(&quot;50to70&quot;);
-    return ASCIILiteral(&quot;over70&quot;);
-}
-
-void Page::measurePostBackgroundingCPUUsage()
-{
-    if (allPages-&gt;size() != 1)
-        return;
-
-    if (!m_postBackgroundingCPUTime) {
-        m_postBackgroundingCPUTime = getCPUTime();
-        if (m_postBackgroundingCPUTime)
-            m_postBackgroundingCPUUsageTimer.startOneShot(backgroundCPUUsageMeasurementDuration);
-        return;
-    }
-    std::optional&lt;CPUTime&gt; cpuTime = getCPUTime();
-    if (!cpuTime)
-        return;
-
-    double cpuUsage = cpuTime.value().percentageCPUUsageSince(*m_postBackgroundingCPUTime);
-    RELEASE_LOG_IF_ALLOWED(PerformanceLogging, &quot;measurePostBackgroundingCPUUsage: Process was using %.1f%% percent CPU after becoming non visible.&quot;, 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-&gt;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-&gt;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() &amp;&amp; allPages-&gt;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 &quot;ActivityState.h&quot;
</span><del>-#include &quot;CPUTime.h&quot;
</del><span class="cx"> #include &quot;FindOptions.h&quot;
</span><span class="cx"> #include &quot;FrameLoaderTypes.h&quot;
</span><span class="cx"> #include &quot;LayoutMilestones.h&quot;
</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&lt;EventThrottlingBehavior&gt; 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&lt;EventThrottlingBehavior&gt; m_eventThrottlingBehaviorOverride;
</span><span class="cx"> 
</span><del>-    Timer m_postPageLoadCPUUsageTimer;
-    std::optional&lt;CPUTime&gt; m_postLoadCPUTime;
-    Timer m_postBackgroundingCPUUsageTimer;
-    std::optional&lt;CPUTime&gt; m_postBackgroundingCPUTime;
</del><ins>+    std::unique_ptr&lt;PerformanceMonitor&gt; m_performanceMonitor;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> inline PageGroup&amp; 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 &quot;config.h&quot;
+#include &quot;PerformanceMonitor.h&quot;
+
+#include &quot;Chrome.h&quot;
+#include &quot;ChromeClient.h&quot;
+#include &quot;DiagnosticLoggingClient.h&quot;
+#include &quot;DiagnosticLoggingKeys.h&quot;
+#include &quot;Logging.h&quot;
+#include &quot;Page.h&quot;
+#include &quot;Settings.h&quot;
+
+namespace WebCore {
+
+#define RELEASE_LOG_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_IF(m_page.isAlwaysOnLoggingAllowed(), channel, &quot;%p - PerformanceMonitor::&quot; 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 &amp; ActivityState::IsVisible))
+        return ActivityStateForCPUSampling::NonVisible;
+    if (state &amp; ActivityState::WindowIsActive)
+        return ActivityStateForCPUSampling::VisibleAndActive;
+    return ActivityStateForCPUSampling::VisibleNonActive;
+}
+
+PerformanceMonitor::PerformanceMonitor(Page&amp; page)
+    : m_page(page)
+    , m_postPageLoadCPUUsageTimer(*this, &amp;PerformanceMonitor::measurePostLoadCPUUsage)
+    , m_postBackgroundingCPUUsageTimer(*this, &amp;PerformanceMonitor::measurePostBackgroundingCPUUsage)
+    , m_perActivityStateCPUUsageTimer(*this, &amp;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() &amp;&amp; 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 &amp; ActivityState::IsVisible;
+
+    // Measure CPU usage of pages when they are no longer visible.
+    if (Settings::isPostBackgroundingCPUUsageMeasurementEnabled() &amp;&amp; visibilityChanged) {
+        m_postBackgroundingCPUTime = std::nullopt;
+        if (newState &amp; 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&lt;CPUTime&gt; cpuTime = getCPUTime();
+    if (!cpuTime)
+        return;
+
+    double cpuUsage = cpuTime.value().percentageCPUUsageSince(*m_postLoadCPUTime);
+    RELEASE_LOG_IF_ALLOWED(PerformanceLogging, &quot;measurePostLoadCPUUsage: Process was using %.1f%% CPU after the page load.&quot;, 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&lt;CPUTime&gt; cpuTime = getCPUTime();
+    if (!cpuTime)
+        return;
+
+    double cpuUsage = cpuTime.value().percentageCPUUsageSince(*m_postBackgroundingCPUTime);
+    RELEASE_LOG_IF_ALLOWED(PerformanceLogging, &quot;measurePostBackgroundingCPUUsage: Process was using %.1f%% CPU after becoming non visible.&quot;, 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 &quot;NonVisible&quot;;
+    case ActivityStateForCPUSampling::VisibleNonActive:
+        return &quot;VisibleNonActive&quot;;
+    case ActivityStateForCPUSampling::VisibleAndActive:
+        return &quot;VisibleAndActive&quot;;
+    }
+}
+
+#endif
+
+void PerformanceMonitor::measureCPUUsageInActivityState(ActivityStateForCPUSampling activityState)
+{
+    if (!m_page.isOnlyNonUtilityPage()) {
+        m_perActivityStateCPUTime = std::nullopt;
+        return;
+    }
+
+    if (!m_perActivityStateCPUTime) {
+        m_perActivityStateCPUTime = getCPUTime();
+        return;
+    }
+
+    std::optional&lt;CPUTime&gt; 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, &quot;measureCPUUsageInActivityState: Process is using %.1f%% CPU in state: %s&quot;, 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 &quot;ActivityState.h&quot;
+#include &quot;CPUTime.h&quot;
+#include &quot;Timer.h&quot;
+#include &lt;wtf/Optional.h&gt;
+
+namespace WebCore {
+
+class Page;
+
+class PerformanceMonitor {
+public:
+    explicit PerformanceMonitor(Page&amp;);
+
+    void didStartProvisionalLoad();
+    void didFinishLoad();
+    void activityStateChanged(ActivityState::Flags oldState, ActivityState::Flags newState);
+
+private:
+    void measurePostLoadCPUUsage();
+    void measurePostBackgroundingCPUUsage();
+    void measurePerActivityStateCPUUsage();
+    void measureCPUUsageInActivityState(ActivityStateForCPUSampling);
+
+    Page&amp; m_page;
+
+    Timer m_postPageLoadCPUUsageTimer;
+    std::optional&lt;CPUTime&gt; m_postLoadCPUTime;
+    Timer m_postBackgroundingCPUUsageTimer;
+    std::optional&lt;CPUTime&gt; m_postBackgroundingCPUTime;
+    Timer m_perActivityStateCPUUsageTimer;
+    std::optional&lt;CPUTime&gt; 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  &lt;matthew_hanson@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Merge r210936. rdar://problem/30058349
+
+    2017-01-19  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+            Implement per activity state CPU usage reporting using diagnostic logging
+            https://bugs.webkit.org/show_bug.cgi?id=167163
+            &lt;rdar://problem/30058349&gt;
+
+            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  &lt;matthew_hanson@apple.com&gt;
+
</ins><span class="cx">         Merge r210913. rdar://problem/30086738
</span><span class="cx"> 
</span><span class="cx">     2017-01-18  Said Abou-Hallawa  &lt;sabouhallawa@apple.com&gt;
</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 &quot;config.h&quot;
+#include &quot;PerActivityStateCPUUsageSampler.h&quot;
+
+#include &quot;Logging.h&quot;
+#include &quot;WebProcessPool.h&quot;
+#include &quot;WebProcessProxy.h&quot;
+#include &lt;WebCore/DiagnosticLoggingKeys.h&gt;
+
+namespace WebKit {
+
+static const int64_t microsecondsPerSecond = 1000000;
+
+using namespace WebCore;
+
+static const std::chrono::minutes loggingInterval { 60 };
+
+PerActivityStateCPUUsageSampler::PerActivityStateCPUUsageSampler(WebProcessPool&amp; processPool)
+    : m_processPool(processPool)
+    , m_loggingTimer(RunLoop::main(), this, &amp;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-&gt;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&amp; pair : m_cpuTimeInActivityState) {
+        double cpuUsage = static_cast&lt;double&gt;(pair.value * 100.) / cpuTimeDelta;
+        String loggingKey = loggingKeyForActivityState(pair.key);
+        page-&gt;logDiagnosticMessageWithValue(DiagnosticLoggingKeys::cpuUsageKey(), loggingKey, loggingKeyForCPUUsage(pair.key, cpuUsage), false);
+        RELEASE_LOG(PerformanceLogging, &quot;WebContent processes used %.1f%% CPU in %s state&quot;, cpuUsage, loggingKey.utf8().data());
+    }
+
+    m_cpuTimeInActivityState.clear();
+    m_lastCPUTime = currentCPUTime;
+}
+
+WebPageProxy* PerActivityStateCPUUsageSampler::pageForLogging() const
+{
+    for (auto&amp; webProcess : m_processPool.processes()) {
+        if (!webProcess-&gt;pageCount())
+            continue;
+        return *webProcess-&gt;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 &lt;WebCore/Page.h&gt;
+#include &lt;wtf/HashMap.h&gt;
+#include &lt;wtf/RunLoop.h&gt;
+
+namespace WebKit {
+
+class WebPageProxy;
+class WebProcessPool;
+
+class PerActivityStateCPUUsageSampler {
+public:
+    explicit PerActivityStateCPUUsageSampler(WebProcessPool&amp;);
+    ~PerActivityStateCPUUsageSampler();
+
+    void reportWebContentCPUTime(int64_t cpuTime, WebCore::ActivityStateForCPUSampling);
+
+private:
+    void loggingTimerFired();
+    WebPageProxy* pageForLogging() const;
+
+    WebProcessPool&amp; m_processPool;
+    RunLoop::Timer&lt;PerActivityStateCPUUsageSampler&gt; m_loggingTimer;
+    typedef HashMap&lt;WebCore::ActivityStateForCPUSampling, int64_t, WTF::IntHash&lt;WebCore::ActivityStateForCPUSampling&gt;, WTF::StrongEnumHashTraits&lt;WebCore::ActivityStateForCPUSampling&gt;&gt; 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 &quot;NetworkProcessCreationParameters.h&quot;
</span><span class="cx"> #include &quot;NetworkProcessMessages.h&quot;
</span><span class="cx"> #include &quot;NetworkProcessProxy.h&quot;
</span><ins>+#include &quot;PerActivityStateCPUUsageSampler.h&quot;
</ins><span class="cx"> #include &quot;SandboxExtension.h&quot;
</span><span class="cx"> #include &quot;StatisticsData.h&quot;
</span><span class="cx"> #include &quot;TextChecker.h&quot;
</span><span class="lines">@@ -168,6 +169,7 @@
</span><span class="cx">     , m_websiteDataStore(m_configuration-&gt;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&lt;HighPerformanceGraphicsUsageSampler&gt;(*this))
</span><ins>+    , m_perActivityStateCPUUsageSampler(std::make_unique&lt;PerActivityStateCPUUsageSampler&gt;(*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-&gt;reportWebContentCPUTime(cpuTime, static_cast&lt;WebCore::ActivityStateForCPUSampling&gt;(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&amp; host);
</span><span class="cx"> 
</span><span class="cx">     WebProcessProxy&amp; createNewWebProcessRespectingProcessCountLimit(); // Will return an existing one if limit is met.
</span><span class="lines">@@ -526,6 +529,7 @@
</span><span class="cx">     RetainPtr&lt;NSObject&gt; m_automaticDashSubstitutionNotificationObserver;
</span><span class="cx"> 
</span><span class="cx">     std::unique_ptr&lt;HighPerformanceGraphicsUsageSampler&gt; m_highPerformanceGraphicsUsageSampler;
</span><ins>+    std::unique_ptr&lt;PerActivityStateCPUUsageSampler&gt; 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 = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 832AE2501BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCacheSpeculativeLoadManager.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 832AE2511BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkCacheSpeculativeLoadManager.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                832ED1891E2FE13B006BA64A /* PerActivityStateCPUUsageSampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PerActivityStateCPUUsageSampler.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                832ED18A1E2FE13B006BA64A /* PerActivityStateCPUUsageSampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PerActivityStateCPUUsageSampler.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 834B250E1A831A8D00CFB150 /* NetworkCacheFileSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCacheFileSystem.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 834B25101A842C8700CFB150 /* NetworkCacheStatistics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCacheStatistics.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 8360349D1ACB34D600626549 /* WebSQLiteDatabaseTracker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSQLiteDatabaseTracker.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</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 &quot;WebPageProxyMessages.h&quot;
</span><span class="cx"> #include &quot;WebPopupMenu.h&quot;
</span><span class="cx"> #include &quot;WebProcess.h&quot;
</span><ins>+#include &quot;WebProcessPoolMessages.h&quot;
</ins><span class="cx"> #include &quot;WebProcessProxyMessages.h&quot;
</span><span class="cx"> #include &quot;WebSearchPopupMenu.h&quot;
</span><span class="cx"> #include &lt;WebCore/ApplicationCacheStorage.h&gt;
</span><span class="lines">@@ -265,6 +266,11 @@
</span><span class="cx">     m_page-&gt;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&lt;uint64_t&gt;(activityState)), 0);
+}
+
</ins><span class="cx"> void WebChromeClient::setToolbarsVisible(bool toolbarsAreVisible)
</span><span class="cx"> {
</span><span class="cx">     m_page-&gt;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>