Change DeferrableOneShotTimer to use std::function instead of being a class template
[WebKit-https.git] / Source / WebCore / loader / cache / MemoryCache.h
1 /*
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.
5
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.
10
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.
15
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.
20
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.
23 */
24
25 #ifndef Cache_h
26 #define Cache_h
27
28 #include "NativeImagePtr.h"
29 #include "SecurityOriginHash.h"
30 #include "SessionIDHash.h"
31 #include <wtf/HashMap.h>
32 #include <wtf/HashSet.h>
33 #include <wtf/Noncopyable.h>
34 #include <wtf/Vector.h>
35 #include <wtf/text/StringHash.h>
36 #include <wtf/text/WTFString.h>
37
38 namespace WebCore  {
39
40 class CachedCSSStyleSheet;
41 class CachedResource;
42 class CachedResourceLoader;
43 class URL;
44 class ResourceRequest;
45 class ResourceResponse;
46 class ScriptExecutionContext;
47 class SecurityOrigin;
48 struct CrossThreadResourceRequestData;
49 struct SecurityOriginHash;
50
51 // This cache holds subresources used by Web pages: images, scripts, stylesheets, etc.
52
53 // The cache keeps a flexible but bounded window of dead resources that grows/shrinks 
54 // depending on the live resource load. Here's an example of cache growth over time,
55 // with a min dead resource capacity of 25% and a max dead resource capacity of 50%:
56
57 //        |-----|                              Dead: -
58 //        |----------|                         Live: +
59 //      --|----------|                         Cache boundary: | (objects outside this mark have been evicted)
60 //      --|----------++++++++++|
61 // -------|-----+++++++++++++++|
62 // -------|-----+++++++++++++++|+++++
63
64 // The behavior of the cache changes in the following way if shouldMakeResourcePurgeableOnEviction
65 // returns true.
66 //
67 // 1. Dead resources in the cache are kept in non-purgeable memory.
68 // 2. When we prune dead resources, instead of freeing them, we mark their memory as purgeable and
69 //    keep the resources until the kernel reclaims the purgeable memory.
70 //
71 // By leaving the in-cache dead resources in dirty resident memory, we decrease the likelihood of
72 // the kernel claiming that memory and forcing us to refetch the resource (for example when a user
73 // presses back).
74 //
75 // And by having an unbounded number of resource objects using purgeable memory, we can use as much
76 // memory as is available on the machine. The trade-off here is that the CachedResource object (and
77 // its member variables) are allocated in non-purgeable TC-malloc'd memory so we would see slightly
78 // more memory use due to this.
79
80 class MemoryCache {
81     WTF_MAKE_NONCOPYABLE(MemoryCache); WTF_MAKE_FAST_ALLOCATED;
82 public:
83     friend MemoryCache* memoryCache();
84
85 #if ENABLE(CACHE_PARTITIONING)
86     typedef HashMap<String, CachedResource*> CachedResourceItem;
87     typedef HashMap<String, OwnPtr<CachedResourceItem>> CachedResourceMap;
88 #else
89     typedef HashMap<String, CachedResource*> CachedResourceMap;
90 #endif
91     typedef HashMap<SessionID, std::unique_ptr<CachedResourceMap>> SessionCachedResourceMap;
92
93     struct LRUList {
94         CachedResource* m_head;
95         CachedResource* m_tail;
96         LRUList() : m_head(0), m_tail(0) { }
97     };
98
99     struct TypeStatistic {
100         int count;
101         int size;
102         int liveSize;
103         int decodedSize;
104         int purgeableSize;
105         int purgedSize;
106 #if ENABLE(DISK_IMAGE_CACHE)
107         int mappedSize;
108         TypeStatistic() : count(0), size(0), liveSize(0), decodedSize(0), purgeableSize(0), purgedSize(0), mappedSize(0) { }
109 #else
110         TypeStatistic() : count(0), size(0), liveSize(0), decodedSize(0), purgeableSize(0), purgedSize(0) { }
111 #endif
112         void addResource(CachedResource*);
113     };
114     
115     struct Statistics {
116         TypeStatistic images;
117         TypeStatistic cssStyleSheets;
118         TypeStatistic scripts;
119         TypeStatistic xslStyleSheets;
120         TypeStatistic fonts;
121     };
122
123     CachedResource* resourceForURL(const URL&);
124     CachedResource* resourceForURL(const URL&, SessionID);
125     CachedResource* resourceForRequest(const ResourceRequest&, SessionID);
126
127     bool add(CachedResource*);
128     void remove(CachedResource* resource) { evict(resource); }
129
130     static URL removeFragmentIdentifierIfNeeded(const URL& originalURL);
131     
132     void revalidationSucceeded(CachedResource* revalidatingResource, const ResourceResponse&);
133     void revalidationFailed(CachedResource* revalidatingResource);
134     
135     // Sets the cache's memory capacities, in bytes. These will hold only approximately, 
136     // since the decoded cost of resources like scripts and stylesheets is not known.
137     //  - minDeadBytes: The maximum number of bytes that dead resources should consume when the cache is under pressure.
138     //  - maxDeadBytes: The maximum number of bytes that dead resources should consume when the cache is not under pressure.
139     //  - totalBytes: The maximum number of bytes that the cache should consume overall.
140     void setCapacities(unsigned minDeadBytes, unsigned maxDeadBytes, unsigned totalBytes);
141
142     // Turn the cache on and off.  Disabling the cache will remove all resources from the cache.  They may
143     // still live on if they are referenced by some Web page though.
144     void setDisabled(bool);
145     bool disabled() const { return m_disabled; }
146
147     void evictResources();
148     
149     void setPruneEnabled(bool enabled) { m_pruneEnabled = enabled; }
150     void prune();
151     void pruneToPercentage(float targetPercentLive);
152
153     void setDeadDecodedDataDeletionInterval(std::chrono::milliseconds interval) { m_deadDecodedDataDeletionInterval = interval; }
154     std::chrono::milliseconds deadDecodedDataDeletionInterval() const { return m_deadDecodedDataDeletionInterval; }
155
156     // Calls to put the cached resource into and out of LRU lists.
157     void insertInLRUList(CachedResource*);
158     void removeFromLRUList(CachedResource*);
159
160     // Called to adjust the cache totals when a resource changes size.
161     void adjustSize(bool live, int delta);
162
163     // Track decoded resources that are in the cache and referenced by a Web page.
164     void insertInLiveDecodedResourcesList(CachedResource*);
165     void removeFromLiveDecodedResourcesList(CachedResource*);
166
167     void addToLiveResourcesSize(CachedResource*);
168     void removeFromLiveResourcesSize(CachedResource*);
169
170     static bool shouldMakeResourcePurgeableOnEviction();
171
172 #if ENABLE(DISK_IMAGE_CACHE)
173     void flushCachedImagesToDisk(); // Flush encoded data from resources still referenced by web pages.
174 #endif
175
176     static void removeUrlFromCache(ScriptExecutionContext*, const String& urlString, SessionID);
177     static void removeRequestFromCache(ScriptExecutionContext*, const ResourceRequest&, SessionID);
178     static void removeRequestFromSessionCaches(ScriptExecutionContext*, const ResourceRequest&);
179
180     // Function to collect cache statistics for the caches window in the Safari Debug menu.
181     Statistics getStatistics();
182     
183     void resourceAccessed(CachedResource*);
184
185     typedef HashSet<RefPtr<SecurityOrigin>> SecurityOriginSet;
186     void removeResourcesWithOrigin(SecurityOrigin*);
187     void getOriginsWithCache(SecurityOriginSet& origins);
188
189     unsigned minDeadCapacity() const { return m_minDeadCapacity; }
190     unsigned maxDeadCapacity() const { return m_maxDeadCapacity; }
191     unsigned capacity() const { return m_capacity; }
192     unsigned liveSize() const { return m_liveSize; }
193     unsigned deadSize() const { return m_deadSize; }
194
195 #if USE(CG)
196     // FIXME: Remove the USE(CG) once we either make NativeImagePtr a smart pointer on all platforms or
197     // remove the usage of CFRetain() in MemoryCache::addImageToCache() so as to make the code platform-independent.
198     bool addImageToCache(NativeImagePtr, const URL&, const String& cachePartition);
199     void removeImageFromCache(const URL&, const String& cachePartition);
200 #endif
201
202     // pruneDead*() - Flush decoded and encoded data from resources not referenced by Web pages.
203     // pruneLive*() - Flush decoded data from resources still referenced by Web pages.
204     void pruneDeadResources(); // Automatically decide how much to prune.
205     void pruneLiveResources(bool shouldDestroyDecodedDataForAllLiveResources = false);
206
207 private:
208     void pruneDeadResourcesToPercentage(float prunePercentage); // Prune to % current size
209     void pruneLiveResourcesToPercentage(float prunePercentage);
210     void pruneDeadResourcesToSize(unsigned targetSize);
211     void pruneLiveResourcesToSize(unsigned targetSize, bool shouldDestroyDecodedDataForAllLiveResources = false);
212
213     MemoryCache();
214     ~MemoryCache(); // Not implemented to make sure nobody accidentally calls delete -- WebCore does not delete singletons.
215
216     LRUList* lruListFor(CachedResource*);
217 #ifndef NDEBUG
218     void dumpStats();
219     void dumpLRULists(bool includeLive) const;
220 #endif
221
222     unsigned liveCapacity() const;
223     unsigned deadCapacity() const;
224
225     bool makeResourcePurgeable(CachedResource*);
226     void evict(CachedResource*);
227
228     CachedResource* resourceForRequestImpl(const ResourceRequest&, CachedResourceMap&);
229     static void removeRequestFromCacheImpl(ScriptExecutionContext*, const ResourceRequest&, SessionID);
230     static void removeRequestFromSessionCachesImpl(ScriptExecutionContext*, const ResourceRequest&);
231     static void crossThreadRemoveRequestFromCache(ScriptExecutionContext*, PassOwnPtr<CrossThreadResourceRequestData>, SessionID);
232     static void crossThreadRemoveRequestFromSessionCaches(ScriptExecutionContext*, PassOwnPtr<CrossThreadResourceRequestData>);
233
234     CachedResourceMap& getSessionMap(SessionID);
235
236     bool m_disabled;  // Whether or not the cache is enabled.
237     bool m_pruneEnabled;
238     bool m_inPruneResources;
239
240     unsigned m_capacity;
241     unsigned m_minDeadCapacity;
242     unsigned m_maxDeadCapacity;
243     std::chrono::milliseconds m_deadDecodedDataDeletionInterval;
244
245     unsigned m_liveSize; // The number of bytes currently consumed by "live" resources in the cache.
246     unsigned m_deadSize; // The number of bytes currently consumed by "dead" resources in the cache.
247
248     // Size-adjusted and popularity-aware LRU list collection for cache objects.  This collection can hold
249     // more resources than the cached resource map, since it can also hold "stale" multiple versions of objects that are
250     // waiting to die when the clients referencing them go away.
251     Vector<LRUList, 32> m_allResources;
252     
253     // List just for live resources with decoded data.  Access to this list is based off of painting the resource.
254     LRUList m_liveDecodedResources;
255     
256     // A URL-based map of all resources that are in the cache (including the freshest version of objects that are currently being 
257     // referenced by a Web page).
258     SessionCachedResourceMap m_sessionResources;
259 };
260
261 inline bool MemoryCache::shouldMakeResourcePurgeableOnEviction()
262 {
263 #if PLATFORM(IOS)
264     return true;
265 #else
266     return false;
267 #endif
268 }
269
270 // Function to obtain the global cache.
271 MemoryCache* memoryCache();
272
273 }
274
275 #endif