summaryrefslogtreecommitdiffstats
path: root/WebCore/loader/Cache.cpp
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-05 14:34:32 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-05 14:34:32 -0800
commit635860845790a19bf50bbc51ba8fb66a96dde068 (patch)
treeef6ad9ff73a5b57f65249d4232a202fa77e6a140 /WebCore/loader/Cache.cpp
parent8e35f3cfc7fba1d1c829dc557ebad6409cbe16a2 (diff)
downloadexternal_webkit-635860845790a19bf50bbc51ba8fb66a96dde068.zip
external_webkit-635860845790a19bf50bbc51ba8fb66a96dde068.tar.gz
external_webkit-635860845790a19bf50bbc51ba8fb66a96dde068.tar.bz2
auto import from //depot/cupcake/@136594
Diffstat (limited to 'WebCore/loader/Cache.cpp')
-rw-r--r--WebCore/loader/Cache.cpp183
1 files changed, 108 insertions, 75 deletions
diff --git a/WebCore/loader/Cache.cpp b/WebCore/loader/Cache.cpp
index 7d30e5f..212fca3 100644
--- a/WebCore/loader/Cache.cpp
+++ b/WebCore/loader/Cache.cpp
@@ -37,8 +37,8 @@
#include "FrameView.h"
#include "Image.h"
#include "ResourceHandle.h"
-#include "SystemTime.h"
#include <stdio.h>
+#include <wtf/CurrentTime.h>
using namespace std;
@@ -95,7 +95,7 @@ static CachedResource* createResource(CachedResource::Type type, const KURL& url
return 0;
}
-CachedResource* Cache::requestResource(DocLoader* docLoader, CachedResource::Type type, const KURL& url, const String& charset, bool isPreload)
+CachedResource* Cache::requestResource(DocLoader* docLoader, CachedResource::Type type, const KURL& url, const String& charset, bool requestIsPreload)
{
// FIXME: Do we really need to special-case an empty URL?
// Would it be better to just go on with the cache code and let it fail later?
@@ -103,25 +103,19 @@ CachedResource* Cache::requestResource(DocLoader* docLoader, CachedResource::Typ
return 0;
// Look up the resource in our map.
- CachedResource* resource = m_resources.get(url.string());
-
- if (resource) {
- if (isPreload && !resource->isPreloaded())
- return 0;
- if (FrameLoader::restrictAccessToLocal() && !FrameLoader::canLoad(url, String(), docLoader->doc())) {
- Document* doc = docLoader->doc();
- if(doc && !isPreload)
- FrameLoader::reportLocalLoadFailed(doc->frame(), resource->url());
- return 0;
- }
- } else {
- if (FrameLoader::restrictAccessToLocal() && !FrameLoader::canLoad(url, String(), docLoader->doc())) {
- Document* doc = docLoader->doc();
- if(doc && !isPreload)
- FrameLoader::reportLocalLoadFailed(doc->frame(), url.string());
- return 0;
- }
-
+ CachedResource* resource = resourceForURL(url.string());
+
+ if (resource && requestIsPreload && !resource->isPreloaded())
+ return 0;
+
+ if (FrameLoader::restrictAccessToLocal() && !FrameLoader::canLoad(url, String(), docLoader->doc())) {
+ Document* doc = docLoader->doc();
+ if (doc && !requestIsPreload)
+ FrameLoader::reportLocalLoadFailed(doc->frame(), url.string());
+ return 0;
+ }
+
+ if (!resource) {
// The resource does not exist. Create it.
resource = createResource(type, url, charset);
ASSERT(resource);
@@ -169,7 +163,7 @@ CachedResource* Cache::requestResource(DocLoader* docLoader, CachedResource::Typ
CachedCSSStyleSheet* Cache::requestUserCSSStyleSheet(DocLoader* docLoader, const String& url, const String& charset)
{
CachedCSSStyleSheet* userSheet;
- if (CachedResource* existing = m_resources.get(url)) {
+ if (CachedResource* existing = resourceForURL(url)) {
if (existing->type() != CachedResource::CSSStyleSheet)
return 0;
userSheet = static_cast<CachedCSSStyleSheet*>(existing);
@@ -248,7 +242,13 @@ void Cache::revalidationFailed(CachedResource* revalidatingResource)
CachedResource* Cache::resourceForURL(const String& url)
{
- return m_resources.get(url);
+ CachedResource* resource = m_resources.get(url);
+ if (resource && !resource->makePurgeable(false)) {
+ ASSERT(!resource->hasClients());
+ evict(resource);
+ return 0;
+ }
+ return resource;
}
unsigned Cache::deadCapacity() const
@@ -278,7 +278,7 @@ void Cache::pruneLiveResources()
unsigned targetSize = static_cast<unsigned>(capacity * cTargetPrunePercentage); // Cut by a percentage to avoid immediately pruning again.
double currentTime = FrameView::currentPaintTimeStamp();
if (!currentTime) // In case prune is called directly, outside of a Frame paint.
- currentTime = WebCore::currentTime();
+ currentTime = WTF::currentTime();
// Destroy any decoded data in live objects that we can.
// Start from the tail, since this is the least recently accessed of the objects.
@@ -315,6 +315,25 @@ void Cache::pruneDeadResources()
unsigned targetSize = static_cast<unsigned>(capacity * cTargetPrunePercentage); // Cut by a percentage to avoid immediately pruning again.
int size = m_allResources.size();
+
+ if (!m_inPruneDeadResources) {
+ // See if we have any purged resources we can evict.
+ for (int i = 0; i < size; i++) {
+ CachedResource* current = m_allResources[i].m_tail;
+ while (current) {
+ CachedResource* prev = current->m_prevInAllResourcesList;
+ if (current->wasPurged()) {
+ ASSERT(!current->hasClients());
+ ASSERT(!current->isPreloaded());
+ evict(current);
+ }
+ current = prev;
+ }
+ }
+ if (targetSize && m_deadSize <= targetSize)
+ return;
+ }
+
bool canShrinkLRULists = true;
m_inPruneDeadResources = true;
for (int i = size - 1; i >= 0; i--) {
@@ -324,7 +343,7 @@ void Cache::pruneDeadResources()
// First flush all the decoded data in this queue.
while (current) {
CachedResource* prev = current->m_prevInAllResourcesList;
- if (!current->hasClients() && !current->isPreloaded() && current->isLoaded() && current->decodedSize()) {
+ if (!current->hasClients() && !current->isPreloaded() && current->isLoaded()) {
// Destroy our decoded data. This will remove us from
// m_liveDecodedResources, and possibly move us to a differnt
// LRU list in m_allResources.
@@ -382,6 +401,15 @@ void Cache::evict(CachedResource* resource)
// 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>.
if (resource->inCache()) {
+ if (!resource->isCacheValidator()) {
+ // Notify all doc loaders that might be observing this object still that it has been
+ // extracted from the set of resources.
+ // No need to do this for cache validator resources, they are replaced automatically by using CachedResourceHandles.
+ HashSet<DocLoader*>::iterator end = m_docLoaders.end();
+ for (HashSet<DocLoader*>::iterator itr = m_docLoaders.begin(); itr != end; ++itr)
+ (*itr)->removeCachedResource(resource);
+ }
+
// Remove from the resource map.
m_resources.remove(resource->url());
resource->setInCache(false);
@@ -389,12 +417,6 @@ void Cache::evict(CachedResource* resource)
// Remove from the appropriate LRU list.
removeFromLRUList(resource);
removeFromLiveDecodedResourcesList(resource);
-
- // Notify all doc loaders that might be observing this object still that it has been
- // extracted from the set of resources.
- HashSet<DocLoader*>::iterator end = m_docLoaders.end();
- for (HashSet<DocLoader*>::iterator itr = m_docLoaders.begin(); itr != end; ++itr)
- (*itr)->removeCachedResource(resource);
// Subtract from our size totals.
int delta = -static_cast<int>(resource->size());
@@ -534,6 +556,10 @@ void Cache::resourceAccessed(CachedResource* resource)
// the queue will possibly change.
removeFromLRUList(resource);
+ // If this is the first time the resource has been accessed, adjust the size of the cache to account for its initial size.
+ if (!resource->accessCount())
+ adjustSize(resource->hasClients(), resource->size());
+
// Add to our access count.
resource->increaseAccessCount();
@@ -631,60 +657,52 @@ void Cache::adjustSize(bool live, int delta)
}
}
+void Cache::TypeStatistic::addResource(CachedResource* o)
+{
+ bool purged = o->wasPurged();
+ bool purgeable = o->isPurgeable() && !purged;
+ int pageSize = (o->encodedSize() + o->overheadSize() + 4095) & ~4095;
+ count++;
+ size += purged ? 0 : o->size();
+ liveSize += o->hasClients() ? o->size() : 0;
+ decodedSize += o->decodedSize();
+ purgeableSize += purgeable ? pageSize : 0;
+ purgedSize += purged ? pageSize : 0;
+}
+
Cache::Statistics Cache::getStatistics()
{
Statistics stats;
CachedResourceMap::iterator e = m_resources.end();
for (CachedResourceMap::iterator i = m_resources.begin(); i != e; ++i) {
- CachedResource *o = i->second;
- switch (o->type()) {
- case CachedResource::ImageResource:
- stats.images.count++;
- stats.images.size += o->size();
- stats.images.liveSize += o->hasClients() ? o->size() : 0;
- stats.images.decodedSize += o->decodedSize();
- break;
-
- case CachedResource::CSSStyleSheet:
- stats.cssStyleSheets.count++;
- stats.cssStyleSheets.size += o->size();
- stats.cssStyleSheets.liveSize += o->hasClients() ? o->size() : 0;
- stats.cssStyleSheets.decodedSize += o->decodedSize();
- break;
-
- case CachedResource::Script:
- stats.scripts.count++;
- stats.scripts.size += o->size();
- stats.scripts.liveSize += o->hasClients() ? o->size() : 0;
- stats.scripts.decodedSize += o->decodedSize();
- break;
+ CachedResource* resource = i->second;
+ switch (resource->type()) {
+ case CachedResource::ImageResource:
+ stats.images.addResource(resource);
+ break;
+ case CachedResource::CSSStyleSheet:
+ stats.cssStyleSheets.addResource(resource);
+ break;
+ case CachedResource::Script:
+ stats.scripts.addResource(resource);
+ break;
#if ENABLE(XSLT)
- case CachedResource::XSLStyleSheet:
- stats.xslStyleSheets.count++;
- stats.xslStyleSheets.size += o->size();
- stats.xslStyleSheets.liveSize += o->hasClients() ? o->size() : 0;
- stats.xslStyleSheets.decodedSize += o->decodedSize();
- break;
+ case CachedResource::XSLStyleSheet:
+ stats.xslStyleSheets.addResource(resource);
+ break;
#endif
- case CachedResource::FontResource:
- stats.fonts.count++;
- stats.fonts.size += o->size();
- stats.fonts.liveSize += o->hasClients() ? o->size() : 0;
- stats.fonts.decodedSize += o->decodedSize();
- break;
+ case CachedResource::FontResource:
+ stats.fonts.addResource(resource);
+ break;
#if ENABLE(XBL)
- case CachedResource::XBL:
- stats.xblDocs.count++;
- stats.xblDocs.size += o->size();
- stats.xblDocs.liveSize += o->hasClients() ? o->size() : 0;
- stats.xblDocs.decodedSize += o->decodedSize();
- break;
+ case CachedResource::XBL:
+ stats.xblDocs.addResource(resource)
+ break;
#endif
- default:
- break;
+ default:
+ break;
}
}
-
return stats;
}
@@ -703,6 +721,21 @@ void Cache::setDisabled(bool disabled)
}
#ifndef NDEBUG
+void Cache::dumpStats()
+{
+ Statistics s = getStatistics();
+ printf("%-11s %-11s %-11s %-11s %-11s %-11s %-11s\n", "", "Count", "Size", "LiveSize", "DecodedSize", "PurgeableSize", "PurgedSize");
+ printf("%-11s %-11s %-11s %-11s %-11s %-11s %-11s\n", "-----------", "-----------", "-----------", "-----------", "-----------", "-----------", "-----------");
+ printf("%-11s %11d %11d %11d %11d %11d %11d\n", "Images", s.images.count, s.images.size, s.images.liveSize, s.images.decodedSize, s.images.purgeableSize, s.images.purgedSize);
+ printf("%-11s %11d %11d %11d %11d %11d %11d\n", "CSS", s.cssStyleSheets.count, s.cssStyleSheets.size, s.cssStyleSheets.liveSize, s.cssStyleSheets.decodedSize, s.cssStyleSheets.purgeableSize, s.cssStyleSheets.purgedSize);
+#if ENABLE(XSLT)
+ printf("%-11s %11d %11d %11d %11d %11d %11d\n", "XSL", s.xslStyleSheets.count, s.xslStyleSheets.size, s.xslStyleSheets.liveSize, s.xslStyleSheets.decodedSize, s.xslStyleSheets.purgeableSize, s.xslStyleSheets.purgedSize);
+#endif
+ printf("%-11s %11d %11d %11d %11d %11d %11d\n", "JavaScript", s.scripts.count, s.scripts.size, s.scripts.liveSize, s.scripts.decodedSize, s.scripts.purgeableSize, s.scripts.purgedSize);
+ printf("%-11s %11d %11d %11d %11d %11d %11d\n", "Fonts", s.fonts.count, s.fonts.size, s.fonts.liveSize, s.fonts.decodedSize, s.fonts.purgeableSize, s.fonts.purgedSize);
+ printf("%-11s %-11s %-11s %-11s %-11s %-11s %-11s\n\n", "-----------", "-----------", "-----------", "-----------", "-----------", "-----------", "-----------");
+}
+
void Cache::dumpLRULists(bool includeLive) const
{
printf("LRU-SP lists in eviction order (Kilobytes decoded, Kilobytes encoded, Access count, Referenced):\n");
@@ -714,7 +747,7 @@ void Cache::dumpLRULists(bool includeLive) const
while (current) {
CachedResource* prev = current->m_prevInAllResourcesList;
if (includeLive || !current->hasClients())
- printf("(%.1fK, %.1fK, %uA, %dR); ", current->decodedSize() / 1024.0f, current->encodedSize() / 1024.0f, current->accessCount(), current->hasClients());
+ printf("(%.1fK, %.1fK, %uA, %dR); ", current->decodedSize() / 1024.0f, (current->encodedSize() + current->overheadSize()) / 1024.0f, current->accessCount(), current->hasClients());
current = prev;
}
}