[iOS] Report domains crashing under memory pressure via enhanced privacy logging.
authorakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 6 Mar 2017 10:02:09 +0000 (10:02 +0000)
committerakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 6 Mar 2017 10:02:09 +0000 (10:02 +0000)
<https://webkit.org/b/169133>
<rdar://problem/29964017>

Reviewed by Antti Koivisto.

Source/WebCore:

* page/DiagnosticLoggingKeys.h:

Source/WebKit2:

Notify the UI process when the memory pressure status changes.
If a web process crashes while under memory pressure, log the domain of the last open page
using enhanced privacy logging.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::processDidCrash):
* UIProcess/WebProcessProxy.h:
(WebKit::WebProcessProxy::memoryPressureStatusChanged):
(WebKit::WebProcessProxy::isUnderMemoryPressure):
* UIProcess/WebProcessProxy.messages.in:
* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::initializeWebProcess):

Source/WTF:

Add a mechanism for getting a callback when the memory pressure status changes.

* wtf/MemoryPressureHandler.cpp:
(WTF::MemoryPressureHandler::measurementTimerFired):
(WTF::MemoryPressureHandler::beginSimulatedMemoryPressure):
(WTF::MemoryPressureHandler::endSimulatedMemoryPressure):
(WTF::MemoryPressureHandler::setUnderMemoryPressure):
(WTF::MemoryPressureHandler::memoryPressureStatusChanged):
* wtf/MemoryPressureHandler.h:
(WTF::MemoryPressureHandler::setMemoryPressureStatusChangedCallback):
(WTF::MemoryPressureHandler::setUnderMemoryPressure): Deleted.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@213444 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WTF/ChangeLog
Source/WTF/wtf/MemoryPressureHandler.cpp
Source/WTF/wtf/MemoryPressureHandler.h
Source/WebCore/ChangeLog
Source/WebCore/page/DiagnosticLoggingKeys.h
Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/WebPageProxy.cpp
Source/WebKit2/UIProcess/WebProcessProxy.h
Source/WebKit2/UIProcess/WebProcessProxy.messages.in
Source/WebKit2/WebProcess/WebProcess.cpp

index df63617..2b8f81e 100644 (file)
@@ -1,3 +1,23 @@
+2017-03-06  Andreas Kling  <akling@apple.com>
+
+        [iOS] Report domains crashing under memory pressure via enhanced privacy logging.
+        <https://webkit.org/b/169133>
+        <rdar://problem/29964017>
+
+        Reviewed by Antti Koivisto.
+
+        Add a mechanism for getting a callback when the memory pressure status changes.
+
+        * wtf/MemoryPressureHandler.cpp:
+        (WTF::MemoryPressureHandler::measurementTimerFired):
+        (WTF::MemoryPressureHandler::beginSimulatedMemoryPressure):
+        (WTF::MemoryPressureHandler::endSimulatedMemoryPressure):
+        (WTF::MemoryPressureHandler::setUnderMemoryPressure):
+        (WTF::MemoryPressureHandler::memoryPressureStatusChanged):
+        * wtf/MemoryPressureHandler.h:
+        (WTF::MemoryPressureHandler::setMemoryPressureStatusChangedCallback):
+        (WTF::MemoryPressureHandler::setUnderMemoryPressure): Deleted.
+
 2017-03-03  Jer Noble  <jer.noble@apple.com>
 
         [Win64] '__int128_t': undeclared identifier in MediaTime.cpp
index 8b84749..eff316e 100644 (file)
@@ -124,6 +124,7 @@ void MemoryPressureHandler::measurementTimerFired()
         RELEASE_LOG(MemoryPressure, "Memory usage policy changed: %s -> %s", toString(m_memoryUsagePolicy), toString(newPolicy));
 
     m_memoryUsagePolicy = newPolicy;
+    memoryPressureStatusChanged();
 
     if (newPolicy == MemoryUsagePolicy::Unrestricted)
         return;
@@ -159,6 +160,7 @@ void MemoryPressureHandler::measurementTimerFired()
     if (footprint.value() < thresholdForPolicy(MemoryUsagePolicy::Panic)) {
         m_memoryUsagePolicy = policyForFootprint(footprint.value());
         RELEASE_LOG(MemoryPressure, "Pressure reduced below panic threshold. New memory usage policy: %s", toString(m_memoryUsagePolicy));
+        memoryPressureStatusChanged();
         return;
     }
 
