summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/loader/cache
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/loader/cache')
-rw-r--r--Source/WebCore/loader/cache/CachedImage.cpp15
-rw-r--r--Source/WebCore/loader/cache/CachedImage.h2
-rw-r--r--Source/WebCore/loader/cache/CachedResourceLoader.cpp21
-rw-r--r--Source/WebCore/loader/cache/CachedResourceLoader.h3
-rw-r--r--Source/WebCore/loader/cache/CachedResourceRequest.cpp2
-rw-r--r--Source/WebCore/loader/cache/CachedResourceRequest.h2
-rw-r--r--Source/WebCore/loader/cache/MemoryCache.cpp35
-rw-r--r--Source/WebCore/loader/cache/MemoryCache.h9
8 files changed, 85 insertions, 4 deletions
diff --git a/Source/WebCore/loader/cache/CachedImage.cpp b/Source/WebCore/loader/cache/CachedImage.cpp
index 057b8ea..b309ae6 100644
--- a/Source/WebCore/loader/cache/CachedImage.cpp
+++ b/Source/WebCore/loader/cache/CachedImage.cpp
@@ -31,6 +31,7 @@
#include "CachedResourceLoader.h"
#include "CachedResourceRequest.h"
#include "Frame.h"
+#include "FrameLoaderClient.h"
#include "FrameLoaderTypes.h"
#include "FrameView.h"
#include "Settings.h"
@@ -55,6 +56,7 @@ CachedImage::CachedImage(const String& url)
: CachedResource(url, ImageResource)
, m_image(0)
, m_decodedDataDeletionTimer(this, &CachedImage::decodedDataDeletionTimerFired)
+ , m_shouldPaintBrokenImage(true)
{
setStatus(Unknown);
}
@@ -63,6 +65,7 @@ CachedImage::CachedImage(Image* image)
: CachedResource(String(), ImageResource)
, m_image(image)
, m_decodedDataDeletionTimer(this, &CachedImage::decodedDataDeletionTimerFired)
+ , m_shouldPaintBrokenImage(true)
{
setStatus(Cached);
setLoading(false);
@@ -124,7 +127,7 @@ Image* CachedImage::image() const
{
ASSERT(!isPurgeable());
- if (errorOccurred())
+ if (errorOccurred() && m_shouldPaintBrokenImage)
return brokenImage();
if (m_image)
@@ -220,6 +223,15 @@ void CachedImage::notifyObservers(const IntRect* changeRect)
c->imageChanged(this, changeRect);
}
+void CachedImage::checkShouldPaintBrokenImage()
+{
+ Frame* frame = m_request ? m_request->cachedResourceLoader()->frame() : 0;
+ if (!frame)
+ return;
+
+ m_shouldPaintBrokenImage = frame->loader()->client()->shouldPaintBrokenImage(KURL(ParsedURLString, m_url));
+}
+
void CachedImage::clear()
{
destroyDecodedData();
@@ -303,6 +315,7 @@ void CachedImage::data(PassRefPtr<SharedBuffer> data, bool allDataReceived)
void CachedImage::error(CachedResource::Status status)
{
+ checkShouldPaintBrokenImage();
clear();
setStatus(status);
ASSERT(errorOccurred());
diff --git a/Source/WebCore/loader/cache/CachedImage.h b/Source/WebCore/loader/cache/CachedImage.h
index 345d1e7..3242409 100644
--- a/Source/WebCore/loader/cache/CachedImage.h
+++ b/Source/WebCore/loader/cache/CachedImage.h
@@ -95,9 +95,11 @@ private:
void notifyObservers(const IntRect* changeRect = 0);
void decodedDataDeletionTimerFired(Timer<CachedImage>*);
virtual PurgePriority purgePriority() const { return PurgeFirst; }
+ void checkShouldPaintBrokenImage();
RefPtr<Image> m_image;
Timer<CachedImage> m_decodedDataDeletionTimer;
+ bool m_shouldPaintBrokenImage;
};
}
diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.cpp b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
index 10c1b6c..71edb1b 100644
--- a/Source/WebCore/loader/cache/CachedResourceLoader.cpp
+++ b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
@@ -41,6 +41,7 @@
#include "FrameLoaderClient.h"
#include "HTMLElement.h"
#include "Logging.h"
+#include "NestingLevelIncrementer.h"
#include "MemoryCache.h"
#include "PingLoader.h"
#include "ResourceLoadScheduler.h"
@@ -84,14 +85,24 @@ CachedResourceLoader::CachedResourceLoader(Document* document)
, m_autoLoadImages(true)
, m_loadFinishing(false)
, m_allowStaleResources(false)
+ , m_isInMethod(0)
#ifdef ANDROID_BLOCK_NETWORK_IMAGE
, m_blockNetworkImage(false)
#endif
+
{
}
CachedResourceLoader::~CachedResourceLoader()
{
+ // Try to catch https://bugs.webkit.org/show_bug.cgi?id=54486
+ // Crashes under CachedResourceLoader::revalidateResource
+ // FIXME: Remove this and the related code when it has served its purpose.
+ if (m_isInMethod)
+ CRASH();
+
+ m_document = 0;
+
cancelRequests();
clearPreloads();
DocumentResourceMap::iterator end = m_documentResources.end();
@@ -116,11 +127,12 @@ CachedResource* CachedResourceLoader::cachedResource(const KURL& resourceURL) co
Frame* CachedResourceLoader::frame() const
{
- return m_document->frame();
+ return m_document ? m_document->frame() : 0;
}
CachedImage* CachedResourceLoader::requestImage(const String& url)
{
+ NestingLevelIncrementer debugIncrementer(m_isInMethod);
if (Frame* f = frame()) {
Settings* settings = f->settings();
if (!f->loader()->client()->allowImages(!settings || settings->areImagesEnabled()))
@@ -158,6 +170,7 @@ CachedCSSStyleSheet* CachedResourceLoader::requestCSSStyleSheet(const String& ur
CachedCSSStyleSheet* CachedResourceLoader::requestUserCSSStyleSheet(const String& requestURL, const String& charset)
{
+ NestingLevelIncrementer debugIncrementer(m_isInMethod);
KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(KURL(KURL(), requestURL));
if (CachedResource* existing = memoryCache()->resourceForURL(url)) {
@@ -269,6 +282,7 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url
CachedResource* CachedResourceLoader::requestResource(CachedResource::Type type, const String& resourceURL, const String& charset, ResourceLoadPriority priority, bool forPreload)
{
+ NestingLevelIncrementer debugIncrementer(m_isInMethod);
KURL url = m_document->completeURL(resourceURL);
LOG(ResourceLoading, "CachedResourceLoader::requestResource '%s', charset '%s', priority=%d, forPreload=%u", url.string().latin1().data(), charset.latin1().data(), priority, forPreload);
@@ -476,6 +490,7 @@ void CachedResourceLoader::printAccessDeniedMessage(const KURL& url) const
void CachedResourceLoader::setAutoLoadImages(bool enable)
{
+ NestingLevelIncrementer debugIncrementer(m_isInMethod);
if (enable == m_autoLoadImages)
return;
@@ -552,6 +567,7 @@ void CachedResourceLoader::removeCachedResource(CachedResource* resource) const
void CachedResourceLoader::load(CachedResource* resource, bool incremental, SecurityCheckPolicy securityCheck, bool sendResourceLoadCallbacks)
{
+ NestingLevelIncrementer debugIncrementer(m_isInMethod);
incrementRequestCount(resource);
RefPtr<CachedResourceRequest> request = CachedResourceRequest::load(this, resource, incremental, securityCheck, sendResourceLoadCallbacks);
@@ -561,6 +577,7 @@ void CachedResourceLoader::load(CachedResource* resource, bool incremental, Secu
void CachedResourceLoader::loadDone(CachedResourceRequest* request)
{
+ NestingLevelIncrementer debugIncrementer(m_isInMethod);
m_loadFinishing = false;
RefPtr<CachedResourceRequest> protect(request);
if (request)
@@ -637,6 +654,7 @@ int CachedResourceLoader::requestCount()
void CachedResourceLoader::preload(CachedResource::Type type, const String& url, const String& charset, bool referencedFromBody)
{
+ NestingLevelIncrementer debugIncrementer(m_isInMethod);
bool hasRendering = m_document->body() && m_document->body()->renderer();
if (!hasRendering && (referencedFromBody || type == CachedResource::ImageResource)) {
// Don't preload images or body resources before we have something to draw. This prevents
@@ -663,6 +681,7 @@ void CachedResourceLoader::checkForPendingPreloads()
void CachedResourceLoader::requestPreload(CachedResource::Type type, const String& url, const String& charset)
{
+ NestingLevelIncrementer debugIncrementer(m_isInMethod);
String encoding;
if (type == CachedResource::Script || type == CachedResource::CSSStyleSheet)
encoding = charset.isEmpty() ? m_document->charset() : charset;
diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.h b/Source/WebCore/loader/cache/CachedResourceLoader.h
index 881ad2f..0302010 100644
--- a/Source/WebCore/loader/cache/CachedResourceLoader.h
+++ b/Source/WebCore/loader/cache/CachedResourceLoader.h
@@ -156,6 +156,9 @@ private:
#ifdef ANDROID_BLOCK_NETWORK_IMAGE
bool m_blockNetworkImage : 1;
#endif
+
+ // FIME: For debugging, remove.
+ unsigned m_isInMethod;
};
}
diff --git a/Source/WebCore/loader/cache/CachedResourceRequest.cpp b/Source/WebCore/loader/cache/CachedResourceRequest.cpp
index 1d2f706..02cf13e 100644
--- a/Source/WebCore/loader/cache/CachedResourceRequest.cpp
+++ b/Source/WebCore/loader/cache/CachedResourceRequest.cpp
@@ -137,7 +137,7 @@ void CachedResourceRequest::willSendRequest(SubresourceLoader*, ResourceRequest&
m_resource->setRequestedFromNetworkingLayer();
}
-void CachedResourceRequest::didFinishLoading(SubresourceLoader* loader)
+void CachedResourceRequest::didFinishLoading(SubresourceLoader* loader, double)
{
if (m_finishing)
return;
diff --git a/Source/WebCore/loader/cache/CachedResourceRequest.h b/Source/WebCore/loader/cache/CachedResourceRequest.h
index 389b9ce..cf791fa 100644
--- a/Source/WebCore/loader/cache/CachedResourceRequest.h
+++ b/Source/WebCore/loader/cache/CachedResourceRequest.h
@@ -49,7 +49,7 @@ namespace WebCore {
virtual void didReceiveResponse(SubresourceLoader*, const ResourceResponse&);
virtual void didReceiveData(SubresourceLoader*, const char*, int);
virtual void didReceiveCachedMetadata(SubresourceLoader*, const char*, int);
- virtual void didFinishLoading(SubresourceLoader*);
+ virtual void didFinishLoading(SubresourceLoader*, double);
virtual void didFail(SubresourceLoader*, const ResourceError&);
RefPtr<SubresourceLoader> m_loader;
diff --git a/Source/WebCore/loader/cache/MemoryCache.cpp b/Source/WebCore/loader/cache/MemoryCache.cpp
index c0927f8..cb11e15 100644
--- a/Source/WebCore/loader/cache/MemoryCache.cpp
+++ b/Source/WebCore/loader/cache/MemoryCache.cpp
@@ -37,6 +37,7 @@
#include "Logging.h"
#include "ResourceHandle.h"
#include "SecurityOrigin.h"
+#include "SecurityOriginHash.h"
#include <stdio.h>
#include <wtf/CurrentTime.h>
#include <wtf/text/CString.h>
@@ -474,6 +475,31 @@ void MemoryCache::resourceAccessed(CachedResource* resource)
insertInLRUList(resource);
}
+void MemoryCache::removeResourcesWithOrigin(SecurityOrigin* origin)
+{
+ Vector<CachedResource*> resourcesWithOrigin;
+
+ CachedResourceMap::iterator e = m_resources.end();
+ for (CachedResourceMap::iterator it = m_resources.begin(); it != e; ++it) {
+ CachedResource* resource = it->second;
+ RefPtr<SecurityOrigin> resourceOrigin = SecurityOrigin::createFromString(resource->url());
+ if (!resourceOrigin)
+ continue;
+ if (resourceOrigin->equal(origin))
+ resourcesWithOrigin.append(resource);
+ }
+
+ for (size_t i = 0; i < resourcesWithOrigin.size(); ++i)
+ remove(resourcesWithOrigin[i]);
+}
+
+void MemoryCache::getOriginsWithCache(SecurityOriginSet& origins)
+{
+ CachedResourceMap::iterator e = m_resources.end();
+ for (CachedResourceMap::iterator it = m_resources.begin(); it != e; ++it)
+ origins.add(SecurityOrigin::create(KURL(KURL(), it->second->url())));
+}
+
void MemoryCache::removeFromLiveDecodedResourcesList(CachedResource* resource)
{
// If we've never been accessed, then we're brand new and not in any list.
@@ -622,6 +648,15 @@ void MemoryCache::setDisabled(bool disabled)
}
}
+void MemoryCache::evictResources()
+{
+ if (disabled())
+ return;
+
+ setDisabled(true);
+ setDisabled(false);
+}
+
#ifndef NDEBUG
void MemoryCache::dumpStats()
{
diff --git a/Source/WebCore/loader/cache/MemoryCache.h b/Source/WebCore/loader/cache/MemoryCache.h
index 12452c1..a092eac 100644
--- a/Source/WebCore/loader/cache/MemoryCache.h
+++ b/Source/WebCore/loader/cache/MemoryCache.h
@@ -40,6 +40,8 @@ class CachedCSSStyleSheet;
class CachedResource;
class CachedResourceLoader;
class KURL;
+class SecurityOrigin;
+struct SecurityOriginHash;
// This cache holds subresources used by Web pages: images, scripts, stylesheets, etc.
@@ -125,6 +127,8 @@ public:
// still live on if they are referenced by some Web page though.
void setDisabled(bool);
bool disabled() const { return m_disabled; }
+
+ void evictResources();
void setPruneEnabled(bool enabled) { m_pruneEnabled = enabled; }
void prune()
@@ -163,11 +167,16 @@ public:
void resourceAccessed(CachedResource*);
+ typedef HashSet<RefPtr<SecurityOrigin>, SecurityOriginHash> SecurityOriginSet;
+ void removeResourcesWithOrigin(SecurityOrigin*);
+ void getOriginsWithCache(SecurityOriginSet& origins);
+
#ifdef ANDROID_INSTRUMENT
unsigned getLiveSize() { return m_liveSize; }
unsigned getDeadSize() { return m_deadSize; }
#endif
+
private:
MemoryCache();
~MemoryCache(); // Not implemented to make sure nobody accidentally calls delete -- WebCore does not delete singletons.