Commit 50a18494 authored by japhet@chromium.org's avatar japhet@chromium.org

Make MemoryCache's LRUList manipulation private

Changes to the LRU lists are hidden behind a call to MemoryCache::update(), which adjusts sizes, access count, and LRU list position as appropriate. All of these are to some degree interrelated, since we keep multiple LRU lists and select one to use based access count and resource size.

Also, remove the Resource::inCache() bit in favor of a
MemoryCache::contains()

BUG=none

Review URL: https://codereview.chromium.org/164333008

git-svn-id: svn://svn.chromium.org/blink/trunk@169748 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent fcfbcdc5
...@@ -369,7 +369,7 @@ void ImageResource::updateImage(bool allDataReceived) ...@@ -369,7 +369,7 @@ void ImageResource::updateImage(bool allDataReceived)
if (sizeAvailable || allDataReceived) { if (sizeAvailable || allDataReceived) {
if (!m_image || m_image->isNull()) { if (!m_image || m_image->isNull()) {
error(errorOccurred() ? status() : DecodeError); error(errorOccurred() ? status() : DecodeError);
if (inCache()) if (memoryCache()->contains(this))
memoryCache()->remove(this); memoryCache()->remove(this);
return; return;
} }
......
...@@ -111,8 +111,7 @@ void MemoryCache::add(Resource* resource) ...@@ -111,8 +111,7 @@ void MemoryCache::add(Resource* resource)
ASSERT(WTF::isMainThread()); ASSERT(WTF::isMainThread());
ASSERT(!m_resources.contains(resource->url())); ASSERT(!m_resources.contains(resource->url()));
m_resources.set(resource->url(), MemoryCacheEntry::create(resource)); m_resources.set(resource->url(), MemoryCacheEntry::create(resource));
resource->setInCache(true); update(resource, 0, resource->size(), true);
resource->updateForAccess();
WTF_LOG(ResourceLoading, "MemoryCache::add Added '%s', resource %p\n", resource->url().string().latin1().data(), resource); WTF_LOG(ResourceLoading, "MemoryCache::add Added '%s', resource %p\n", resource->url().string().latin1().data(), resource);
} }
...@@ -120,15 +119,17 @@ void MemoryCache::add(Resource* resource) ...@@ -120,15 +119,17 @@ void MemoryCache::add(Resource* resource)
void MemoryCache::replace(Resource* newResource, Resource* oldResource) void MemoryCache::replace(Resource* newResource, Resource* oldResource)
{ {
evict(oldResource); evict(oldResource);
ASSERT(!m_resources.contains(newResource->url())); add(newResource);
m_resources.set(newResource->url(), MemoryCacheEntry::create(newResource));
newResource->setInCache(true);
insertInLRUList(newResource);
int delta = newResource->size();
if (newResource->decodedSize() && newResource->hasClients()) if (newResource->decodedSize() && newResource->hasClients())
insertInLiveDecodedResourcesList(newResource); insertInLiveDecodedResourcesList(newResource);
if (delta) }
adjustSize(newResource->hasClients(), delta);
bool MemoryCache::contains(Resource* resource)
{
if (resource->url().isNull())
return false;
MemoryCacheEntry* entry = m_resources.get(resource->url());
return entry && entry->m_resource == resource;
} }
Resource* MemoryCache::resourceForURL(const KURL& resourceURL) Resource* MemoryCache::resourceForURL(const KURL& resourceURL)
...@@ -242,7 +243,7 @@ void MemoryCache::pruneDeadResources() ...@@ -242,7 +243,7 @@ void MemoryCache::pruneDeadResources()
while (current) { while (current) {
// Protect 'previous' so it can't get deleted during destroyDecodedData(). // Protect 'previous' so it can't get deleted during destroyDecodedData().
MemoryCacheEntry* previous = current->m_previousInAllResourcesList; MemoryCacheEntry* previous = current->m_previousInAllResourcesList;
ASSERT(!previous || previous->m_resource->inCache()); ASSERT(!previous || contains(previous->m_resource.get()));
if (!current->m_resource->hasClients() && !current->m_resource->isPreloaded() && current->m_resource->isLoaded()) { if (!current->m_resource->hasClients() && !current->m_resource->isPreloaded() && current->m_resource->isLoaded()) {
// Destroy our decoded data. This will remove us from // Destroy our decoded data. This will remove us from
// m_liveDecodedResources, and possibly move us to a different // m_liveDecodedResources, and possibly move us to a different
...@@ -254,7 +255,7 @@ void MemoryCache::pruneDeadResources() ...@@ -254,7 +255,7 @@ void MemoryCache::pruneDeadResources()
} }
// Decoded data may reference other resources. Stop iterating if 'previous' somehow got // Decoded data may reference other resources. Stop iterating if 'previous' somehow got
// kicked out of cache during destroyDecodedData(). // kicked out of cache during destroyDecodedData().
if (previous && !previous->m_resource->inCache()) if (previous && !contains(previous->m_resource.get()))
break; break;
current = previous; current = previous;
} }
...@@ -263,13 +264,13 @@ void MemoryCache::pruneDeadResources() ...@@ -263,13 +264,13 @@ void MemoryCache::pruneDeadResources()
current = m_allResources[i].m_tail; current = m_allResources[i].m_tail;
while (current) { while (current) {
MemoryCacheEntry* previous = current->m_previousInAllResourcesList; MemoryCacheEntry* previous = current->m_previousInAllResourcesList;
ASSERT(!previous || previous->m_resource->inCache()); ASSERT(!previous || contains(previous->m_resource.get()));
if (!current->m_resource->hasClients() && !current->m_resource->isPreloaded() && !current->m_resource->isCacheValidator()) { if (!current->m_resource->hasClients() && !current->m_resource->isPreloaded() && !current->m_resource->isCacheValidator()) {
evict(current->m_resource.get()); evict(current->m_resource.get());
if (targetSize && m_deadSize <= targetSize) if (targetSize && m_deadSize <= targetSize)
return; return;
} }
if (previous && !previous->m_resource->inCache()) if (previous && !contains(previous->m_resource.get()))
break; break;
current = previous; current = previous;
} }
...@@ -300,42 +301,28 @@ bool MemoryCache::evict(Resource* resource) ...@@ -300,42 +301,28 @@ bool MemoryCache::evict(Resource* resource)
WTF_LOG(ResourceLoading, "Evicting resource %p for '%s' from cache", resource, resource->url().string().latin1().data()); WTF_LOG(ResourceLoading, "Evicting resource %p for '%s' from cache", resource, resource->url().string().latin1().data());
// The resource may have already been removed by someone other than our caller, // 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>. // who needed a fresh copy for a reload. See <http://bugs.webkit.org/show_bug.cgi?id=12479#c6>.
if (resource->inCache()) { if (contains(resource)) {
// Remove from the appropriate LRU list. update(resource, resource->size(), 0, false);
removeFromLRUList(resource);
removeFromLiveDecodedResourcesList(resource); removeFromLiveDecodedResourcesList(resource);
adjustSize(resource->hasClients(), -static_cast<ptrdiff_t>(resource->size()));
// Remove from the resource map. // Remove from the resource map.
m_resources.remove(resource->url()); m_resources.remove(resource->url());
resource->setInCache(false);
} else {
ASSERT(!m_resources.get(resource->url()) || m_resources.get(resource->url())->m_resource != resource);
} }
return resource->deleteIfPossible(); return resource->deleteIfPossible();
} }
MemoryCache::LRUList* MemoryCache::lruListFor(MemoryCacheEntry* entry) MemoryCache::LRUList* MemoryCache::lruListFor(unsigned accessCount, size_t size)
{ {
unsigned accessCount = std::max(entry->m_resource->accessCount(), 1U); ASSERT(accessCount > 0);
unsigned queueIndex = WTF::fastLog2(entry->m_resource->size() / accessCount); unsigned queueIndex = WTF::fastLog2(size / accessCount);
if (m_allResources.size() <= queueIndex) if (m_allResources.size() <= queueIndex)
m_allResources.grow(queueIndex + 1); m_allResources.grow(queueIndex + 1);
return &m_allResources[queueIndex]; return &m_allResources[queueIndex];
} }
void MemoryCache::removeFromLRUList(Resource* resource) void MemoryCache::removeFromLRUList(MemoryCacheEntry* entry, LRUList* list)
{ {
MemoryCacheEntry* entry = m_resources.get(resource->url());
ASSERT(entry->m_resource == resource);
LRUList* list = lruListFor(entry);
MemoryCacheEntry* next = entry->m_nextInAllResourcesList;
MemoryCacheEntry* previous = entry->m_previousInAllResourcesList;
if (!next && !previous && list->m_head != entry)
return;
#if !ASSERT_DISABLED #if !ASSERT_DISABLED
// Verify that we are in fact in this list. // Verify that we are in fact in this list.
bool found = false; bool found = false;
...@@ -348,6 +335,8 @@ void MemoryCache::removeFromLRUList(Resource* resource) ...@@ -348,6 +335,8 @@ void MemoryCache::removeFromLRUList(Resource* resource)
ASSERT(found); ASSERT(found);
#endif #endif
MemoryCacheEntry* next = entry->m_nextInAllResourcesList;
MemoryCacheEntry* previous = entry->m_previousInAllResourcesList;
entry->m_nextInAllResourcesList = 0; entry->m_nextInAllResourcesList = 0;
entry->m_previousInAllResourcesList = 0; entry->m_previousInAllResourcesList = 0;
...@@ -362,28 +351,20 @@ void MemoryCache::removeFromLRUList(Resource* resource) ...@@ -362,28 +351,20 @@ void MemoryCache::removeFromLRUList(Resource* resource)
list->m_head = next; list->m_head = next;
} }
void MemoryCache::insertInLRUList(Resource* resource) void MemoryCache::insertInLRUList(MemoryCacheEntry* entry, LRUList* list)
{ {
MemoryCacheEntry* entry = m_resources.get(resource->url());
ASSERT(entry->m_resource == resource);
// Make sure we aren't in some list already.
ASSERT(!entry->m_nextInAllResourcesList && !entry->m_previousInAllResourcesList); ASSERT(!entry->m_nextInAllResourcesList && !entry->m_previousInAllResourcesList);
ASSERT(resource->inCache());
LRUList* list = lruListFor(entry);
entry->m_nextInAllResourcesList = list->m_head; entry->m_nextInAllResourcesList = list->m_head;
if (list->m_head)
list->m_head->m_previousInAllResourcesList = entry;
list->m_head = entry; list->m_head = entry;
if (!entry->m_nextInAllResourcesList) if (entry->m_nextInAllResourcesList)
entry->m_nextInAllResourcesList->m_previousInAllResourcesList = entry;
else
list->m_tail = entry; list->m_tail = entry;
#if !ASSERT_DISABLED #if !ASSERT_DISABLED
// Verify that we are in now in the list like we should be. // Verify that we are in now in the list like we should be.
list = lruListFor(entry);
bool found = false; bool found = false;
for (MemoryCacheEntry* current = list->m_head; current; current = current->m_nextInAllResourcesList) { for (MemoryCacheEntry* current = list->m_head; current; current = current->m_nextInAllResourcesList) {
if (current == entry) { if (current == entry) {
...@@ -470,8 +451,8 @@ void MemoryCache::insertInLiveDecodedResourcesList(Resource* resource) ...@@ -470,8 +451,8 @@ void MemoryCache::insertInLiveDecodedResourcesList(Resource* resource)
bool MemoryCache::isInLiveDecodedResourcesList(Resource* resource) bool MemoryCache::isInLiveDecodedResourcesList(Resource* resource)
{ {
MemoryCacheEntry* entry = m_resources.get(resource->url()); MemoryCacheEntry* entry = m_resources.get(resource->url());
ASSERT(entry->m_resource == resource); ASSERT(entry && entry->m_resource == resource);
return entry ? entry->m_inLiveDecodedResourcesList : false; return entry->m_inLiveDecodedResourcesList;
} }
void MemoryCache::addToLiveResourcesSize(Resource* resource) void MemoryCache::addToLiveResourcesSize(Resource* resource)
...@@ -488,9 +469,22 @@ void MemoryCache::removeFromLiveResourcesSize(Resource* resource) ...@@ -488,9 +469,22 @@ void MemoryCache::removeFromLiveResourcesSize(Resource* resource)
m_deadSize += resource->size(); m_deadSize += resource->size();
} }
void MemoryCache::adjustSize(bool live, ptrdiff_t delta) void MemoryCache::update(Resource* resource, size_t oldSize, size_t newSize, bool wasAccessed)
{ {
if (live) { ASSERT(contains(resource));
MemoryCacheEntry* entry = m_resources.get(resource->url());
// 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->hasClients()) {
ASSERT(delta >= 0 || m_liveSize >= static_cast<size_t>(-delta) ); ASSERT(delta >= 0 || m_liveSize >= static_cast<size_t>(-delta) );
m_liveSize += delta; m_liveSize += delta;
} else { } else {
......
...@@ -72,6 +72,7 @@ public: ...@@ -72,6 +72,7 @@ public:
ResourcePtr<Resource> m_resource; ResourcePtr<Resource> m_resource;
bool m_inLiveDecodedResourcesList; bool m_inLiveDecodedResourcesList;
unsigned m_accessCount;
MemoryCacheEntry* m_previousInLiveResourcesList; MemoryCacheEntry* m_previousInLiveResourcesList;
MemoryCacheEntry* m_nextInLiveResourcesList; MemoryCacheEntry* m_nextInLiveResourcesList;
...@@ -82,6 +83,7 @@ public: ...@@ -82,6 +83,7 @@ public:
MemoryCacheEntry(Resource* resource) MemoryCacheEntry(Resource* resource)
: m_resource(resource) : m_resource(resource)
, m_inLiveDecodedResourcesList(false) , m_inLiveDecodedResourcesList(false)
, m_accessCount(0)
, m_previousInLiveResourcesList(0) , m_previousInLiveResourcesList(0)
, m_nextInLiveResourcesList(0) , m_nextInLiveResourcesList(0)
, m_previousInAllResourcesList(0) , m_previousInAllResourcesList(0)
...@@ -135,6 +137,7 @@ public: ...@@ -135,6 +137,7 @@ public:
void add(Resource*); void add(Resource*);
void replace(Resource* newResource, Resource* oldResource); void replace(Resource* newResource, Resource* oldResource);
void remove(Resource* resource) { evict(resource); } void remove(Resource* resource) { evict(resource); }
bool contains(Resource*);
static KURL removeFragmentIdentifierIfNeeded(const KURL& originalURL); static KURL removeFragmentIdentifierIfNeeded(const KURL& originalURL);
...@@ -151,12 +154,9 @@ public: ...@@ -151,12 +154,9 @@ public:
void prune(Resource* justReleasedResource = 0); void prune(Resource* justReleasedResource = 0);
// Calls to put the cached resource into and out of LRU lists. // Called to adjust a resource's size, lru list position, and access count.
void insertInLRUList(Resource*); void update(Resource*, size_t oldSize, size_t newSize, bool wasAccessed = false);
void removeFromLRUList(Resource*); void updateForAccess(Resource* resource) { update(resource, resource->size(), resource->size(), true); }
// Called to adjust the cache totals when a resource changes size.
void adjustSize(bool live, ptrdiff_t delta);
// Track decoded resources that are in the cache and referenced by a Web page. // Track decoded resources that are in the cache and referenced by a Web page.
void insertInLiveDecodedResourcesList(Resource*); void insertInLiveDecodedResourcesList(Resource*);
...@@ -181,13 +181,17 @@ public: ...@@ -181,13 +181,17 @@ public:
virtual void didProcessTask() OVERRIDE; virtual void didProcessTask() OVERRIDE;
private: private:
LRUList* lruListFor(MemoryCacheEntry*); LRUList* lruListFor(unsigned accessCount, size_t);
#ifdef MEMORY_CACHE_STATS #ifdef MEMORY_CACHE_STATS
void dumpStats(Timer<MemoryCache>*); void dumpStats(Timer<MemoryCache>*);
void dumpLRULists(bool includeLive) const; void dumpLRULists(bool includeLive) const;
#endif #endif
// Calls to put the cached resource into and out of LRU lists.
void insertInLRUList(MemoryCacheEntry*, LRUList*);
void removeFromLRUList(MemoryCacheEntry*, LRUList*);
size_t liveCapacity() const; size_t liveCapacity() const;
size_t deadCapacity() const; size_t deadCapacity() const;
......
...@@ -287,8 +287,8 @@ TEST_F(MemoryCacheTest, ClientRemoval) ...@@ -287,8 +287,8 @@ TEST_F(MemoryCacheTest, ClientRemoval)
ASSERT_GT(resource2->decodedSize(), 0u); ASSERT_GT(resource2->decodedSize(), 0u);
ASSERT_EQ(memoryCache()->deadSize(), resource1->size()); ASSERT_EQ(memoryCache()->deadSize(), resource1->size());
ASSERT_EQ(memoryCache()->liveSize(), resource2->size()); ASSERT_EQ(memoryCache()->liveSize(), resource2->size());
ASSERT_TRUE(resource1->inCache()); ASSERT_TRUE(memoryCache()->contains(resource1.get()));
ASSERT_TRUE(resource2->inCache()); ASSERT_TRUE(memoryCache()->contains(resource2.get()));
// Removing the client from resource2 should result in immediate // Removing the client from resource2 should result in immediate
// eviction of resource2 because we are over the prune deferral limit. // eviction of resource2 because we are over the prune deferral limit.
...@@ -297,8 +297,8 @@ TEST_F(MemoryCacheTest, ClientRemoval) ...@@ -297,8 +297,8 @@ TEST_F(MemoryCacheTest, ClientRemoval)
ASSERT_GT(resource2->decodedSize(), 0u); ASSERT_GT(resource2->decodedSize(), 0u);
ASSERT_EQ(memoryCache()->deadSize(), resource1->size()); ASSERT_EQ(memoryCache()->deadSize(), resource1->size());
ASSERT_EQ(memoryCache()->liveSize(), 0u); ASSERT_EQ(memoryCache()->liveSize(), 0u);
ASSERT_TRUE(resource1->inCache()); ASSERT_TRUE(memoryCache()->contains(resource1.get()));
ASSERT_FALSE(resource2->inCache()); ASSERT_FALSE(memoryCache()->contains(resource2.get()));
} }
// Verifies that CachedResources are evicted from the decode cache // Verifies that CachedResources are evicted from the decode cache
...@@ -371,19 +371,16 @@ TEST_F(MemoryCacheTest, MultipleReplace) ...@@ -371,19 +371,16 @@ TEST_F(MemoryCacheTest, MultipleReplace)
{ {
ResourcePtr<FakeResource> resource1 = new FakeResource(ResourceRequest(""), Resource::Raw); ResourcePtr<FakeResource> resource1 = new FakeResource(ResourceRequest(""), Resource::Raw);
memoryCache()->add(resource1.get()); memoryCache()->add(resource1.get());
EXPECT_EQ(1U, resource1->accessCount());
ResourcePtr<FakeResource> resource2 = new FakeResource(ResourceRequest(""), Resource::Raw); ResourcePtr<FakeResource> resource2 = new FakeResource(ResourceRequest(""), Resource::Raw);
memoryCache()->replace(resource2.get(), resource1.get()); memoryCache()->replace(resource2.get(), resource1.get());
EXPECT_TRUE(resource2->inCache()); EXPECT_TRUE(memoryCache()->contains(resource2.get()));
EXPECT_FALSE(resource1->inCache()); EXPECT_FALSE(memoryCache()->contains(resource1.get()));
EXPECT_EQ(0U, resource2->accessCount());
ResourcePtr<FakeResource> resource3 = new FakeResource(ResourceRequest(""), Resource::Raw); ResourcePtr<FakeResource> resource3 = new FakeResource(ResourceRequest(""), Resource::Raw);
memoryCache()->replace(resource3.get(), resource2.get()); memoryCache()->replace(resource3.get(), resource2.get());
EXPECT_TRUE(resource3->inCache()); EXPECT_TRUE(memoryCache()->contains(resource3.get()));
EXPECT_FALSE(resource2->inCache()); EXPECT_FALSE(memoryCache()->contains(resource2.get()));
EXPECT_EQ(0U, resource3->accessCount());
} }
} // namespace } // namespace
...@@ -102,14 +102,12 @@ Resource::Resource(const ResourceRequest& request, Type type) ...@@ -102,14 +102,12 @@ Resource::Resource(const ResourceRequest& request, Type type)
, m_identifier(0) , m_identifier(0)
, m_encodedSize(0) , m_encodedSize(0)
, m_decodedSize(0) , m_decodedSize(0)
, m_accessCount(0)
, m_handleCount(0) , m_handleCount(0)
, m_preloadCount(0) , m_preloadCount(0)
, m_protectorCount(0) , m_protectorCount(0)
, m_preloadResult(PreloadNotReferenced) , m_preloadResult(PreloadNotReferenced)
, m_cacheLiveResourcePriority(CacheLiveResourcePriorityLow) , m_cacheLiveResourcePriority(CacheLiveResourcePriorityLow)
, m_requestedFromNetworkingLayer(false) , m_requestedFromNetworkingLayer(false)
, m_inCache(false)
, m_loading(false) , m_loading(false)
, m_switchingClientsToRevalidatedResource(false) , m_switchingClientsToRevalidatedResource(false)
, m_type(type) , m_type(type)
...@@ -140,7 +138,7 @@ Resource::~Resource() ...@@ -140,7 +138,7 @@ Resource::~Resource()
{ {
ASSERT(!m_resourceToRevalidate); // Should be true because canDelete() checks this. ASSERT(!m_resourceToRevalidate); // Should be true because canDelete() checks this.
ASSERT(canDelete()); ASSERT(canDelete());
RELEASE_ASSERT(!inCache()); RELEASE_ASSERT(!memoryCache()->contains(this));
RELEASE_ASSERT(!ResourceCallback::callbackHandler()->isScheduled(this)); RELEASE_ASSERT(!ResourceCallback::callbackHandler()->isScheduled(this));
ASSERT(!m_deleted); ASSERT(!m_deleted);
ASSERT(url().isNull() || memoryCache()->resourceForURL(KURL(ParsedURLString, url())) != this); ASSERT(url().isNull() || memoryCache()->resourceForURL(KURL(ParsedURLString, url())) != this);
...@@ -357,7 +355,7 @@ bool Resource::unlock() ...@@ -357,7 +355,7 @@ bool Resource::unlock()
if (!m_data->isLocked()) if (!m_data->isLocked())
return true; return true;
if (!inCache() || hasClients() || m_handleCount > 1 || m_proxyResource || m_resourceToRevalidate || !m_loadFinishTime || !isSafeToUnlock()) if (!memoryCache()->contains(this) || hasClients() || m_handleCount > 1 || m_proxyResource || m_resourceToRevalidate || !m_loadFinishTime || !isSafeToUnlock())
return false; return false;
m_data->unlock(); m_data->unlock();
...@@ -412,7 +410,7 @@ CachedMetadata* Resource::cachedMetadata(unsigned dataTypeID) const ...@@ -412,7 +410,7 @@ CachedMetadata* Resource::cachedMetadata(unsigned dataTypeID) const
void Resource::setCacheLiveResourcePriority(CacheLiveResourcePriority priority) void Resource::setCacheLiveResourcePriority(CacheLiveResourcePriority priority)
{ {
if (inCache() && memoryCache()->isInLiveDecodedResourcesList(this) && cacheLiveResourcePriority() != static_cast<unsigned>(priority)) { if (memoryCache()->contains(this) && memoryCache()->isInLiveDecodedResourcesList(this) && cacheLiveResourcePriority() != static_cast<unsigned>(priority)) {
memoryCache()->removeFromLiveDecodedResourcesList(this); memoryCache()->removeFromLiveDecodedResourcesList(this);
m_cacheLiveResourcePriority = priority; m_cacheLiveResourcePriority = priority;
memoryCache()->insertInLiveDecodedResourcesList(this); memoryCache()->insertInLiveDecodedResourcesList(this);
...@@ -468,7 +466,7 @@ bool Resource::addClientToSet(ResourceClient* client) ...@@ -468,7 +466,7 @@ bool Resource::addClientToSet(ResourceClient* client)
else else
m_preloadResult = PreloadReferenced; m_preloadResult = PreloadReferenced;
} }
if (!hasClients() && inCache()) if (!hasClients() && memoryCache()->contains(this))
memoryCache()->addToLiveResourcesSize(this); memoryCache()->addToLiveResourcesSize(this);
// If we have existing data to send to the new client and the resource type supprts it, send it asynchronously. // If we have existing data to send to the new client and the resource type supprts it, send it asynchronously.
...@@ -497,7 +495,7 @@ void Resource::removeClient(ResourceClient* client) ...@@ -497,7 +495,7 @@ void Resource::removeClient(ResourceClient* client)
bool deleted = deleteIfPossible(); bool deleted = deleteIfPossible();
if (!deleted && !hasClients()) { if (!deleted && !hasClients()) {
if (inCache()) { if (memoryCache()->contains(this)) {
memoryCache()->removeFromLiveResourcesSize(this); memoryCache()->removeFromLiveResourcesSize(this);
memoryCache()->removeFromLiveDecodedResourcesList(this); memoryCache()->removeFromLiveDecodedResourcesList(this);
} }
...@@ -543,7 +541,7 @@ void Resource::cancelTimerFired(Timer<Resource>* timer) ...@@ -543,7 +541,7 @@ void Resource::cancelTimerFired(Timer<Resource>* timer)
bool Resource::deleteIfPossible() bool Resource::deleteIfPossible()
{ {
if (canDelete() && !inCache()) { if (canDelete() && !memoryCache()->contains(this)) {
InspectorInstrumentation::willDestroyResource(this); InspectorInstrumentation::willDestroyResource(this);
delete this; delete this;
return true; return true;
...@@ -551,25 +549,14 @@ bool Resource::deleteIfPossible() ...@@ -551,25 +549,14 @@ bool Resource::deleteIfPossible()
return false; return false;
} }
void Resource::setDecodedSize(size_t size) void Resource::setDecodedSize(size_t decodedSize)
{ {
if (size == m_decodedSize) if (decodedSize == m_decodedSize)
return; return;
size_t oldSize = size();
m_decodedSize = decodedSize;
ptrdiff_t delta = size - m_decodedSize; if (memoryCache()->contains(this)) {
// The object must now be moved to a different queue, since its size has been changed.
// We have to remove explicitly before updating m_decodedSize, so that we find the correct previous
// queue.
if (inCache())
memoryCache()->removeFromLRUList(this);
m_decodedSize = size;
if (inCache()) {
// Now insert into the new LRU list.
memoryCache()->insertInLRUList(this);
// Insert into or remove from the live decoded list if necessary. // Insert into or remove from the live decoded list if necessary.
// When inserting into the LiveDecodedResourcesList it is possible // When inserting into the LiveDecodedResourcesList it is possible
// that the m_lastDecodedAccessTime is still zero or smaller than // that the m_lastDecodedAccessTime is still zero or smaller than
...@@ -583,38 +570,24 @@ void Resource::setDecodedSize(size_t size) ...@@ -583,38 +570,24 @@ void Resource::setDecodedSize(size_t size)
memoryCache()->removeFromLiveDecodedResourcesList(this); memoryCache()->removeFromLiveDecodedResourcesList(this);
// Update the cache's size totals. // Update the cache's size totals.
memoryCache()->adjustSize(hasClients(), delta); memoryCache()->update(this, oldSize, size());
} }
} }
void Resource::setEncodedSize(size_t size) void Resource::setEncodedSize(size_t encodedSize)
{ {
if (size == m_encodedSize) if (encodedSize == m_encodedSize)
return; return;
size_t oldSize = size();
ptrdiff_t delta = size - m_encodedSize; m_encodedSize = encodedSize;
if (memoryCache()->contains(this))
// The object must now be moved to a different queue, since its size has been changed. memoryCache()->update(this, oldSize, size());
// We have to remove explicitly before updating m_encodedSize, so that we find the correct previous
// queue.
if (inCache())
memoryCache()->removeFromLRUList(this);
m_encodedSize = size;
if (inCache()) {
// Now insert into the new LRU list.
memoryCache()->insertInLRUList(this);
// Update the cache's size totals.
memoryCache()->adjustSize(hasClients(), delta);
}
} }
void Resource::didAccessDecodedData(double timeStamp) void Resource::didAccessDecodedData(double timeStamp)
{ {
m_lastDecodedAccessTime = timeStamp; m_lastDecodedAccessTime = timeStamp;
if (inCache()) { if (memoryCache()->contains(this)) {
if (memoryCache()->isInLiveDecodedResourcesList(this)) { if (memoryCache()->isInLiveDecodedResourcesList(this)) {
memoryCache()->removeFromLiveDecodedResourcesList(this); memoryCache()->removeFromLiveDecodedResourcesList(this);
memoryCache()->insertInLiveDecodedResourcesList(this); memoryCache()->insertInLiveDecodedResourcesList(this);
...@@ -677,8 +650,8 @@ void Resource::clearResourceToRevalidate() ...@@ -677,8 +650,8 @@ void Resource::clearResourceToRevalidate()
void Resource::switchClientsToRevalidatedResource() void Resource::switchClientsToRevalidatedResource()
{ {
ASSERT(m_resourceToRevalidate); ASSERT(m_resourceToRevalidate);
ASSERT(m_resourceToRevalidate->inCache()); ASSERT(memoryCache()->contains(m_resourceToRevalidate));
ASSERT(!inCache()); ASSERT(!memoryCache()->contains(this));
WTF_LOG(ResourceLoading, "Resource %p switchClientsToRevalidatedResource %p", this, m_resourceToRevalidate); WTF_LOG(ResourceLoading, "Resource %p switchClientsToRevalidatedResource %p", this, m_resourceToRevalidate);
...@@ -747,9 +720,9 @@ void Resource::updateResponseAfterRevalidation(const ResourceResponse& validatin ...@@ -747,9 +720,9 @@ void Resource::updateResponseAfterRevalidation(const ResourceResponse& validatin
void Resource::revalidationSucceeded(const ResourceResponse& response) void Resource::revalidationSucceeded(const ResourceResponse& response)
{ {
ASSERT(m_resourceToRevalidate); ASSERT(m_resourceToRevalidate);
ASSERT(!m_resourceToRevalidate->inCache()); ASSERT(!memoryCache()->contains(m_resourceToRevalidate));
ASSERT(m_resourceToRevalidate->isLoaded()); ASSERT(m_resourceToRevalidate->isLoaded());
ASSERT(inCache()); ASSERT(memoryCache()->contains(this));
// Calling evict() can potentially delete revalidatingResource, which we use // Calling evict() can potentially delete revalidatingResource, which we use
// below. This mustn't be the case since revalidation means it is loaded // below. This mustn't be the case since revalidation means it is loaded
...@@ -773,22 +746,6 @@ void Resource::revalidationFailed() ...@@ -773,22 +746,6 @@ void Resource::revalidationFailed()
clearResourceToRevalidate(); clearResourceToRevalidate();
} }
void Resource::updateForAccess()
{
ASSERT(inCache());
// Need to make sure to remove before we increase the access count, since
// the queue will possibly change.
memoryCache()->removeFromLRUList(this);
// If this is the first time the resource has been accessed, adjust the size of the cache to account for its initial size.
if (!m_accessCount)
memoryCache()->adjustSize(hasClients(), size());
m_accessCount++;
memoryCache()->insertInLRUList(this);
}
void Resource::registerHandle(ResourcePtrBase* h) void Resource::registerHandle(ResourcePtrBase* h)
{ {
++m_handleCount; ++m_handleCount;
...@@ -808,7 +765,7 @@ void Resource::unregisterHandle(ResourcePtrBase* h) ...@@ -808,7 +765,7 @@ void Resource::unregisterHandle(ResourcePtrBase* h)
if (deleteIfPossible()) if (deleteIfPossible())
return; return;
unlock(); unlock();
} else if (m_handleCount == 1 && inCache()) { } else if (m_handleCount == 1 && memoryCache()->contains(this)) {
unlock(); unlock();
} }
} }
......
...@@ -160,9 +160,6 @@ public: ...@@ -160,9 +160,6 @@ public:
|| type() == Raw; || type() == Raw;
} }
void updateForAccess();
unsigned accessCount() const { return m_accessCount; }
// Computes the status of an object after loading. // Computes the status of an object after loading.
// Updates the expire date on the cache entry file // Updates the expire date on the cache entry file
void finish(double finishTime = 0.0); void finish(double finishTime = 0.0);
...@@ -171,13 +168,6 @@ public: ...@@ -171,13 +168,6 @@ public:
bool passesAccessControlCheck(SecurityOrigin*); bool passesAccessControlCheck(SecurityOrigin*);
bool passesAccessControlCheck(SecurityOrigin*, String& errorDescription); bool passesAccessControlCheck(SecurityOrigin*, String& errorDescription);
// Called by the cache if the object has been removed from the cache
// while still being referenced. This means the object should delete itself
// if the number of clients observing it ever drops to 0.
// The resource can be brought back to cache after successful revalidation.
void setInCache(bool inCache) { m_inCache = inCache; }
bool inCache() const { return m_inCache; }
void setCacheLiveResourcePriority(CacheLiveResourcePriority); void setCacheLiveResourcePriority(CacheLiveResourcePriority);
unsigned cacheLiveResourcePriority() const { return m_cacheLiveResourcePriority; } unsigned cacheLiveResourcePriority() const { return m_cacheLiveResourcePriority; }
...@@ -358,7 +348,6 @@ private: ...@@ -358,7 +348,6 @@ private:
size_t m_encodedSize; size_t m_encodedSize;
size_t m_decodedSize; size_t m_decodedSize;
unsigned m_accessCount;
unsigned m_handleCount; unsigned m_handleCount;
unsigned m_preloadCount; unsigned m_preloadCount;
unsigned m_protectorCount; unsigned m_protectorCount;
...@@ -367,7 +356,6 @@ private: ...@@ -367,7 +356,6 @@ private:
unsigned m_cacheLiveResourcePriority : 2; // CacheLiveResourcePriority unsigned m_cacheLiveResourcePriority : 2; // CacheLiveResourcePriority
unsigned m_requestedFromNetworkingLayer : 1; unsigned m_requestedFromNetworkingLayer : 1;
unsigned m_inCache : 1;
unsigned m_loading : 1; unsigned m_loading : 1;
unsigned m_switchingClientsToRevalidatedResource : 1; unsigned m_switchingClientsToRevalidatedResource : 1;
......
...@@ -629,7 +629,7 @@ ResourcePtr<Resource> ResourceFetcher::requestResource(Resource::Type type, Fetc ...@@ -629,7 +629,7 @@ ResourcePtr<Resource> ResourceFetcher::requestResource(Resource::Type type, Fetc
resource = revalidateResource(request, resource.get()); resource = revalidateResource(request, resource.get());
break; break;
case Use: case Use:
resource->updateForAccess(); memoryCache()->updateForAccess(resource.get());
notifyLoadedFromMemoryCache(resource.get()); notifyLoadedFromMemoryCache(resource.get());
break; break;
} }
...@@ -653,7 +653,7 @@ ResourcePtr<Resource> ResourceFetcher::requestResource(Resource::Type type, Fetc ...@@ -653,7 +653,7 @@ ResourcePtr<Resource> ResourceFetcher::requestResource(Resource::Type type, Fetc
if (resourceNeedsLoad(resource.get(), request, policy)) { if (resourceNeedsLoad(resource.get(), request, policy)) {
if (!shouldLoadNewResource(type)) { if (!shouldLoadNewResource(type)) {
if (resource->inCache()) if (memoryCache()->contains(resource.get()))
memoryCache()->remove(resource.get()); memoryCache()->remove(resource.get());
return 0; return 0;
} }
...@@ -668,7 +668,7 @@ ResourcePtr<Resource> ResourceFetcher::requestResource(Resource::Type type, Fetc ...@@ -668,7 +668,7 @@ ResourcePtr<Resource> ResourceFetcher::requestResource(Resource::Type type, Fetc
// In that case, the requester should have access to the relevant ResourceError, so // In that case, the requester should have access to the relevant ResourceError, so
// we need to return a non-null Resource. // we need to return a non-null Resource.
if (resource->errorOccurred()) { if (resource->errorOccurred()) {
if (resource->inCache()) if (memoryCache()->contains(resource.get()))
memoryCache()->remove(resource.get()); memoryCache()->remove(resource.get());
return request.options().synchronousPolicy == RequestSynchronously ? resource : 0; return request.options().synchronousPolicy == RequestSynchronously ? resource : 0;
} }
...@@ -774,7 +774,7 @@ void ResourceFetcher::addAdditionalRequestHeaders(ResourceRequest& request, Reso ...@@ -774,7 +774,7 @@ void ResourceFetcher::addAdditionalRequestHeaders(ResourceRequest& request, Reso
ResourcePtr<Resource> ResourceFetcher::revalidateResource(const FetchRequest& request, Resource* resource) ResourcePtr<Resource> ResourceFetcher::revalidateResource(const FetchRequest& request, Resource* resource)
{ {
ASSERT(resource); ASSERT(resource);
ASSERT(resource->inCache()); ASSERT(memoryCache()->contains(resource));
ASSERT(resource->isLoaded()); ASSERT(resource->isLoaded());
ASSERT(resource->canUseCacheValidator()); ASSERT(resource->canUseCacheValidator());
ASSERT(!resource->resourceToRevalidate()); ASSERT(!resource->resourceToRevalidate());
......
...@@ -451,7 +451,6 @@ void XMLDocumentParser::insertErrorMessageBlock() ...@@ -451,7 +451,6 @@ void XMLDocumentParser::insertErrorMessageBlock()
void XMLDocumentParser::notifyFinished(Resource* unusedResource) void XMLDocumentParser::notifyFinished(Resource* unusedResource)
{ {
ASSERT_UNUSED(unusedResource, unusedResource == m_pendingScript); ASSERT_UNUSED(unusedResource, unusedResource == m_pendingScript);
ASSERT(m_pendingScript->accessCount() > 0);
ScriptSourceCode sourceCode(m_pendingScript.get()); ScriptSourceCode sourceCode(m_pendingScript.get());
bool errorOccurred = m_pendingScript->errorOccurred(); bool errorOccurred = m_pendingScript->errorOccurred();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment