Discard media controls JS/CSS caches under memory pressure.
authorakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 Jan 2017 15:36:41 +0000 (15:36 +0000)
committerakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 Jan 2017 15:36:41 +0000 (15:36 +0000)
<https://webkit.org/b/166639>

Reviewed by Antti Koivisto.

Source/WebCore:

Add a RenderTheme::purgeCaches() virtual and teach the iOS and macOS implementations
to drop their cached media controls JS/CSS strings there. The strings are only cleared
if nothing else is referencing them, which gives us a decent "weak cache" behavior.

This sheds ~300kB memory on iOS with the current media controls.

* page/MemoryRelease.cpp:
(WebCore::releaseNoncriticalMemory):
* rendering/RenderTheme.h:
(WebCore::RenderTheme::purgeCaches):
* rendering/RenderThemeIOS.h:
* rendering/RenderThemeIOS.mm:
(WebCore::RenderThemeIOS::purgeCaches):
* rendering/RenderThemeMac.h:
* rendering/RenderThemeMac.mm:
(WebCore::RenderThemeMac::purgeCaches):

Source/WTF:

* wtf/text/WTFString.h:
(WTF::String::clearImplIfNotShared): Add a helper for clearing a String if the underlying
StringImpl is not referenced by anyone else.

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

Source/WTF/ChangeLog
Source/WTF/wtf/text/WTFString.h
Source/WebCore/ChangeLog
Source/WebCore/page/MemoryRelease.cpp
Source/WebCore/rendering/RenderTheme.h
Source/WebCore/rendering/RenderThemeIOS.h
Source/WebCore/rendering/RenderThemeIOS.mm
Source/WebCore/rendering/RenderThemeMac.h
Source/WebCore/rendering/RenderThemeMac.mm

index b71ce0f..ec05cae 100644 (file)
@@ -1,3 +1,14 @@
+2017-01-02  Andreas Kling  <akling@apple.com>
+
+        Discard media controls JS/CSS caches under memory pressure.
+        <https://webkit.org/b/166639>
+
+        Reviewed by Antti Koivisto.
+
+        * wtf/text/WTFString.h:
+        (WTF::String::clearImplIfNotShared): Add a helper for clearing a String if the underlying
+        StringImpl is not referenced by anyone else.
+
 2016-12-22  Mark Lam  <mark.lam@apple.com>
 
         De-duplicate finally blocks.
index f53ac11..01c7681 100644 (file)
@@ -469,6 +469,14 @@ public:
         return (*m_impl)[index];
     }
 
+    // Turns this String empty if the StringImpl is not referenced by anyone else.
+    // This is useful for clearing String-based caches.
+    void clearImplIfNotShared()
+    {
+        if (m_impl && m_impl->hasOneRef())
+            m_impl = nullptr;
+    }
+
 private:
     template <typename CharacterType>
     void removeInternal(const CharacterType*, unsigned, int);
index bf0ea56..d5576d4 100644 (file)
@@ -1,3 +1,27 @@
+2017-01-02  Andreas Kling  <akling@apple.com>
+
+        Discard media controls JS/CSS caches under memory pressure.
+        <https://webkit.org/b/166639>
+
+        Reviewed by Antti Koivisto.
+
+        Add a RenderTheme::purgeCaches() virtual and teach the iOS and macOS implementations
+        to drop their cached media controls JS/CSS strings there. The strings are only cleared
+        if nothing else is referencing them, which gives us a decent "weak cache" behavior.
+
+        This sheds ~300kB memory on iOS with the current media controls.
+
+        * page/MemoryRelease.cpp:
+        (WebCore::releaseNoncriticalMemory):
+        * rendering/RenderTheme.h:
+        (WebCore::RenderTheme::purgeCaches):
+        * rendering/RenderThemeIOS.h:
+        * rendering/RenderThemeIOS.mm:
+        (WebCore::RenderThemeIOS::purgeCaches):
+        * rendering/RenderThemeMac.h:
+        * rendering/RenderThemeMac.mm:
+        (WebCore::RenderThemeMac::purgeCaches):
+
 2017-01-02  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [GTK] Since the memory pressure relief has been activated, my disk has a high usage and the desktop stalls
index 7affe29..e9203dd 100644 (file)
@@ -38,6 +38,7 @@
 #include "MemoryCache.h"
 #include "Page.h"
 #include "PageCache.h"
+#include "RenderTheme.h"
 #include "ScrollingThread.h"
 #include "StyleScope.h"
 #include "StyledElement.h"
@@ -48,6 +49,8 @@ namespace WebCore {
 
 static void releaseNoncriticalMemory()
 {
+    RenderTheme::defaultTheme()->purgeCaches();
+
     FontCache::singleton().purgeInactiveFontData();
 
     clearWidthCaches();
index 35499bb..a9c2e86 100644 (file)
@@ -72,6 +72,8 @@ public:
         return themeForPage(nullptr);
     };
 
+    virtual void purgeCaches() { }
+
     // This method is called whenever style has been computed for an element and the appearance
     // property has been set to a value other than "none".  The theme should map in all of the appropriate
     // metrics and defaults given the contents of the style.  This includes sophisticated operations like
index 33aa3b4..f5fe65f 100644 (file)
@@ -121,6 +121,8 @@ private:
     RenderThemeIOS();
     virtual ~RenderThemeIOS() { }
 
+    void purgeCaches() override;
+
     const Color& shadowColor() const;
     FloatRect addRoundedBorderClip(const RenderObject& box, GraphicsContext&, const IntRect&);
 
index 085c005..100a5d1 100644 (file)
@@ -1305,6 +1305,14 @@ String RenderThemeIOS::mediaControlsStyleSheet()
 #endif
 }
 
+void RenderThemeIOS::purgeCaches()
+{
+    m_legacyMediaControlsScript.clearImplIfNotShared();
+    m_mediaControlsScript.clearImplIfNotShared();
+    m_legacyMediaControlsStyleSheet.clearImplIfNotShared();
+    m_mediaControlsStyleSheet.clearImplIfNotShared();
+}
+
 String RenderThemeIOS::mediaControlsScript()
 {
 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
index 42d3a12..85452f1 100644 (file)
@@ -172,6 +172,8 @@ private:
 
     Color systemColor(CSSValueID) const override;
 
+    void purgeCaches() override;
+
     // Get the control size based off the font. Used by some of the controls (like buttons).
     NSControlSize controlSizeForFont(const RenderStyle&) const;
     NSControlSize controlSizeForSystemFont(const RenderStyle&) const;
index 03fd458..8587a0e 100644 (file)
@@ -246,6 +246,14 @@ String RenderThemeMac::mediaControlsStyleSheet()
 #endif
 }
 
+void RenderThemeMac::purgeCaches()
+{
+    m_legacyMediaControlsScript.clearImplIfNotShared();
+    m_mediaControlsScript.clearImplIfNotShared();
+    m_legacyMediaControlsStyleSheet.clearImplIfNotShared();
+    m_mediaControlsStyleSheet.clearImplIfNotShared();
+}
+
 String RenderThemeMac::mediaControlsScript()
 {
 #if ENABLE(MEDIA_CONTROLS_SCRIPT)