Title: [243357] trunk/Source
Revision
243357
Author
beid...@apple.com
Date
2019-03-21 20:00:44 -0700 (Thu, 21 Mar 2019)

Log Message

Certain WebProcesses should opt-out of the freezer.
<rdar://problem/42846139> and https://bugs.webkit.org/show_bug.cgi?id=196062

Reviewed by Andy Estes.

Source/bmalloc:

* bmalloc.xcodeproj/project.pbxproj:
* bmalloc/darwin/MemoryStatusSPI.h:

Source/WebKit:

WebProcesses should opt-in and opt-out of the freezer as is appropriate.
By default a WebProcess is freezer eligible.
If any of the following become true then it should become ineligible:
- The WebProcess is a pre-warmed process.
- The WebProcess is in the process cache.
- The WebProcess is not actively hosting any web pages (e.g. it only has suspending web pages)

The most complicated part of the above is guaranteeing that any operation that changes
the active pages hosted by the process causes a recalculation of the freezer opt-in state.

To do that this replaces the basic WebPageProxyMap with a custom class.

* UIProcess/WebProcessProxy.cpp:
(WebKit::globalPageMap):
(WebKit::WebProcessProxy::WebProcessProxy):
(WebKit::WebProcessProxy::validateFreezerStatus):
(WebKit::WebProcessProxy::setIsInProcessCache):
(WebKit::WebProcessProxy::markIsNoLongerInPrewarmedPool):
(WebKit::WebProcessProxy::didFinishLaunching):
* UIProcess/WebProcessProxy.h:
(WebKit::WebProcessProxy::WebPageProxyMap::WebPageProxyMap):
(WebKit::WebProcessProxy::WebPageProxyMap::size const):
(WebKit::WebProcessProxy::WebPageProxyMap::values):
(WebKit::WebProcessProxy::WebPageProxyMap::values const):
(WebKit::WebProcessProxy::WebPageProxyMap::begin):
(WebKit::WebProcessProxy::WebPageProxyMap::end):
(WebKit::WebProcessProxy::WebPageProxyMap::get):
(WebKit::WebProcessProxy::WebPageProxyMap::contains const):
(WebKit::WebProcessProxy::WebPageProxyMap::isEmpty const):
(WebKit::WebProcessProxy::WebPageProxyMap::set):
(WebKit::WebProcessProxy::WebPageProxyMap::take):

* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::setFreezable):
* WebProcess/WebProcess.h:
* WebProcess/WebProcess.messages.in:

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (243356 => 243357)


--- trunk/Source/WebKit/ChangeLog	2019-03-22 02:47:35 UTC (rev 243356)
+++ trunk/Source/WebKit/ChangeLog	2019-03-22 03:00:44 UTC (rev 243357)
@@ -1,3 +1,47 @@
+2019-03-21  Brady Eidson  <beid...@apple.com>
+
+        Certain WebProcesses should opt-out of the freezer.
+        <rdar://problem/42846139> and https://bugs.webkit.org/show_bug.cgi?id=196062
+
+        Reviewed by Andy Estes.
+
+        WebProcesses should opt-in and opt-out of the freezer as is appropriate.
+        By default a WebProcess is freezer eligible.
+        If any of the following become true then it should become ineligible:
+        - The WebProcess is a pre-warmed process.
+        - The WebProcess is in the process cache.
+        - The WebProcess is not actively hosting any web pages (e.g. it only has suspending web pages)
+
+        The most complicated part of the above is guaranteeing that any operation that changes
+        the active pages hosted by the process causes a recalculation of the freezer opt-in state.
+
+        To do that this replaces the basic WebPageProxyMap with a custom class.
+
+        * UIProcess/WebProcessProxy.cpp:
+        (WebKit::globalPageMap):
+        (WebKit::WebProcessProxy::WebProcessProxy):
+        (WebKit::WebProcessProxy::validateFreezerStatus):
+        (WebKit::WebProcessProxy::setIsInProcessCache):
+        (WebKit::WebProcessProxy::markIsNoLongerInPrewarmedPool):
+        (WebKit::WebProcessProxy::didFinishLaunching):
+        * UIProcess/WebProcessProxy.h:
+        (WebKit::WebProcessProxy::WebPageProxyMap::WebPageProxyMap):
+        (WebKit::WebProcessProxy::WebPageProxyMap::size const):
+        (WebKit::WebProcessProxy::WebPageProxyMap::values):
+        (WebKit::WebProcessProxy::WebPageProxyMap::values const):
+        (WebKit::WebProcessProxy::WebPageProxyMap::begin):
+        (WebKit::WebProcessProxy::WebPageProxyMap::end):
+        (WebKit::WebProcessProxy::WebPageProxyMap::get):
+        (WebKit::WebProcessProxy::WebPageProxyMap::contains const):
+        (WebKit::WebProcessProxy::WebPageProxyMap::isEmpty const):
+        (WebKit::WebProcessProxy::WebPageProxyMap::set):
+        (WebKit::WebProcessProxy::WebPageProxyMap::take):
+
+        * WebProcess/WebProcess.cpp:
+        (WebKit::WebProcess::setFreezable):
+        * WebProcess/WebProcess.h:
+        * WebProcess/WebProcess.messages.in:
+
 2019-03-21  Tim Horton  <timothy_hor...@apple.com>
 
         Adopt UIWKDocumentContext

Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp (243356 => 243357)


--- trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp	2019-03-22 02:47:35 UTC (rev 243356)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp	2019-03-22 03:00:44 UTC (rev 243357)
@@ -115,10 +115,10 @@
     return ++uniquePageID;
 }
 
-static WebProcessProxy::WebPageProxyMap& globalPageMap()
+static WebProcessProxy::WebPageProxyMap::MapType& globalPageMap()
 {
     ASSERT(isMainThreadOrCheckDisabled());
-    static NeverDestroyed<WebProcessProxy::WebPageProxyMap> pageMap;
+    static NeverDestroyed<WebProcessProxy::WebPageProxyMap::MapType> pageMap;
     return pageMap;
 }
 
@@ -136,6 +136,7 @@
     , m_backgroundResponsivenessTimer(*this)
     , m_processPool(processPool, isPrewarmed == IsPrewarmed::Yes ? IsWeak::Yes : IsWeak::No)
     , m_mayHaveUniversalFileReadSandboxExtension(false)
+    , m_pageMap(*this)
     , m_numberOfTimesSuddenTerminationWasDisabled(0)
     , m_throttler(*this, processPool.shouldTakeUIBackgroundAssertion())
     , m_isResponsive(NoOrMaybe::Maybe)
@@ -187,6 +188,18 @@
 #endif
 }
 
+void WebProcessProxy::validateFreezerStatus()
+{
+#if PLATFORM(IOS_FAMILY)
+    bool value = !m_isPrewarmed && !m_isInProcessCache && !m_pageMap.isEmpty() && !isServiceWorkerProcess();
+    if (m_currentIsFreezableValue != WTF::nullopt && m_currentIsFreezableValue == value)
+        return;
+
+    m_currentIsFreezableValue = value;
+    send(Messages::WebProcess::SetFreezable(value), 0);
+#endif
+}
+
 void WebProcessProxy::setIsInProcessCache(bool value)
 {
     ASSERT(m_isInProcessCache != value);
@@ -202,6 +215,8 @@
         RELEASE_ASSERT(m_processPool);
         m_processPool.setIsWeak(IsWeak::No);
     }
+    
+    validateFreezerStatus();
 }
 
 void WebProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions)
@@ -379,6 +394,8 @@
     RELEASE_ASSERT(m_processPool);
     m_processPool.setIsWeak(IsWeak::No);
 
+    validateFreezerStatus();
+
     send(Messages::WebProcess::MarkIsNoLongerPrewarmed(), 0);
 }
 
@@ -772,6 +789,8 @@
 
     unblockAccessibilityServerIfNeeded();
 #endif
+
+    validateFreezerStatus();
 }
 
 WebFrameProxy* WebProcessProxy::webFrame(uint64_t frameID) const

Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.h (243356 => 243357)