@@ -168,13 +170,19 @@ void MemoryPressureHandler::measurementTimerFired()
 
 void MemoryPressureHandler::beginSimulatedMemoryPressure()
 {
+    if (m_isSimulatingMemoryPressure)
+        return;
     m_isSimulatingMemoryPressure = true;
+    memoryPressureStatusChanged();
     respondToMemoryPressure(Critical::Yes, Synchronous::Yes);
 }
 
 void MemoryPressureHandler::endSimulatedMemoryPressure()
 {
+    if (!m_isSimulatingMemoryPressure)
+        return;
     m_isSimulatingMemoryPressure = false;
+    memoryPressureStatusChanged();
 }
 
 void MemoryPressureHandler::releaseMemory(Critical critical, Synchronous synchronous)
@@ -187,6 +195,20 @@ void MemoryPressureHandler::releaseMemory(Critical critical, Synchronous synchro
     platformReleaseMemory(critical);
 }
 
+void MemoryPressureHandler::setUnderMemoryPressure(bool underMemoryPressure)
+{
+    if (m_underMemoryPressure == underMemoryPressure)
+        return;
+    m_underMemoryPressure = underMemoryPressure;
+    memoryPressureStatusChanged();
+}
+
+void MemoryPressureHandler::memoryPressureStatusChanged()
+{
+    if (m_memoryPressureStatusChangedCallback)
+        m_memoryPressureStatusChangedCallback(isUnderMemoryPressure());
+}
+
 void MemoryPressureHandler::ReliefLogger::logMemoryUsageChange()
 {
 #if !RELEASE_LOG_DISABLED
index 6d3b0d4..42b2f57 100644 (file)
@@ -68,6 +68,7 @@ public:
 
     void setMemoryKillCallback(WTF::Function<void()> function) { m_memoryKillCallback = WTFMove(function); }
     void setProcessIsEligibleForMemoryKillCallback(WTF::Function<bool()> function) { m_processIsEligibleForMemoryKillCallback = WTFMove(function); }
+    void setMemoryPressureStatusChangedCallback(WTF::Function<void(bool)> function) { m_memoryPressureStatusChangedCallback = WTFMove(function); }
 
     void setLowMemoryHandler(LowMemoryHandler&& handler)
     {
@@ -82,7 +83,7 @@ public:
 #endif
             || m_isSimulatingMemoryPressure;
     }
-    void setUnderMemoryPressure(bool b) { m_underMemoryPressure = b; }
+    void setUnderMemoryPressure(bool);
 
 #if OS(LINUX)
     void setMemoryPressureMonitorHandle(int fd);
@@ -140,6 +141,8 @@ public:
     WTF_EXPORT_PRIVATE void endSimulatedMemoryPressure();
 
 private:
+    void memoryPressureStatusChanged();
+
     void uninstall();
 
     void holdOff(unsigned);
@@ -184,9 +187,8 @@ private:
     MemoryUsagePolicy m_memoryUsagePolicy { MemoryUsagePolicy::Unrestricted };
     WTF::Function<void()> m_memoryKillCallback;
     WTF::Function<bool()> m_processIsEligibleForMemoryKillCallback;
+    WTF::Function<void(bool)> m_memoryPressureStatusChangedCallback;
 
-    WTFLogChannel m_logChannel;
-    
 #if OS(WINDOWS)
     void windowsMeasurementTimerFired();
     RunLoop::Timer<MemoryPressureHandler> m_windowsMeasurementTimer;
index df99da9..9f2aade 100644 (file)
@@ -1,3 +1,13 @@
+2017-03-06  Andreas Kling  <akling@apple.com>
+
+        [iOS] Report domains crashing under memory pressure via enhanced privacy logging.
+        <https://webkit.org/b/169133>
+        <rdar://problem/29964017>
+
+        Reviewed by Antti Koivisto.
+
+        * page/DiagnosticLoggingKeys.h:
+
 2017-03-05  Simon Fraser  <simon.fraser@apple.com>
 
         Avoid backing store for layers with empty text nodes in a few more cases
index e202834..35dcd8a 100644 (file)
@@ -51,7 +51,7 @@ public:
     static String diskCacheAfterValidationKey();
     static String documentLoaderStoppingKey();
     static String domainCausingEnergyDrainKey();
-    static String domainCausingJetsamKey();
+    WEBCORE_EXPORT static String domainCausingJetsamKey();
     static String domainVisitedKey();
     static String engineFailedToLoadKey();
     WEBCORE_EXPORT static String entryRightlyNotWarmedUpKey();
index dc4b72a..47666f8 100644 (file)
@@ -1,3 +1,24 @@
+2017-03-06  Andreas Kling  <akling@apple.com>
+
+        [iOS] Report domains crashing under memory pressure via enhanced privacy logging.
+        <https://webkit.org/b/169133>
+        <rdar://problem/29964017>
+
+        Reviewed by Antti Koivisto.
+
+        Notify the UI process when the memory pressure status changes.
+        If a web process crashes while under memory pressure, log the domain of the last open page
+        using enhanced privacy logging.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::processDidCrash):
+        * UIProcess/WebProcessProxy.h:
+        (WebKit::WebProcessProxy::memoryPressureStatusChanged):
+        (WebKit::WebProcessProxy::isUnderMemoryPressure):
+        * UIProcess/WebProcessProxy.messages.in:
+        * WebProcess/WebProcess.cpp:
+        (WebKit::WebProcess::initializeWebProcess):
+
 2017-03-05  Brady Eidson  <beidson@apple.com>
 
         Remove new files accidentally added in r213441
