OLD | NEW |
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) 2002 Waldo Bastian (bastian@kde.org) | 4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) |
5 Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. | 5 Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. |
6 | 6 |
7 This library is free software; you can redistribute it and/or | 7 This library is free software; you can redistribute it and/or |
8 modify it under the terms of the GNU Library General Public | 8 modify it under the terms of the GNU Library General Public |
9 License as published by the Free Software Foundation; either | 9 License as published by the Free Software Foundation; either |
10 version 2 of the License, or (at your option) any later version. | 10 version 2 of the License, or (at your option) any later version. |
(...skipping 23 matching lines...) Expand all Loading... |
34 #include "wtf/text/CString.h" | 34 #include "wtf/text/CString.h" |
35 | 35 |
36 namespace blink { | 36 namespace blink { |
37 | 37 |
38 static Persistent<MemoryCache>* gMemoryCache; | 38 static Persistent<MemoryCache>* gMemoryCache; |
39 | 39 |
40 static const unsigned cDefaultCacheCapacity = 8192 * 1024; | 40 static const unsigned cDefaultCacheCapacity = 8192 * 1024; |
41 static const unsigned cDeferredPruneDeadCapacityFactor = 2; | 41 static const unsigned cDeferredPruneDeadCapacityFactor = 2; |
42 static const int cMinDelayBeforeLiveDecodedPrune = 1; // Seconds. | 42 static const int cMinDelayBeforeLiveDecodedPrune = 1; // Seconds. |
43 static const double cMaxPruneDeferralDelay = 0.5; // Seconds. | 43 static const double cMaxPruneDeferralDelay = 0.5; // Seconds. |
44 static const float cTargetPrunePercentage = | 44 |
45 .95f; // Percentage of capacity toward which we prune, to avoid immediately
pruning again. | 45 // Percentage of capacity toward which we prune, to avoid immediately pruning |
| 46 // again. |
| 47 static const float cTargetPrunePercentage = .95f; |
46 | 48 |
47 MemoryCache* memoryCache() { | 49 MemoryCache* memoryCache() { |
48 DCHECK(WTF::isMainThread()); | 50 DCHECK(WTF::isMainThread()); |
49 if (!gMemoryCache) | 51 if (!gMemoryCache) |
50 gMemoryCache = new Persistent<MemoryCache>(MemoryCache::create()); | 52 gMemoryCache = new Persistent<MemoryCache>(MemoryCache::create()); |
51 return gMemoryCache->get(); | 53 return gMemoryCache->get(); |
52 } | 54 } |
53 | 55 |
54 MemoryCache* replaceMemoryCacheForTesting(MemoryCache* cache) { | 56 MemoryCache* replaceMemoryCacheForTesting(MemoryCache* cache) { |
55 memoryCache(); | 57 memoryCache(); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 visitor->trace(m_allResources); | 124 visitor->trace(m_allResources); |
123 visitor->trace(m_liveDecodedResources); | 125 visitor->trace(m_liveDecodedResources); |
124 visitor->trace(m_resourceMaps); | 126 visitor->trace(m_resourceMaps); |
125 MemoryCacheDumpClient::trace(visitor); | 127 MemoryCacheDumpClient::trace(visitor); |
126 MemoryCoordinatorClient::trace(visitor); | 128 MemoryCoordinatorClient::trace(visitor); |
127 } | 129 } |
128 | 130 |
129 KURL MemoryCache::removeFragmentIdentifierIfNeeded(const KURL& originalURL) { | 131 KURL MemoryCache::removeFragmentIdentifierIfNeeded(const KURL& originalURL) { |
130 if (!originalURL.hasFragmentIdentifier()) | 132 if (!originalURL.hasFragmentIdentifier()) |
131 return originalURL; | 133 return originalURL; |
132 // Strip away fragment identifier from HTTP URLs. | 134 // Strip away fragment identifier from HTTP URLs. Data URLs must be |
133 // Data URLs must be unmodified. For file and custom URLs clients may expect r
esources | 135 // unmodified. For file and custom URLs clients may expect resources to be |
134 // to be unique even when they differ by the fragment identifier only. | 136 // unique even when they differ by the fragment identifier only. |
135 if (!originalURL.protocolIsInHTTPFamily()) | 137 if (!originalURL.protocolIsInHTTPFamily()) |
136 return originalURL; | 138 return originalURL; |
137 KURL url = originalURL; | 139 KURL url = originalURL; |
138 url.removeFragmentIdentifier(); | 140 url.removeFragmentIdentifier(); |
139 return url; | 141 return url; |
140 } | 142 } |
141 | 143 |
142 String MemoryCache::defaultCacheIdentifier() { | 144 String MemoryCache::defaultCacheIdentifier() { |
143 return emptyString(); | 145 return emptyString(); |
144 } | 146 } |
(...skipping 16 matching lines...) Expand all Loading... |
161 CHECK(!contains(resource)); | 163 CHECK(!contains(resource)); |
162 resources->set(url, MemoryCacheEntry::create(resource)); | 164 resources->set(url, MemoryCacheEntry::create(resource)); |
163 update(resource, 0, resource->size(), true); | 165 update(resource, 0, resource->size(), true); |
164 | 166 |
165 RESOURCE_LOADING_DVLOG(1) << "MemoryCache::add Added " | 167 RESOURCE_LOADING_DVLOG(1) << "MemoryCache::add Added " |
166 << resource->url().getString() << ", resource " | 168 << resource->url().getString() << ", resource " |
167 << resource; | 169 << resource; |
168 } | 170 } |
169 | 171 |
170 void MemoryCache::remove(Resource* resource) { | 172 void MemoryCache::remove(Resource* resource) { |
171 // The resource may have already been removed by someone other than our caller
, | 173 // The resource may have already been removed by someone other than our |
172 // who needed a fresh copy for a reload. | 174 // caller, who needed a fresh copy for a reload. |
173 if (MemoryCacheEntry* entry = getEntryForResource(resource)) | 175 if (MemoryCacheEntry* entry = getEntryForResource(resource)) |
174 evict(entry); | 176 evict(entry); |
175 } | 177 } |
176 | 178 |
177 bool MemoryCache::contains(const Resource* resource) const { | 179 bool MemoryCache::contains(const Resource* resource) const { |
178 return getEntryForResource(resource); | 180 return getEntryForResource(resource); |
179 } | 181 } |
180 | 182 |
181 Resource* MemoryCache::resourceForURL(const KURL& resourceURL) { | 183 Resource* MemoryCache::resourceForURL(const KURL& resourceURL) { |
182 return resourceForURL(resourceURL, defaultCacheIdentifier()); | 184 return resourceForURL(resourceURL, defaultCacheIdentifier()); |
(...skipping 24 matching lines...) Expand all Loading... |
207 if (MemoryCacheEntry* entry = resourceMapIter.value->get(url)) { | 209 if (MemoryCacheEntry* entry = resourceMapIter.value->get(url)) { |
208 Resource* resource = entry->resource(); | 210 Resource* resource = entry->resource(); |
209 DCHECK(resource); | 211 DCHECK(resource); |
210 results.append(resource); | 212 results.append(resource); |
211 } | 213 } |
212 } | 214 } |
213 return results; | 215 return results; |
214 } | 216 } |
215 | 217 |
216 size_t MemoryCache::deadCapacity() const { | 218 size_t MemoryCache::deadCapacity() const { |
217 // Dead resource capacity is whatever space is not occupied by live resources,
bounded by an independent minimum and maximum. | 219 // Dead resource capacity is whatever space is not occupied by live resources, |
| 220 // bounded by an independent minimum and maximum. |
218 size_t capacity = | 221 size_t capacity = |
219 m_capacity - | 222 m_capacity - |
220 std::min(m_liveSize, m_capacity); // Start with available capacity. | 223 std::min(m_liveSize, m_capacity); // Start with available capacity. |
221 capacity = std::max(capacity, | 224 capacity = std::max(capacity, |
222 m_minDeadCapacity); // Make sure it's above the minimum. | 225 m_minDeadCapacity); // Make sure it's above the minimum. |
223 capacity = std::min(capacity, | 226 capacity = std::min(capacity, |
224 m_maxDeadCapacity); // Make sure it's below the maximum. | 227 m_maxDeadCapacity); // Make sure it's below the maximum. |
225 return capacity; | 228 return capacity; |
226 } | 229 } |
227 | 230 |
228 size_t MemoryCache::liveCapacity() const { | 231 size_t MemoryCache::liveCapacity() const { |
229 // Live resource capacity is whatever is left over after calculating dead reso
urce capacity. | 232 // Live resource capacity is whatever is left over after calculating dead |
| 233 // resource capacity. |
230 return m_capacity - deadCapacity(); | 234 return m_capacity - deadCapacity(); |
231 } | 235 } |
232 | 236 |
233 void MemoryCache::pruneLiveResources(PruneStrategy strategy) { | 237 void MemoryCache::pruneLiveResources(PruneStrategy strategy) { |
234 DCHECK(!m_prunePending); | 238 DCHECK(!m_prunePending); |
235 size_t capacity = liveCapacity(); | 239 size_t capacity = liveCapacity(); |
236 if (strategy == MaximalPrune) | 240 if (strategy == MaximalPrune) |
237 capacity = 0; | 241 capacity = 0; |
238 if (!m_liveSize || (capacity && m_liveSize <= capacity)) | 242 if (!m_liveSize || (capacity && m_liveSize <= capacity)) |
239 return; | 243 return; |
240 | 244 |
241 size_t targetSize = static_cast<size_t>( | 245 // Cut by a percentage to avoid immediately pruning again. |
242 capacity * | 246 size_t targetSize = static_cast<size_t>(capacity * cTargetPrunePercentage); |
243 cTargetPrunePercentage); // Cut by a percentage to avoid immediately prun
ing again. | |
244 | 247 |
245 // Destroy any decoded data in live objects that we can. | 248 // Destroy any decoded data in live objects that we can. Start from the tail, |
246 // Start from the tail, since this is the lowest priority | 249 // since this is the lowest priority and least recently accessed of the |
247 // and least recently accessed of the objects. | 250 // objects. |
248 | 251 |
249 // The list might not be sorted by the m_lastDecodedFrameTimeStamp. The impact | 252 // The list might not be sorted by the m_lastDecodedFrameTimeStamp. The impact |
250 // of this weaker invariant is minor as the below if statement to check the | 253 // of this weaker invariant is minor as the below if statement to check the |
251 // elapsedTime will evaluate to false as the current time will be a lot | 254 // elapsedTime will evaluate to false as the current time will be a lot |
252 // greater than the current->m_lastDecodedFrameTimeStamp. | 255 // greater than the current->m_lastDecodedFrameTimeStamp. For more details |
253 // For more details see: https://bugs.webkit.org/show_bug.cgi?id=30209 | 256 // see: https://bugs.webkit.org/show_bug.cgi?id=30209 |
254 | 257 |
255 MemoryCacheEntry* current = m_liveDecodedResources.m_tail; | 258 MemoryCacheEntry* current = m_liveDecodedResources.m_tail; |
256 while (current) { | 259 while (current) { |
257 Resource* resource = current->resource(); | 260 Resource* resource = current->resource(); |
258 MemoryCacheEntry* previous = current->m_previousInLiveResourcesList; | 261 MemoryCacheEntry* previous = current->m_previousInLiveResourcesList; |
259 DCHECK(resource->isAlive()); | 262 DCHECK(resource->isAlive()); |
260 | 263 |
261 if (resource->isLoaded() && resource->decodedSize()) { | 264 if (resource->isLoaded() && resource->decodedSize()) { |
262 // Check to see if the remaining resources are too new to prune. | 265 // Check to see if the remaining resources are too new to prune. |
263 double elapsedTime = | 266 double elapsedTime = |
264 m_pruneFrameTimeStamp - current->m_lastDecodedAccessTime; | 267 m_pruneFrameTimeStamp - current->m_lastDecodedAccessTime; |
265 if (strategy == AutomaticPrune && | 268 if (strategy == AutomaticPrune && |
266 elapsedTime < m_delayBeforeLiveDecodedPrune) | 269 elapsedTime < m_delayBeforeLiveDecodedPrune) |
267 return; | 270 return; |
268 | 271 |
269 // Destroy our decoded data if possible. This will remove us | 272 // Destroy our decoded data if possible. This will remove us from |
270 // from m_liveDecodedResources, and possibly move us to a | 273 // m_liveDecodedResources, and possibly move us to a different LRU list in |
271 // different LRU list in m_allResources. | 274 // m_allResources. |
272 resource->prune(); | 275 resource->prune(); |
273 | 276 |
274 if (targetSize && m_liveSize <= targetSize) | 277 if (targetSize && m_liveSize <= targetSize) |
275 return; | 278 return; |
276 } | 279 } |
277 current = previous; | 280 current = previous; |
278 } | 281 } |
279 } | 282 } |
280 | 283 |
281 void MemoryCache::pruneDeadResources(PruneStrategy strategy) { | 284 void MemoryCache::pruneDeadResources(PruneStrategy strategy) { |
282 size_t capacity = deadCapacity(); | 285 size_t capacity = deadCapacity(); |
283 if (strategy == MaximalPrune) | 286 if (strategy == MaximalPrune) |
284 capacity = 0; | 287 capacity = 0; |
285 if (!m_deadSize || (capacity && m_deadSize <= capacity)) | 288 if (!m_deadSize || (capacity && m_deadSize <= capacity)) |
286 return; | 289 return; |
287 | 290 |
288 size_t targetSize = static_cast<size_t>( | 291 // Cut by a percentage to avoid immediately pruning again. |
289 capacity * | 292 size_t targetSize = static_cast<size_t>(capacity * cTargetPrunePercentage); |
290 cTargetPrunePercentage); // Cut by a percentage to avoid immediately prun
ing again. | |
291 | 293 |
292 int size = m_allResources.size(); | 294 int size = m_allResources.size(); |
293 if (targetSize && m_deadSize <= targetSize) | 295 if (targetSize && m_deadSize <= targetSize) |
294 return; | 296 return; |
295 | 297 |
296 bool canShrinkLRULists = true; | 298 bool canShrinkLRULists = true; |
297 for (int i = size - 1; i >= 0; i--) { | 299 for (int i = size - 1; i >= 0; i--) { |
298 // Remove from the tail, since this is the least frequently accessed of the
objects. | 300 // Remove from the tail, since this is the least frequently accessed of the |
| 301 // objects. |
299 MemoryCacheEntry* current = m_allResources[i].m_tail; | 302 MemoryCacheEntry* current = m_allResources[i].m_tail; |
300 | 303 |
301 // First flush all the decoded data in this queue. | 304 // First flush all the decoded data in this queue. |
302 while (current) { | 305 while (current) { |
303 Resource* resource = current->resource(); | 306 Resource* resource = current->resource(); |
304 MemoryCacheEntry* previous = current->m_previousInAllResourcesList; | 307 MemoryCacheEntry* previous = current->m_previousInAllResourcesList; |
305 | 308 |
306 // Decoded data may reference other resources. Skip |current| if | 309 // Decoded data may reference other resources. Skip |current| if |current| |
307 // |current| somehow got kicked out of cache during | 310 // somehow got kicked out of cache during destroyDecodedData(). |
308 // destroyDecodedData(). | |
309 if (!resource || !contains(resource)) { | 311 if (!resource || !contains(resource)) { |
310 current = previous; | 312 current = previous; |
311 continue; | 313 continue; |
312 } | 314 } |
313 | 315 |
314 if (!resource->isAlive() && !resource->isPreloaded() && | 316 if (!resource->isAlive() && !resource->isPreloaded() && |
315 resource->isLoaded()) { | 317 resource->isLoaded()) { |
316 // Destroy our decoded data. This will remove us from | 318 // Destroy our decoded data. This will remove us from |
317 // m_liveDecodedResources, and possibly move us to a different | 319 // m_liveDecodedResources, and possibly move us to a different LRU list |
318 // LRU list in m_allResources. | 320 // in m_allResources. |
319 resource->prune(); | 321 resource->prune(); |
320 | 322 |
321 if (targetSize && m_deadSize <= targetSize) | 323 if (targetSize && m_deadSize <= targetSize) |
322 return; | 324 return; |
323 } | 325 } |
324 current = previous; | 326 current = previous; |
325 } | 327 } |
326 | 328 |
327 // Now evict objects from this queue. | 329 // Now evict objects from this queue. |
328 current = m_allResources[i].m_tail; | 330 current = m_allResources[i].m_tail; |
329 while (current) { | 331 while (current) { |
330 Resource* resource = current->resource(); | 332 Resource* resource = current->resource(); |
331 MemoryCacheEntry* previous = current->m_previousInAllResourcesList; | 333 MemoryCacheEntry* previous = current->m_previousInAllResourcesList; |
332 if (!resource || !contains(resource)) { | 334 if (!resource || !contains(resource)) { |
333 current = previous; | 335 current = previous; |
334 continue; | 336 continue; |
335 } | 337 } |
336 if (!resource->isAlive() && !resource->isPreloaded()) { | 338 if (!resource->isAlive() && !resource->isPreloaded()) { |
337 evict(current); | 339 evict(current); |
338 if (targetSize && m_deadSize <= targetSize) | 340 if (targetSize && m_deadSize <= targetSize) |
339 return; | 341 return; |
340 } | 342 } |
341 current = previous; | 343 current = previous; |
342 } | 344 } |
343 | 345 |
344 // Shrink the vector back down so we don't waste time inspecting | 346 // Shrink the vector back down so we don't waste time inspecting empty LRU |
345 // empty LRU lists on future prunes. | 347 // lists on future prunes. |
346 if (m_allResources[i].m_head) | 348 if (m_allResources[i].m_head) |
347 canShrinkLRULists = false; | 349 canShrinkLRULists = false; |
348 else if (canShrinkLRULists) | 350 else if (canShrinkLRULists) |
349 m_allResources.resize(i); | 351 m_allResources.resize(i); |
350 } | 352 } |
351 } | 353 } |
352 | 354 |
353 void MemoryCache::setCapacities(size_t minDeadBytes, | 355 void MemoryCache::setCapacities(size_t minDeadBytes, |
354 size_t maxDeadBytes, | 356 size_t maxDeadBytes, |
355 size_t totalBytes) { | 357 size_t totalBytes) { |
356 DCHECK_LE(minDeadBytes, maxDeadBytes); | 358 DCHECK_LE(minDeadBytes, maxDeadBytes); |
357 DCHECK_LE(maxDeadBytes, totalBytes); | 359 DCHECK_LE(maxDeadBytes, totalBytes); |
358 m_minDeadCapacity = minDeadBytes; | 360 m_minDeadCapacity = minDeadBytes; |
359 m_maxDeadCapacity = maxDeadBytes; | 361 m_maxDeadCapacity = maxDeadBytes; |
360 m_maxDeferredPruneDeadCapacity = | 362 m_maxDeferredPruneDeadCapacity = |
361 cDeferredPruneDeadCapacityFactor * maxDeadBytes; | 363 cDeferredPruneDeadCapacityFactor * maxDeadBytes; |
362 m_capacity = totalBytes; | 364 m_capacity = totalBytes; |
363 prune(); | 365 prune(); |
364 } | 366 } |
365 | 367 |
366 void MemoryCache::evict(MemoryCacheEntry* entry) { | 368 void MemoryCache::evict(MemoryCacheEntry* entry) { |
367 DCHECK(WTF::isMainThread()); | 369 DCHECK(WTF::isMainThread()); |
368 | 370 |
369 Resource* resource = entry->resource(); | 371 Resource* resource = entry->resource(); |
370 DCHECK(resource); | 372 DCHECK(resource); |
371 RESOURCE_LOADING_DVLOG(1) << "Evicting resource " << resource << " for " | 373 RESOURCE_LOADING_DVLOG(1) << "Evicting resource " << resource << " for " |
372 << resource->url().getString() << " from cache"; | 374 << resource->url().getString() << " from cache"; |
373 TRACE_EVENT1("blink", "MemoryCache::evict", "resource", | 375 TRACE_EVENT1("blink", "MemoryCache::evict", "resource", |
374 resource->url().getString().utf8()); | 376 resource->url().getString().utf8()); |
375 // The resource may have already been removed by someone other than our caller
, | 377 // The resource may have already been removed by someone other than our |
376 // who needed a fresh copy for a reload. See <http://bugs.webkit.org/show_bug.
cgi?id=12479#c6>. | 378 // caller, who needed a fresh copy for a reload. See |
| 379 // <http://bugs.webkit.org/show_bug.cgi?id=12479#c6>. |
377 update(resource, resource->size(), 0, false); | 380 update(resource, resource->size(), 0, false); |
378 removeFromLiveDecodedResourcesList(entry); | 381 removeFromLiveDecodedResourcesList(entry); |
379 | 382 |
380 ResourceMap* resources = m_resourceMaps.get(resource->cacheIdentifier()); | 383 ResourceMap* resources = m_resourceMaps.get(resource->cacheIdentifier()); |
381 DCHECK(resources); | 384 DCHECK(resources); |
382 KURL url = removeFragmentIdentifierIfNeeded(resource->url()); | 385 KURL url = removeFragmentIdentifierIfNeeded(resource->url()); |
383 ResourceMap::iterator it = resources->find(url); | 386 ResourceMap::iterator it = resources->find(url); |
384 DCHECK_NE(it, resources->end()); | 387 DCHECK_NE(it, resources->end()); |
385 | 388 |
386 MemoryCacheEntry* entryPtr = it->value; | 389 MemoryCacheEntry* entryPtr = it->value; |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 } | 537 } |
535 | 538 |
536 void MemoryCache::update(Resource* resource, | 539 void MemoryCache::update(Resource* resource, |
537 size_t oldSize, | 540 size_t oldSize, |
538 size_t newSize, | 541 size_t newSize, |
539 bool wasAccessed) { | 542 bool wasAccessed) { |
540 MemoryCacheEntry* entry = getEntryForResource(resource); | 543 MemoryCacheEntry* entry = getEntryForResource(resource); |
541 if (!entry) | 544 if (!entry) |
542 return; | 545 return; |
543 | 546 |
544 // The object must now be moved to a different queue, since either its size or
its accessCount has been changed, | 547 // The object must now be moved to a different queue, since either its size or |
545 // and both of those are used to determine which LRU queue the resource should
be in. | 548 // its accessCount has been changed, and both of those are used to determine |
| 549 // which LRU queue the resource should be in. |
546 if (oldSize) | 550 if (oldSize) |
547 removeFromLRUList(entry, lruListFor(entry->m_accessCount, oldSize)); | 551 removeFromLRUList(entry, lruListFor(entry->m_accessCount, oldSize)); |
548 if (wasAccessed) | 552 if (wasAccessed) |
549 entry->m_accessCount++; | 553 entry->m_accessCount++; |
550 if (newSize) | 554 if (newSize) |
551 insertInLRUList(entry, lruListFor(entry->m_accessCount, newSize)); | 555 insertInLRUList(entry, lruListFor(entry->m_accessCount, newSize)); |
552 | 556 |
553 ptrdiff_t delta = newSize - oldSize; | 557 ptrdiff_t delta = newSize - oldSize; |
554 if (resource->isAlive()) { | 558 if (resource->isAlive()) { |
555 DCHECK(delta >= 0 || m_liveSize >= static_cast<size_t>(-delta)); | 559 DCHECK(delta >= 0 || m_liveSize >= static_cast<size_t>(-delta)); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 | 649 |
646 void MemoryCache::prune() { | 650 void MemoryCache::prune() { |
647 TRACE_EVENT0("renderer", "MemoryCache::prune()"); | 651 TRACE_EVENT0("renderer", "MemoryCache::prune()"); |
648 | 652 |
649 if (m_inPruneResources) | 653 if (m_inPruneResources) |
650 return; | 654 return; |
651 if (m_liveSize + m_deadSize <= m_capacity && m_maxDeadCapacity && | 655 if (m_liveSize + m_deadSize <= m_capacity && m_maxDeadCapacity && |
652 m_deadSize <= m_maxDeadCapacity) // Fast path. | 656 m_deadSize <= m_maxDeadCapacity) // Fast path. |
653 return; | 657 return; |
654 | 658 |
655 // To avoid burdening the current thread with repetitive pruning jobs, | 659 // To avoid burdening the current thread with repetitive pruning jobs, pruning |
656 // pruning is postponed until the end of the current task. If it has | 660 // is postponed until the end of the current task. If it has been more than |
657 // been more than m_maxPruneDeferralDelay since the last prune, | 661 // m_maxPruneDeferralDelay since the last prune, then we prune immediately. If |
658 // then we prune immediately. | 662 // the current thread's run loop is not active, then pruning will happen |
659 // If the current thread's run loop is not active, then pruning will happen | 663 // immediately only if it has been over m_maxPruneDeferralDelay since the last |
660 // immediately only if it has been over m_maxPruneDeferralDelay | 664 // prune. |
661 // since the last prune. | |
662 double currentTime = WTF::currentTime(); | 665 double currentTime = WTF::currentTime(); |
663 if (m_prunePending) { | 666 if (m_prunePending) { |
664 if (currentTime - m_pruneTimeStamp >= m_maxPruneDeferralDelay) { | 667 if (currentTime - m_pruneTimeStamp >= m_maxPruneDeferralDelay) { |
665 pruneNow(currentTime, AutomaticPrune); | 668 pruneNow(currentTime, AutomaticPrune); |
666 } | 669 } |
667 } else { | 670 } else { |
668 if (currentTime - m_pruneTimeStamp >= m_maxPruneDeferralDelay) { | 671 if (currentTime - m_pruneTimeStamp >= m_maxPruneDeferralDelay) { |
669 pruneNow(currentTime, AutomaticPrune); // Delay exceeded, prune now. | 672 pruneNow(currentTime, AutomaticPrune); // Delay exceeded, prune now. |
670 } else { | 673 } else { |
671 // Defer. | 674 // Defer. |
(...skipping 16 matching lines...) Expand all Loading... |
688 pruneNow(currentTime, MaximalPrune); | 691 pruneNow(currentTime, MaximalPrune); |
689 } | 692 } |
690 | 693 |
691 void MemoryCache::pruneNow(double currentTime, PruneStrategy strategy) { | 694 void MemoryCache::pruneNow(double currentTime, PruneStrategy strategy) { |
692 if (m_prunePending) { | 695 if (m_prunePending) { |
693 m_prunePending = false; | 696 m_prunePending = false; |
694 Platform::current()->currentThread()->removeTaskObserver(this); | 697 Platform::current()->currentThread()->removeTaskObserver(this); |
695 } | 698 } |
696 | 699 |
697 AutoReset<bool> reentrancyProtector(&m_inPruneResources, true); | 700 AutoReset<bool> reentrancyProtector(&m_inPruneResources, true); |
698 pruneDeadResources( | 701 |
699 strategy); // Prune dead first, in case it was "borrowing" capacity from
live. | 702 // Prune dead first, in case it was "borrowing" capacity from live. |
| 703 pruneDeadResources(strategy); |
700 pruneLiveResources(strategy); | 704 pruneLiveResources(strategy); |
701 m_pruneFrameTimeStamp = m_lastFramePaintTimeStamp; | 705 m_pruneFrameTimeStamp = m_lastFramePaintTimeStamp; |
702 m_pruneTimeStamp = currentTime; | 706 m_pruneTimeStamp = currentTime; |
703 } | 707 } |
704 | 708 |
705 void MemoryCache::updateFramePaintTimestamp() { | 709 void MemoryCache::updateFramePaintTimestamp() { |
706 m_lastFramePaintTimeStamp = currentTime(); | 710 m_lastFramePaintTimeStamp = currentTime(); |
707 } | 711 } |
708 | 712 |
709 bool MemoryCache::onMemoryDump(WebMemoryDumpLevelOfDetail levelOfDetail, | 713 bool MemoryCache::onMemoryDump(WebMemoryDumpLevelOfDetail levelOfDetail, |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
753 bool MemoryCache::isInSameLRUListForTest(const Resource* x, const Resource* y) { | 757 bool MemoryCache::isInSameLRUListForTest(const Resource* x, const Resource* y) { |
754 MemoryCacheEntry* ex = getEntryForResource(x); | 758 MemoryCacheEntry* ex = getEntryForResource(x); |
755 MemoryCacheEntry* ey = getEntryForResource(y); | 759 MemoryCacheEntry* ey = getEntryForResource(y); |
756 DCHECK(ex); | 760 DCHECK(ex); |
757 DCHECK(ey); | 761 DCHECK(ey); |
758 return lruListFor(ex->m_accessCount, x->size()) == | 762 return lruListFor(ex->m_accessCount, x->size()) == |
759 lruListFor(ey->m_accessCount, y->size()); | 763 lruListFor(ey->m_accessCount, y->size()); |
760 } | 764 } |
761 | 765 |
762 } // namespace blink | 766 } // namespace blink |
OLD | NEW |