--- trunk/Source/WebKit/UIProcess/WebProcessProxy.h	2019-03-22 02:47:35 UTC (rev 243356)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.h	2019-03-22 03:00:44 UTC (rev 243357)
@@ -96,7 +96,6 @@
 class WebProcessProxy : public AuxiliaryProcessProxy, public ResponsivenessTimer::Client, public ThreadSafeRefCounted<WebProcessProxy>, public CanMakeWeakPtr<WebProcessProxy>, private ProcessThrottlerClient {
 public:
     typedef HashMap<uint64_t, RefPtr<WebFrameProxy>> WebFrameProxyMap;
-    typedef HashMap<uint64_t, WebPageProxy*> WebPageProxyMap;
     typedef HashMap<uint64_t, RefPtr<API::UserInitiatedAction>> UserInitiatedActionMap;
 
     enum class IsPrewarmed {
@@ -137,6 +136,45 @@
     void addProvisionalPageProxy(ProvisionalPageProxy& provisionalPage) { ASSERT(!m_provisionalPages.contains(&provisionalPage)); m_provisionalPages.add(&provisionalPage); }
     void removeProvisionalPageProxy(ProvisionalPageProxy& provisionalPage) { ASSERT(m_provisionalPages.contains(&provisionalPage)); m_provisionalPages.remove(&provisionalPage); }
 
+    class WebPageProxyMap {
+    public:
+        WebPageProxyMap(WebProcessProxy& proxy)
+            : m_proxy(proxy)
+        {
+        }
+
+        typedef HashMap<uint64_t, WebPageProxy*> MapType;
+        using ValuesConstIteratorRange = MapType::ValuesConstIteratorRange;
+
+        auto size() const { return m_map.size(); }
+        auto values() { return m_map.values(); }
+        auto values() const { return m_map.values(); }
+        auto begin() { return m_map.begin(); }
+        auto end() { return m_map.end(); }
+        auto get(uint64_t key) { return m_map.get(key); }
+        auto contains(uint64_t key) const { return m_map.contains(key); }
+        auto isEmpty() const { return m_map.isEmpty(); }
+
+        auto set(uint64_t key, WebPageProxy* value)
+        {
+            auto result = m_map.set(key, value);
+            m_proxy.validateFreezerStatus();
+            return result;
+        }
+
+        auto take(uint64_t key)
+        {
+            auto result = m_map.take(key);
+            m_proxy.validateFreezerStatus();
+            return result;
+        }
+
+    private:
+        WebProcessProxy& m_proxy;
+        MapType m_map;
+    };
+
+    
     typename WebPageProxyMap::ValuesConstIteratorRange pages() const { return m_pageMap.values(); }
     unsigned pageCount() const { return m_pageMap.size(); }
     unsigned provisionalPageCount() const { return m_provisionalPages.size(); }
@@ -321,6 +359,8 @@
 
     bool isJITEnabled() const final;
 
+    void validateFreezerStatus();
+
 private:
     // IPC message handlers.
     void updateBackForwardItem(const BackForwardListItemState&);
@@ -469,6 +509,7 @@
     unsigned m_suspendedPageCount { 0 };
     bool m_hasCommittedAnyProvisionalLoads { false };
     bool m_isPrewarmed;
+    Optional<bool> m_currentIsFreezableValue;
 
 #if PLATFORM(WATCHOS)
     ProcessThrottler::BackgroundActivityToken m_backgroundActivityTokenForFullscreenFormControls;

Modified: trunk/Source/WebKit/WebProcess/WebProcess.cpp (243356 => 243357)


--- trunk/Source/WebKit/WebProcess/WebProcess.cpp	2019-03-22 02:47:35 UTC (rev 243356)
+++ trunk/Source/WebKit/WebProcess/WebProcess.cpp	2019-03-22 03:00:44 UTC (rev 243357)
@@ -149,6 +149,10 @@
 #include <_javascript_Core/RemoteInspector.h>
 #endif
 
+#if PLATFORM(IOS_FAMILY)
+#include <bmalloc/MemoryStatusSPI.h>
+#endif
+
 // This should be less than plugInAutoStartExpirationTimeThreshold in PlugInAutoStartProvider.
 static const Seconds plugInAutoStartExpirationTimeUpdateThreshold { 29 * 24 * 60 * 60 };
 
@@ -1871,7 +1875,15 @@
     PlatformKeyboardEvent::setCurrentModifierState({ });
 }
 
+void WebProcess::setFreezable(bool freezable)
+{
 #if PLATFORM(IOS_FAMILY)
+    auto result = memorystatus_control(MEMORYSTATUS_CMD_SET_PROCESS_IS_FREEZABLE, getpid(), freezable ? 1 : 0, nullptr, 0);
+    ASSERT_UNUSED(result, !result);
+#endif
+}
+
+#if PLATFORM(IOS_FAMILY)
 void WebProcess::unblockAccessibilityServer(const SandboxExtension::Handle& handle)
 {
     bool ok = SandboxExtension::consumePermanently(handle);

Modified: trunk/Source/WebKit/WebProcess/WebProcess.h (243356 => 243357)


--- trunk/Source/WebKit/WebProcess/WebProcess.h	2019-03-22 02:47:35 UTC (rev 243356)
+++ trunk/Source/WebKit/WebProcess/WebProcess.h	2019-03-22 03:00:44 UTC (rev 243357)
@@ -426,6 +426,7 @@
 #endif
 
     void clearCurrentModifierStateForTesting();
+    void setFreezable(bool);
 
     RefPtr<WebConnectionToUIProcess> m_webConnection;
 

Modified: trunk/Source/WebKit/WebProcess/WebProcess.messages.in (243356 => 243357)


--- trunk/Source/WebKit/WebProcess/WebProcess.messages.in	2019-03-22 02:47:35 UTC (rev 243356)
+++ trunk/Source/WebKit/WebProcess/WebProcess.messages.in	2019-03-22 03:00:44 UTC (rev 243357)
@@ -161,4 +161,6 @@
 #if PLATFORM(IOS_FAMILY)
     UnblockAccessibilityServer(WebKit::SandboxExtension::Handle handle)
 #endif
+
+    SetFreezable(bool freezable)
 }

Modified: trunk/Source/bmalloc/ChangeLog (243356 => 243357)


--- trunk/Source/bmalloc/ChangeLog	2019-03-22 02:47:35 UTC (rev 243356)
+++ trunk/Source/bmalloc/ChangeLog	2019-03-22 03:00:44 UTC (rev 243357)
@@ -1,3 +1,13 @@
+2019-03-21  Brady Eidson  <beid...@apple.com>
+
+        Certain WebProcesses should opt-out of the freezer.
+        <rdar://problem/42846139> and https://bugs.webkit.org/show_bug.cgi?id=196062
+
+        Reviewed by Andy Estes.
+
+        * bmalloc.xcodeproj/project.pbxproj:
+        * bmalloc/darwin/MemoryStatusSPI.h:
+
 2019-03-19  Michael Catanzaro  <mcatanz...@igalia.com>
 
         Unreviewed, fix -Wformat warning

Modified: trunk/Source/bmalloc/bmalloc/darwin/MemoryStatusSPI.h (243356 => 243357)


--- trunk/Source/bmalloc/bmalloc/darwin/MemoryStatusSPI.h	2019-03-22 02:47:35 UTC (rev 243356)
+++ trunk/Source/bmalloc/bmalloc/darwin/MemoryStatusSPI.h	2019-03-22 03:00:44 UTC (rev 243357)
@@ -43,6 +43,8 @@
 } memorystatus_memlimit_properties_t;
 
 #define MEMORYSTATUS_CMD_GET_MEMLIMIT_PROPERTIES 8
+#define MEMORYSTATUS_CMD_SET_PROCESS_IS_FREEZABLE 18
+#define MEMORYSTATUS_CMD_GET_PROCESS_IS_FREEZABLE 19
 
 }
 #endif // __has_include(<System/sys/kern_memorystatus.h>)

Modified: trunk/Source/bmalloc/bmalloc.xcodeproj/project.pbxproj (243356 => 243357)


--- trunk/Source/bmalloc/bmalloc.xcodeproj/project.pbxproj	2019-03-22 02:47:35 UTC (rev 243356)
+++ trunk/Source/bmalloc/bmalloc.xcodeproj/project.pbxproj	2019-03-22 03:00:44 UTC (rev 243357)
@@ -131,7 +131,7 @@
 		4426E2801C838EE0008EB042 /* Logging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4426E27E1C838EE0008EB042 /* Logging.cpp */; };
 		4426E2811C838EE0008EB042 /* Logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 4426E27F1C838EE0008EB042 /* Logging.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		4426E2831C839547008EB042 /* BSoftLinking.h in Headers */ = {isa = PBXBuildFile; fileRef = 4426E2821C839547008EB042 /* BSoftLinking.h */; };
-		52F47249210BA30200B730BB /* MemoryStatusSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 52F47248210BA2F500B730BB /* MemoryStatusSPI.h */; };
+		52F47249210BA30200B730BB /* MemoryStatusSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 52F47248210BA2F500B730BB /* MemoryStatusSPI.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		6543DDB420EEAEF3003B23D8 /* PerThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6543DDB320EEAEF3003B23D8 /* PerThread.cpp */; };
 		6599C5CC1EC3F15900A2F7BB /* AvailableMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6599C5CA1EC3F15900A2F7BB /* AvailableMemory.cpp */; };
 		6599C5CD1EC3F15900A2F7BB /* AvailableMemory.h in Headers */ = {isa = PBXBuildFile; fileRef = 6599C5CB1EC3F15900A2F7BB /* AvailableMemory.h */; settings = {ATTRIBUTES = (Private, ); }; };
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to