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