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 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 | 246 |
247 // The list might not be sorted by the m_lastDecodedFrameTimeStamp. The impa
ct | 247 // The list might not be sorted by the m_lastDecodedFrameTimeStamp. The impa
ct |
248 // of this weaker invariant is minor as the below if statement to check the | 248 // of this weaker invariant is minor as the below if statement to check the |
249 // elapsedTime will evaluate to false as the current time will be a lot | 249 // elapsedTime will evaluate to false as the current time will be a lot |
250 // greater than the current->m_lastDecodedFrameTimeStamp. | 250 // greater than the current->m_lastDecodedFrameTimeStamp. |
251 // For more details see: https://bugs.webkit.org/show_bug.cgi?id=30209 | 251 // For more details see: https://bugs.webkit.org/show_bug.cgi?id=30209 |
252 | 252 |
253 MemoryCacheEntry* current = m_liveDecodedResources.m_tail; | 253 MemoryCacheEntry* current = m_liveDecodedResources.m_tail; |
254 while (current) { | 254 while (current) { |
255 MemoryCacheEntry* previous = current->m_previousInLiveResourcesList; | 255 MemoryCacheEntry* previous = current->m_previousInLiveResourcesList; |
256 ASSERT(current->m_resource->hasClients()); | 256 ASSERT(current->m_resource->hasClientsOrObservers()); |
257 if (current->m_resource->isLoaded() && current->m_resource->decodedSize(
)) { | 257 if (current->m_resource->isLoaded() && current->m_resource->decodedSize(
)) { |
258 // Check to see if the remaining resources are too new to prune. | 258 // Check to see if the remaining resources are too new to prune. |
259 double elapsedTime = m_pruneFrameTimeStamp - current->m_lastDecodedA
ccessTime; | 259 double elapsedTime = m_pruneFrameTimeStamp - current->m_lastDecodedA
ccessTime; |
260 if (strategy == AutomaticPrune && elapsedTime < m_delayBeforeLiveDec
odedPrune) | 260 if (strategy == AutomaticPrune && elapsedTime < m_delayBeforeLiveDec
odedPrune) |
261 return; | 261 return; |
262 | 262 |
263 // Destroy our decoded data if possible. This will remove us | 263 // Destroy our decoded data if possible. This will remove us |
264 // from m_liveDecodedResources, and possibly move us to a | 264 // from m_liveDecodedResources, and possibly move us to a |
265 // different LRU list in m_allResources. | 265 // different LRU list in m_allResources. |
266 current->m_resource->prune(); | 266 current->m_resource->prune(); |
(...skipping 27 matching lines...) Expand all Loading... |
294 // First flush all the decoded data in this queue. | 294 // First flush all the decoded data in this queue. |
295 while (current) { | 295 while (current) { |
296 MemoryCacheEntry* previous = current->m_previousInAllResourcesList; | 296 MemoryCacheEntry* previous = current->m_previousInAllResourcesList; |
297 if (previous) { | 297 if (previous) { |
298 ASSERT(previous->m_resource); | 298 ASSERT(previous->m_resource); |
299 ASSERT(contains(previous->m_resource.get())); | 299 ASSERT(contains(previous->m_resource.get())); |
300 } | 300 } |
301 // TODO(leon.han@intel.com): We shouldn't be hitting the case | 301 // TODO(leon.han@intel.com): We shouldn't be hitting the case |
302 // that current->m_resource is null here, would turn the case into | 302 // that current->m_resource is null here, would turn the case into |
303 // ASSERT(current->m_resource) after crbug.com/594644 got resolved. | 303 // ASSERT(current->m_resource) after crbug.com/594644 got resolved. |
304 if (current->m_resource && !current->m_resource->hasClients() && !cu
rrent->m_resource->isPreloaded() && current->m_resource->isLoaded()) { | 304 if (current->m_resource && !current->m_resource->hasClientsOrObserve
rs() && !current->m_resource->isPreloaded() && current->m_resource->isLoaded())
{ |
305 // Destroy our decoded data. This will remove us from | 305 // Destroy our decoded data. This will remove us from |
306 // m_liveDecodedResources, and possibly move us to a different | 306 // m_liveDecodedResources, and possibly move us to a different |
307 // LRU list in m_allResources. | 307 // LRU list in m_allResources. |
308 current->m_resource->prune(); | 308 current->m_resource->prune(); |
309 | 309 |
310 if (targetSize && m_deadSize <= targetSize) | 310 if (targetSize && m_deadSize <= targetSize) |
311 return; | 311 return; |
312 } | 312 } |
313 // Decoded data may reference other resources. Stop iterating if 'pr
evious' somehow got | 313 // Decoded data may reference other resources. Stop iterating if 'pr
evious' somehow got |
314 // kicked out of cache during destroyDecodedData(). | 314 // kicked out of cache during destroyDecodedData(). |
315 if (!previous || !previous->m_resource || !contains(previous->m_reso
urce.get())) | 315 if (!previous || !previous->m_resource || !contains(previous->m_reso
urce.get())) |
316 break; | 316 break; |
317 current = previous; | 317 current = previous; |
318 } | 318 } |
319 | 319 |
320 // Now evict objects from this queue. | 320 // Now evict objects from this queue. |
321 current = m_allResources[i].m_tail; | 321 current = m_allResources[i].m_tail; |
322 while (current) { | 322 while (current) { |
323 MemoryCacheEntry* previous = current->m_previousInAllResourcesList; | 323 MemoryCacheEntry* previous = current->m_previousInAllResourcesList; |
324 if (previous) { | 324 if (previous) { |
325 ASSERT(previous->m_resource); | 325 ASSERT(previous->m_resource); |
326 ASSERT(contains(previous->m_resource.get())); | 326 ASSERT(contains(previous->m_resource.get())); |
327 } | 327 } |
328 // TODO(leon.han@intel.com): We shouldn't be hitting the case | 328 // TODO(leon.han@intel.com): We shouldn't be hitting the case |
329 // that current->m_resource is null here, would turn the case into | 329 // that current->m_resource is null here, would turn the case into |
330 // ASSERT(current->m_resource) after crbug.com/594644 got resolved. | 330 // ASSERT(current->m_resource) after crbug.com/594644 got resolved. |
331 if (current->m_resource && !current->m_resource->hasClients() && !cu
rrent->m_resource->isPreloaded()) { | 331 if (current->m_resource && !current->m_resource->hasClientsOrObserve
rs() && !current->m_resource->isPreloaded()) { |
332 evict(current); | 332 evict(current); |
333 if (targetSize && m_deadSize <= targetSize) | 333 if (targetSize && m_deadSize <= targetSize) |
334 return; | 334 return; |
335 } | 335 } |
336 if (!previous || !previous->m_resource || !contains(previous->m_reso
urce.get())) | 336 if (!previous || !previous->m_resource || !contains(previous->m_reso
urce.get())) |
337 break; | 337 break; |
338 current = previous; | 338 current = previous; |
339 } | 339 } |
340 | 340 |
341 // Shrink the vector back down so we don't waste time inspecting | 341 // Shrink the vector back down so we don't waste time inspecting |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
533 // The object must now be moved to a different queue, since either its size
or its accessCount has been changed, | 533 // The object must now be moved to a different queue, since either its size
or its accessCount has been changed, |
534 // and both of those are used to determine which LRU queue the resource shou
ld be in. | 534 // and both of those are used to determine which LRU queue the resource shou
ld be in. |
535 if (oldSize) | 535 if (oldSize) |
536 removeFromLRUList(entry, lruListFor(entry->m_accessCount, oldSize)); | 536 removeFromLRUList(entry, lruListFor(entry->m_accessCount, oldSize)); |
537 if (wasAccessed) | 537 if (wasAccessed) |
538 entry->m_accessCount++; | 538 entry->m_accessCount++; |
539 if (newSize) | 539 if (newSize) |
540 insertInLRUList(entry, lruListFor(entry->m_accessCount, newSize)); | 540 insertInLRUList(entry, lruListFor(entry->m_accessCount, newSize)); |
541 | 541 |
542 ptrdiff_t delta = newSize - oldSize; | 542 ptrdiff_t delta = newSize - oldSize; |
543 if (resource->hasClients()) { | 543 if (resource->hasClientsOrObservers()) { |
544 ASSERT(delta >= 0 || m_liveSize >= static_cast<size_t>(-delta) ); | 544 ASSERT(delta >= 0 || m_liveSize >= static_cast<size_t>(-delta) ); |
545 m_liveSize += delta; | 545 m_liveSize += delta; |
546 } else { | 546 } else { |
547 ASSERT(delta >= 0 || m_deadSize >= static_cast<size_t>(-delta) ); | 547 ASSERT(delta >= 0 || m_deadSize >= static_cast<size_t>(-delta) ); |
548 m_deadSize += delta; | 548 m_deadSize += delta; |
549 } | 549 } |
550 } | 550 } |
551 | 551 |
552 void MemoryCache::updateDecodedResource(Resource* resource, UpdateReason reason) | 552 void MemoryCache::updateDecodedResource(Resource* resource, UpdateReason reason) |
553 { | 553 { |
554 MemoryCacheEntry* entry = getEntryForResource(resource); | 554 MemoryCacheEntry* entry = getEntryForResource(resource); |
555 if (!entry) | 555 if (!entry) |
556 return; | 556 return; |
557 | 557 |
558 removeFromLiveDecodedResourcesList(entry); | 558 removeFromLiveDecodedResourcesList(entry); |
559 if (resource->decodedSize() && resource->hasClients()) | 559 if (resource->decodedSize() && resource->hasClientsOrObservers()) |
560 insertInLiveDecodedResourcesList(entry); | 560 insertInLiveDecodedResourcesList(entry); |
561 | 561 |
562 if (reason != UpdateForAccess) | 562 if (reason != UpdateForAccess) |
563 return; | 563 return; |
564 | 564 |
565 double timestamp = resource->isImage() ? m_lastFramePaintTimeStamp : 0.0; | 565 double timestamp = resource->isImage() ? m_lastFramePaintTimeStamp : 0.0; |
566 if (!timestamp) | 566 if (!timestamp) |
567 timestamp = currentTime(); | 567 timestamp = currentTime(); |
568 entry->m_lastDecodedAccessTime = timestamp; | 568 entry->m_lastDecodedAccessTime = timestamp; |
569 } | 569 } |
570 | 570 |
571 void MemoryCache::removeURLFromCache(const KURL& url) | 571 void MemoryCache::removeURLFromCache(const KURL& url) |
572 { | 572 { |
573 WillBeHeapVector<RawPtrWillBeMember<Resource>> resources = resourcesForURL(u
rl); | 573 WillBeHeapVector<RawPtrWillBeMember<Resource>> resources = resourcesForURL(u
rl); |
574 for (Resource* resource : resources) | 574 for (Resource* resource : resources) |
575 memoryCache()->remove(resource); | 575 memoryCache()->remove(resource); |
576 } | 576 } |
577 | 577 |
578 void MemoryCache::TypeStatistic::addResource(Resource* o) | 578 void MemoryCache::TypeStatistic::addResource(Resource* o) |
579 { | 579 { |
580 bool purgeable = o->isPurgeable(); | 580 bool purgeable = o->isPurgeable(); |
581 size_t pageSize = (o->encodedSize() + o->overheadSize() + 4095) & ~4095; | 581 size_t pageSize = (o->encodedSize() + o->overheadSize() + 4095) & ~4095; |
582 count++; | 582 count++; |
583 size += o->size(); | 583 size += o->size(); |
584 liveSize += o->hasClients() ? o->size() : 0; | 584 liveSize += o->hasClientsOrObservers() ? o->size() : 0; |
585 decodedSize += o->decodedSize(); | 585 decodedSize += o->decodedSize(); |
586 encodedSize += o->encodedSize(); | 586 encodedSize += o->encodedSize(); |
587 encodedSizeDuplicatedInDataURLs += o->url().protocolIsData() ? o->encodedSiz
e() : 0; | 587 encodedSizeDuplicatedInDataURLs += o->url().protocolIsData() ? o->encodedSiz
e() : 0; |
588 purgeableSize += purgeable ? pageSize : 0; | 588 purgeableSize += purgeable ? pageSize : 0; |
589 } | 589 } |
590 | 590 |
591 MemoryCache::Statistics MemoryCache::getStatistics() | 591 MemoryCache::Statistics MemoryCache::getStatistics() |
592 { | 592 { |
593 Statistics stats; | 593 Statistics stats; |
594 for (const auto& resourceMapIter : m_resourceMaps) { | 594 for (const auto& resourceMapIter : m_resourceMaps) { |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 void MemoryCache::dumpLRULists(bool includeLive) const | 765 void MemoryCache::dumpLRULists(bool includeLive) const |
766 { | 766 { |
767 printf("LRU-SP lists in eviction order (Kilobytes decoded, Kilobytes encoded
, Access count, Referenced, isPurgeable):\n"); | 767 printf("LRU-SP lists in eviction order (Kilobytes decoded, Kilobytes encoded
, Access count, Referenced, isPurgeable):\n"); |
768 | 768 |
769 int size = m_allResources.size(); | 769 int size = m_allResources.size(); |
770 for (int i = size - 1; i >= 0; i--) { | 770 for (int i = size - 1; i >= 0; i--) { |
771 printf("\n\nList %d: ", i); | 771 printf("\n\nList %d: ", i); |
772 MemoryCacheEntry* current = m_allResources[i].m_tail; | 772 MemoryCacheEntry* current = m_allResources[i].m_tail; |
773 while (current) { | 773 while (current) { |
774 RefPtrWillBeRawPtr<Resource> currentResource = current->m_resource; | 774 RefPtrWillBeRawPtr<Resource> currentResource = current->m_resource; |
775 if (includeLive || !currentResource->hasClients()) | 775 if (includeLive || !currentResource->hasClientsOrObservers()) |
776 printf("(%.1fK, %.1fK, %uA, %dR, %d); ", currentResource->decode
dSize() / 1024.0f, (currentResource->encodedSize() + currentResource->overheadSi
ze()) / 1024.0f, current->m_accessCount, currentResource->hasClients(), currentR
esource->isPurgeable()); | 776 printf("(%.1fK, %.1fK, %uA, %dR, %d); ", currentResource->decode
dSize() / 1024.0f, (currentResource->encodedSize() + currentResource->overheadSi
ze()) / 1024.0f, current->m_accessCount, currentResource->hasClientsOrObservers(
), currentResource->isPurgeable()); |
777 | 777 |
778 current = current->m_previousInAllResourcesList; | 778 current = current->m_previousInAllResourcesList; |
779 } | 779 } |
780 } | 780 } |
781 } | 781 } |
782 | 782 |
783 #endif // MEMORY_CACHE_STATS | 783 #endif // MEMORY_CACHE_STATS |
784 | 784 |
785 } // namespace blink | 785 } // namespace blink |
OLD | NEW |