Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(419)

Side by Side Diff: third_party/WebKit/Source/core/fetch/MemoryCache.h

Issue 2411243004: [WeakMemoryCache] Remove LRU lists, prune order control and live/dead distinction (Closed)
Patch Set: Rebase Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
3 Copyright (C) 2001 Dirk Mueller <mueller@kde.org> 3 Copyright (C) 2001 Dirk Mueller <mueller@kde.org>
4 Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 4 Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
5 5
6 This library is free software; you can redistribute it and/or 6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public 7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either 8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version. 9 version 2 of the License, or (at your option) any later version.
10 10
(...skipping 22 matching lines...) Expand all
33 #include "public/platform/WebThread.h" 33 #include "public/platform/WebThread.h"
34 #include "wtf/Allocator.h" 34 #include "wtf/Allocator.h"
35 #include "wtf/HashMap.h" 35 #include "wtf/HashMap.h"
36 #include "wtf/Noncopyable.h" 36 #include "wtf/Noncopyable.h"
37 #include "wtf/Vector.h" 37 #include "wtf/Vector.h"
38 #include "wtf/text/StringHash.h" 38 #include "wtf/text/StringHash.h"
39 #include "wtf/text/WTFString.h" 39 #include "wtf/text/WTFString.h"
40 40
41 namespace blink { 41 namespace blink {
42 42
43 class Resource;
44 class KURL; 43 class KURL;
45 class ExecutionContext;
46 44
47 // This cache holds subresources used by Web pages: images, scripts, 45 // Member<MemoryCacheEntry> + MemoryCacheEntry::clearResourceWeak() monitors
48 // stylesheets, etc. 46 // eviction from MemoryCache due to Resource garbage collection.
49 47 // WeakMember<Resource> + Resource's prefinalizer cannot determine whether the
50 // The cache keeps a flexible but bounded window of dead resources that 48 // Resource was on MemoryCache or not, because WeakMember is already cleared
51 // grows/shrinks depending on the live resource load. Here's an example of cache 49 // when the prefinalizer is executed.
52 // growth over time, with a min dead resource capacity of 25% and a max dead
53 // resource capacity of 50%:
54 //
55 // Dead: -
56 // Live: +
57 // Cache boundary: | (objects outside this mark have been evicted)
58 //
59 // |-----|
60 // |----------|
61 // --|----------|
62 // --|----------++++++++++|
63 // -------|-----+++++++++++++++|
64 // -------|-----+++++++++++++++|+++++
65
66 enum UpdateReason { UpdateForAccess, UpdateForPropertyChange };
67
68 // MemoryCacheEntry class is used only in MemoryCache class, but we don't make
69 // MemoryCacheEntry class an inner class of MemoryCache because of dependency
70 // from MemoryCacheLRUList.
71 class MemoryCacheEntry final : public GarbageCollected<MemoryCacheEntry> { 50 class MemoryCacheEntry final : public GarbageCollected<MemoryCacheEntry> {
72 public: 51 public:
73 static MemoryCacheEntry* create(Resource* resource) { 52 static MemoryCacheEntry* create(Resource* resource) {
74 return new MemoryCacheEntry(resource); 53 return new MemoryCacheEntry(resource);
75 } 54 }
76 DECLARE_TRACE(); 55 DECLARE_TRACE();
77 void dispose(); 56 Resource* resource() const { return m_resource; }
78 Resource* resource();
79 57
80 bool m_inLiveDecodedResourcesList;
81 unsigned m_accessCount;
82 double m_lastDecodedAccessTime; // Used as a thrash guard 58 double m_lastDecodedAccessTime; // Used as a thrash guard
83 59
84 Member<MemoryCacheEntry> m_previousInLiveResourcesList;
85 Member<MemoryCacheEntry> m_nextInLiveResourcesList;
86 Member<MemoryCacheEntry> m_previousInAllResourcesList;
87 Member<MemoryCacheEntry> m_nextInAllResourcesList;
88
89 private: 60 private:
90 explicit MemoryCacheEntry(Resource* resource) 61 explicit MemoryCacheEntry(Resource* resource)
91 : m_inLiveDecodedResourcesList(false), 62 : m_lastDecodedAccessTime(0.0), m_resource(resource) {}
92 m_accessCount(0),
93 m_lastDecodedAccessTime(0.0),
94 m_previousInLiveResourcesList(nullptr),
95 m_nextInLiveResourcesList(nullptr),
96 m_previousInAllResourcesList(nullptr),
97 m_nextInAllResourcesList(nullptr),
98 m_resource(resource) {}
99 63
100 void clearResourceWeak(Visitor*); 64 void clearResourceWeak(Visitor*);
101 65
102 WeakMember<Resource> m_resource; 66 WeakMember<Resource> m_resource;
103 }; 67 };
104 68
105 WILL_NOT_BE_EAGERLY_TRACED_CLASS(MemoryCacheEntry); 69 WILL_NOT_BE_EAGERLY_TRACED_CLASS(MemoryCacheEntry);
106 70
107 // MemoryCacheLRUList is used only in MemoryCache class, but we don't make 71 // This cache holds subresources used by Web pages: images, scripts,
108 // MemoryCacheLRUList an inner struct of MemoryCache because we can't define 72 // stylesheets, etc.
109 // VectorTraits for inner structs.
110 struct MemoryCacheLRUList final {
111 DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
112
113 public:
114 Member<MemoryCacheEntry> m_head;
115 Member<MemoryCacheEntry> m_tail;
116
117 MemoryCacheLRUList() : m_head(nullptr), m_tail(nullptr) {}
118 DECLARE_TRACE();
119 };
120
121 } // namespace blink
122
123 WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::MemoryCacheLRUList);
124
125 namespace blink {
126
127 class CORE_EXPORT MemoryCache final 73 class CORE_EXPORT MemoryCache final
128 : public GarbageCollectedFinalized<MemoryCache>, 74 : public GarbageCollectedFinalized<MemoryCache>,
129 public WebThread::TaskObserver, 75 public WebThread::TaskObserver,
130 public MemoryCacheDumpClient, 76 public MemoryCacheDumpClient,
131 public MemoryCoordinatorClient { 77 public MemoryCoordinatorClient {
132 USING_GARBAGE_COLLECTED_MIXIN(MemoryCache); 78 USING_GARBAGE_COLLECTED_MIXIN(MemoryCache);
133 WTF_MAKE_NONCOPYABLE(MemoryCache); 79 WTF_MAKE_NONCOPYABLE(MemoryCache);
134 80
135 public: 81 public:
136 static MemoryCache* create(); 82 static MemoryCache* create();
137 ~MemoryCache(); 83 ~MemoryCache();
138 DECLARE_TRACE(); 84 DECLARE_TRACE();
139 85
140 struct TypeStatistic { 86 struct TypeStatistic {
141 STACK_ALLOCATED(); 87 STACK_ALLOCATED();
142 size_t count; 88 size_t count;
143 size_t size; 89 size_t size;
144 size_t liveSize;
145 size_t decodedSize; 90 size_t decodedSize;
146 size_t encodedSize; 91 size_t encodedSize;
147 size_t overheadSize; 92 size_t overheadSize;
148 size_t encodedSizeDuplicatedInDataURLs; 93 size_t encodedSizeDuplicatedInDataURLs;
149 94
150 TypeStatistic() 95 TypeStatistic()
151 : count(0), 96 : count(0),
152 size(0), 97 size(0),
153 liveSize(0),
154 decodedSize(0), 98 decodedSize(0),
155 encodedSize(0), 99 encodedSize(0),
156 overheadSize(0), 100 overheadSize(0),
157 encodedSizeDuplicatedInDataURLs(0) {} 101 encodedSizeDuplicatedInDataURLs(0) {}
158 102
159 void addResource(Resource*); 103 void addResource(Resource*);
160 }; 104 };
161 105
162 struct Statistics { 106 struct Statistics {
163 STACK_ALLOCATED(); 107 STACK_ALLOCATED();
164 TypeStatistic images; 108 TypeStatistic images;
165 TypeStatistic cssStyleSheets; 109 TypeStatistic cssStyleSheets;
166 TypeStatistic scripts; 110 TypeStatistic scripts;
167 TypeStatistic xslStyleSheets; 111 TypeStatistic xslStyleSheets;
168 TypeStatistic fonts; 112 TypeStatistic fonts;
169 TypeStatistic other; 113 TypeStatistic other;
170 }; 114 };
171 115
172 Resource* resourceForURL(const KURL&); 116 Resource* resourceForURL(const KURL&) const;
173 Resource* resourceForURL(const KURL&, const String& cacheIdentifier); 117 Resource* resourceForURL(const KURL&, const String& cacheIdentifier) const;
174 HeapVector<Member<Resource>> resourcesForURL(const KURL&); 118 HeapVector<Member<Resource>> resourcesForURL(const KURL&) const;
175 119
176 void add(Resource*); 120 void add(Resource*);
177 void remove(Resource*); 121 void remove(Resource*);
178 bool contains(const Resource*) const; 122 bool contains(const Resource*) const;
179 123
180 static KURL removeFragmentIdentifierIfNeeded(const KURL& originalURL); 124 static KURL removeFragmentIdentifierIfNeeded(const KURL& originalURL);
181 125
182 static String defaultCacheIdentifier(); 126 static String defaultCacheIdentifier();
183 127
184 // Sets the cache's memory capacities, in bytes. These will hold only 128 // Sets the cache's memory capacities, in bytes. These will hold only
185 // approximately, since the decoded cost of resources like scripts and 129 // approximately, since the decoded cost of resources like scripts and
186 // stylesheets is not known. 130 // stylesheets is not known.
187 // - minDeadBytes: The maximum number of bytes that dead resources should
188 // consume when the cache is under pressure.
189 // - maxDeadBytes: The maximum number of bytes that dead resources should
190 // consume when the cache is not under pressure.
191 // - totalBytes: The maximum number of bytes that the cache should consume 131 // - totalBytes: The maximum number of bytes that the cache should consume
192 // overall. 132 // overall.
193 void setCapacities(size_t minDeadBytes, 133 void setCapacities(size_t totalBytes);
Nate Chapin 2016/10/21 18:48:20 Nit: there's only one variable, so rename to setCa
hiroshige 2016/10/24 10:35:28 Done.
194 size_t maxDeadBytes,
195 size_t totalBytes);
196 void setDelayBeforeLiveDecodedPrune(double seconds) { 134 void setDelayBeforeLiveDecodedPrune(double seconds) {
197 m_delayBeforeLiveDecodedPrune = seconds; 135 m_delayBeforeLiveDecodedPrune = seconds;
198 } 136 }
199 void setMaxPruneDeferralDelay(double seconds) { 137 void setMaxPruneDeferralDelay(double seconds) {
200 m_maxPruneDeferralDelay = seconds; 138 m_maxPruneDeferralDelay = seconds;
201 } 139 }
202 140
203 enum EvictResourcePolicy { EvictAllResources, DoNotEvictUnusedPreloads }; 141 enum EvictResourcePolicy { EvictAllResources, DoNotEvictUnusedPreloads };
204 void evictResources(EvictResourcePolicy = EvictAllResources); 142 void evictResources(EvictResourcePolicy = EvictAllResources);
205 143
206 void prune(); 144 void prune();
207 145
208 // Called to adjust a resource's size, lru list position, and access count. 146 // Called to update MemoryCache::size().
209 void update(Resource*, 147 void update(Resource*, size_t oldSize, size_t newSize);
210 size_t oldSize,
211 size_t newSize,
212 bool wasAccessed = false);
213 void updateForAccess(Resource* resource) {
214 update(resource, resource->size(), resource->size(), true);
215 }
216 void updateDecodedResource(Resource*, UpdateReason);
217
218 void makeLive(Resource*);
219 void makeDead(Resource*);
220 148
221 void removeURLFromCache(const KURL&); 149 void removeURLFromCache(const KURL&);
222 150
223 Statistics getStatistics(); 151 Statistics getStatistics() const;
224 152
225 size_t minDeadCapacity() const { return m_minDeadCapacity; }
226 size_t maxDeadCapacity() const { return m_maxDeadCapacity; }
227 size_t capacity() const { return m_capacity; } 153 size_t capacity() const { return m_capacity; }
228 size_t liveSize() const { return m_liveSize; } 154 size_t size() const { return m_size; }
229 size_t deadSize() const { return m_deadSize; }
230 155
231 // TaskObserver implementation 156 // TaskObserver implementation
232 void willProcessTask() override; 157 void willProcessTask() override;
233 void didProcessTask() override; 158 void didProcessTask() override;
234 159
235 void pruneAll(); 160 void pruneAll();
236 161
237 void updateFramePaintTimestamp(); 162 void updateFramePaintTimestamp();
238 163
239 // Take memory usage snapshot for tracing. 164 // Take memory usage snapshot for tracing.
240 bool onMemoryDump(WebMemoryDumpLevelOfDetail, WebProcessMemoryDump*) override; 165 bool onMemoryDump(WebMemoryDumpLevelOfDetail, WebProcessMemoryDump*) override;
241 166
242 void onMemoryPressure(WebMemoryPressureLevel) override; 167 void onMemoryPressure(WebMemoryPressureLevel) override;
243 168
244 bool isInSameLRUListForTest(const Resource*, const Resource*);
245
246 private: 169 private:
247 enum PruneStrategy { 170 enum PruneStrategy {
248 // Automatically decide how much to prune. 171 // Automatically decide how much to prune.
249 AutomaticPrune, 172 AutomaticPrune,
250 // Maximally prune resources. 173 // Maximally prune resources.
251 MaximalPrune 174 MaximalPrune
252 }; 175 };
253 176
177 // A URL-based map of all resources that are in the cache (including the
178 // freshest version of objects that are currently being referenced by a Web
179 // page). removeFragmentIdentifierIfNeeded() should be called for the url
180 // before using it as a key for the map.
181 using ResourceMap = HeapHashMap<String, Member<MemoryCacheEntry>>;
182 using ResourceMapIndex = HeapHashMap<String, Member<ResourceMap>>;
183 ResourceMap* ensureResourceMap(const String& cacheIdentifier);
184 ResourceMapIndex m_resourceMaps;
185
254 MemoryCache(); 186 MemoryCache();
255 187
256 MemoryCacheLRUList* lruListFor(unsigned accessCount, size_t); 188 void addInternal(ResourceMap*, MemoryCacheEntry*);
189 void removeInternal(ResourceMap*, const ResourceMap::iterator&);
257 190
258 // Calls to put the cached resource into and out of LRU lists. 191 void pruneResources(PruneStrategy);
259 void insertInLRUList(MemoryCacheEntry*, MemoryCacheLRUList*);
260 void removeFromLRUList(MemoryCacheEntry*, MemoryCacheLRUList*);
261 bool containedInLRUList(MemoryCacheEntry*, MemoryCacheLRUList*);
262
263 // Track decoded resources that are in the cache and referenced by a Web page.
264 void insertInLiveDecodedResourcesList(MemoryCacheEntry*);
265 void removeFromLiveDecodedResourcesList(MemoryCacheEntry*);
266 bool containedInLiveDecodedResourcesList(MemoryCacheEntry*);
267
268 size_t liveCapacity() const;
269 size_t deadCapacity() const;
270
271 // pruneDeadResources() - Flush decoded and encoded data from resources not
272 // referenced by Web pages.
273 // pruneLiveResources() - Flush decoded data from resources still referenced
274 // by Web pages.
275 void pruneDeadResources(PruneStrategy);
276 void pruneLiveResources(PruneStrategy);
277 void pruneNow(double currentTime, PruneStrategy); 192 void pruneNow(double currentTime, PruneStrategy);
278 193
279 void evict(MemoryCacheEntry*);
280
281 MemoryCacheEntry* getEntryForResource(const Resource*) const;
282
283 static void removeURLFromCacheInternal(ExecutionContext*, const KURL&);
284
285 bool m_inPruneResources; 194 bool m_inPruneResources;
286 bool m_prunePending; 195 bool m_prunePending;
287 double m_maxPruneDeferralDelay; 196 double m_maxPruneDeferralDelay;
288 double m_pruneTimeStamp; 197 double m_pruneTimeStamp;
289 double m_pruneFrameTimeStamp; 198 double m_pruneFrameTimeStamp;
290 double m_lastFramePaintTimeStamp; // used for detecting decoded resource 199 double m_lastFramePaintTimeStamp; // used for detecting decoded resource
291 // thrash in the cache 200 // thrash in the cache
292 201
293 size_t m_capacity; 202 size_t m_capacity;
294 size_t m_minDeadCapacity;
295 size_t m_maxDeadCapacity;
296 size_t m_maxDeferredPruneDeadCapacity;
297 double m_delayBeforeLiveDecodedPrune; 203 double m_delayBeforeLiveDecodedPrune;
298 204
299 // The number of bytes currently consumed by "live" resources in the cache. 205 // The number of bytes currently consumed by resources in the cache.
300 size_t m_liveSize; 206 size_t m_size;
301 // The number of bytes currently consumed by "dead" resources in the cache.
302 size_t m_deadSize;
303
304 // Size-adjusted and popularity-aware LRU list collection for cache objects.
305 // This collection can hold more resources than the cached resource map, since
306 // it can also hold "stale" multiple versions of objects that are waiting to
307 // die when the clients referencing them go away.
308 HeapVector<MemoryCacheLRUList, 32> m_allResources;
309
310 // Lists just for live resources with decoded data. Access to this list is
311 // based off of painting the resource.
312 MemoryCacheLRUList m_liveDecodedResources;
313
314 // A URL-based map of all resources that are in the cache (including the
315 // freshest version of objects that are currently being referenced by a Web
316 // page). removeFragmentIdentifierIfNeeded() should be called for the url
317 // before using it as a key for the map.
318 using ResourceMap = HeapHashMap<String, Member<MemoryCacheEntry>>;
319 using ResourceMapIndex = HeapHashMap<String, Member<ResourceMap>>;
320 ResourceMap* ensureResourceMap(const String& cacheIdentifier);
321 ResourceMapIndex m_resourceMaps;
322 207
323 HeapHashSet<WeakMember<Resource>> m_allResourcesForMemoryInfra; 208 HeapHashSet<WeakMember<Resource>> m_allResourcesForMemoryInfra;
324 209
325 friend class MemoryCacheTest; 210 friend class MemoryCacheTest;
326 }; 211 };
327 212
328 // Returns the global cache. 213 // Returns the global cache.
329 CORE_EXPORT MemoryCache* memoryCache(); 214 CORE_EXPORT MemoryCache* memoryCache();
330 215
331 // Sets the global cache, used to swap in a test instance. Returns the old 216 // Sets the global cache, used to swap in a test instance. Returns the old
332 // MemoryCache object. 217 // MemoryCache object.
333 CORE_EXPORT MemoryCache* replaceMemoryCacheForTesting(MemoryCache*); 218 CORE_EXPORT MemoryCache* replaceMemoryCacheForTesting(MemoryCache*);
334 219
335 } // namespace blink 220 } // namespace blink
336 221
337 #endif 222 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698