2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
3 Copyright (C) 2001 Dirk Mueller <mueller@kde.org>
4 Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
21 This class provides all functionality needed for loading images, style sheets and html
22 pages from the web. It has a memory cache for these objects.
28 #include "CachedResource.h"
29 #include "PlatformString.h"
30 #include <wtf/HashMap.h>
31 #include <wtf/HashSet.h>
32 #include <wtf/Noncopyable.h>
33 #include <wtf/Vector.h>
34 #include <wtf/text/StringHash.h>
38 class CachedCSSStyleSheet;
40 class CachedResourceLoader;
43 struct SecurityOriginHash;
45 // This cache holds subresources used by Web pages: images, scripts, stylesheets, etc.
47 // The cache keeps a flexible but bounded window of dead resources that grows/shrinks
48 // depending on the live resource load. Here's an example of cache growth over time,
49 // with a min dead resource capacity of 25% and a max dead resource capacity of 50%:
52 // |----------| Live: +
53 // --|----------| Cache boundary: | (objects outside this mark have been evicted)
54 // --|----------++++++++++|
55 // -------|-----+++++++++++++++|
56 // -------|-----+++++++++++++++|+++++
58 // The behavior of the cache changes in the following way if shouldMakeResourcePurgeableOnEviction
61 // 1. Dead resources in the cache are kept in non-purgeable memory.
62 // 2. When we prune dead resources, instead of freeing them, we mark their memory as purgeable and
63 // keep the resources until the kernel reclaims the purgeable memory.
65 // By leaving the in-cache dead resources in dirty resident memory, we decrease the likelihood of
66 // the kernel claiming that memory and forcing us to refetch the resource (for example when a user
69 // And by having an unbounded number of resource objects using purgeable memory, we can use as much
70 // memory as is available on the machine. The trade-off here is that the CachedResource object (and
71 // its member variables) are allocated in non-purgeable TC-malloc'd memory so we would see slightly
72 // more memory use due to this.
75 WTF_MAKE_NONCOPYABLE(MemoryCache); WTF_MAKE_FAST_ALLOCATED;
77 friend MemoryCache* memoryCache();
79 typedef HashMap<String, CachedResource*> CachedResourceMap;
82 CachedResource* m_head;
83 CachedResource* m_tail;
84 LRUList() : m_head(0), m_tail(0) { }
87 struct TypeStatistic {
94 TypeStatistic() : count(0), size(0), liveSize(0), decodedSize(0), purgeableSize(0), purgedSize(0) { }
95 void addResource(CachedResource*);
100 TypeStatistic cssStyleSheets;
101 TypeStatistic scripts;
102 TypeStatistic xslStyleSheets;
106 CachedResource* resourceForURL(const KURL&);
108 bool add(CachedResource* resource);
109 void remove(CachedResource* resource) { evict(resource); }
111 static KURL removeFragmentIdentifierIfNeeded(const KURL& originalURL);
113 void revalidationSucceeded(CachedResource* revalidatingResource, const ResourceResponse&);
114 void revalidationFailed(CachedResource* revalidatingResource);
116 // Sets the cache's memory capacities, in bytes. These will hold only approximately,
117 // since the decoded cost of resources like scripts and stylesheets is not known.
118 // - minDeadBytes: The maximum number of bytes that dead resources should consume when the cache is under pressure.
119 // - maxDeadBytes: The maximum number of bytes that dead resources should consume when the cache is not under pressure.
120 // - totalBytes: The maximum number of bytes that the cache should consume overall.
121 void setCapacities(unsigned minDeadBytes, unsigned maxDeadBytes, unsigned totalBytes);
123 // Turn the cache on and off. Disabling the cache will remove all resources from the cache. They may
124 // still live on if they are referenced by some Web page though.
125 void setDisabled(bool);
126 bool disabled() const { return m_disabled; }
128 void evictResources();
130 void setPruneEnabled(bool enabled) { m_pruneEnabled = enabled; }
132 void pruneToPercentage(float targetPercentLive);
134 void setDeadDecodedDataDeletionInterval(double interval) { m_deadDecodedDataDeletionInterval = interval; }
135 double deadDecodedDataDeletionInterval() const { return m_deadDecodedDataDeletionInterval; }
137 void addCachedResourceLoader(CachedResourceLoader*);
138 void removeCachedResourceLoader(CachedResourceLoader*);
140 // Calls to put the cached resource into and out of LRU lists.
141 void insertInLRUList(CachedResource*);
142 void removeFromLRUList(CachedResource*);
144 // Called to adjust the cache totals when a resource changes size.
145 void adjustSize(bool live, int delta);
147 // Track decoded resources that are in the cache and referenced by a Web page.
148 void insertInLiveDecodedResourcesList(CachedResource*);
149 void removeFromLiveDecodedResourcesList(CachedResource*);
151 void addToLiveResourcesSize(CachedResource*);
152 void removeFromLiveResourcesSize(CachedResource*);
154 static bool shouldMakeResourcePurgeableOnEviction();
156 // Function to collect cache statistics for the caches window in the Safari Debug menu.
157 Statistics getStatistics();
159 void resourceAccessed(CachedResource*);
161 typedef HashSet<RefPtr<SecurityOrigin>, SecurityOriginHash> SecurityOriginSet;
162 void removeResourcesWithOrigin(SecurityOrigin*);
163 void getOriginsWithCache(SecurityOriginSet& origins);
167 ~MemoryCache(); // Not implemented to make sure nobody accidentally calls delete -- WebCore does not delete singletons.
169 LRUList* lruListFor(CachedResource*);
172 void dumpLRULists(bool includeLive) const;
175 unsigned liveCapacity() const;
176 unsigned deadCapacity() const;
178 // pruneDead*() - Flush decoded and encoded data from resources not referenced by Web pages.
179 // pruneLive*() - Flush decoded data from resources still referenced by Web pages.
180 void pruneDeadResources(); // Automatically decide how much to prune.
181 void pruneLiveResources();
182 void pruneDeadResourcesToPercentage(float prunePercentage); // Prune to % current size
183 void pruneLiveResourcesToPercentage(float prunePercentage);
184 void pruneDeadResourcesToSize(unsigned targetSize);
185 void pruneLiveResourcesToSize(unsigned targetSize);
187 bool makeResourcePurgeable(CachedResource*);
188 void evict(CachedResource*);
190 bool m_disabled; // Whether or not the cache is enabled.
192 bool m_inPruneDeadResources;
195 unsigned m_minDeadCapacity;
196 unsigned m_maxDeadCapacity;
197 double m_deadDecodedDataDeletionInterval;
199 unsigned m_liveSize; // The number of bytes currently consumed by "live" resources in the cache.
200 unsigned m_deadSize; // The number of bytes currently consumed by "dead" resources in the cache.
202 // Size-adjusted and popularity-aware LRU list collection for cache objects. This collection can hold
203 // more resources than the cached resource map, since it can also hold "stale" multiple versions of objects that are
204 // waiting to die when the clients referencing them go away.
205 Vector<LRUList, 32> m_allResources;
207 // List just for live resources with decoded data. Access to this list is based off of painting the resource.
208 LRUList m_liveDecodedResources;
210 // A URL-based map of all resources that are in the cache (including the freshest version of objects that are currently being
211 // referenced by a Web page).
212 HashMap<String, CachedResource*> m_resources;
215 inline bool MemoryCache::shouldMakeResourcePurgeableOnEviction()
224 // Function to obtain the global cache.
225 MemoryCache* memoryCache();