Diff
Modified: branches/safari-603-branch/Source/WebCore/CMakeLists.txt (210963 => 210964)
--- 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)
@@ -2059,6 +2059,7 @@
page/Performance.cpp
page/PerformanceEntry.cpp
page/PerformanceLogging.cpp
+ page/PerformanceMonitor.cpp
page/PerformanceNavigation.cpp
page/PerformanceResourceTiming.cpp
page/PerformanceTiming.cpp
Modified: branches/safari-603-branch/Source/WebCore/ChangeLog (210963 => 210964)
--- 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)
@@ -1,5 +1,59 @@
2017-01-20 Matthew Hanson <matthew_han...@apple.com>
+ Merge r210936. rdar://problem/30058349
+
+ 2017-01-19 Chris Dumez <cdu...@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_han...@apple.com>
+
Merge r210473. rdar://problem/29204422
2017-01-06 Jer Noble <jer.no...@apple.com>
Modified: branches/safari-603-branch/Source/WebCore/WebCore.xcodeproj/project.pbxproj (210963 => 210964)
--- 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)
@@ -3073,6 +3073,8 @@
83F1206B1B8C104700D75F63 /* JSNodeFilterCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83F1206A1B8C103600D75F63 /* JSNodeFilterCustom.cpp */; };
83FE7CA71DA9F1A70037237C /* UIEventInit.h in Headers */ = {isa = PBXBuildFile; fileRef = 83FE7CA41DA9F1660037237C /* UIEventInit.h */; settings = {ATTRIBUTES = (Private, ); }; };
83FE7CA81DA9F1B60037237C /* EventModifierInit.h in Headers */ = {isa = PBXBuildFile; fileRef = 83FE7CA31DA9F1650037237C /* EventModifierInit.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 83FE90271E307C30003E9199 /* PerformanceMonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 83FE90261E307C1C003E9199 /* PerformanceMonitor.h */; };
+ 83FE90281E307C33003E9199 /* PerformanceMonitor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83FE90251E307C1C003E9199 /* PerformanceMonitor.cpp */; };
8419D2A7120D92D000141F8F /* SVGPathByteStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 8419D2A4120D92D000141F8F /* SVGPathByteStream.h */; };
8419D2A8120D92D000141F8F /* SVGPathByteStreamBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8419D2A5120D92D000141F8F /* SVGPathByteStreamBuilder.cpp */; };
8419D2A9120D92D000141F8F /* SVGPathByteStreamBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 8419D2A6120D92D000141F8F /* SVGPathByteStreamBuilder.h */; };
@@ -10626,6 +10628,8 @@
83FE7CA41DA9F1660037237C /* UIEventInit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIEventInit.h; sourceTree = "<group>"; };
83FE7CA51DA9F1660037237C /* UIEventInit.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = UIEventInit.idl; sourceTree = "<group>"; };
83FE7CA61DA9F1660037237C /* EventModifierInit.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = EventModifierInit.idl; sourceTree = "<group>"; };
+ 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>"; };
8419D2A4120D92D000141F8F /* SVGPathByteStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGPathByteStream.h; sourceTree = "<group>"; };
8419D2A5120D92D000141F8F /* SVGPathByteStreamBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGPathByteStreamBuilder.cpp; sourceTree = "<group>"; };
8419D2A6120D92D000141F8F /* SVGPathByteStreamBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGPathByteStreamBuilder.h; sourceTree = "<group>"; };
@@ -18057,6 +18061,8 @@
86BE33FC15058CB200CE0FD8 /* PerformanceEntry.idl */,
AD5A0C211DECA10100707054 /* PerformanceLogging.cpp */,
AD5A0C201DECA0B500707054 /* PerformanceLogging.h */,
+ 83FE90251E307C1C003E9199 /* PerformanceMonitor.cpp */,
+ 83FE90261E307C1C003E9199 /* PerformanceMonitor.h */,
8AF4E55211DC5A36000ED3DE /* PerformanceNavigation.cpp */,
8AF4E55311DC5A36000ED3DE /* PerformanceNavigation.h */,
8AF4E55411DC5A36000ED3DE /* PerformanceNavigation.idl */,
@@ -26752,6 +26758,7 @@
85031B440A44EFC700F992E0 /* KeyboardEvent.h in Headers */,
1AE00D59182DAC8D00087DD7 /* KeyedCoding.h in Headers */,
517A63C51B74318F00E7DCDC /* KeyedDecoderCF.h in Headers */,
+ 83FE90271E307C30003E9199 /* PerformanceMonitor.h in Headers */,
517A63C61B74319200E7DCDC /* KeyedEncoderCF.h in Headers */,
A513B3D7114B1666001C429B /* KeyEventCocoa.h in Headers */,
265541391489811C000DFC5D /* KeyEventCodesIOS.h in Headers */,
@@ -31178,6 +31185,7 @@
073BE34E17D180B2002BD431 /* RTCSessionDescriptionDescriptor.cpp in Sources */,
078E090E17D14CEE00420AA1 /* RTCStatsReport.cpp in Sources */,
078E091017D14CEE00420AA1 /* RTCStatsResponse.cpp in Sources */,
+ 83FE90281E307C33003E9199 /* PerformanceMonitor.cpp in Sources */,
5E2C43671BCEE3770001E2BC /* RTCTrackEvent.cpp in Sources */,
5824ABA21AE81116009074B7 /* RubyElement.cpp in Sources */,
5824ABA61AE81384009074B7 /* RubyTextElement.cpp in Sources */,
Modified: branches/safari-603-branch/Source/WebCore/page/ActivityState.h (210963 => 210964)
--- 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)
@@ -45,4 +45,10 @@
static const Flags AllFlags = WindowIsActive | IsFocused | IsVisible | IsVisibleOrOccluded | IsInWindow | IsVisuallyIdle | IsAudible | IsLoading;
};
+enum class ActivityStateForCPUSampling {
+ NonVisible,
+ VisibleNonActive,
+ VisibleAndActive
+};
+
} // namespace WebCore
Modified: branches/safari-603-branch/Source/WebCore/page/ChromeClient.h (210963 => 210964)
--- 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)
@@ -21,6 +21,7 @@
#pragma once
+#include "ActivityState.h"
#include "AXObjectCache.h"
#include "Cursor.h"
#include "DatabaseDetails.h"
@@ -460,6 +461,8 @@
virtual void didInvalidateDocumentMarkerRects() { }
+ virtual void reportProcessCPUTime(int64_t, ActivityStateForCPUSampling) { }
+
protected:
virtual ~ChromeClient() { }
};
Modified: branches/safari-603-branch/Source/WebCore/page/DiagnosticLoggingKeys.cpp (210963 => 210964)
--- 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)
@@ -163,6 +163,11 @@
return ASCIILiteral("noStore");
}
+String DiagnosticLoggingKeys::nonVisibleStateKey()
+{
+ return ASCIILiteral("nonVisibleState");
+}
+
String DiagnosticLoggingKeys::notInMemoryCacheKey()
{
return ASCIILiteral("notInMemoryCache");
@@ -598,6 +603,16 @@
return ASCIILiteral("video");
}
+String DiagnosticLoggingKeys::visibleNonActiveStateKey()
+{
+ return ASCIILiteral("visibleNonActiveState");
+}
+
+String DiagnosticLoggingKeys::visibleAndActiveStateKey()
+{
+ return ASCIILiteral("visibleAndActiveState");
+}
+
String DiagnosticLoggingKeys::wastedSpeculativeWarmupWithRevalidationKey()
{
return ASCIILiteral("wastedSpeculativeWarmupWithRevalidation");
@@ -658,5 +673,37 @@
return ASCIILiteral("webGL");
}
+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");
+}
+
} // namespace WebCore
Modified: branches/safari-603-branch/Source/WebCore/page/DiagnosticLoggingKeys.h (210963 => 210964)
--- 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)
@@ -40,7 +40,7 @@
static String cachedResourceRevalidationKey();
static String canCacheKey();
static String cannotSuspendActiveDOMObjectsKey();
- static String cpuUsageKey();
+ WEBCORE_EXPORT static String cpuUsageKey();
WEBCORE_EXPORT static String createSharedBufferFailedKey();
WEBCORE_EXPORT static String deltaKey();
static String deniedByClientKey();
@@ -88,6 +88,7 @@
static String noDocumentLoaderKey();
WEBCORE_EXPORT static String noLongerInCacheKey();
static String noStoreKey();
+ WEBCORE_EXPORT static String nonVisibleStateKey();
WEBCORE_EXPORT static String notHTTPFamilyKey();
WEBCORE_EXPORT static String notInCacheKey();
static String notInMemoryCacheKey();
@@ -150,6 +151,8 @@
WEBCORE_EXPORT static String userKey();
WEBCORE_EXPORT static String varyingHeaderMismatchKey();
static String videoKey();
+ WEBCORE_EXPORT static String visibleNonActiveStateKey();
+ WEBCORE_EXPORT static String visibleAndActiveStateKey();
WEBCORE_EXPORT static String wastedSpeculativeWarmupWithRevalidationKey();
WEBCORE_EXPORT static String wastedSpeculativeWarmupWithoutRevalidationKey();
WEBCORE_EXPORT static String webGLKey();
@@ -156,6 +159,9 @@
WEBCORE_EXPORT static String webViewKey();
WEBCORE_EXPORT static String zoomedKey();
+ WEBCORE_EXPORT static String foregroundCPUUsageToDiagnosticLoggingKey(double cpuUsage);
+ WEBCORE_EXPORT static String backgroundCPUUsageToDiagnosticLoggingKey(double cpuUsage);
+
// Success / Failure keys.
static String successKey();
static String failureKey();
Modified: branches/safari-603-branch/Source/WebCore/page/Page.cpp (210963 => 210964)
--- 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)
@@ -66,6 +66,7 @@
#include "PageDebuggable.h"
#include "PageGroup.h"
#include "PageOverlayController.h"
+#include "PerformanceMonitor.h"
#include "PlatformMediaSessionManager.h"
#include "PlugInClient.h"
#include "PluginData.h"
@@ -126,13 +127,13 @@
namespace WebCore {
-#define RELEASE_LOG_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_IF(isAlwaysOnLoggingAllowed(), channel, "%p - Page::" fmt, this, ##__VA_ARGS__)
-
static HashSet<Page*>* allPages;
+static unsigned nonUtilityPageCount { 0 };
-static const std::chrono::seconds cpuUsageMeasurementDelay { 5 };
-static const std::chrono::seconds postLoadCPUUsageMeasurementDuration { 10 };
-static const std::chrono::minutes backgroundCPUUsageMeasurementDuration { 5 };
+static inline bool isUtilityPageChromeClient(ChromeClient& chromeClient)
+{
+ return chromeClient.isEmptyChromeClient() || chromeClient.isSVGImageChromeClient();
+}
DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, pageCounter, ("Page"));
@@ -252,8 +253,8 @@
, m_visitedLinkStore(*WTFMove(pageConfiguration.visitedLinkStore))
, m_sessionID(SessionID::defaultSessionID())
, m_isClosing(false)
- , m_postPageLoadCPUUsageTimer(*this, &Page::measurePostLoadCPUUsage)
- , m_postBackgroundingCPUUsageTimer(*this, &Page::measurePostBackgroundingCPUUsage)
+ , m_isUtilityPage(isUtilityPageChromeClient(chrome().client()))
+ , m_performanceMonitor(isUtilityPage() ? nullptr : std::make_unique<PerformanceMonitor>(*this))
{
updateTimerThrottlingState();
@@ -270,6 +271,8 @@
ASSERT(!allPages->contains(this));
allPages->add(this);
+ if (!isUtilityPage())
+ ++nonUtilityPageCount;
#ifndef NDEBUG
pageCounter.increment();
@@ -294,6 +297,8 @@
m_mainFrame->setView(nullptr);
setGroupName(String());
allPages->remove(this);
+ if (!isUtilityPage())
+ --nonUtilityPageCount;
m_settings->pageDestroyed();
@@ -937,8 +942,8 @@
void Page::didStartProvisionalLoad()
{
- m_postLoadCPUTime = std::nullopt;
- m_postPageLoadCPUUsageTimer.stop();
+ if (m_performanceMonitor)
+ m_performanceMonitor->didStartProvisionalLoad();
}
void Page::didFinishLoad()
@@ -945,85 +950,15 @@
{
resetRelevantPaintedObjectCounter();
- // 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);
- }
+ if (m_performanceMonitor)
+ m_performanceMonitor->didFinishLoad();
}
-static String foregroundCPUUsageToDiagnosticLogginKey(double cpuUsage)
+bool Page::isOnlyNonUtilityPage() const
{
- 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");
+ return !isUtilityPage() && nonUtilityPageCount == 1;
}
-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);
-}
-
void Page::setTopContentInset(float contentInset)
{
if (m_topContentInset == contentInset)
@@ -1576,6 +1511,9 @@
if (wasVisibleAndActive != isVisibleAndActive())
PlatformMediaSessionManager::updateNowPlayingInfoIfNecessary();
+
+ if (m_performanceMonitor)
+ m_performanceMonitor->activityStateChanged(oldActivityState, activityState);
}
bool Page::isVisibleAndActive() const
@@ -1632,13 +1570,6 @@
if (FrameView* view = mainFrame().view())
view->hide();
}
-
- // 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);
}
void Page::setIsPrerender()
Modified: branches/safari-603-branch/Source/WebCore/page/Page.h (210963 => 210964)
--- 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)
@@ -21,7 +21,6 @@
#pragma once
#include "ActivityState.h"
-#include "CPUTime.h"
#include "FindOptions.h"
#include "FrameLoaderTypes.h"
#include "LayoutMilestones.h"
@@ -105,6 +104,7 @@
class PageConsoleClient;
class PageDebuggable;
class PageGroup;
+class PerformanceMonitor;
class PlugInClient;
class PluginData;
class PluginInfoProvider;
@@ -357,6 +357,8 @@
// Notifications when the Page starts and stops being presented via a native window.
WEBCORE_EXPORT void setActivityState(ActivityState::Flags);
+ ActivityState::Flags activityState() const { return m_activityState; }
+
bool isVisibleAndActive() const;
WEBCORE_EXPORT void setIsVisible(bool);
WEBCORE_EXPORT void setIsPrerender();
@@ -559,6 +561,10 @@
void setEventThrottlingBehaviorOverride(std::optional<EventThrottlingBehavior> throttling) { m_eventThrottlingBehaviorOverride = throttling; }
WebGLStateTracker* webGLStateTracker() const { return m_webGLStateTracker.get(); }
+
+ bool isOnlyNonUtilityPage() const;
+ bool isUtilityPage() const { return m_isUtilityPage; }
+
private:
WEBCORE_EXPORT void initGroup();
@@ -572,9 +578,6 @@
void checkSubframeCountConsistency() const;
#endif
- void measurePostLoadCPUUsage();
- void measurePostBackgroundingCPUUsage();
-
enum ShouldHighlightMatches { DoNotHighlightMatches, HighlightMatches };
enum ShouldMarkMatches { DoNotMarkMatches, MarkMatches };
@@ -756,15 +759,13 @@
bool m_showAllPlugins { false };
bool m_controlledByAutomation { false };
bool m_resourceCachingDisabled { false };
+ bool m_isUtilityPage;
UserInterfaceLayoutDirection m_userInterfaceLayoutDirection { UserInterfaceLayoutDirection::LTR };
// For testing.
std::optional<EventThrottlingBehavior> m_eventThrottlingBehaviorOverride;
- Timer m_postPageLoadCPUUsageTimer;
- std::optional<CPUTime> m_postLoadCPUTime;
- Timer m_postBackgroundingCPUUsageTimer;
- std::optional<CPUTime> m_postBackgroundingCPUTime;
+ std::unique_ptr<PerformanceMonitor> m_performanceMonitor;
};
inline PageGroup& Page::group()
Added: branches/safari-603-branch/Source/WebCore/page/PerformanceMonitor.cpp (0 => 210964)
--- 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)
@@ -0,0 +1,200 @@
+/*
+ * 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
Copied: branches/safari-603-branch/Source/WebCore/page/PerformanceMonitor.h (from rev 210963, branches/safari-603-branch/Source/WebCore/page/ActivityState.h) (0 => 210964)
--- 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)
@@ -0,0 +1,61 @@
+/*
+ * 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;
+};
+
+}
Modified: branches/safari-603-branch/Source/WebCore/page/Settings.cpp (210963 => 210964)
--- 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)
@@ -778,24 +778,6 @@
#endif
}
-bool Settings::isPostLoadCPUUsageMeasurementEnabled()
-{
-#if PLATFORM(COCOA)
- return true;
-#else
- return false;
-#endif
-}
-
-bool Settings::isPostBackgroundingCPUUsageMeasurementEnabled()
-{
-#if PLATFORM(MAC)
- return true;
-#else
- return false;
-#endif
-}
-
void Settings::setAllowsAnySSLCertificate(bool allowAnySSLCertificate)
{
gAllowsAnySSLCertificate = allowAnySSLCertificate;
Modified: branches/safari-603-branch/Source/WebCore/page/Settings.h (210963 => 210964)
--- 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)
@@ -201,6 +201,7 @@
static bool isPostLoadCPUUsageMeasurementEnabled();
static bool isPostBackgroundingCPUUsageMeasurementEnabled();
+ static bool isPerActivityStateCPUUsageMeasurementEnabled();
static bool globalConstRedeclarationShouldThrow();
@@ -423,4 +424,31 @@
static bool gAllowsAnySSLCertificate;
};
+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
+}
+
} // namespace WebCore
Modified: branches/safari-603-branch/Source/WebKit2/ChangeLog (210963 => 210964)
--- 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)
@@ -1,5 +1,39 @@
2017-01-20 Matthew Hanson <matthew_han...@apple.com>
+ Merge r210936. rdar://problem/30058349
+
+ 2017-01-19 Chris Dumez <cdu...@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_han...@apple.com>
+
Merge r210913. rdar://problem/30086738
2017-01-18 Said Abou-Hallawa <sabouhall...@apple.com>
Modified: branches/safari-603-branch/Source/WebKit2/Platform/Logging.h (210963 => 210964)
--- 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)
@@ -57,6 +57,7 @@
M(NetworkCacheStorage) \
M(NetworkScheduling) \
M(NetworkSession) \
+ M(PerformanceLogging) \
M(Plugins) \
M(Printing) \
M(ProcessSuspension) \
Added: branches/safari-603-branch/Source/WebKit2/UIProcess/PerActivityStateCPUUsageSampler.cpp (0 => 210964)
--- 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)
@@ -0,0 +1,116 @@
+/*
+ * 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
Copied: branches/safari-603-branch/Source/WebKit2/UIProcess/PerActivityStateCPUUsageSampler.h (from rev 210963, branches/safari-603-branch/Source/WebCore/page/ActivityState.h) (0 => 210964)
--- 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)
@@ -0,0 +1,55 @@
+/*
+ * 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
Modified: branches/safari-603-branch/Source/WebKit2/UIProcess/WebProcessPool.cpp (210963 => 210964)
--- 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)
@@ -42,6 +42,7 @@
#include "NetworkProcessCreationParameters.h"
#include "NetworkProcessMessages.h"
#include "NetworkProcessProxy.h"
+#include "PerActivityStateCPUUsageSampler.h"
#include "SandboxExtension.h"
#include "StatisticsData.h"
#include "TextChecker.h"
@@ -168,6 +169,7 @@
, m_websiteDataStore(m_configuration->shouldHaveLegacyDataStore() ? API::WebsiteDataStore::create(legacyWebsiteDataStoreConfiguration(m_configuration)).ptr() : nullptr)
#if PLATFORM(MAC)
, m_highPerformanceGraphicsUsageSampler(std::make_unique<HighPerformanceGraphicsUsageSampler>(*this))
+ , m_perActivityStateCPUUsageSampler(std::make_unique<PerActivityStateCPUUsageSampler>(*this))
#endif
, m_shouldUseTestingNetworkSession(false)
, m_processTerminationEnabled(true)
@@ -1435,4 +1437,15 @@
sendToAllProcesses(Messages::WebProcess::SetHiddenPageTimerThrottlingIncreaseLimit(limitInMilliseconds));
}
+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
+}
+
} // namespace WebKit
Modified: branches/safari-603-branch/Source/WebKit2/UIProcess/WebProcessPool.h (210963 => 210964)
--- 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)
@@ -81,6 +81,7 @@
class DownloadProxy;
class HighPerformanceGraphicsUsageSampler;
class UIGamepad;
+class PerActivityStateCPUUsageSampler;
class WebAutomationSession;
class WebContextSupplement;
class WebIconDatabase;
@@ -254,6 +255,8 @@
void clearCachedCredentials();
void terminateDatabaseProcess();
+ void reportWebContentCPUTime(int64_t cpuTime, uint64_t activityState);
+
void allowSpecificHTTPSCertificateForHost(const WebCertificateInfo*, const String& host);
WebProcessProxy& createNewWebProcessRespectingProcessCountLimit(); // Will return an existing one if limit is met.
@@ -526,6 +529,7 @@
RetainPtr<NSObject> m_automaticDashSubstitutionNotificationObserver;
std::unique_ptr<HighPerformanceGraphicsUsageSampler> m_highPerformanceGraphicsUsageSampler;
+ std::unique_ptr<PerActivityStateCPUUsageSampler> m_perActivityStateCPUUsageSampler;
#endif
String m_overrideIconDatabasePath;
Modified: branches/safari-603-branch/Source/WebKit2/UIProcess/WebProcessPool.messages.in (210963 => 210964)
--- 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)
@@ -34,4 +34,6 @@
# Plug-in messages.
void AddPlugInAutoStartOriginHash(String pageOrigin, uint32_t hash, WebCore::SessionID sessionID)
void PlugInDidReceiveUserInteraction(uint32_t hash, WebCore::SessionID sessionID)
+
+ ReportWebContentCPUTime(int64_t cpuTime, uint64_t activityState)
}
Modified: branches/safari-603-branch/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj (210963 => 210964)
--- 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)
@@ -1236,6 +1236,8 @@
831EEBBE1BD85C4300BB64C3 /* NetworkCacheSpeculativeLoad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 831EEBBC1BD85C4300BB64C3 /* NetworkCacheSpeculativeLoad.cpp */; };
832AE2521BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 832AE2501BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.h */; };
832AE2531BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 832AE2511BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.cpp */; };
+ 832ED18B1E2FE157006BA64A /* PerActivityStateCPUUsageSampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 832ED1891E2FE13B006BA64A /* PerActivityStateCPUUsageSampler.cpp */; };
+ 832ED18C1E2FE157006BA64A /* PerActivityStateCPUUsageSampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 832ED18A1E2FE13B006BA64A /* PerActivityStateCPUUsageSampler.h */; };
834B250F1A831A8D00CFB150 /* NetworkCacheFileSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 834B250E1A831A8D00CFB150 /* NetworkCacheFileSystem.h */; };
834B25121A842C8700CFB150 /* NetworkCacheStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 834B25101A842C8700CFB150 /* NetworkCacheStatistics.h */; };
8360349F1ACB34D600626549 /* WebSQLiteDatabaseTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8360349D1ACB34D600626549 /* WebSQLiteDatabaseTracker.cpp */; };
@@ -3390,6 +3392,8 @@
831EEBBC1BD85C4300BB64C3 /* NetworkCacheSpeculativeLoad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkCacheSpeculativeLoad.cpp; sourceTree = "<group>"; };
832AE2501BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCacheSpeculativeLoadManager.h; sourceTree = "<group>"; };
832AE2511BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkCacheSpeculativeLoadManager.cpp; sourceTree = "<group>"; };
+ 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>"; };
834B250E1A831A8D00CFB150 /* NetworkCacheFileSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCacheFileSystem.h; sourceTree = "<group>"; };
834B25101A842C8700CFB150 /* NetworkCacheStatistics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCacheStatistics.h; sourceTree = "<group>"; };
8360349D1ACB34D600626549 /* WebSQLiteDatabaseTracker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSQLiteDatabaseTracker.cpp; sourceTree = "<group>"; };
@@ -6274,6 +6278,8 @@
BC6EDAA5111271C600E7678B /* PageClient.h */,
1AC75379183A9FDA0072CB15 /* PageLoadState.cpp */,
1AC7537A183A9FDB0072CB15 /* PageLoadState.h */,
+ 832ED1891E2FE13B006BA64A /* PerActivityStateCPUUsageSampler.cpp */,
+ 832ED18A1E2FE13B006BA64A /* PerActivityStateCPUUsageSampler.h */,
37716A59195B910500EE8B1B /* ProcessAssertion.cpp */,
86F9536018FF4FD4001DB2EF /* ProcessAssertion.h */,
86E67A22190F411800004AB7 /* ProcessThrottler.cpp */,
@@ -8070,6 +8076,7 @@
CE1A0BD71A48E6C60054EF74 /* TextInputSPI.h in Headers */,
1AAF263914687C39004A1E8A /* TiledCoreAnimationDrawingArea.h in Headers */,
1AF05D8714688348008B1E81 /* TiledCoreAnimationDrawingAreaProxy.h in Headers */,
+ 832ED18C1E2FE157006BA64A /* PerActivityStateCPUUsageSampler.h in Headers */,
1AFE436618B6C081009C7A48 /* UIDelegate.h in Headers */,
515BE1B51D5917FF00DD7C68 /* UIGamepad.h in Headers */,
515BE1A91D55293400DD7C68 /* UIGamepadProvider.h in Headers */,
@@ -9233,6 +9240,7 @@
93A88B471BC8829700ABA5C2 /* APIHitTestResult.cpp in Sources */,
7CD3A4821A5D02FA009623B8 /* APINavigation.cpp in Sources */,
BCF69FA31176D01400471A52 /* APINavigationData.cpp in Sources */,
+ 832ED18B1E2FE157006BA64A /* PerActivityStateCPUUsageSampler.cpp in Sources */,
B63403F914910D57001070B5 /* APIObject.cpp in Sources */,
378E1A3D181ED6FF0031007A /* APIObject.mm in Sources */,
BC857FB612B830E600EDEB2E /* APIOpenPanelParameters.cpp in Sources */,
Modified: branches/safari-603-branch/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp (210963 => 210964)
--- 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)
@@ -49,6 +49,7 @@
#include "WebPageProxyMessages.h"
#include "WebPopupMenu.h"
#include "WebProcess.h"
+#include "WebProcessPoolMessages.h"
#include "WebProcessProxyMessages.h"
#include "WebSearchPopupMenu.h"
#include <WebCore/ApplicationCacheStorage.h>
@@ -265,6 +266,11 @@
m_page->runModal();
}
+void WebChromeClient::reportProcessCPUTime(int64_t cpuTime, ActivityStateForCPUSampling activityState)
+{
+ WebProcess::singleton().send(Messages::WebProcessPool::ReportWebContentCPUTime(cpuTime, static_cast<uint64_t>(activityState)), 0);
+}
+
void WebChromeClient::setToolbarsVisible(bool toolbarsAreVisible)
{
m_page->send(Messages::WebPageProxy::SetToolbarsAreVisible(toolbarsAreVisible));
Modified: branches/safari-603-branch/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h (210963 => 210964)
--- 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)
@@ -74,6 +74,8 @@
bool canRunModal() override;
void runModal() override;
+
+ void reportProcessCPUTime(int64_t, WebCore::ActivityStateForCPUSampling) final;
void setToolbarsVisible(bool) override;
bool toolbarsVisible() override;