| 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 20 matching lines...) Expand all Loading... |
| 31 #include "public/platform/Platform.h" | 31 #include "public/platform/Platform.h" |
| 32 #include "wtf/Assertions.h" | 32 #include "wtf/Assertions.h" |
| 33 #include "wtf/CurrentTime.h" | 33 #include "wtf/CurrentTime.h" |
| 34 #include "wtf/MainThread.h" | 34 #include "wtf/MainThread.h" |
| 35 #include "wtf/MathExtras.h" | 35 #include "wtf/MathExtras.h" |
| 36 #include "wtf/TemporaryChange.h" | 36 #include "wtf/TemporaryChange.h" |
| 37 #include "wtf/text/CString.h" | 37 #include "wtf/text/CString.h" |
| 38 | 38 |
| 39 namespace blink { | 39 namespace blink { |
| 40 | 40 |
| 41 static OwnPtrWillBePersistent<MemoryCache>* gMemoryCache; | 41 static Persistent<MemoryCache>* gMemoryCache; |
| 42 | 42 |
| 43 static const unsigned cDefaultCacheCapacity = 8192 * 1024; | 43 static const unsigned cDefaultCacheCapacity = 8192 * 1024; |
| 44 static const unsigned cDeferredPruneDeadCapacityFactor = 2; | 44 static const unsigned cDeferredPruneDeadCapacityFactor = 2; |
| 45 static const int cMinDelayBeforeLiveDecodedPrune = 1; // Seconds. | 45 static const int cMinDelayBeforeLiveDecodedPrune = 1; // Seconds. |
| 46 static const double cMaxPruneDeferralDelay = 0.5; // Seconds. | 46 static const double cMaxPruneDeferralDelay = 0.5; // Seconds. |
| 47 static const float cTargetPrunePercentage = .95f; // Percentage of capacity towa
rd which we prune, to avoid immediately pruning again. | 47 static const float cTargetPrunePercentage = .95f; // Percentage of capacity towa
rd which we prune, to avoid immediately pruning again. |
| 48 | 48 |
| 49 MemoryCache* memoryCache() | 49 MemoryCache* memoryCache() |
| 50 { | 50 { |
| 51 ASSERT(WTF::isMainThread()); | 51 ASSERT(WTF::isMainThread()); |
| 52 if (!gMemoryCache) | 52 if (!gMemoryCache) |
| 53 gMemoryCache = new OwnPtrWillBePersistent<MemoryCache>(MemoryCache::crea
te()); | 53 gMemoryCache = new Persistent<MemoryCache>(MemoryCache::create()); |
| 54 return gMemoryCache->get(); | 54 return gMemoryCache->get(); |
| 55 } | 55 } |
| 56 | 56 |
| 57 PassOwnPtrWillBeRawPtr<MemoryCache> replaceMemoryCacheForTesting(PassOwnPtrWillB
eRawPtr<MemoryCache> cache) | 57 MemoryCache* replaceMemoryCacheForTesting(MemoryCache* cache) |
| 58 { | 58 { |
| 59 #if ENABLE(OILPAN) | 59 #if ENABLE(OILPAN) |
| 60 // Move m_liveResources content to keep Resource objects alive. | 60 // Move m_liveResources content to keep Resource objects alive. |
| 61 for (const auto& resource : memoryCache()->m_liveResources) | 61 for (const auto& resource : memoryCache()->m_liveResources) |
| 62 cache->m_liveResources.add(resource); | 62 cache->m_liveResources.add(resource); |
| 63 memoryCache()->m_liveResources.clear(); | 63 memoryCache()->m_liveResources.clear(); |
| 64 #else | 64 #endif |
| 65 // Make sure we have non-empty gMemoryCache. | |
| 66 memoryCache(); | 65 memoryCache(); |
| 67 #endif | 66 MemoryCache* oldCache = gMemoryCache->release(); |
| 68 OwnPtrWillBeRawPtr<MemoryCache> oldCache = gMemoryCache->release(); | |
| 69 *gMemoryCache = cache; | 67 *gMemoryCache = cache; |
| 70 return oldCache.release(); | 68 return oldCache; |
| 71 } | 69 } |
| 72 | 70 |
| 73 DEFINE_TRACE(MemoryCacheEntry) | 71 DEFINE_TRACE(MemoryCacheEntry) |
| 74 { | 72 { |
| 75 visitor->trace(m_previousInLiveResourcesList); | 73 visitor->trace(m_previousInLiveResourcesList); |
| 76 visitor->trace(m_nextInLiveResourcesList); | 74 visitor->trace(m_nextInLiveResourcesList); |
| 77 visitor->trace(m_previousInAllResourcesList); | 75 visitor->trace(m_previousInAllResourcesList); |
| 78 visitor->trace(m_nextInAllResourcesList); | 76 visitor->trace(m_nextInAllResourcesList); |
| 79 } | 77 } |
| 80 | 78 |
| 81 #if ENABLE(OILPAN) | |
| 82 void MemoryCacheEntry::dispose() | 79 void MemoryCacheEntry::dispose() |
| 83 { | 80 { |
| 84 m_resource.clear(); | 81 m_resource.clear(); |
| 85 } | 82 } |
| 86 #endif | |
| 87 | 83 |
| 88 DEFINE_TRACE(MemoryCacheLRUList) | 84 DEFINE_TRACE(MemoryCacheLRUList) |
| 89 { | 85 { |
| 90 visitor->trace(m_head); | 86 visitor->trace(m_head); |
| 91 visitor->trace(m_tail); | 87 visitor->trace(m_tail); |
| 92 } | 88 } |
| 93 | 89 |
| 94 inline MemoryCache::MemoryCache() | 90 inline MemoryCache::MemoryCache() |
| 95 : m_inPruneResources(false) | 91 : m_inPruneResources(false) |
| 96 , m_prunePending(false) | 92 , m_prunePending(false) |
| (...skipping 11 matching lines...) Expand all Loading... |
| 108 #ifdef MEMORY_CACHE_STATS | 104 #ifdef MEMORY_CACHE_STATS |
| 109 , m_statsTimer(this, &MemoryCache::dumpStats) | 105 , m_statsTimer(this, &MemoryCache::dumpStats) |
| 110 #endif | 106 #endif |
| 111 { | 107 { |
| 112 #ifdef MEMORY_CACHE_STATS | 108 #ifdef MEMORY_CACHE_STATS |
| 113 const double statsIntervalInSeconds = 15; | 109 const double statsIntervalInSeconds = 15; |
| 114 m_statsTimer.startRepeating(statsIntervalInSeconds, FROM_HERE); | 110 m_statsTimer.startRepeating(statsIntervalInSeconds, FROM_HERE); |
| 115 #endif | 111 #endif |
| 116 } | 112 } |
| 117 | 113 |
| 118 PassOwnPtrWillBeRawPtr<MemoryCache> MemoryCache::create() | 114 MemoryCache* MemoryCache::create() |
| 119 { | 115 { |
| 120 return adoptPtrWillBeNoop(new MemoryCache()); | 116 return new MemoryCache; |
| 121 } | 117 } |
| 122 | 118 |
| 123 MemoryCache::~MemoryCache() | 119 MemoryCache::~MemoryCache() |
| 124 { | 120 { |
| 125 if (m_prunePending) | 121 if (m_prunePending) |
| 126 Platform::current()->currentThread()->removeTaskObserver(this); | 122 Platform::current()->currentThread()->removeTaskObserver(this); |
| 127 } | 123 } |
| 128 | 124 |
| 129 DEFINE_TRACE(MemoryCache) | 125 DEFINE_TRACE(MemoryCache) |
| 130 { | 126 { |
| 131 #if ENABLE(OILPAN) | |
| 132 visitor->trace(m_allResources); | 127 visitor->trace(m_allResources); |
| 133 for (size_t i = 0; i < WTF_ARRAY_LENGTH(m_liveDecodedResources); ++i) | 128 for (size_t i = 0; i < WTF_ARRAY_LENGTH(m_liveDecodedResources); ++i) |
| 134 visitor->trace(m_liveDecodedResources[i]); | 129 visitor->trace(m_liveDecodedResources[i]); |
| 135 visitor->trace(m_resourceMaps); | 130 visitor->trace(m_resourceMaps); |
| 131 #if ENABLE(OILPAN) |
| 136 visitor->trace(m_liveResources); | 132 visitor->trace(m_liveResources); |
| 137 #endif | 133 #endif |
| 138 } | 134 } |
| 139 | 135 |
| 140 KURL MemoryCache::removeFragmentIdentifierIfNeeded(const KURL& originalURL) | 136 KURL MemoryCache::removeFragmentIdentifierIfNeeded(const KURL& originalURL) |
| 141 { | 137 { |
| 142 if (!originalURL.hasFragmentIdentifier()) | 138 if (!originalURL.hasFragmentIdentifier()) |
| 143 return originalURL; | 139 return originalURL; |
| 144 // Strip away fragment identifier from HTTP URLs. | 140 // Strip away fragment identifier from HTTP URLs. |
| 145 // Data URLs must be unmodified. For file and custom URLs clients may expect
resources | 141 // Data URLs must be unmodified. For file and custom URLs clients may expect
resources |
| 146 // to be unique even when they differ by the fragment identifier only. | 142 // to be unique even when they differ by the fragment identifier only. |
| 147 if (!originalURL.protocolIsInHTTPFamily()) | 143 if (!originalURL.protocolIsInHTTPFamily()) |
| 148 return originalURL; | 144 return originalURL; |
| 149 KURL url = originalURL; | 145 KURL url = originalURL; |
| 150 url.removeFragmentIdentifier(); | 146 url.removeFragmentIdentifier(); |
| 151 return url; | 147 return url; |
| 152 } | 148 } |
| 153 | 149 |
| 154 String MemoryCache::defaultCacheIdentifier() | 150 String MemoryCache::defaultCacheIdentifier() |
| 155 { | 151 { |
| 156 return emptyString(); | 152 return emptyString(); |
| 157 } | 153 } |
| 158 | 154 |
| 159 MemoryCache::ResourceMap* MemoryCache::ensureResourceMap(const String& cacheIden
tifier) | 155 MemoryCache::ResourceMap* MemoryCache::ensureResourceMap(const String& cacheIden
tifier) |
| 160 { | 156 { |
| 161 if (!m_resourceMaps.contains(cacheIdentifier)) { | 157 if (!m_resourceMaps.contains(cacheIdentifier)) { |
| 162 ResourceMapIndex::AddResult result = m_resourceMaps.add(cacheIdentifier,
adoptPtrWillBeNoop(new ResourceMap())); | 158 ResourceMapIndex::AddResult result = m_resourceMaps.add(cacheIdentifier,
new ResourceMap()); |
| 163 RELEASE_ASSERT(result.isNewEntry); | 159 RELEASE_ASSERT(result.isNewEntry); |
| 164 } | 160 } |
| 165 return m_resourceMaps.get(cacheIdentifier); | 161 return m_resourceMaps.get(cacheIdentifier); |
| 166 } | 162 } |
| 167 | 163 |
| 168 void MemoryCache::add(Resource* resource) | 164 void MemoryCache::add(Resource* resource) |
| 169 { | 165 { |
| 170 ASSERT(WTF::isMainThread()); | 166 ASSERT(WTF::isMainThread()); |
| 171 ASSERT(resource->url().isValid()); | 167 ASSERT(resource->url().isValid()); |
| 172 ResourceMap* resources = ensureResourceMap(resource->cacheIdentifier()); | 168 ResourceMap* resources = ensureResourceMap(resource->cacheIdentifier()); |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 409 WTF_LOG(ResourceLoading, "Evicting resource %p for '%s' from cache", resourc
e, resource->url().string().latin1().data()); | 405 WTF_LOG(ResourceLoading, "Evicting resource %p for '%s' from cache", resourc
e, resource->url().string().latin1().data()); |
| 410 // The resource may have already been removed by someone other than our call
er, | 406 // The resource may have already been removed by someone other than our call
er, |
| 411 // who needed a fresh copy for a reload. See <http://bugs.webkit.org/show_bu
g.cgi?id=12479#c6>. | 407 // who needed a fresh copy for a reload. See <http://bugs.webkit.org/show_bu
g.cgi?id=12479#c6>. |
| 412 update(resource, resource->size(), 0, false); | 408 update(resource, resource->size(), 0, false); |
| 413 removeFromLiveDecodedResourcesList(entry); | 409 removeFromLiveDecodedResourcesList(entry); |
| 414 | 410 |
| 415 ResourceMap* resources = m_resourceMaps.get(resource->cacheIdentifier()); | 411 ResourceMap* resources = m_resourceMaps.get(resource->cacheIdentifier()); |
| 416 ASSERT(resources); | 412 ASSERT(resources); |
| 417 ResourceMap::iterator it = resources->find(resource->url()); | 413 ResourceMap::iterator it = resources->find(resource->url()); |
| 418 ASSERT(it != resources->end()); | 414 ASSERT(it != resources->end()); |
| 419 #if ENABLE(OILPAN) | 415 |
| 420 MemoryCacheEntry* entryPtr = it->value; | 416 MemoryCacheEntry* entryPtr = it->value; |
| 421 #else | |
| 422 OwnPtr<MemoryCacheEntry> entryPtr; | |
| 423 entryPtr.swap(it->value); | |
| 424 #endif | |
| 425 resources->remove(it); | 417 resources->remove(it); |
| 426 #if ENABLE(OILPAN) | |
| 427 if (entryPtr) | 418 if (entryPtr) |
| 428 entryPtr->dispose(); | 419 entryPtr->dispose(); |
| 429 #endif | 420 |
| 430 return canDelete; | 421 return canDelete; |
| 431 } | 422 } |
| 432 | 423 |
| 433 MemoryCacheEntry* MemoryCache::getEntryForResource(const Resource* resource) con
st | 424 MemoryCacheEntry* MemoryCache::getEntryForResource(const Resource* resource) con
st |
| 434 { | 425 { |
| 435 if (resource->url().isNull() || resource->url().isEmpty()) | 426 if (resource->url().isNull() || resource->url().isEmpty()) |
| 436 return nullptr; | 427 return nullptr; |
| 437 ResourceMap* resources = m_resourceMaps.get(resource->cacheIdentifier()); | 428 ResourceMap* resources = m_resourceMaps.get(resource->cacheIdentifier()); |
| 438 if (!resources) | 429 if (!resources) |
| 439 return nullptr; | 430 return nullptr; |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 782 pruneLiveResources(strategy); | 773 pruneLiveResources(strategy); |
| 783 m_pruneFrameTimeStamp = m_lastFramePaintTimeStamp; | 774 m_pruneFrameTimeStamp = m_lastFramePaintTimeStamp; |
| 784 m_pruneTimeStamp = currentTime; | 775 m_pruneTimeStamp = currentTime; |
| 785 } | 776 } |
| 786 | 777 |
| 787 void MemoryCache::updateFramePaintTimestamp() | 778 void MemoryCache::updateFramePaintTimestamp() |
| 788 { | 779 { |
| 789 m_lastFramePaintTimeStamp = currentTime(); | 780 m_lastFramePaintTimeStamp = currentTime(); |
| 790 } | 781 } |
| 791 | 782 |
| 792 #if ENABLE(OILPAN) | |
| 793 void MemoryCache::registerLiveResource(Resource& resource) | 783 void MemoryCache::registerLiveResource(Resource& resource) |
| 794 { | 784 { |
| 785 #if ENABLE(OILPAN) |
| 795 ASSERT(!m_liveResources.contains(&resource)); | 786 ASSERT(!m_liveResources.contains(&resource)); |
| 796 m_liveResources.add(&resource); | 787 m_liveResources.add(&resource); |
| 788 #endif |
| 797 } | 789 } |
| 798 | 790 |
| 799 void MemoryCache::unregisterLiveResource(Resource& resource) | 791 void MemoryCache::unregisterLiveResource(Resource& resource) |
| 800 { | 792 { |
| 793 #if ENABLE(OILPAN) |
| 801 ASSERT(m_liveResources.contains(&resource)); | 794 ASSERT(m_liveResources.contains(&resource)); |
| 802 m_liveResources.remove(&resource); | 795 m_liveResources.remove(&resource); |
| 796 #endif |
| 803 } | 797 } |
| 804 | 798 |
| 805 #else | |
| 806 | |
| 807 void MemoryCache::registerLiveResource(Resource&) | |
| 808 { | |
| 809 } | |
| 810 | |
| 811 void MemoryCache::unregisterLiveResource(Resource&) | |
| 812 { | |
| 813 } | |
| 814 #endif | |
| 815 | |
| 816 #ifdef MEMORY_CACHE_STATS | 799 #ifdef MEMORY_CACHE_STATS |
| 817 | 800 |
| 818 void MemoryCache::dumpStats(Timer<MemoryCache>*) | 801 void MemoryCache::dumpStats(Timer<MemoryCache>*) |
| 819 { | 802 { |
| 820 Statistics s = getStatistics(); | 803 Statistics s = getStatistics(); |
| 821 printf("%-13s %-13s %-13s %-13s %-13s %-13s %-13s\n", "", "Count", "Size", "
LiveSize", "DecodedSize", "PurgeableSize", "PurgedSize"); | 804 printf("%-13s %-13s %-13s %-13s %-13s %-13s %-13s\n", "", "Count", "Size", "
LiveSize", "DecodedSize", "PurgeableSize", "PurgedSize"); |
| 822 printf("%-13s %-13s %-13s %-13s %-13s %-13s %-13s\n", "-------------", "----
---------", "-------------", "-------------", "-------------", "-------------",
"-------------"); | 805 printf("%-13s %-13s %-13s %-13s %-13s %-13s %-13s\n", "-------------", "----
---------", "-------------", "-------------", "-------------", "-------------",
"-------------"); |
| 823 printf("%-13s %13d %13d %13d %13d %13d %13d\n", "Images", s.images.count, s.
images.size, s.images.liveSize, s.images.decodedSize, s.images.purgeableSize, s.
images.purgedSize); | 806 printf("%-13s %13d %13d %13d %13d %13d %13d\n", "Images", s.images.count, s.
images.size, s.images.liveSize, s.images.decodedSize, s.images.purgeableSize, s.
images.purgedSize); |
| 824 printf("%-13s %13d %13d %13d %13d %13d %13d\n", "CSS", s.cssStyleSheets.coun
t, s.cssStyleSheets.size, s.cssStyleSheets.liveSize, s.cssStyleSheets.decodedSiz
e, s.cssStyleSheets.purgeableSize, s.cssStyleSheets.purgedSize); | 807 printf("%-13s %13d %13d %13d %13d %13d %13d\n", "CSS", s.cssStyleSheets.coun
t, s.cssStyleSheets.size, s.cssStyleSheets.liveSize, s.cssStyleSheets.decodedSiz
e, s.cssStyleSheets.purgeableSize, s.cssStyleSheets.purgedSize); |
| 825 printf("%-13s %13d %13d %13d %13d %13d %13d\n", "XSL", s.xslStyleSheets.coun
t, s.xslStyleSheets.size, s.xslStyleSheets.liveSize, s.xslStyleSheets.decodedSiz
e, s.xslStyleSheets.purgeableSize, s.xslStyleSheets.purgedSize); | 808 printf("%-13s %13d %13d %13d %13d %13d %13d\n", "XSL", s.xslStyleSheets.coun
t, s.xslStyleSheets.size, s.xslStyleSheets.liveSize, s.xslStyleSheets.decodedSiz
e, s.xslStyleSheets.purgeableSize, s.xslStyleSheets.purgedSize); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 851 printf("(%.1fK, %.1fK, %uA, %dR, %d, %d); ", currentResource->de
codedSize() / 1024.0f, (currentResource->encodedSize() + currentResource->overhe
adSize()) / 1024.0f, current->m_accessCount, currentResource->hasClients(), curr
entResource->isPurgeable(), currentResource->wasPurged()); | 834 printf("(%.1fK, %.1fK, %uA, %dR, %d, %d); ", currentResource->de
codedSize() / 1024.0f, (currentResource->encodedSize() + currentResource->overhe
adSize()) / 1024.0f, current->m_accessCount, currentResource->hasClients(), curr
entResource->isPurgeable(), currentResource->wasPurged()); |
| 852 | 835 |
| 853 current = current->m_previousInAllResourcesList; | 836 current = current->m_previousInAllResourcesList; |
| 854 } | 837 } |
| 855 } | 838 } |
| 856 } | 839 } |
| 857 | 840 |
| 858 #endif // MEMORY_CACHE_STATS | 841 #endif // MEMORY_CACHE_STATS |
| 859 | 842 |
| 860 } // namespace blink | 843 } // namespace blink |
| OLD | NEW |