Memory cache live resources repeatedly purged during painting
[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 "SessionID.h"
31 #include "Timer.h"
32 #include <wtf/Forward.h>
33 #include <wtf/HashMap.h>
34 #include <wtf/HashSet.h>
35 #include <wtf/ListHashSet.h>
36 #include <wtf/Noncopyable.h>
37 #include <wtf/Vector.h>
38 #include <wtf/text/StringHash.h>
39 #include <wtf/text/WTFString.h>
40
41 namespace WebCore  {
42
43 class CachedResource;
44 class URL;
45 class ResourceRequest;
46 class ResourceResponse;
47 class ScriptExecutionContext;
48 class SecurityOrigin;
49
50 // This cache holds subresources used by Web pages: images, scripts, stylesheets, etc.
51
52 // The cache keeps a flexible but bounded window of dead resources that grows/shrinks 
53 // depending on the live resource load. Here's an example of cache growth over time,
54 // with a min dead resource capacity of 25% and a max dead resource capacity of 50%:
55
56 //        |-----|                              Dead: -
57 //        |----------|                         Live: +
58 //      --|----------|                         Cache boundary: | (objects outside this mark have been evicted)
59 //      --|----------++++++++++|
60 // -------|-----+++++++++++++++|
61 // -------|-----+++++++++++++++|+++++
62
63 class MemoryCache {
64     WTF_MAKE_NONCOPYABLE(MemoryCache); WTF_MAKE_FAST_ALLOCATED;
65     friend NeverDestroyed<MemoryCache>;
66     friend class Internals;
67 public:
68     struct TypeStatistic {
69         int count;
70         int size;
71         int liveSize;
72         int decodedSize;
73
74         TypeStatistic()
75             : count(0)
76             , size(0)
77             , liveSize(0)
78             , decodedSize(0)
79         { 
80         }
81
82         void addResource(CachedResource&);
83     };
84     
85     struct Statistics {
86         TypeStatistic images;
87         TypeStatistic cssStyleSheets;
88         TypeStatistic scripts;
89         TypeStatistic xslStyleSheets;
90         TypeStatistic fonts;
91     };
92
93     WEBCORE_EXPORT static MemoryCache& singleton();
94
95     WEBCORE_EXPORT CachedResource* resourceForRequest(const ResourceRequest&, SessionID);
96
97     bool add(CachedResource&);
98     void remove(CachedResource&);
99
100     static URL removeFragmentIdentifierIfNeeded(const URL& originalURL);
101     
102     void revalidationSucceeded(CachedResource& revalidatingResource, const ResourceResponse&);
103     void revalidationFailed(CachedResource& revalidatingResource);
104     
105     // Sets the cache's memory capacities, in bytes. These will hold only approximately, 
106     // since the decoded cost of resources like scripts and stylesheets is not known.
107     //  - minDeadBytes: The maximum number of bytes that dead resources should consume when the cache is under pressure.
108     //  - maxDeadBytes: The maximum number of bytes that dead resources should consume when the cache is not under pressure.
109     //  - totalBytes: The maximum number of bytes that the cache should consume overall.
110     WEBCORE_EXPORT void setCapacities(unsigned minDeadBytes, unsigned maxDeadBytes, unsigned totalBytes);
111
112     // Turn the cache on and off.  Disabling the cache will remove all resources from the cache.  They may
113     // still live on if they are referenced by some Web page though.
114     WEBCORE_EXPORT void setDisabled(bool);
115     bool disabled() const { return m_disabled; }
116
117     WEBCORE_EXPORT void evictResources();
118     WEBCORE_EXPORT void evictResources(SessionID);
119     
120     void prune();
121     void pruneSoon();
122     unsigned size() const { return m_liveSize + m_deadSize; }
123
124     void setDeadDecodedDataDeletionInterval(std::chrono::milliseconds interval) { m_deadDecodedDataDeletionInterval = interval; }
125     std::chrono::milliseconds deadDecodedDataDeletionInterval() const { return m_deadDecodedDataDeletionInterval; }
126
127     // Calls to put the cached resource into and out of LRU lists.
128     void insertInLRUList(CachedResource&);
129     void removeFromLRUList(CachedResource&);
130
131     // Called to adjust the cache totals when a resource changes size.
132     void adjustSize(bool live, int delta);
133
134     // Track decoded resources that are in the cache and referenced by a Web page.
135     void insertInLiveDecodedResourcesList(CachedResource&);
136     void removeFromLiveDecodedResourcesList(CachedResource&);
137
138     void addToLiveResourcesSize(CachedResource&);
139     void removeFromLiveResourcesSize(CachedResource&);
140
141     static void removeRequestFromSessionCaches(ScriptExecutionContext&, const ResourceRequest&);
142
143     // Function to collect cache statistics for the caches window in the Safari Debug menu.
144     WEBCORE_EXPORT Statistics getStatistics();
145     
146     void resourceAccessed(CachedResource&);
147     bool inLiveDecodedResourcesList(CachedResource& resource) const { return m_liveDecodedResources.contains(&resource); }
148
149     typedef HashSet<RefPtr<SecurityOrigin>> SecurityOriginSet;
150     WEBCORE_EXPORT void removeResourcesWithOrigin(SecurityOrigin&);
151     WEBCORE_EXPORT void removeResourcesWithOrigins(SessionID, const HashSet<RefPtr<SecurityOrigin>>&);
152     WEBCORE_EXPORT void getOriginsWithCache(SecurityOriginSet& origins);
153     WEBCORE_EXPORT HashSet<RefPtr<SecurityOrigin>> originsWithCache(SessionID) const;
154
155 #if USE(CG)
156     // FIXME: Remove the USE(CG) once we either make NativeImagePtr a smart pointer on all platforms or
157     // remove the usage of CFRetain() in MemoryCache::addImageToCache() so as to make the code platform-independent.
158     WEBCORE_EXPORT bool addImageToCache(NativeImagePtr, const URL&, const String& domainForCachePartition);
159     WEBCORE_EXPORT void removeImageFromCache(const URL&, const String& domainForCachePartition);
160 #endif
161
162     // pruneDead*() - Flush decoded and encoded data from resources not referenced by Web pages.
163     // pruneLive*() - Flush decoded data from resources still referenced by Web pages.
164     WEBCORE_EXPORT void pruneDeadResources(); // Automatically decide how much to prune.
165     WEBCORE_EXPORT void pruneLiveResources(bool shouldDestroyDecodedDataForAllLiveResources = false);
166
167     WEBCORE_EXPORT void pruneDeadResourcesToSize(unsigned targetSize);
168     WEBCORE_EXPORT void pruneLiveResourcesToSize(unsigned targetSize, bool shouldDestroyDecodedDataForAllLiveResources = false);
169
170 private:
171 #if ENABLE(CACHE_PARTITIONING)
172     typedef HashMap<std::pair<URL, String /* partitionName */>, CachedResource*> CachedResourceMap;
173 #else
174     typedef HashMap<URL, CachedResource*> CachedResourceMap;
175 #endif
176     typedef ListHashSet<CachedResource*> LRUList;
177
178     MemoryCache();
179     ~MemoryCache(); // Not implemented to make sure nobody accidentally calls delete -- WebCore does not delete singletons.
180
181     LRUList& lruListFor(CachedResource&);
182 #ifndef NDEBUG
183     void dumpStats();
184     void dumpLRULists(bool includeLive) const;
185 #endif
186
187     unsigned liveCapacity() const;
188     unsigned deadCapacity() const;
189     bool needsPruning() const;
190     void pruneTimerFired();
191
192     CachedResource* resourceForRequestImpl(const ResourceRequest&, CachedResourceMap&);
193
194     CachedResourceMap& ensureSessionResourceMap(SessionID);
195     CachedResourceMap* sessionResourceMap(SessionID) const;
196
197     bool m_disabled;  // Whether or not the cache is enabled.
198     bool m_inPruneResources;
199
200     unsigned m_capacity;
201     unsigned m_minDeadCapacity;
202     unsigned m_maxDeadCapacity;
203     std::chrono::milliseconds m_deadDecodedDataDeletionInterval;
204
205     unsigned m_liveSize; // The number of bytes currently consumed by "live" resources in the cache.
206     unsigned m_deadSize; // The number of bytes currently consumed by "dead" resources in the cache.
207
208     // Size-adjusted and popularity-aware LRU list collection for cache objects.  This collection can hold
209     // more resources than the cached resource map, since it can also hold "stale" multiple versions of objects that are
210     // waiting to die when the clients referencing them go away.
211     Vector<std::unique_ptr<LRUList>, 32> m_allResources;
212     
213     // List just for live resources with decoded data.  Access to this list is based off of painting the resource.
214     LRUList m_liveDecodedResources;
215     
216     // A URL-based map of all resources that are in the cache (including the freshest version of objects that are currently being 
217     // referenced by a Web page).
218     typedef HashMap<SessionID, std::unique_ptr<CachedResourceMap>> SessionCachedResourceMap;
219     SessionCachedResourceMap m_sessionResources;
220
221     Timer m_pruneTimer;
222 };
223
224 }
225
226 #endif