index b68ac87..7507171 100644 (file)
 #include "WebsiteDataStore.h"
 #include <WebCore/BitmapImage.h>
 #include <WebCore/DiagnosticLoggingClient.h>
+#include <WebCore/DiagnosticLoggingKeys.h>
 #include <WebCore/DragController.h>
 #include <WebCore/DragData.h>
 #include <WebCore/EventNames.h>
 #include <WebCore/JSDOMBinding.h>
 #include <WebCore/JSDOMExceptionHandling.h>
 #include <WebCore/MIMETypeRegistry.h>
+#include <WebCore/PublicSuffix.h>
 #include <WebCore/RenderEmbeddedObject.h>
 #include <WebCore/SerializedCryptoKeyWrap.h>
 #include <WebCore/TextCheckerClient.h>
@@ -5283,6 +5285,17 @@ void WebPageProxy::processDidCrash()
 {
     ASSERT(m_isValid);
 
+#if PLATFORM(IOS)
+    if (m_process->isUnderMemoryPressure()) {
+        String url = m_pageLoadState.activeURL();
+        if (url.isEmpty() && m_backForwardList->currentItem())
+            url = m_backForwardList->currentItem()->url();
+        String domain = WebCore::topPrivatelyControlledDomain(WebCore::URL(WebCore::ParsedURLString, url).host());
+        if (!domain.isEmpty())
+            logDiagnosticMessageWithEnhancedPrivacy(WebCore::DiagnosticLoggingKeys::domainCausingJetsamKey(), domain, WebCore::ShouldSample::No);
+    }
+#endif
+
     // There is a nested transaction in resetStateAfterProcessExited() that we don't want to commit before the client call.
     PageLoadState::Transaction transaction = m_pageLoadState.transaction();
 
index c359763..01cb89f 100644 (file)
@@ -158,6 +158,9 @@ public:
     void isResponsive(std::function<void(bool isWebProcessResponsive)>);
     void didReceiveMainThreadPing();
 
+    void memoryPressureStatusChanged(bool isUnderMemoryPressure) { m_isUnderMemoryPressure = isUnderMemoryPressure; }
+    bool isUnderMemoryPressure() const { return m_isUnderMemoryPressure; }
+
 private:
     explicit WebProcessProxy(WebProcessPool&, WebsiteDataStore*);
 
@@ -263,6 +266,8 @@ private:
 
     // FIXME: WebsiteDataStores should be made per-WebPageProxy throughout WebKit2. Get rid of this member.
     RefPtr<WebsiteDataStore> m_websiteDataStore;
+
+    bool m_isUnderMemoryPressure { false };
 };
 
 } // namespace WebKit
index f21565b..925b4dc 100644 (file)
@@ -49,4 +49,6 @@ messages -> WebProcessProxy LegacyReceiver {
     ReleaseIconForPageURL(String pageURL)
 
     DidReceiveMainThreadPing()
+
+    MemoryPressureStatusChanged(bool isUnderMemoryPressure)
 }
index baa78e7..015f161 100644 (file)
@@ -270,6 +270,10 @@ void WebProcess::initializeWebProcess(WebProcessCreationParameters&& parameters)
             return WebCore::processIsEligibleForMemoryKill();
         });
 #endif
+        memoryPressureHandler.setMemoryPressureStatusChangedCallback([this](bool isUnderMemoryPressure) {
+            if (parentProcessConnection())
+                parentProcessConnection()->send(Messages::WebProcessProxy::MemoryPressureStatusChanged(isUnderMemoryPressure), 0);
+        });
         memoryPressureHandler.install();
     }