15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Copyright (C) 2001 Dirk Mueller (mueller@kde.org) 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Copyright (C) 2002 Waldo Bastian (bastian@kde.org) 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) This library is free software; you can redistribute it and/or 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) modify it under the terms of the GNU Library General Public 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) License as published by the Free Software Foundation; either 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) version 2 of the License, or (at your option) any later version. 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) This library is distributed in the hope that it will be useful, 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) but WITHOUT ANY WARRANTY; without even the implied warranty of 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Library General Public License for more details. 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) You should have received a copy of the GNU Library General Public License 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) along with this library; see the file COPYING.LIB. If not, write to 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Boston, MA 02110-1301, USA. 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)*/ 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 2453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/cache/MemoryCache.h" 2553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <stdio.h> 2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/CrossThreadTask.h" 2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h" 29fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch#include "core/loader/cache/Resource.h" 30fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch#include "core/loader/cache/ResourcePtr.h" 3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/FrameView.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/Logging.h" 33591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/workers/WorkerGlobalScope.h" 3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/workers/WorkerLoaderProxy.h" 3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/workers/WorkerThread.h" 36e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "weborigin/SecurityOrigin.h" 37e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "weborigin/SecurityOriginHash.h" 38521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "wtf/Assertions.h" 39521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "wtf/CurrentTime.h" 40521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "wtf/MathExtras.h" 41521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "wtf/TemporaryChange.h" 42521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "wtf/text/CString.h" 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace std; 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 48521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)static MemoryCache* gMemoryCache; 49521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const int cDefaultCacheCapacity = 8192 * 1024; 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const double cMinDelayBeforeLiveDecodedPrune = 1; // Seconds. 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const float cTargetPrunePercentage = .95f; // Percentage of capacity toward which we prune, to avoid immediately pruning again. 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)MemoryCache* memoryCache() 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(WTF::isMainThread()); 57521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (!gMemoryCache) 58521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) gMemoryCache = new MemoryCache(); 59521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return gMemoryCache; 60521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 62521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void setMemoryCacheForTesting(MemoryCache* memoryCache) 63521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 64521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) gMemoryCache = memoryCache; 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)MemoryCache::MemoryCache() 6893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) : m_inPruneResources(false) 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_capacity(cDefaultCacheCapacity) 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_minDeadCapacity(0) 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_maxDeadCapacity(cDefaultCacheCapacity) 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_liveSize(0) 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_deadSize(0) 741fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch , m_delayBeforeLiveDecodedPrune(cMinDelayBeforeLiveDecodedPrune) 755267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#ifdef MEMORY_CACHE_STATS 765267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) , m_statsTimer(this, &MemoryCache::dumpStats) 775267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#endif 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 795267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#ifdef MEMORY_CACHE_STATS 805267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) const double statsIntervalInSeconds = 15; 815267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) m_statsTimer.startRepeating(statsIntervalInSeconds); 825267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#endif 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)KURL MemoryCache::removeFragmentIdentifierIfNeeded(const KURL& originalURL) 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!originalURL.hasFragmentIdentifier()) 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return originalURL; 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Strip away fragment identifier from HTTP URLs. 9002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // Data URLs must be unmodified. For file and custom URLs clients may expect resources 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // to be unique even when they differ by the fragment identifier only. 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!originalURL.protocolIsInHTTPFamily()) 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return originalURL; 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) KURL url = originalURL; 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) url.removeFragmentIdentifier(); 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return url; 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 99fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdochvoid MemoryCache::add(Resource* resource) 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(WTF::isMainThread()); 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_resources.set(resource->url(), resource); 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) resource->setInCache(true); 10493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) resource->updateForAccess(); 10502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LOG(ResourceLoading, "MemoryCache::add Added '%s', resource %p\n", resource->url().string().latin1().data(), resource); 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 109fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdochvoid MemoryCache::replace(Resource* newResource, Resource* oldResource) 110e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch{ 111e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch evict(oldResource); 112e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch ASSERT(!m_resources.get(newResource->url())); 113e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch m_resources.set(newResource->url(), newResource); 114e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch newResource->setInCache(true); 115e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch insertInLRUList(newResource); 116e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch int delta = newResource->size(); 117e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (newResource->decodedSize() && newResource->hasClients()) 118e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch insertInLiveDecodedResourcesList(newResource); 119e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (delta) 120e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch adjustSize(newResource->hasClients(), delta); 121e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch} 122e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 123fff8884795cb540f87cf6e6d67b629519b00eb8bBen MurdochResource* MemoryCache::resourceForURL(const KURL& resourceURL) 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(WTF::isMainThread()); 12653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) KURL url = removeFragmentIdentifierIfNeeded(resourceURL); 127fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch Resource* resource = m_resources.get(url); 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (resource && !resource->makePurgeable(false)) { 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!resource->hasClients()); 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) evict(resource); 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return resource; 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdochunsigned MemoryCache::deadCapacity() const 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Dead resource capacity is whatever space is not occupied by live resources, bounded by an independent minimum and maximum. 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned capacity = m_capacity - min(m_liveSize, m_capacity); // Start with available capacity. 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) capacity = max(capacity, m_minDeadCapacity); // Make sure it's above the minimum. 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) capacity = min(capacity, m_maxDeadCapacity); // Make sure it's below the maximum. 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return capacity; 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdochunsigned MemoryCache::liveCapacity() const 14602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch{ 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Live resource capacity is whatever is left over after calculating dead resource capacity. 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_capacity - deadCapacity(); 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void MemoryCache::pruneLiveResources() 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned capacity = liveCapacity(); 154e6d4491e48613634a83c1957c72759da80987961Ben Murdoch if (!m_liveSize || (capacity && m_liveSize <= capacity)) 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned targetSize = static_cast<unsigned>(capacity * cTargetPrunePercentage); // Cut by a percentage to avoid immediately pruning again. 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double currentTime = FrameView::currentPaintTimeStamp(); 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!currentTime) // In case prune is called directly, outside of a Frame paint. 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currentTime = WTF::currentTime(); 16202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Destroy any decoded data in live objects that we can. 1641fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch // Start from the tail, since this is the lowest priority 1651fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch // and least recently accessed of the objects. 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The list might not be sorted by the m_lastDecodedAccessTime. The impact 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // of this weaker invariant is minor as the below if statement to check the 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // elapsedTime will evaluate to false as the currentTime will be a lot 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // greater than the current->m_lastDecodedAccessTime. 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // For more details see: https://bugs.webkit.org/show_bug.cgi?id=30209 1721fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch 1731fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch // Start pruning from the lowest priority list. 1741fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch for (int priority = Resource::CacheLiveResourcePriorityLow; priority <= Resource::CacheLiveResourcePriorityHigh; ++priority) { 1751fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch Resource* current = m_liveDecodedResources[priority].m_tail; 1761fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch while (current) { 1771fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch Resource* prev = current->m_prevInLiveResourcesList; 1781fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch ASSERT(current->hasClients()); 1791fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch if (current->isLoaded() && current->decodedSize()) { 1801fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch // Check to see if the remaining resources are too new to prune. 1811fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch double elapsedTime = currentTime - current->m_lastDecodedAccessTime; 1821fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch if (elapsedTime < m_delayBeforeLiveDecodedPrune) 1831fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch return; 1841fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch 1851fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch // Destroy our decoded data. This will remove us from 1861fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch // m_liveDecodedResources, and possibly move us to a different LRU 1871fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch // list in m_allResources. 1881fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch current->destroyDecodedData(); 1891fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch 1901fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch if (targetSize && m_liveSize <= targetSize) 1911fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch return; 1921fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch } 1931fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch current = prev; 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void MemoryCache::pruneDeadResources() 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned capacity = deadCapacity(); 201e6d4491e48613634a83c1957c72759da80987961Ben Murdoch if (!m_deadSize || (capacity && m_deadSize <= capacity)) 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned targetSize = static_cast<unsigned>(capacity * cTargetPrunePercentage); // Cut by a percentage to avoid immediately pruning again. 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int size = m_allResources.size(); 20702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // See if we have any purged resources we can evict. 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (int i = 0; i < size; i++) { 210fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch Resource* current = m_allResources[i].m_tail; 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (current) { 212fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch Resource* prev = current->m_prevInAllResourcesList; 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (current->wasPurged()) { 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!current->hasClients()); 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!current->isPreloaded()); 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) evict(current); 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) current = prev; 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (targetSize && m_deadSize <= targetSize) 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool canShrinkLRULists = true; 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (int i = size - 1; i >= 0; i--) { 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Remove from the tail, since this is the least frequently accessed of the objects. 227fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch Resource* current = m_allResources[i].m_tail; 22802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // First flush all the decoded data in this queue. 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (current) { 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Protect 'previous' so it can't get deleted during destroyDecodedData(). 232fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch ResourcePtr<Resource> previous = current->m_prevInAllResourcesList; 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!previous || previous->inCache()); 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!current->hasClients() && !current->isPreloaded() && current->isLoaded()) { 23502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // Destroy our decoded data. This will remove us from 23602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // m_liveDecodedResources, and possibly move us to a different 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // LRU list in m_allResources. 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) current->destroyDecodedData(); 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (targetSize && m_deadSize <= targetSize) 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Decoded data may reference other resources. Stop iterating if 'previous' somehow got 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // kicked out of cache during destroyDecodedData(). 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (previous && !previous->inCache()) 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) current = previous.get(); 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Now evict objects from this queue. 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) current = m_allResources[i].m_tail; 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (current) { 253fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch ResourcePtr<Resource> previous = current->m_prevInAllResourcesList; 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!previous || previous->inCache()); 255521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (!current->hasClients() && !current->isPreloaded() && !current->isCacheValidator()) { 256521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) evict(current); 257521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (targetSize && m_deadSize <= targetSize) 258521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return; 259521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) } 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (previous && !previous->inCache()) 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) current = previous.get(); 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 26402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Shrink the vector back down so we don't waste time inspecting 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // empty LRU lists on future prunes. 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_allResources[i].m_head) 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) canShrinkLRULists = false; 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (canShrinkLRULists) 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_allResources.resize(i); 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void MemoryCache::setCapacities(unsigned minDeadBytes, unsigned maxDeadBytes, unsigned totalBytes) 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(minDeadBytes <= maxDeadBytes); 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(maxDeadBytes <= totalBytes); 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_minDeadCapacity = minDeadBytes; 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_maxDeadCapacity = maxDeadBytes; 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_capacity = totalBytes; 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) prune(); 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 284fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdochvoid MemoryCache::evict(Resource* resource) 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(WTF::isMainThread()); 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LOG(ResourceLoading, "Evicting resource %p for '%s' from cache", resource, resource->url().string().latin1().data()); 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The resource may have already been removed by someone other than our caller, 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // who needed a fresh copy for a reload. See <http://bugs.webkit.org/show_bug.cgi?id=12479#c6>. 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (resource->inCache()) { 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Remove from the resource map. 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_resources.remove(resource->url()); 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) resource->setInCache(false); 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Remove from the appropriate LRU list. 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) removeFromLRUList(resource); 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) removeFromLiveDecodedResourcesList(resource); 298521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) adjustSize(resource->hasClients(), -static_cast<int>(resource->size())); 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_resources.get(resource->url()) != resource); 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) resource->deleteIfPossible(); 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 305fff8884795cb540f87cf6e6d67b629519b00eb8bBen MurdochMemoryCache::LRUList* MemoryCache::lruListFor(Resource* resource) 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned accessCount = max(resource->accessCount(), 1U); 308926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) unsigned queueIndex = WTF::fastLog2(resource->size() / accessCount); 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef NDEBUG 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) resource->m_lruIndex = queueIndex; 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_allResources.size() <= queueIndex) 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_allResources.grow(queueIndex + 1); 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return &m_allResources[queueIndex]; 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 317fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdochvoid MemoryCache::removeFromLRUList(Resource* resource) 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If we've never been accessed, then we're brand new and not in any list. 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (resource->accessCount() == 0) 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if !ASSERT_DISABLED 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned oldListIndex = resource->m_lruIndex; 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LRUList* list = lruListFor(resource); 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if !ASSERT_DISABLED 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Verify that the list we got is the list we want. 3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(resource->m_lruIndex == oldListIndex); 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Verify that we are in fact in this list. 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool found = false; 335fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch for (Resource* current = list->m_head; current; current = current->m_nextInAllResourcesList) { 3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (current == resource) { 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) found = true; 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(found); 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 344fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch Resource* next = resource->m_nextInAllResourcesList; 345fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch Resource* prev = resource->m_prevInAllResourcesList; 34602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (next == 0 && prev == 0 && list->m_head != resource) 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 34902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) resource->m_nextInAllResourcesList = 0; 3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) resource->m_prevInAllResourcesList = 0; 35202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (next) 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next->m_prevInAllResourcesList = prev; 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (list->m_tail == resource) 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) list->m_tail = prev; 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (prev) 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) prev->m_nextInAllResourcesList = next; 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (list->m_head == resource) 3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) list->m_head = next; 3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 364fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdochvoid MemoryCache::insertInLRUList(Resource* resource) 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Make sure we aren't in some list already. 3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!resource->m_nextInAllResourcesList && !resource->m_prevInAllResourcesList); 3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(resource->inCache()); 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(resource->accessCount() > 0); 37002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LRUList* list = lruListFor(resource); 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) resource->m_nextInAllResourcesList = list->m_head; 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (list->m_head) 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) list->m_head->m_prevInAllResourcesList = resource; 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) list->m_head = resource; 37702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!resource->m_nextInAllResourcesList) 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) list->m_tail = resource; 38002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if !ASSERT_DISABLED 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Verify that we are in now in the list like we should be. 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) list = lruListFor(resource); 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool found = false; 385fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch for (Resource* current = list->m_head; current; current = current->m_nextInAllResourcesList) { 3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (current == resource) { 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) found = true; 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(found); 3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 396fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdochvoid MemoryCache::removeFromLiveDecodedResourcesList(Resource* resource) 3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If we've never been accessed, then we're brand new and not in any list. 3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!resource->m_inLiveDecodedResourcesList) 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) resource->m_inLiveDecodedResourcesList = false; 4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4031fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch LRUList* list = &m_liveDecodedResources[resource->cacheLiveResourcePriority()]; 4041fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch 4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if !ASSERT_DISABLED 4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Verify that we are in fact in this list. 4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool found = false; 4081fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch for (Resource* current = list->m_head; current; current = current->m_nextInLiveResourcesList) { 4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (current == resource) { 4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) found = true; 4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(found); 4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 417fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch Resource* next = resource->m_nextInLiveResourcesList; 418fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch Resource* prev = resource->m_prevInLiveResourcesList; 41902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4201fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch if (!next && !prev && list->m_head != resource) 4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 42202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) resource->m_nextInLiveResourcesList = 0; 4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) resource->m_prevInLiveResourcesList = 0; 42502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (next) 4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next->m_prevInLiveResourcesList = prev; 4281fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch else if (list->m_tail == resource) 4291fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch list->m_tail = prev; 4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (prev) 4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) prev->m_nextInLiveResourcesList = next; 4331fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch else if (list->m_head == resource) 4341fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch list->m_head = next; 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 437fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdochvoid MemoryCache::insertInLiveDecodedResourcesList(Resource* resource) 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Make sure we aren't in the list already. 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!resource->m_nextInLiveResourcesList && !resource->m_prevInLiveResourcesList && !resource->m_inLiveDecodedResourcesList); 4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) resource->m_inLiveDecodedResourcesList = true; 4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4431fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch LRUList* list = &m_liveDecodedResources[resource->cacheLiveResourcePriority()]; 4441fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch resource->m_nextInLiveResourcesList = list->m_head; 4451fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch if (list->m_head) 4461fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch list->m_head->m_prevInLiveResourcesList = resource; 4471fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch list->m_head = resource; 44802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!resource->m_nextInLiveResourcesList) 4501fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch list->m_tail = resource; 45102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if !ASSERT_DISABLED 4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Verify that we are in now in the list like we should be. 4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool found = false; 4551fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch for (Resource* current = list->m_head; current; current = current->m_nextInLiveResourcesList) { 4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (current == resource) { 4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) found = true; 4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(found); 4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 466fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdochvoid MemoryCache::addToLiveResourcesSize(Resource* resource) 4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_liveSize += resource->size(); 4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_deadSize -= resource->size(); 4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 472fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdochvoid MemoryCache::removeFromLiveResourcesSize(Resource* resource) 4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_liveSize -= resource->size(); 4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_deadSize += resource->size(); 4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void MemoryCache::adjustSize(bool live, int delta) 4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (live) { 4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(delta >= 0 || ((int)m_liveSize + delta >= 0)); 4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_liveSize += delta; 4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(delta >= 0 || ((int)m_deadSize + delta >= 0)); 4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_deadSize += delta; 4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4895267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)void MemoryCache::removeURLFromCache(ScriptExecutionContext* context, const KURL& url) 4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 491591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (context->isWorkerGlobalScope()) { 492591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); 493591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch workerGlobalScope->thread()->workerLoaderProxy().postTaskToLoader(createCallbackTask(&removeURLFromCacheInternal, url)); 4945267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return; 4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4965267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) removeURLFromCacheInternal(context, url); 4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4995267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)void MemoryCache::removeURLFromCacheInternal(ScriptExecutionContext*, const KURL& url) 5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 501fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch if (Resource* resource = memoryCache()->resourceForURL(url)) 50253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) memoryCache()->remove(resource); 503926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 504926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 505fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdochvoid MemoryCache::TypeStatistic::addResource(Resource* o) 5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool purged = o->wasPurged(); 50802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch bool purgeable = o->isPurgeable() && !purged; 5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int pageSize = (o->encodedSize() + o->overheadSize() + 4095) & ~4095; 5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) count++; 5115267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) size += purged ? 0 : o->size(); 5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) liveSize += o->hasClients() ? o->size() : 0; 5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) decodedSize += o->decodedSize(); 5145267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) encodedSize += o->encodedSize(); 5155267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) encodedSizeDuplicatedInDataURLs += o->url().protocolIsData() ? o->encodedSize() : 0; 5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) purgeableSize += purgeable ? pageSize : 0; 5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) purgedSize += purged ? pageSize : 0; 5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)MemoryCache::Statistics MemoryCache::getStatistics() 5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Statistics stats; 523fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch ResourceMap::iterator e = m_resources.end(); 524fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch for (ResourceMap::iterator i = m_resources.begin(); i != e; ++i) { 525fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch Resource* resource = i->value; 52653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) switch (resource->type()) { 527e6d4491e48613634a83c1957c72759da80987961Ben Murdoch case Resource::Image: 52853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) stats.images.addResource(resource); 52953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) break; 530fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch case Resource::CSSStyleSheet: 53153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) stats.cssStyleSheets.addResource(resource); 53253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) break; 533fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch case Resource::Script: 53453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) stats.scripts.addResource(resource); 53553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) break; 536fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch case Resource::XSLStyleSheet: 53753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) stats.xslStyleSheets.addResource(resource); 53853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) break; 539e6d4491e48613634a83c1957c72759da80987961Ben Murdoch case Resource::Font: 54053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) stats.fonts.addResource(resource); 54153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) break; 54253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) default: 543521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) stats.other.addResource(resource); 54453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) break; 5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return stats; 5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 55093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void MemoryCache::evictResources() 5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (;;) { 553fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch ResourceMap::iterator i = m_resources.begin(); 55453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (i == m_resources.end()) 5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 55653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) evict(i->value); 5575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void MemoryCache::prune() 5615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_liveSize + m_deadSize <= m_capacity && m_maxDeadCapacity && m_deadSize <= m_maxDeadCapacity) // Fast path. 5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 564e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (m_inPruneResources) 565e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return; 566e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch TemporaryChange<bool> reentrancyProtector(m_inPruneResources, true); 567e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) pruneDeadResources(); // Prune dead first, in case it was "borrowing" capacity from live. 5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) pruneLiveResources(); 5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5735267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#ifdef MEMORY_CACHE_STATS 5745267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 5755267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)void MemoryCache::dumpStats(Timer<MemoryCache>*) 5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Statistics s = getStatistics(); 5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) printf("%-13s %-13s %-13s %-13s %-13s %-13s %-13s\n", "", "Count", "Size", "LiveSize", "DecodedSize", "PurgeableSize", "PurgedSize"); 5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) printf("%-13s %-13s %-13s %-13s %-13s %-13s %-13s\n", "-------------", "-------------", "-------------", "-------------", "-------------", "-------------", "-------------"); 5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 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); 5815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) printf("%-13s %13d %13d %13d %13d %13d %13d\n", "CSS", s.cssStyleSheets.count, s.cssStyleSheets.size, s.cssStyleSheets.liveSize, s.cssStyleSheets.decodedSize, s.cssStyleSheets.purgeableSize, s.cssStyleSheets.purgedSize); 5825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) printf("%-13s %13d %13d %13d %13d %13d %13d\n", "XSL", s.xslStyleSheets.count, s.xslStyleSheets.size, s.xslStyleSheets.liveSize, s.xslStyleSheets.decodedSize, s.xslStyleSheets.purgeableSize, s.xslStyleSheets.purgedSize); 5835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) printf("%-13s %13d %13d %13d %13d %13d %13d\n", "JavaScript", s.scripts.count, s.scripts.size, s.scripts.liveSize, s.scripts.decodedSize, s.scripts.purgeableSize, s.scripts.purgedSize); 5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) printf("%-13s %13d %13d %13d %13d %13d %13d\n", "Fonts", s.fonts.count, s.fonts.size, s.fonts.liveSize, s.fonts.decodedSize, s.fonts.purgeableSize, s.fonts.purgedSize); 585521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) printf("%-13s %13d %13d %13d %13d %13d %13d\n", "Other", s.other.count, s.other.size, s.other.liveSize, s.other.decodedSize, s.other.purgeableSize, s.other.purgedSize); 5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) printf("%-13s %-13s %-13s %-13s %-13s %-13s %-13s\n\n", "-------------", "-------------", "-------------", "-------------", "-------------", "-------------", "-------------"); 5875267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 5885267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) printf("Duplication of encoded data from data URLs\n"); 5895267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) printf("%-13s %13d of %13d\n", "Images", s.images.encodedSizeDuplicatedInDataURLs, s.images.encodedSize); 5905267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) printf("%-13s %13d of %13d\n", "CSS", s.cssStyleSheets.encodedSizeDuplicatedInDataURLs, s.cssStyleSheets.encodedSize); 5915267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) printf("%-13s %13d of %13d\n", "XSL", s.xslStyleSheets.encodedSizeDuplicatedInDataURLs, s.xslStyleSheets.encodedSize); 5925267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) printf("%-13s %13d of %13d\n", "JavaScript", s.scripts.encodedSizeDuplicatedInDataURLs, s.scripts.encodedSize); 5935267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) printf("%-13s %13d of %13d\n", "Fonts", s.fonts.encodedSizeDuplicatedInDataURLs, s.fonts.encodedSize); 594521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) printf("%-13s %13d of %13d\n", "Other", s.other.encodedSizeDuplicatedInDataURLs, s.other.encodedSize); 5955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void MemoryCache::dumpLRULists(bool includeLive) const 5985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) printf("LRU-SP lists in eviction order (Kilobytes decoded, Kilobytes encoded, Access count, Referenced, isPurgeable, wasPurged):\n"); 6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int size = m_allResources.size(); 6025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (int i = size - 1; i >= 0; i--) { 6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) printf("\n\nList %d: ", i); 604fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch Resource* current = m_allResources[i].m_tail; 6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (current) { 606fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch Resource* prev = current->m_prevInAllResourcesList; 6075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (includeLive || !current->hasClients()) 6085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) printf("(%.1fK, %.1fK, %uA, %dR, %d, %d); ", current->decodedSize() / 1024.0f, (current->encodedSize() + current->overheadSize()) / 1024.0f, current->accessCount(), current->hasClients(), current->isPurgeable(), current->wasPurged()); 6095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) current = prev; 6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6145267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 6155267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#endif // MEMORY_CACHE_STATS 6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore 618