[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

ggaren at apple.com ggaren at apple.com
Wed Dec 22 13:37:48 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 8af7b56a9172bd613ceadadcaa23d8be74e0643e
Author: ggaren at apple.com <ggaren at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Sep 22 00:18:03 2010 +0000

    Use purgeable memory to keep more dead resources in cache
    https://bugs.webkit.org/show_bug.cgi?id=44806
    <rdar://problem/8350901>
    
    Patch by Pratik Solanki <psolanki at apple.com> on 2010-09-21
    Reviewed by Geoffrey Garen and Darin Adler.
    
    This changes the behavior of dead resources in the WebCore cache to be the following if
    shouldMakeResourcePurgeableOnEviction() returns true.
    
    1. Dead resources in the cache are kept in non-purgeable memory.
    2. When we prune dead resources, instead of freeing them, we mark their memory as purgeable
    and keep the resources until the kernel reclaims the purgeable memory.
    
    By leaving the in-cache dead resources in dirty resident memory, we decrease the likelihood
    of the kernel claiming that memory and forcing us to refetch the resource (for example when
    a user presses back).
    
    And by having an unbounded number of resource objects using purgeable memory, we can use
    as much memory as is available on the machine. The trade-off is that the CachedResource
    object (and its member variables) are allocated in non-purgeable TC-malloc'd memory so
    we would see slightly more memory use due to this.
    
    * loader/Cache.cpp:
    (WebCore::Cache::resourceForURL): Adjust sizes appropriately if we made resource memory
    non-purgeable.
    (WebCore::Cache::pruneDeadResources): When removing dead resources, try first to mark their
    memory as purgeable. If not, evict the resource.
    (WebCore::Cache::makeResourcePurgeable): Added. Try to mark resource
    memory as purgeable. If successful, adjust the sizes so that we don't
    factor this resources size in the Cache size calculation.
    (WebCore::Cache::evict): Don't decrement size if we already did it in makeResourcePurgeable.
    (WebCore::Cache::dumpLRULists): Extra debug logging.
    * loader/Cache.h:
    (WebCore::Cache::shouldMakeResourcePurgeableOnEviction): Added. Indicates if the new
    behaviour is enabled.
    * loader/CachedCSSStyleSheet.cpp:
    (WebCore::CachedCSSStyleSheet::allClientsRemoved): Do not mark memory as purgeable. The
    Cache class takes care of this.
    * loader/CachedImage.cpp:
    (WebCore::CachedImage::destroyDecodedData): Ditto.
    * loader/CachedScript.cpp:
    (WebCore::CachedScript::destroyDecodedData): Ditto.
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@67996 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 6595a15..9f76436 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,48 @@
+2010-09-21  Pratik Solanki  <psolanki at apple.com>
+
+        Reviewed by Geoffrey Garen and Darin Adler.
+
+        Use purgeable memory to keep more dead resources in cache
+        https://bugs.webkit.org/show_bug.cgi?id=44806
+        <rdar://problem/8350901>
+
+        This changes the behavior of dead resources in the WebCore cache to be the following if
+        shouldMakeResourcePurgeableOnEviction() returns true.
+
+        1. Dead resources in the cache are kept in non-purgeable memory.
+        2. When we prune dead resources, instead of freeing them, we mark their memory as purgeable
+        and keep the resources until the kernel reclaims the purgeable memory.
+
+        By leaving the in-cache dead resources in dirty resident memory, we decrease the likelihood
+        of the kernel claiming that memory and forcing us to refetch the resource (for example when
+        a user presses back).
+
+        And by having an unbounded number of resource objects using purgeable memory, we can use
+        as much memory as is available on the machine. The trade-off is that the CachedResource
+        object (and its member variables) are allocated in non-purgeable TC-malloc'd memory so
+        we would see slightly more memory use due to this.
+
+        * loader/Cache.cpp:
+        (WebCore::Cache::resourceForURL): Adjust sizes appropriately if we made resource memory
+        non-purgeable.
+        (WebCore::Cache::pruneDeadResources): When removing dead resources, try first to mark their
+        memory as purgeable. If not, evict the resource.
+        (WebCore::Cache::makeResourcePurgeable): Added. Try to mark resource
+        memory as purgeable. If successful, adjust the sizes so that we don't
+        factor this resources size in the Cache size calculation.
+        (WebCore::Cache::evict): Don't decrement size if we already did it in makeResourcePurgeable.
+        (WebCore::Cache::dumpLRULists): Extra debug logging.
+        * loader/Cache.h:
+        (WebCore::Cache::shouldMakeResourcePurgeableOnEviction): Added. Indicates if the new
+        behaviour is enabled.
+        * loader/CachedCSSStyleSheet.cpp:
+        (WebCore::CachedCSSStyleSheet::allClientsRemoved): Do not mark memory as purgeable. The
+        Cache class takes care of this.
+        * loader/CachedImage.cpp:
+        (WebCore::CachedImage::destroyDecodedData): Ditto.
+        * loader/CachedScript.cpp:
+        (WebCore::CachedScript::destroyDecodedData): Ditto.
+
 2010-09-21  Dan Bernstein  <mitz at apple.com>
 
         Reviewed by Darin Adler.
diff --git a/WebCore/loader/Cache.cpp b/WebCore/loader/Cache.cpp
index dbcec00..647dfac 100644
--- a/WebCore/loader/Cache.cpp
+++ b/WebCore/loader/Cache.cpp
@@ -238,11 +238,15 @@ void Cache::revalidationFailed(CachedResource* revalidatingResource)
 CachedResource* Cache::resourceForURL(const String& url)
 {
     CachedResource* resource = m_resources.get(url);
+    bool wasPurgeable = Cache::shouldMakeResourcePurgeableOnEviction() && resource && resource->isPurgeable();
     if (resource && !resource->makePurgeable(false)) {
         ASSERT(!resource->hasClients());
         evict(resource);
         return 0;
     }
+    // Add the size back since we had subtracted it when we marked the memory as purgeable.
+    if (wasPurgeable)
+        adjustSize(resource->hasClients(), resource->size());
     return resource;
 }
 
@@ -363,7 +367,9 @@ void Cache::pruneDeadResources()
         while (current) {
             CachedResource* prev = current->m_prevInAllResourcesList;
             if (!current->hasClients() && !current->isPreloaded() && !current->isCacheValidator()) {
-                evict(current);
+                if (!makeResourcePurgeable(current))
+                    evict(current);
+
                 // If evict() caused pruneDeadResources() to be re-entered, bail out. This can happen when removing an
                 // SVG CachedImage that has subresources.
                 if (!m_inPruneDeadResources)
@@ -397,6 +403,25 @@ void Cache::setCapacities(unsigned minDeadBytes, unsigned maxDeadBytes, unsigned
     prune();
 }
 
+bool Cache::makeResourcePurgeable(CachedResource* resource)
+{
+    if (!Cache::shouldMakeResourcePurgeableOnEviction())
+        return false;
+
+    if (!resource->inCache())
+        return false;
+
+    if (!resource->isSafeToMakePurgeable())
+        return false;
+
+    if (!resource->makePurgeable(true))
+        return false;
+
+    adjustSize(resource->hasClients(), -resource->size());
+
+    return true;
+}
+
 void Cache::evict(CachedResource* resource)
 {
     // The resource may have already been removed by someone other than our caller,
@@ -410,10 +435,10 @@ void Cache::evict(CachedResource* resource)
         removeFromLRUList(resource);
         removeFromLiveDecodedResourcesList(resource);
 
-        // Subtract from our size totals.
-        int delta = -static_cast<int>(resource->size());
-        if (delta)
-            adjustSize(resource->hasClients(), delta);
+        // If the resource was purged, it means we had already decremented the size when we made the
+        // resource purgeable in makeResourcePurgeable().
+        if (!Cache::shouldMakeResourcePurgeableOnEviction() || !resource->wasPurged())
+            adjustSize(resource->hasClients(), -resource->size());
     } else
         ASSERT(m_resources.get(resource->url()) != resource);
 
@@ -725,7 +750,7 @@ void Cache::dumpStats()
 
 void Cache::dumpLRULists(bool includeLive) const
 {
-    printf("LRU-SP lists in eviction order (Kilobytes decoded, Kilobytes encoded, Access count, Referenced):\n");
+    printf("LRU-SP lists in eviction order (Kilobytes decoded, Kilobytes encoded, Access count, Referenced, isPurgeable, wasPurged):\n");
 
     int size = m_allResources.size();
     for (int i = size - 1; i >= 0; i--) {
@@ -734,7 +759,8 @@ void Cache::dumpLRULists(bool includeLive) const
         while (current) {
             CachedResource* prev = current->m_prevInAllResourcesList;
             if (includeLive || !current->hasClients())
-                printf("(%.1fK, %.1fK, %uA, %dR); ", current->decodedSize() / 1024.0f, (current->encodedSize() + current->overheadSize()) / 1024.0f, current->accessCount(), current->hasClients());
+                printf("(%.1fK, %.1fK, %uA, %dR, %d, %d); ", current->decodedSize() / 1024.0f, (current->encodedSize() + current->overheadSize()) / 1024.0f, current->accessCount(), current->hasClients(), current->isPurgeable(), current->wasPurged());
+
             current = prev;
         }
     }
diff --git a/WebCore/loader/Cache.h b/WebCore/loader/Cache.h
index 5743696..14ddc21 100644
--- a/WebCore/loader/Cache.h
+++ b/WebCore/loader/Cache.h
@@ -55,6 +55,22 @@ class KURL;
 // -------|-----+++++++++++++++|
 // -------|-----+++++++++++++++|+++++
 
+// The behavior of the cache changes in the following way if shouldMakeResourcePurgeableOnEviction
+// returns true.
+//
+// 1. Dead resources in the cache are kept in non-purgeable memory.
+// 2. When we prune dead resources, instead of freeing them, we mark their memory as purgeable and
+//    keep the resources until the kernel reclaims the purgeable memory.
+//
+// By leaving the in-cache dead resources in dirty resident memory, we decrease the likelihood of
+// the kernel claiming that memory and forcing us to refetch the resource (for example when a user
+// presses back).
+//
+// And by having an unbounded number of resource objects using purgeable memory, we can use as much
+// memory as is available on the machine. The trade-off here is that the CachedResource object (and
+// its member variables) are allocated in non-purgeable TC-malloc'd memory so we would see slightly
+// more memory use due to this.
+
 class Cache : public Noncopyable {
 public:
     friend Cache* cache();
@@ -148,6 +164,8 @@ public:
     void addToLiveResourcesSize(CachedResource*);
     void removeFromLiveResourcesSize(CachedResource*);
 
+    static bool shouldMakeResourcePurgeableOnEviction();
+
     // Function to collect cache statistics for the caches window in the Safari Debug menu.
     Statistics getStatistics();
 
@@ -168,6 +186,7 @@ private:
     void pruneDeadResources(); // Flush decoded and encoded data from resources not referenced by Web pages.
     void pruneLiveResources(); // Flush decoded data from resources still referenced by Web pages.
 
+    bool makeResourcePurgeable(CachedResource*);
     void evict(CachedResource*);
 
     // Member variables.
@@ -199,6 +218,15 @@ private:
     HashMap<String, CachedResource*> m_resources;
 };
 
+inline bool Cache::shouldMakeResourcePurgeableOnEviction()
+{
+#if PLATFORM(IOS)
+    return true;
+#else
+    return false;
+#endif
+}
+
 // Function to obtain the global cache.
 Cache* cache();
 
diff --git a/WebCore/loader/CachedCSSStyleSheet.cpp b/WebCore/loader/CachedCSSStyleSheet.cpp
index 7866efd..877cd1d 100644
--- a/WebCore/loader/CachedCSSStyleSheet.cpp
+++ b/WebCore/loader/CachedCSSStyleSheet.cpp
@@ -27,6 +27,7 @@
 #include "config.h"
 #include "CachedCSSStyleSheet.h"
 
+#include "Cache.h"
 #include "CachedResourceClient.h"
 #include "CachedResourceClientWalker.h"
 #include "HTTPParsers.h"
@@ -58,7 +59,7 @@ void CachedCSSStyleSheet::didAddClient(CachedResourceClient *c)
 
 void CachedCSSStyleSheet::allClientsRemoved()
 {
-    if (isSafeToMakePurgeable())
+    if (!Cache::shouldMakeResourcePurgeableOnEviction() && isSafeToMakePurgeable())
         makePurgeable(true);
 }
 
diff --git a/WebCore/loader/CachedImage.cpp b/WebCore/loader/CachedImage.cpp
index 202f32c..2c18f35 100644
--- a/WebCore/loader/CachedImage.cpp
+++ b/WebCore/loader/CachedImage.cpp
@@ -331,7 +331,8 @@ void CachedImage::destroyDecodedData()
         // Invoking addClient() will reconstruct the image object.
         m_image = 0;
         setDecodedSize(0);
-        makePurgeable(true);
+        if (!Cache::shouldMakeResourcePurgeableOnEviction())
+            makePurgeable(true);
     } else if (m_image && !errorOccurred())
         m_image->destroyDecodedData();
 }
diff --git a/WebCore/loader/CachedScript.cpp b/WebCore/loader/CachedScript.cpp
index 58895d6..1898438 100644
--- a/WebCore/loader/CachedScript.cpp
+++ b/WebCore/loader/CachedScript.cpp
@@ -27,6 +27,7 @@
 #include "config.h"
 #include "CachedScript.h"
 
+#include "Cache.h"
 #include "CachedResourceClient.h"
 #include "CachedResourceClientWalker.h"
 #include "SharedBuffer.h"
@@ -110,7 +111,7 @@ void CachedScript::destroyDecodedData()
 {
     m_script = String();
     setDecodedSize(0);
-    if (isSafeToMakePurgeable())
+    if (!Cache::shouldMakeResourcePurgeableOnEviction() && isSafeToMakePurgeable())
         makePurgeable(true);
 }
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list