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 dade33621c1c86616ba772536871ae2abe19f339..8aad84ef9bff434fae49d13d63ca1421cd1fa296 100644 |
--- a/third_party/WebKit/Source/core/fetch/MemoryCache.cpp |
+++ b/third_party/WebKit/Source/core/fetch/MemoryCache.cpp |
@@ -23,6 +23,7 @@ |
#include "core/fetch/MemoryCache.h" |
#include "platform/Logging.h" |
+#include "platform/RuntimeEnabledFeatures.h" |
#include "platform/TraceEvent.h" |
#include "platform/weborigin/SecurityOrigin.h" |
#include "platform/weborigin/SecurityOriginHash.h" |
@@ -60,9 +61,25 @@ MemoryCache* replaceMemoryCacheForTesting(MemoryCache* cache) |
return oldCache; |
} |
+MemoryCacheEntry::MemoryCacheEntry(Resource* resource) |
+ : m_inLiveDecodedResourcesList(false) |
+ , m_accessCount(0) |
+ , m_lastDecodedAccessTime(0.0) |
+ , m_previousInLiveResourcesList(nullptr) |
+ , m_nextInLiveResourcesList(nullptr) |
+ , m_previousInAllResourcesList(nullptr) |
+ , m_nextInAllResourcesList(nullptr) |
+{ |
+ if (RuntimeEnabledFeatures::weakMemoryCacheEnabled()) |
+ m_resourceWeak = resource; |
+ else |
+ m_resource = resource; |
+} |
+ |
DEFINE_TRACE(MemoryCacheEntry) |
{ |
visitor->trace(m_resource); |
+ visitor->trace(m_resourceWeak); |
visitor->trace(m_previousInLiveResourcesList); |
visitor->trace(m_nextInLiveResourcesList); |
visitor->trace(m_previousInAllResourcesList); |
@@ -72,10 +89,13 @@ DEFINE_TRACE(MemoryCacheEntry) |
void MemoryCacheEntry::dispose() |
{ |
m_resource.clear(); |
+ m_resourceWeak.clear(); |
} |
Resource* MemoryCacheEntry::resource() |
{ |
+ if (RuntimeEnabledFeatures::weakMemoryCacheEnabled()) |
+ return m_resourceWeak.get(); |
return m_resource.get(); |
} |
@@ -163,7 +183,7 @@ void MemoryCache::add(Resource* resource) |
ASSERT(resource->url().isValid()); |
ResourceMap* resources = ensureResourceMap(resource->cacheIdentifier()); |
KURL url = removeFragmentIdentifierIfNeeded(resource->url()); |
- RELEASE_ASSERT(!resources->contains(url)); |
+ RELEASE_ASSERT(!contains(resource)); |
resources->set(url, MemoryCacheEntry::create(resource)); |
update(resource, 0, resource->size(), true); |
@@ -213,8 +233,11 @@ HeapVector<Member<Resource>> MemoryCache::resourcesForURL(const KURL& resourceUR |
KURL url = removeFragmentIdentifierIfNeeded(resourceURL); |
HeapVector<Member<Resource>> results; |
for (const auto& resourceMapIter : m_resourceMaps) { |
- if (MemoryCacheEntry* entry = resourceMapIter.value->get(url)) |
- results.append(entry->resource()); |
+ if (MemoryCacheEntry* entry = resourceMapIter.value->get(url)) { |
+ Resource* resource = entry->resource(); |
+ if (resource) |
+ results.append(resource); |
+ } |
} |
return results; |
} |
@@ -259,6 +282,10 @@ void MemoryCache::pruneLiveResources(PruneStrategy strategy) |
while (current) { |
Resource* resource = current->resource(); |
MemoryCacheEntry* previous = current->m_previousInLiveResourcesList; |
+ if (!resource) { |
+ current = previous; |
+ continue; |
+ } |
ASSERT(resource->hasClientsOrObservers()); |
if (resource->isLoaded() && resource->decodedSize()) { |
@@ -365,6 +392,7 @@ void MemoryCache::evict(MemoryCacheEntry* entry) |
ASSERT(WTF::isMainThread()); |
Resource* resource = entry->resource(); |
+ DCHECK(resource); |
WTF_LOG(ResourceLoading, "Evicting resource %p for '%s' from cache", resource, resource->url().getString().latin1().data()); |
// 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>. |
@@ -385,7 +413,7 @@ void MemoryCache::evict(MemoryCacheEntry* entry) |
MemoryCacheEntry* MemoryCache::getEntryForResource(const Resource* resource) const |
{ |
- if (resource->url().isNull() || resource->url().isEmpty()) |
+ if (!resource || resource->url().isNull() || resource->url().isEmpty()) |
return nullptr; |
ResourceMap* resources = m_resourceMaps.get(resource->cacheIdentifier()); |
if (!resources) |
@@ -598,6 +626,8 @@ MemoryCache::Statistics MemoryCache::getStatistics() |
for (const auto& resourceMapIter : m_resourceMaps) { |
for (const auto& resourceIter : *resourceMapIter.value) { |
Resource* resource = resourceIter.value->resource(); |
+ if (!resource) |
+ continue; |
switch (resource->getType()) { |
case Resource::Image: |
stats.images.addResource(resource); |
@@ -634,7 +664,10 @@ void MemoryCache::evictResources() |
ResourceMap::iterator resourceIter = resources->begin(); |
if (resourceIter == resources->end()) |
break; |
- evict(resourceIter->value.get()); |
+ if (resourceIter->value->resource()) |
+ evict(resourceIter->value.get()); |
+ else |
+ resources->remove(resourceIter); |
} |
m_resourceMaps.remove(resourceMapIter); |
} |
@@ -728,7 +761,8 @@ bool MemoryCache::onMemoryDump(WebMemoryDumpLevelOfDetail levelOfDetail, WebProc |
for (const auto& resourceMapIter : m_resourceMaps) { |
for (const auto& resourceIter : *resourceMapIter.value) { |
Resource* resource = resourceIter.value->resource(); |
- resource->onMemoryDump(levelOfDetail, memoryDump); |
+ if (resource) |
+ resource->onMemoryDump(levelOfDetail, memoryDump); |
} |
} |
return true; |
@@ -777,7 +811,7 @@ void MemoryCache::dumpLRULists(bool includeLive) const |
MemoryCacheEntry* current = m_allResources[i].m_tail; |
while (current) { |
Resource* currentResource = current->resource(); |
- if (includeLive || !currentResource->hasClientsOrObservers()) |
+ if (currentResource && (includeLive || !currentResource->hasClientsOrObservers())) |
printf("(%.1fK, %.1fK, %uA, %dR, %d); ", currentResource->decodedSize() / 1024.0f, (currentResource->encodedSize() + currentResource->overheadSize()) / 1024.0f, current->m_accessCount, currentResource->hasClientsOrObservers(), currentResource->isPurgeable()); |
current = current->m_previousInAllResourcesList; |