| Index: third_party/WebKit/Source/core/fetch/MemoryCache.cpp
|
| diff --git a/third_party/WebKit/Source/core/fetch/MemoryCache.cpp b/third_party/WebKit/Source/core/fetch/MemoryCache.cpp
|
| index 7d7f7f23b2949e8ce759cbc84af818c7f76c379d..d0539d107bf7641407caa089dccc3a6fc69444a6 100644
|
| --- a/third_party/WebKit/Source/core/fetch/MemoryCache.cpp
|
| +++ b/third_party/WebKit/Source/core/fetch/MemoryCache.cpp
|
| @@ -38,7 +38,6 @@ namespace blink {
|
| static Persistent<MemoryCache>* gMemoryCache;
|
|
|
| static const unsigned cDefaultCacheCapacity = 8192 * 1024;
|
| -static const unsigned cDeferredPruneDeadCapacityFactor = 2;
|
| static const int cMinDelayBeforeLiveDecodedPrune = 1; // Seconds.
|
| static const double cMaxPruneDeferralDelay = 0.5; // Seconds.
|
|
|
| @@ -65,10 +64,6 @@ DEFINE_TRACE(MemoryCacheEntry) {
|
| visitor->template registerWeakMembers<MemoryCacheEntry,
|
| &MemoryCacheEntry::clearResourceWeak>(
|
| this);
|
| - visitor->trace(m_previousInLiveResourcesList);
|
| - visitor->trace(m_nextInLiveResourcesList);
|
| - visitor->trace(m_previousInAllResourcesList);
|
| - visitor->trace(m_nextInAllResourcesList);
|
| }
|
|
|
| void MemoryCacheEntry::clearResourceWeak(Visitor* visitor) {
|
| @@ -78,19 +73,6 @@ void MemoryCacheEntry::clearResourceWeak(Visitor* visitor) {
|
| m_resource.clear();
|
| }
|
|
|
| -void MemoryCacheEntry::dispose() {
|
| - m_resource.clear();
|
| -}
|
| -
|
| -Resource* MemoryCacheEntry::resource() {
|
| - return m_resource.get();
|
| -}
|
| -
|
| -DEFINE_TRACE(MemoryCacheLRUList) {
|
| - visitor->trace(m_head);
|
| - visitor->trace(m_tail);
|
| -}
|
| -
|
| inline MemoryCache::MemoryCache()
|
| : m_inPruneResources(false),
|
| m_prunePending(false),
|
| @@ -99,13 +81,8 @@ inline MemoryCache::MemoryCache()
|
| m_pruneFrameTimeStamp(0.0),
|
| m_lastFramePaintTimeStamp(0.0),
|
| m_capacity(cDefaultCacheCapacity),
|
| - m_minDeadCapacity(0),
|
| - m_maxDeadCapacity(cDefaultCacheCapacity),
|
| - m_maxDeferredPruneDeadCapacity(cDeferredPruneDeadCapacityFactor *
|
| - cDefaultCacheCapacity),
|
| m_delayBeforeLiveDecodedPrune(cMinDelayBeforeLiveDecodedPrune),
|
| - m_liveSize(0),
|
| - m_deadSize(0) {
|
| + m_size(0) {
|
| MemoryCacheDumpProvider::instance()->setMemoryCache(this);
|
| if (ProcessHeap::isLowEndDevice())
|
| MemoryCoordinator::instance().registerClient(this);
|
| @@ -121,8 +98,6 @@ MemoryCache::~MemoryCache() {
|
| }
|
|
|
| DEFINE_TRACE(MemoryCache) {
|
| - visitor->trace(m_allResources);
|
| - visitor->trace(m_liveDecodedResources);
|
| visitor->trace(m_resourceMaps);
|
| MemoryCacheDumpClient::trace(visitor);
|
| MemoryCoordinatorClient::trace(visitor);
|
| @@ -156,52 +131,100 @@ MemoryCache::ResourceMap* MemoryCache::ensureResourceMap(
|
| }
|
|
|
| void MemoryCache::add(Resource* resource) {
|
| - DCHECK(WTF::isMainThread());
|
| - DCHECK(resource->url().isValid());
|
| + DCHECK(resource);
|
| ResourceMap* resources = ensureResourceMap(resource->cacheIdentifier());
|
| - KURL url = removeFragmentIdentifierIfNeeded(resource->url());
|
| - CHECK(!contains(resource));
|
| - resources->set(url, MemoryCacheEntry::create(resource));
|
| - update(resource, 0, resource->size(), true);
|
| -
|
| + addInternal(resources, MemoryCacheEntry::create(resource));
|
| RESOURCE_LOADING_DVLOG(1) << "MemoryCache::add Added "
|
| << resource->url().getString() << ", resource "
|
| << resource;
|
| }
|
|
|
| +void MemoryCache::addInternal(ResourceMap* resourceMap,
|
| + MemoryCacheEntry* entry) {
|
| + DCHECK(WTF::isMainThread());
|
| + DCHECK(resourceMap);
|
| +
|
| + Resource* resource = entry->resource();
|
| + if (!resource)
|
| + return;
|
| + DCHECK(resource->url().isValid());
|
| +
|
| + KURL url = removeFragmentIdentifierIfNeeded(resource->url());
|
| + ResourceMap::iterator it = resourceMap->find(url);
|
| + if (it != resourceMap->end()) {
|
| + Resource* oldResource = it->value->resource();
|
| + CHECK_NE(oldResource, resource);
|
| + update(oldResource, oldResource->size(), 0);
|
| + }
|
| + resourceMap->set(url, entry);
|
| + update(resource, 0, resource->size());
|
| +}
|
| +
|
| void MemoryCache::remove(Resource* resource) {
|
| - // The resource may have already been removed by someone other than our
|
| - // caller, who needed a fresh copy for a reload.
|
| - if (MemoryCacheEntry* entry = getEntryForResource(resource))
|
| - evict(entry);
|
| + DCHECK(WTF::isMainThread());
|
| + DCHECK(resource);
|
| + RESOURCE_LOADING_DVLOG(1) << "Evicting resource " << resource << " for "
|
| + << resource->url().getString() << " from cache";
|
| + TRACE_EVENT1("blink", "MemoryCache::evict", "resource",
|
| + resource->url().getString().utf8());
|
| +
|
| + ResourceMap* resources = m_resourceMaps.get(resource->cacheIdentifier());
|
| + if (!resources)
|
| + return;
|
| +
|
| + KURL url = removeFragmentIdentifierIfNeeded(resource->url());
|
| + ResourceMap::iterator it = resources->find(url);
|
| + if (it == resources->end() || it->value->resource() != resource)
|
| + return;
|
| + removeInternal(resources, it);
|
| +}
|
| +
|
| +void MemoryCache::removeInternal(ResourceMap* resourceMap,
|
| + const ResourceMap::iterator& it) {
|
| + DCHECK(WTF::isMainThread());
|
| + DCHECK(resourceMap);
|
| +
|
| + Resource* resource = it->value->resource();
|
| + DCHECK(resource);
|
| +
|
| + update(resource, resource->size(), 0);
|
| + resourceMap->remove(it);
|
| }
|
|
|
| bool MemoryCache::contains(const Resource* resource) const {
|
| - return getEntryForResource(resource);
|
| + if (!resource || resource->url().isEmpty())
|
| + return false;
|
| + const ResourceMap* resources =
|
| + m_resourceMaps.get(resource->cacheIdentifier());
|
| + if (!resources)
|
| + return false;
|
| + KURL url = removeFragmentIdentifierIfNeeded(resource->url());
|
| + MemoryCacheEntry* entry = resources->get(url);
|
| + return entry && resource == entry->resource();
|
| }
|
|
|
| -Resource* MemoryCache::resourceForURL(const KURL& resourceURL) {
|
| +Resource* MemoryCache::resourceForURL(const KURL& resourceURL) const {
|
| return resourceForURL(resourceURL, defaultCacheIdentifier());
|
| }
|
|
|
| Resource* MemoryCache::resourceForURL(const KURL& resourceURL,
|
| - const String& cacheIdentifier) {
|
| + const String& cacheIdentifier) const {
|
| DCHECK(WTF::isMainThread());
|
| if (!resourceURL.isValid() || resourceURL.isNull())
|
| return nullptr;
|
| DCHECK(!cacheIdentifier.isNull());
|
| - ResourceMap* resources = m_resourceMaps.get(cacheIdentifier);
|
| + const ResourceMap* resources = m_resourceMaps.get(cacheIdentifier);
|
| if (!resources)
|
| return nullptr;
|
| - KURL url = removeFragmentIdentifierIfNeeded(resourceURL);
|
| - MemoryCacheEntry* entry = resources->get(url);
|
| + MemoryCacheEntry* entry =
|
| + resources->get(removeFragmentIdentifierIfNeeded(resourceURL));
|
| if (!entry)
|
| return nullptr;
|
| return entry->resource();
|
| }
|
|
|
| HeapVector<Member<Resource>> MemoryCache::resourcesForURL(
|
| - const KURL& resourceURL) {
|
| + const KURL& resourceURL) const {
|
| DCHECK(WTF::isMainThread());
|
| KURL url = removeFragmentIdentifierIfNeeded(resourceURL);
|
| HeapVector<Member<Resource>> results;
|
| @@ -215,384 +238,56 @@ HeapVector<Member<Resource>> MemoryCache::resourcesForURL(
|
| return results;
|
| }
|
|
|
| -size_t MemoryCache::deadCapacity() const {
|
| - // Dead resource capacity is whatever space is not occupied by live resources,
|
| - // bounded by an independent minimum and maximum.
|
| - size_t capacity =
|
| - m_capacity -
|
| - std::min(m_liveSize, m_capacity); // Start with available capacity.
|
| - capacity = std::max(capacity,
|
| - m_minDeadCapacity); // Make sure it's above the minimum.
|
| - capacity = std::min(capacity,
|
| - m_maxDeadCapacity); // Make sure it's below the maximum.
|
| - return capacity;
|
| -}
|
| -
|
| -size_t MemoryCache::liveCapacity() const {
|
| - // Live resource capacity is whatever is left over after calculating dead
|
| - // resource capacity.
|
| - return m_capacity - deadCapacity();
|
| -}
|
| -
|
| -void MemoryCache::pruneLiveResources(PruneStrategy strategy) {
|
| +void MemoryCache::pruneResources(PruneStrategy strategy) {
|
| DCHECK(!m_prunePending);
|
| - size_t capacity = liveCapacity();
|
| - if (strategy == MaximalPrune)
|
| - capacity = 0;
|
| - if (!m_liveSize || (capacity && m_liveSize <= capacity))
|
| - return;
|
| -
|
| - // Cut by a percentage to avoid immediately pruning again.
|
| - size_t targetSize = static_cast<size_t>(capacity * cTargetPrunePercentage);
|
| -
|
| - // Destroy any decoded data in live objects that we can. Start from the tail,
|
| - // since this is the lowest priority and least recently accessed of the
|
| - // objects.
|
| -
|
| - // The list might not be sorted by the m_lastDecodedFrameTimeStamp. The impact
|
| - // of this weaker invariant is minor as the below if statement to check the
|
| - // elapsedTime will evaluate to false as the current time will be a lot
|
| - // greater than the current->m_lastDecodedFrameTimeStamp. For more details
|
| - // see: https://bugs.webkit.org/show_bug.cgi?id=30209
|
| -
|
| - MemoryCacheEntry* current = m_liveDecodedResources.m_tail;
|
| - while (current) {
|
| - Resource* resource = current->resource();
|
| - MemoryCacheEntry* previous = current->m_previousInLiveResourcesList;
|
| - DCHECK(resource->isAlive());
|
| -
|
| - if (resource->isLoaded() && resource->decodedSize()) {
|
| - // Check to see if the remaining resources are too new to prune.
|
| - double elapsedTime =
|
| - m_pruneFrameTimeStamp - current->m_lastDecodedAccessTime;
|
| - if (strategy == AutomaticPrune &&
|
| - elapsedTime < m_delayBeforeLiveDecodedPrune)
|
| - return;
|
| -
|
| - // Destroy our decoded data if possible. This will remove us from
|
| - // m_liveDecodedResources, and possibly move us to a different LRU list in
|
| - // m_allResources.
|
| - resource->prune();
|
| -
|
| - if (targetSize && m_liveSize <= targetSize)
|
| - return;
|
| - }
|
| - current = previous;
|
| - }
|
| -}
|
| -
|
| -void MemoryCache::pruneDeadResources(PruneStrategy strategy) {
|
| - size_t capacity = deadCapacity();
|
| - if (strategy == MaximalPrune)
|
| - capacity = 0;
|
| - if (!m_deadSize || (capacity && m_deadSize <= capacity))
|
| + const size_t sizeLimit = (strategy == MaximalPrune) ? 0 : capacity();
|
| + if (m_size <= sizeLimit)
|
| return;
|
|
|
| // Cut by a percentage to avoid immediately pruning again.
|
| - size_t targetSize = static_cast<size_t>(capacity * cTargetPrunePercentage);
|
| + size_t targetSize = static_cast<size_t>(sizeLimit * cTargetPrunePercentage);
|
|
|
| - int size = m_allResources.size();
|
| - if (targetSize && m_deadSize <= targetSize)
|
| - return;
|
| -
|
| - bool canShrinkLRULists = true;
|
| - for (int i = size - 1; i >= 0; i--) {
|
| - // Remove from the tail, since this is the least frequently accessed of the
|
| - // objects.
|
| - MemoryCacheEntry* current = m_allResources[i].m_tail;
|
| -
|
| - // First flush all the decoded data in this queue.
|
| - while (current) {
|
| - Resource* resource = current->resource();
|
| - MemoryCacheEntry* previous = current->m_previousInAllResourcesList;
|
| -
|
| - // Decoded data may reference other resources. Skip |current| if |current|
|
| - // somehow got kicked out of cache during destroyDecodedData().
|
| - if (!resource || !contains(resource)) {
|
| - current = previous;
|
| - continue;
|
| - }
|
| -
|
| - if (!resource->isAlive() && !resource->isPreloaded() &&
|
| - resource->isLoaded()) {
|
| - // Destroy our decoded data. This will remove us from
|
| - // m_liveDecodedResources, and possibly move us to a different LRU list
|
| - // in m_allResources.
|
| + for (const auto& resourceMapIter : m_resourceMaps) {
|
| + for (const auto& resourceIter : *resourceMapIter.value) {
|
| + Resource* resource = resourceIter.value->resource();
|
| + DCHECK(resource);
|
| + if (resource->isLoaded() && resource->decodedSize()) {
|
| + // Check to see if the remaining resources are too new to prune.
|
| + double elapsedTime =
|
| + m_pruneFrameTimeStamp - resourceIter.value->m_lastDecodedAccessTime;
|
| + if (strategy == AutomaticPrune &&
|
| + elapsedTime < m_delayBeforeLiveDecodedPrune)
|
| + continue;
|
| resource->prune();
|
| -
|
| - if (targetSize && m_deadSize <= targetSize)
|
| + if (m_size <= targetSize)
|
| return;
|
| }
|
| - current = previous;
|
| }
|
| -
|
| - // Now evict objects from this queue.
|
| - current = m_allResources[i].m_tail;
|
| - while (current) {
|
| - Resource* resource = current->resource();
|
| - MemoryCacheEntry* previous = current->m_previousInAllResourcesList;
|
| - if (!resource || !contains(resource)) {
|
| - current = previous;
|
| - continue;
|
| - }
|
| - if (!resource->isAlive() && !resource->isPreloaded()) {
|
| - evict(current);
|
| - if (targetSize && m_deadSize <= targetSize)
|
| - return;
|
| - }
|
| - current = previous;
|
| - }
|
| -
|
| - // Shrink the vector back down so we don't waste time inspecting empty LRU
|
| - // lists on future prunes.
|
| - if (m_allResources[i].m_head)
|
| - canShrinkLRULists = false;
|
| - else if (canShrinkLRULists)
|
| - m_allResources.resize(i);
|
| }
|
| }
|
|
|
| -void MemoryCache::setCapacities(size_t minDeadBytes,
|
| - size_t maxDeadBytes,
|
| - size_t totalBytes) {
|
| - DCHECK_LE(minDeadBytes, maxDeadBytes);
|
| - DCHECK_LE(maxDeadBytes, totalBytes);
|
| - m_minDeadCapacity = minDeadBytes;
|
| - m_maxDeadCapacity = maxDeadBytes;
|
| - m_maxDeferredPruneDeadCapacity =
|
| - cDeferredPruneDeadCapacityFactor * maxDeadBytes;
|
| +void MemoryCache::setCapacity(size_t totalBytes) {
|
| m_capacity = totalBytes;
|
| prune();
|
| }
|
|
|
| -void MemoryCache::evict(MemoryCacheEntry* entry) {
|
| - DCHECK(WTF::isMainThread());
|
| -
|
| - Resource* resource = entry->resource();
|
| - DCHECK(resource);
|
| - RESOURCE_LOADING_DVLOG(1) << "Evicting resource " << resource << " for "
|
| - << resource->url().getString() << " from cache";
|
| - TRACE_EVENT1("blink", "MemoryCache::evict", "resource",
|
| - resource->url().getString().utf8());
|
| - // The resource may have already been removed by someone other than our
|
| - // caller, who needed a fresh copy for a reload. See
|
| - // <http://bugs.webkit.org/show_bug.cgi?id=12479#c6>.
|
| - update(resource, resource->size(), 0, false);
|
| - removeFromLiveDecodedResourcesList(entry);
|
| -
|
| - ResourceMap* resources = m_resourceMaps.get(resource->cacheIdentifier());
|
| - DCHECK(resources);
|
| - KURL url = removeFragmentIdentifierIfNeeded(resource->url());
|
| - ResourceMap::iterator it = resources->find(url);
|
| - DCHECK_NE(it, resources->end());
|
| -
|
| - MemoryCacheEntry* entryPtr = it->value;
|
| - resources->remove(it);
|
| - if (entryPtr)
|
| - entryPtr->dispose();
|
| -}
|
| -
|
| -MemoryCacheEntry* MemoryCache::getEntryForResource(
|
| - const Resource* resource) const {
|
| - if (!resource || resource->url().isNull() || resource->url().isEmpty())
|
| - return nullptr;
|
| - ResourceMap* resources = m_resourceMaps.get(resource->cacheIdentifier());
|
| - if (!resources)
|
| - return nullptr;
|
| - KURL url = removeFragmentIdentifierIfNeeded(resource->url());
|
| - MemoryCacheEntry* entry = resources->get(url);
|
| - if (!entry || entry->resource() != resource)
|
| - return nullptr;
|
| - return entry;
|
| -}
|
| -
|
| -MemoryCacheLRUList* MemoryCache::lruListFor(unsigned accessCount, size_t size) {
|
| - DCHECK_GT(accessCount, 0u);
|
| - unsigned queueIndex = WTF::fastLog2(size / accessCount);
|
| - if (m_allResources.size() <= queueIndex)
|
| - m_allResources.grow(queueIndex + 1);
|
| - return &m_allResources[queueIndex];
|
| -}
|
| -
|
| -void MemoryCache::removeFromLRUList(MemoryCacheEntry* entry,
|
| - MemoryCacheLRUList* list) {
|
| - DCHECK(containedInLRUList(entry, list));
|
| -
|
| - MemoryCacheEntry* next = entry->m_nextInAllResourcesList;
|
| - MemoryCacheEntry* previous = entry->m_previousInAllResourcesList;
|
| - entry->m_nextInAllResourcesList = nullptr;
|
| - entry->m_previousInAllResourcesList = nullptr;
|
| -
|
| - if (next)
|
| - next->m_previousInAllResourcesList = previous;
|
| - else
|
| - list->m_tail = previous;
|
| -
|
| - if (previous)
|
| - previous->m_nextInAllResourcesList = next;
|
| - else
|
| - list->m_head = next;
|
| -
|
| - DCHECK(!containedInLRUList(entry, list));
|
| -}
|
| -
|
| -void MemoryCache::insertInLRUList(MemoryCacheEntry* entry,
|
| - MemoryCacheLRUList* list) {
|
| - DCHECK(!containedInLRUList(entry, list));
|
| -
|
| - entry->m_nextInAllResourcesList = list->m_head;
|
| - list->m_head = entry;
|
| -
|
| - if (entry->m_nextInAllResourcesList)
|
| - entry->m_nextInAllResourcesList->m_previousInAllResourcesList = entry;
|
| - else
|
| - list->m_tail = entry;
|
| -
|
| - DCHECK(containedInLRUList(entry, list));
|
| -}
|
| -
|
| -bool MemoryCache::containedInLRUList(MemoryCacheEntry* entry,
|
| - MemoryCacheLRUList* list) {
|
| - for (MemoryCacheEntry* current = list->m_head; current;
|
| - current = current->m_nextInAllResourcesList) {
|
| - if (current == entry)
|
| - return true;
|
| - }
|
| - DCHECK(!entry->m_nextInAllResourcesList);
|
| - DCHECK(!entry->m_previousInAllResourcesList);
|
| - return false;
|
| -}
|
| -
|
| -void MemoryCache::removeFromLiveDecodedResourcesList(MemoryCacheEntry* entry) {
|
| - // If we've never been accessed, then we're brand new and not in any list.
|
| - if (!entry->m_inLiveDecodedResourcesList)
|
| - return;
|
| - DCHECK(containedInLiveDecodedResourcesList(entry));
|
| -
|
| - entry->m_inLiveDecodedResourcesList = false;
|
| -
|
| - MemoryCacheEntry* next = entry->m_nextInLiveResourcesList;
|
| - MemoryCacheEntry* previous = entry->m_previousInLiveResourcesList;
|
| -
|
| - entry->m_nextInLiveResourcesList = nullptr;
|
| - entry->m_previousInLiveResourcesList = nullptr;
|
| -
|
| - if (next)
|
| - next->m_previousInLiveResourcesList = previous;
|
| - else
|
| - m_liveDecodedResources.m_tail = previous;
|
| -
|
| - if (previous)
|
| - previous->m_nextInLiveResourcesList = next;
|
| - else
|
| - m_liveDecodedResources.m_head = next;
|
| -
|
| - DCHECK(!containedInLiveDecodedResourcesList(entry));
|
| -}
|
| -
|
| -void MemoryCache::insertInLiveDecodedResourcesList(MemoryCacheEntry* entry) {
|
| - DCHECK(!containedInLiveDecodedResourcesList(entry));
|
| -
|
| - entry->m_inLiveDecodedResourcesList = true;
|
| -
|
| - entry->m_nextInLiveResourcesList = m_liveDecodedResources.m_head;
|
| - if (m_liveDecodedResources.m_head)
|
| - m_liveDecodedResources.m_head->m_previousInLiveResourcesList = entry;
|
| - m_liveDecodedResources.m_head = entry;
|
| -
|
| - if (!entry->m_nextInLiveResourcesList)
|
| - m_liveDecodedResources.m_tail = entry;
|
| -
|
| - DCHECK(containedInLiveDecodedResourcesList(entry));
|
| -}
|
| -
|
| -bool MemoryCache::containedInLiveDecodedResourcesList(MemoryCacheEntry* entry) {
|
| - for (MemoryCacheEntry* current = m_liveDecodedResources.m_head; current;
|
| - current = current->m_nextInLiveResourcesList) {
|
| - if (current == entry) {
|
| - DCHECK(entry->m_inLiveDecodedResourcesList);
|
| - return true;
|
| - }
|
| - }
|
| - DCHECK(!entry->m_nextInLiveResourcesList);
|
| - DCHECK(!entry->m_previousInLiveResourcesList);
|
| - DCHECK(!entry->m_inLiveDecodedResourcesList);
|
| - return false;
|
| -}
|
| -
|
| -void MemoryCache::makeLive(Resource* resource) {
|
| - if (!contains(resource))
|
| - return;
|
| - DCHECK_GE(m_deadSize, resource->size());
|
| - m_liveSize += resource->size();
|
| - m_deadSize -= resource->size();
|
| -}
|
| -
|
| -void MemoryCache::makeDead(Resource* resource) {
|
| +void MemoryCache::update(Resource* resource, size_t oldSize, size_t newSize) {
|
| if (!contains(resource))
|
| return;
|
| - m_liveSize -= resource->size();
|
| - m_deadSize += resource->size();
|
| - removeFromLiveDecodedResourcesList(getEntryForResource(resource));
|
| -}
|
| -
|
| -void MemoryCache::update(Resource* resource,
|
| - size_t oldSize,
|
| - size_t newSize,
|
| - bool wasAccessed) {
|
| - MemoryCacheEntry* entry = getEntryForResource(resource);
|
| - if (!entry)
|
| - return;
|
| -
|
| - // The object must now be moved to a different queue, since either its size or
|
| - // its accessCount has been changed, and both of those are used to determine
|
| - // which LRU queue the resource should be in.
|
| - if (oldSize)
|
| - removeFromLRUList(entry, lruListFor(entry->m_accessCount, oldSize));
|
| - if (wasAccessed)
|
| - entry->m_accessCount++;
|
| - if (newSize)
|
| - insertInLRUList(entry, lruListFor(entry->m_accessCount, newSize));
|
| -
|
| ptrdiff_t delta = newSize - oldSize;
|
| - if (resource->isAlive()) {
|
| - DCHECK(delta >= 0 || m_liveSize >= static_cast<size_t>(-delta));
|
| - m_liveSize += delta;
|
| - } else {
|
| - DCHECK(delta >= 0 || m_deadSize >= static_cast<size_t>(-delta));
|
| - m_deadSize += delta;
|
| - }
|
| -}
|
| -
|
| -void MemoryCache::updateDecodedResource(Resource* resource,
|
| - UpdateReason reason) {
|
| - MemoryCacheEntry* entry = getEntryForResource(resource);
|
| - if (!entry)
|
| - return;
|
| -
|
| - removeFromLiveDecodedResourcesList(entry);
|
| - if (resource->decodedSize() && resource->isAlive())
|
| - insertInLiveDecodedResourcesList(entry);
|
| -
|
| - if (reason != UpdateForAccess)
|
| - return;
|
| -
|
| - double timestamp = resource->isImage() ? m_lastFramePaintTimeStamp : 0.0;
|
| - if (!timestamp)
|
| - timestamp = currentTime();
|
| - entry->m_lastDecodedAccessTime = timestamp;
|
| + DCHECK(delta >= 0 || m_size >= static_cast<size_t>(-delta));
|
| + m_size += delta;
|
| }
|
|
|
| void MemoryCache::removeURLFromCache(const KURL& url) {
|
| HeapVector<Member<Resource>> resources = resourcesForURL(url);
|
| for (Resource* resource : resources)
|
| - memoryCache()->remove(resource);
|
| + remove(resource);
|
| }
|
|
|
| void MemoryCache::TypeStatistic::addResource(Resource* o) {
|
| count++;
|
| size += o->size();
|
| - liveSize += o->isAlive() ? o->size() : 0;
|
| decodedSize += o->decodedSize();
|
| encodedSize += o->encodedSize();
|
| overheadSize += o->overheadSize();
|
| @@ -600,7 +295,7 @@ void MemoryCache::TypeStatistic::addResource(Resource* o) {
|
| o->url().protocolIsData() ? o->encodedSize() : 0;
|
| }
|
|
|
| -MemoryCache::Statistics MemoryCache::getStatistics() {
|
| +MemoryCache::Statistics MemoryCache::getStatistics() const {
|
| Statistics stats;
|
| for (const auto& resourceMapIter : m_resourceMaps) {
|
| for (const auto& resourceIter : *resourceMapIter.value) {
|
| @@ -641,22 +336,18 @@ void MemoryCache::evictResources(EvictResourcePolicy policy) {
|
| DCHECK(resourceIter.get());
|
| DCHECK(resourceIter->value.get());
|
| DCHECK(resourceIter->value->resource());
|
| - if (policy == EvictAllResources ||
|
| - !(resourceIter->value->resource() &&
|
| - resourceIter->value->resource()->isUnusedPreload())) {
|
| - evict(resourceIter->value.get());
|
| - } else {
|
| + Resource* resource = resourceIter->value->resource();
|
| + DCHECK(resource);
|
| + if (policy != EvictAllResources && resource->isUnusedPreload()) {
|
| // Store unused preloads aside, so they could be added back later.
|
| // That is in order to avoid the performance impact of iterating over
|
| // the same resource multiple times.
|
| unusedPreloads.append(resourceIter->value.get());
|
| - resources->remove(resourceIter);
|
| }
|
| + removeInternal(resources, resourceIter);
|
| }
|
| for (const auto& unusedPreload : unusedPreloads) {
|
| - KURL url =
|
| - removeFragmentIdentifierIfNeeded(unusedPreload->resource()->url());
|
| - resources->set(url, unusedPreload);
|
| + addInternal(resources, unusedPreload);
|
| }
|
| // We may iterate multiple times over resourceMaps with unused preloads.
|
| // That's extremely unlikely to have any real-life performance impact.
|
| @@ -674,8 +365,7 @@ void MemoryCache::prune() {
|
|
|
| if (m_inPruneResources)
|
| return;
|
| - if (m_liveSize + m_deadSize <= m_capacity && m_maxDeadCapacity &&
|
| - m_deadSize <= m_maxDeadCapacity) // Fast path.
|
| + if (m_size <= m_capacity) // Fast path.
|
| return;
|
|
|
| // To avoid burdening the current thread with repetitive pruning jobs, pruning
|
| @@ -721,9 +411,7 @@ void MemoryCache::pruneNow(double currentTime, PruneStrategy strategy) {
|
|
|
| AutoReset<bool> reentrancyProtector(&m_inPruneResources, true);
|
|
|
| - // Prune dead first, in case it was "borrowing" capacity from live.
|
| - pruneDeadResources(strategy);
|
| - pruneLiveResources(strategy);
|
| + pruneResources(strategy);
|
| m_pruneFrameTimeStamp = m_lastFramePaintTimeStamp;
|
| m_pruneTimeStamp = currentTime;
|
| }
|
| @@ -776,13 +464,4 @@ void MemoryCache::onMemoryPressure(WebMemoryPressureLevel level) {
|
| pruneAll();
|
| }
|
|
|
| -bool MemoryCache::isInSameLRUListForTest(const Resource* x, const Resource* y) {
|
| - MemoryCacheEntry* ex = getEntryForResource(x);
|
| - MemoryCacheEntry* ey = getEntryForResource(y);
|
| - DCHECK(ex);
|
| - DCHECK(ey);
|
| - return lruListFor(ex->m_accessCount, x->size()) ==
|
| - lruListFor(ey->m_accessCount, y->size());
|
| -}
|
| -
|
| } // namespace blink
|
|
|