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

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

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

Powered by Google App Engine
This is Rietveld 408576698