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. |
11 | 11 |
12 This library is distributed in the hope that it will be useful, | 12 This library is distributed in the hope that it will be useful, |
13 but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 Library General Public License for more details. | 15 Library General Public License for more details. |
16 | 16 |
17 You should have received a copy of the GNU Library General Public License | 17 You should have received a copy of the GNU Library General Public License |
18 along with this library; see the file COPYING.LIB. If not, write to | 18 along with this library; see the file COPYING.LIB. If not, write to |
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
20 Boston, MA 02110-1301, USA. | 20 Boston, MA 02110-1301, USA. |
21 */ | 21 */ |
22 | 22 |
23 #include "core/fetch/MemoryCache.h" | 23 #include "core/fetch/MemoryCache.h" |
24 | 24 |
25 #include "platform/Logging.h" | 25 #include "platform/Logging.h" |
| 26 #include "platform/RuntimeEnabledFeatures.h" |
26 #include "platform/TraceEvent.h" | 27 #include "platform/TraceEvent.h" |
27 #include "platform/weborigin/SecurityOrigin.h" | 28 #include "platform/weborigin/SecurityOrigin.h" |
28 #include "platform/weborigin/SecurityOriginHash.h" | 29 #include "platform/weborigin/SecurityOriginHash.h" |
29 #include "public/platform/Platform.h" | 30 #include "public/platform/Platform.h" |
30 #include "wtf/Assertions.h" | 31 #include "wtf/Assertions.h" |
31 #include "wtf/CurrentTime.h" | 32 #include "wtf/CurrentTime.h" |
32 #include "wtf/MathExtras.h" | 33 #include "wtf/MathExtras.h" |
33 #include "wtf/TemporaryChange.h" | 34 #include "wtf/TemporaryChange.h" |
34 #include "wtf/text/CString.h" | 35 #include "wtf/text/CString.h" |
35 | 36 |
(...skipping 17 matching lines...) Expand all Loading... |
53 | 54 |
54 MemoryCache* replaceMemoryCacheForTesting(MemoryCache* cache) | 55 MemoryCache* replaceMemoryCacheForTesting(MemoryCache* cache) |
55 { | 56 { |
56 memoryCache(); | 57 memoryCache(); |
57 MemoryCache* oldCache = gMemoryCache->release(); | 58 MemoryCache* oldCache = gMemoryCache->release(); |
58 *gMemoryCache = cache; | 59 *gMemoryCache = cache; |
59 MemoryCacheDumpProvider::instance()->setMemoryCache(cache); | 60 MemoryCacheDumpProvider::instance()->setMemoryCache(cache); |
60 return oldCache; | 61 return oldCache; |
61 } | 62 } |
62 | 63 |
| 64 MemoryCacheEntry::MemoryCacheEntry(Resource* resource) |
| 65 : m_inLiveDecodedResourcesList(false) |
| 66 , m_accessCount(0) |
| 67 , m_lastDecodedAccessTime(0.0) |
| 68 , m_previousInLiveResourcesList(nullptr) |
| 69 , m_nextInLiveResourcesList(nullptr) |
| 70 , m_previousInAllResourcesList(nullptr) |
| 71 , m_nextInAllResourcesList(nullptr) |
| 72 { |
| 73 if (RuntimeEnabledFeatures::weakMemoryCacheEnabled()) |
| 74 m_resourceWeak = resource; |
| 75 else |
| 76 m_resource = resource; |
| 77 } |
| 78 |
63 DEFINE_TRACE(MemoryCacheEntry) | 79 DEFINE_TRACE(MemoryCacheEntry) |
64 { | 80 { |
65 visitor->trace(m_resource); | 81 visitor->trace(m_resource); |
| 82 visitor->trace(m_resourceWeak); |
66 visitor->trace(m_previousInLiveResourcesList); | 83 visitor->trace(m_previousInLiveResourcesList); |
67 visitor->trace(m_nextInLiveResourcesList); | 84 visitor->trace(m_nextInLiveResourcesList); |
68 visitor->trace(m_previousInAllResourcesList); | 85 visitor->trace(m_previousInAllResourcesList); |
69 visitor->trace(m_nextInAllResourcesList); | 86 visitor->trace(m_nextInAllResourcesList); |
70 } | 87 } |
71 | 88 |
72 void MemoryCacheEntry::dispose() | 89 void MemoryCacheEntry::dispose() |
73 { | 90 { |
74 m_resource.clear(); | 91 m_resource.clear(); |
| 92 m_resourceWeak.clear(); |
75 } | 93 } |
76 | 94 |
77 Resource* MemoryCacheEntry::resource() | 95 Resource* MemoryCacheEntry::resource() |
78 { | 96 { |
| 97 if (RuntimeEnabledFeatures::weakMemoryCacheEnabled()) |
| 98 return m_resourceWeak.get(); |
79 return m_resource.get(); | 99 return m_resource.get(); |
80 } | 100 } |
81 | 101 |
82 DEFINE_TRACE(MemoryCacheLRUList) | 102 DEFINE_TRACE(MemoryCacheLRUList) |
83 { | 103 { |
84 visitor->trace(m_head); | 104 visitor->trace(m_head); |
85 visitor->trace(m_tail); | 105 visitor->trace(m_tail); |
86 } | 106 } |
87 | 107 |
88 inline MemoryCache::MemoryCache() | 108 inline MemoryCache::MemoryCache() |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 } | 176 } |
157 return m_resourceMaps.get(cacheIdentifier); | 177 return m_resourceMaps.get(cacheIdentifier); |
158 } | 178 } |
159 | 179 |
160 void MemoryCache::add(Resource* resource) | 180 void MemoryCache::add(Resource* resource) |
161 { | 181 { |
162 ASSERT(WTF::isMainThread()); | 182 ASSERT(WTF::isMainThread()); |
163 ASSERT(resource->url().isValid()); | 183 ASSERT(resource->url().isValid()); |
164 ResourceMap* resources = ensureResourceMap(resource->cacheIdentifier()); | 184 ResourceMap* resources = ensureResourceMap(resource->cacheIdentifier()); |
165 KURL url = removeFragmentIdentifierIfNeeded(resource->url()); | 185 KURL url = removeFragmentIdentifierIfNeeded(resource->url()); |
166 RELEASE_ASSERT(!resources->contains(url)); | 186 RELEASE_ASSERT(!contains(resource)); |
167 resources->set(url, MemoryCacheEntry::create(resource)); | 187 resources->set(url, MemoryCacheEntry::create(resource)); |
168 update(resource, 0, resource->size(), true); | 188 update(resource, 0, resource->size(), true); |
169 | 189 |
170 WTF_LOG(ResourceLoading, "MemoryCache::add Added '%s', resource %p\n", resou
rce->url().getString().latin1().data(), resource); | 190 WTF_LOG(ResourceLoading, "MemoryCache::add Added '%s', resource %p\n", resou
rce->url().getString().latin1().data(), resource); |
171 } | 191 } |
172 | 192 |
173 void MemoryCache::remove(Resource* resource) | 193 void MemoryCache::remove(Resource* resource) |
174 { | 194 { |
175 // The resource may have already been removed by someone other than our call
er, | 195 // The resource may have already been removed by someone other than our call
er, |
176 // who needed a fresh copy for a reload. | 196 // who needed a fresh copy for a reload. |
(...skipping 29 matching lines...) Expand all Loading... |
206 return nullptr; | 226 return nullptr; |
207 return resource; | 227 return resource; |
208 } | 228 } |
209 | 229 |
210 HeapVector<Member<Resource>> MemoryCache::resourcesForURL(const KURL& resourceUR
L) | 230 HeapVector<Member<Resource>> MemoryCache::resourcesForURL(const KURL& resourceUR
L) |
211 { | 231 { |
212 ASSERT(WTF::isMainThread()); | 232 ASSERT(WTF::isMainThread()); |
213 KURL url = removeFragmentIdentifierIfNeeded(resourceURL); | 233 KURL url = removeFragmentIdentifierIfNeeded(resourceURL); |
214 HeapVector<Member<Resource>> results; | 234 HeapVector<Member<Resource>> results; |
215 for (const auto& resourceMapIter : m_resourceMaps) { | 235 for (const auto& resourceMapIter : m_resourceMaps) { |
216 if (MemoryCacheEntry* entry = resourceMapIter.value->get(url)) | 236 if (MemoryCacheEntry* entry = resourceMapIter.value->get(url)) { |
217 results.append(entry->resource()); | 237 Resource* resource = entry->resource(); |
| 238 if (resource) |
| 239 results.append(resource); |
| 240 } |
218 } | 241 } |
219 return results; | 242 return results; |
220 } | 243 } |
221 | 244 |
222 size_t MemoryCache::deadCapacity() const | 245 size_t MemoryCache::deadCapacity() const |
223 { | 246 { |
224 // Dead resource capacity is whatever space is not occupied by live resource
s, bounded by an independent minimum and maximum. | 247 // Dead resource capacity is whatever space is not occupied by live resource
s, bounded by an independent minimum and maximum. |
225 size_t capacity = m_capacity - std::min(m_liveSize, m_capacity); // Start wi
th available capacity. | 248 size_t capacity = m_capacity - std::min(m_liveSize, m_capacity); // Start wi
th available capacity. |
226 capacity = std::max(capacity, m_minDeadCapacity); // Make sure it's above th
e minimum. | 249 capacity = std::max(capacity, m_minDeadCapacity); // Make sure it's above th
e minimum. |
227 capacity = std::min(capacity, m_maxDeadCapacity); // Make sure it's below th
e maximum. | 250 capacity = std::min(capacity, m_maxDeadCapacity); // Make sure it's below th
e maximum. |
(...skipping 24 matching lines...) Expand all Loading... |
252 // The list might not be sorted by the m_lastDecodedFrameTimeStamp. The impa
ct | 275 // The list might not be sorted by the m_lastDecodedFrameTimeStamp. The impa
ct |
253 // of this weaker invariant is minor as the below if statement to check the | 276 // of this weaker invariant is minor as the below if statement to check the |
254 // elapsedTime will evaluate to false as the current time will be a lot | 277 // elapsedTime will evaluate to false as the current time will be a lot |
255 // greater than the current->m_lastDecodedFrameTimeStamp. | 278 // greater than the current->m_lastDecodedFrameTimeStamp. |
256 // For more details see: https://bugs.webkit.org/show_bug.cgi?id=30209 | 279 // For more details see: https://bugs.webkit.org/show_bug.cgi?id=30209 |
257 | 280 |
258 MemoryCacheEntry* current = m_liveDecodedResources.m_tail; | 281 MemoryCacheEntry* current = m_liveDecodedResources.m_tail; |
259 while (current) { | 282 while (current) { |
260 Resource* resource = current->resource(); | 283 Resource* resource = current->resource(); |
261 MemoryCacheEntry* previous = current->m_previousInLiveResourcesList; | 284 MemoryCacheEntry* previous = current->m_previousInLiveResourcesList; |
| 285 if (!resource) { |
| 286 current = previous; |
| 287 continue; |
| 288 } |
262 ASSERT(resource->hasClientsOrObservers()); | 289 ASSERT(resource->hasClientsOrObservers()); |
263 | 290 |
264 if (resource->isLoaded() && resource->decodedSize()) { | 291 if (resource->isLoaded() && resource->decodedSize()) { |
265 // Check to see if the remaining resources are too new to prune. | 292 // Check to see if the remaining resources are too new to prune. |
266 double elapsedTime = m_pruneFrameTimeStamp - current->m_lastDecodedA
ccessTime; | 293 double elapsedTime = m_pruneFrameTimeStamp - current->m_lastDecodedA
ccessTime; |
267 if (strategy == AutomaticPrune && elapsedTime < m_delayBeforeLiveDec
odedPrune) | 294 if (strategy == AutomaticPrune && elapsedTime < m_delayBeforeLiveDec
odedPrune) |
268 return; | 295 return; |
269 | 296 |
270 // Destroy our decoded data if possible. This will remove us | 297 // Destroy our decoded data if possible. This will remove us |
271 // from m_liveDecodedResources, and possibly move us to a | 298 // from m_liveDecodedResources, and possibly move us to a |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 m_maxDeferredPruneDeadCapacity = cDeferredPruneDeadCapacityFactor * maxDeadB
ytes; | 385 m_maxDeferredPruneDeadCapacity = cDeferredPruneDeadCapacityFactor * maxDeadB
ytes; |
359 m_capacity = totalBytes; | 386 m_capacity = totalBytes; |
360 prune(); | 387 prune(); |
361 } | 388 } |
362 | 389 |
363 void MemoryCache::evict(MemoryCacheEntry* entry) | 390 void MemoryCache::evict(MemoryCacheEntry* entry) |
364 { | 391 { |
365 ASSERT(WTF::isMainThread()); | 392 ASSERT(WTF::isMainThread()); |
366 | 393 |
367 Resource* resource = entry->resource(); | 394 Resource* resource = entry->resource(); |
| 395 DCHECK(resource); |
368 WTF_LOG(ResourceLoading, "Evicting resource %p for '%s' from cache", resourc
e, resource->url().getString().latin1().data()); | 396 WTF_LOG(ResourceLoading, "Evicting resource %p for '%s' from cache", resourc
e, resource->url().getString().latin1().data()); |
369 // The resource may have already been removed by someone other than our call
er, | 397 // The resource may have already been removed by someone other than our call
er, |
370 // who needed a fresh copy for a reload. See <http://bugs.webkit.org/show_bu
g.cgi?id=12479#c6>. | 398 // who needed a fresh copy for a reload. See <http://bugs.webkit.org/show_bu
g.cgi?id=12479#c6>. |
371 update(resource, resource->size(), 0, false); | 399 update(resource, resource->size(), 0, false); |
372 removeFromLiveDecodedResourcesList(entry); | 400 removeFromLiveDecodedResourcesList(entry); |
373 | 401 |
374 ResourceMap* resources = m_resourceMaps.get(resource->cacheIdentifier()); | 402 ResourceMap* resources = m_resourceMaps.get(resource->cacheIdentifier()); |
375 ASSERT(resources); | 403 ASSERT(resources); |
376 KURL url = removeFragmentIdentifierIfNeeded(resource->url()); | 404 KURL url = removeFragmentIdentifierIfNeeded(resource->url()); |
377 ResourceMap::iterator it = resources->find(url); | 405 ResourceMap::iterator it = resources->find(url); |
378 ASSERT(it != resources->end()); | 406 ASSERT(it != resources->end()); |
379 | 407 |
380 MemoryCacheEntry* entryPtr = it->value; | 408 MemoryCacheEntry* entryPtr = it->value; |
381 resources->remove(it); | 409 resources->remove(it); |
382 if (entryPtr) | 410 if (entryPtr) |
383 entryPtr->dispose(); | 411 entryPtr->dispose(); |
384 } | 412 } |
385 | 413 |
386 MemoryCacheEntry* MemoryCache::getEntryForResource(const Resource* resource) con
st | 414 MemoryCacheEntry* MemoryCache::getEntryForResource(const Resource* resource) con
st |
387 { | 415 { |
388 if (resource->url().isNull() || resource->url().isEmpty()) | 416 if (!resource || resource->url().isNull() || resource->url().isEmpty()) |
389 return nullptr; | 417 return nullptr; |
390 ResourceMap* resources = m_resourceMaps.get(resource->cacheIdentifier()); | 418 ResourceMap* resources = m_resourceMaps.get(resource->cacheIdentifier()); |
391 if (!resources) | 419 if (!resources) |
392 return nullptr; | 420 return nullptr; |
393 KURL url = removeFragmentIdentifierIfNeeded(resource->url()); | 421 KURL url = removeFragmentIdentifierIfNeeded(resource->url()); |
394 MemoryCacheEntry* entry = resources->get(url); | 422 MemoryCacheEntry* entry = resources->get(url); |
395 if (!entry || entry->resource() != resource) | 423 if (!entry || entry->resource() != resource) |
396 return nullptr; | 424 return nullptr; |
397 return entry; | 425 return entry; |
398 } | 426 } |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 encodedSizeDuplicatedInDataURLs += o->url().protocolIsData() ? o->encodedSiz
e() : 0; | 619 encodedSizeDuplicatedInDataURLs += o->url().protocolIsData() ? o->encodedSiz
e() : 0; |
592 purgeableSize += purgeable ? pageSize : 0; | 620 purgeableSize += purgeable ? pageSize : 0; |
593 } | 621 } |
594 | 622 |
595 MemoryCache::Statistics MemoryCache::getStatistics() | 623 MemoryCache::Statistics MemoryCache::getStatistics() |
596 { | 624 { |
597 Statistics stats; | 625 Statistics stats; |
598 for (const auto& resourceMapIter : m_resourceMaps) { | 626 for (const auto& resourceMapIter : m_resourceMaps) { |
599 for (const auto& resourceIter : *resourceMapIter.value) { | 627 for (const auto& resourceIter : *resourceMapIter.value) { |
600 Resource* resource = resourceIter.value->resource(); | 628 Resource* resource = resourceIter.value->resource(); |
| 629 if (!resource) |
| 630 continue; |
601 switch (resource->getType()) { | 631 switch (resource->getType()) { |
602 case Resource::Image: | 632 case Resource::Image: |
603 stats.images.addResource(resource); | 633 stats.images.addResource(resource); |
604 break; | 634 break; |
605 case Resource::CSSStyleSheet: | 635 case Resource::CSSStyleSheet: |
606 stats.cssStyleSheets.addResource(resource); | 636 stats.cssStyleSheets.addResource(resource); |
607 break; | 637 break; |
608 case Resource::Script: | 638 case Resource::Script: |
609 stats.scripts.addResource(resource); | 639 stats.scripts.addResource(resource); |
610 break; | 640 break; |
(...skipping 16 matching lines...) Expand all Loading... |
627 { | 657 { |
628 while (true) { | 658 while (true) { |
629 ResourceMapIndex::iterator resourceMapIter = m_resourceMaps.begin(); | 659 ResourceMapIndex::iterator resourceMapIter = m_resourceMaps.begin(); |
630 if (resourceMapIter == m_resourceMaps.end()) | 660 if (resourceMapIter == m_resourceMaps.end()) |
631 break; | 661 break; |
632 ResourceMap* resources = resourceMapIter->value.get(); | 662 ResourceMap* resources = resourceMapIter->value.get(); |
633 while (true) { | 663 while (true) { |
634 ResourceMap::iterator resourceIter = resources->begin(); | 664 ResourceMap::iterator resourceIter = resources->begin(); |
635 if (resourceIter == resources->end()) | 665 if (resourceIter == resources->end()) |
636 break; | 666 break; |
637 evict(resourceIter->value.get()); | 667 if (resourceIter->value->resource()) |
| 668 evict(resourceIter->value.get()); |
| 669 else |
| 670 resources->remove(resourceIter); |
638 } | 671 } |
639 m_resourceMaps.remove(resourceMapIter); | 672 m_resourceMaps.remove(resourceMapIter); |
640 } | 673 } |
641 } | 674 } |
642 | 675 |
643 void MemoryCache::prune(Resource* justReleasedResource) | 676 void MemoryCache::prune(Resource* justReleasedResource) |
644 { | 677 { |
645 TRACE_EVENT0("renderer", "MemoryCache::prune()"); | 678 TRACE_EVENT0("renderer", "MemoryCache::prune()"); |
646 | 679 |
647 if (m_inPruneResources) | 680 if (m_inPruneResources) |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
721 void MemoryCache::updateFramePaintTimestamp() | 754 void MemoryCache::updateFramePaintTimestamp() |
722 { | 755 { |
723 m_lastFramePaintTimeStamp = currentTime(); | 756 m_lastFramePaintTimeStamp = currentTime(); |
724 } | 757 } |
725 | 758 |
726 bool MemoryCache::onMemoryDump(WebMemoryDumpLevelOfDetail levelOfDetail, WebProc
essMemoryDump* memoryDump) | 759 bool MemoryCache::onMemoryDump(WebMemoryDumpLevelOfDetail levelOfDetail, WebProc
essMemoryDump* memoryDump) |
727 { | 760 { |
728 for (const auto& resourceMapIter : m_resourceMaps) { | 761 for (const auto& resourceMapIter : m_resourceMaps) { |
729 for (const auto& resourceIter : *resourceMapIter.value) { | 762 for (const auto& resourceIter : *resourceMapIter.value) { |
730 Resource* resource = resourceIter.value->resource(); | 763 Resource* resource = resourceIter.value->resource(); |
731 resource->onMemoryDump(levelOfDetail, memoryDump); | 764 if (resource) |
| 765 resource->onMemoryDump(levelOfDetail, memoryDump); |
732 } | 766 } |
733 } | 767 } |
734 return true; | 768 return true; |
735 } | 769 } |
736 | 770 |
737 bool MemoryCache::isInSameLRUListForTest(const Resource* x, const Resource* y) | 771 bool MemoryCache::isInSameLRUListForTest(const Resource* x, const Resource* y) |
738 { | 772 { |
739 MemoryCacheEntry* ex = getEntryForResource(x); | 773 MemoryCacheEntry* ex = getEntryForResource(x); |
740 MemoryCacheEntry* ey = getEntryForResource(y); | 774 MemoryCacheEntry* ey = getEntryForResource(y); |
741 ASSERT(ex); | 775 ASSERT(ex); |
(...skipping 28 matching lines...) Expand all Loading... |
770 void MemoryCache::dumpLRULists(bool includeLive) const | 804 void MemoryCache::dumpLRULists(bool includeLive) const |
771 { | 805 { |
772 printf("LRU-SP lists in eviction order (Kilobytes decoded, Kilobytes encoded
, Access count, Referenced, isPurgeable):\n"); | 806 printf("LRU-SP lists in eviction order (Kilobytes decoded, Kilobytes encoded
, Access count, Referenced, isPurgeable):\n"); |
773 | 807 |
774 int size = m_allResources.size(); | 808 int size = m_allResources.size(); |
775 for (int i = size - 1; i >= 0; i--) { | 809 for (int i = size - 1; i >= 0; i--) { |
776 printf("\n\nList %d: ", i); | 810 printf("\n\nList %d: ", i); |
777 MemoryCacheEntry* current = m_allResources[i].m_tail; | 811 MemoryCacheEntry* current = m_allResources[i].m_tail; |
778 while (current) { | 812 while (current) { |
779 Resource* currentResource = current->resource(); | 813 Resource* currentResource = current->resource(); |
780 if (includeLive || !currentResource->hasClientsOrObservers()) | 814 if (currentResource && (includeLive || !currentResource->hasClientsO
rObservers())) |
781 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()); | 815 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()); |
782 | 816 |
783 current = current->m_previousInAllResourcesList; | 817 current = current->m_previousInAllResourcesList; |
784 } | 818 } |
785 } | 819 } |
786 } | 820 } |
787 | 821 |
788 #endif // MEMORY_CACHE_STATS | 822 #endif // MEMORY_CACHE_STATS |
789 | 823 |
790 } // namespace blink | 824 } // namespace blink |
OLD | NEW |