summaryrefslogtreecommitdiff
path: root/Source/WebCore/loader/cache
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
commit2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (patch)
tree988e8c5b116dd0466244ae2fe5af8ee9be926d76 /Source/WebCore/loader/cache
parentdd91e772430dc294e3bf478c119ef8d43c0a3358 (diff)
downloadqtwebkit-2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47.tar.gz
Imported WebKit commit 7e538425aa020340619e927792f3d895061fb54b (http://svn.webkit.org/repository/webkit/trunk@116286)
Diffstat (limited to 'Source/WebCore/loader/cache')
-rw-r--r--Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp41
-rw-r--r--Source/WebCore/loader/cache/CachedCSSStyleSheet.h9
-rw-r--r--Source/WebCore/loader/cache/CachedFont.cpp3
-rw-r--r--Source/WebCore/loader/cache/CachedImage.cpp50
-rw-r--r--Source/WebCore/loader/cache/CachedRawResource.cpp30
-rw-r--r--Source/WebCore/loader/cache/CachedRawResource.h2
-rwxr-xr-xSource/WebCore/loader/cache/CachedResource.cpp3
-rw-r--r--Source/WebCore/loader/cache/CachedResourceLoader.cpp28
-rw-r--r--Source/WebCore/loader/cache/CachedResourceLoader.h11
-rw-r--r--Source/WebCore/loader/cache/MemoryCache.cpp91
-rw-r--r--Source/WebCore/loader/cache/MemoryCache.h8
11 files changed, 190 insertions, 86 deletions
diff --git a/Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp b/Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp
index 3b52cd6dc..41fa61744 100644
--- a/Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp
+++ b/Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp
@@ -27,12 +27,14 @@
#include "config.h"
#include "CachedCSSStyleSheet.h"
-#include "MemoryCache.h"
+#include "CSSStyleSheet.h"
#include "CachedResourceClientWalker.h"
#include "CachedStyleSheetClient.h"
#include "HTTPParsers.h"
-#include "TextResourceDecoder.h"
+#include "MemoryCache.h"
#include "SharedBuffer.h"
+#include "TextResourceDecoder.h"
+#include <wtf/CurrentTime.h>
#include <wtf/Vector.h>
namespace WebCore {
@@ -148,5 +150,38 @@ bool CachedCSSStyleSheet::canUseSheet(bool enforceMIMEType, bool* hasValidMIMETy
return true;
return typeOK;
}
-
+
+void CachedCSSStyleSheet::destroyDecodedData()
+{
+ m_parsedStyleSheetCache.clear();
+ setDecodedSize(0);
+}
+
+PassRefPtr<StyleSheetInternal> CachedCSSStyleSheet::restoreParsedStyleSheet(const CSSParserContext& context)
+{
+ if (!m_parsedStyleSheetCache)
+ return 0;
+ // Cached parsed stylesheet has mutated, kick it out.
+ if (!m_parsedStyleSheetCache->isCacheable()) {
+ m_parsedStyleSheetCache.clear();
+ setDecodedSize(0);
+ return 0;
+ }
+ // Contexts must be identical so we know we would get the same exact result if we parsed again.
+ if (m_parsedStyleSheetCache->parserContext() != context)
+ return 0;
+
+ didAccessDecodedData(currentTime());
+ // FIXME: Implement copy-on-write to avoid copying when not necessary.
+ return m_parsedStyleSheetCache->copy();
+}
+
+void CachedCSSStyleSheet::saveParsedStyleSheet(PassRefPtr<StyleSheetInternal> sheet)
+{
+ ASSERT(sheet && sheet->isCacheable());
+ m_parsedStyleSheetCache = sheet;
+
+ setDecodedSize(m_parsedStyleSheetCache->estimatedSizeInBytes());
+}
+
}
diff --git a/Source/WebCore/loader/cache/CachedCSSStyleSheet.h b/Source/WebCore/loader/cache/CachedCSSStyleSheet.h
index 1c0ae78b1..eb58298ac 100644
--- a/Source/WebCore/loader/cache/CachedCSSStyleSheet.h
+++ b/Source/WebCore/loader/cache/CachedCSSStyleSheet.h
@@ -33,7 +33,9 @@ namespace WebCore {
class CachedResourceClient;
class SharedBuffer;
+ class StyleSheetInternal;
class TextResourceDecoder;
+ struct CSSParserContext;
class CachedCSSStyleSheet : public CachedResource {
public:
@@ -51,7 +53,12 @@ namespace WebCore {
virtual void data(PassRefPtr<SharedBuffer> data, bool allDataReceived);
virtual void error(CachedResource::Status);
+ virtual void destroyDecodedData() OVERRIDE;
+
void checkNotify();
+
+ PassRefPtr<StyleSheetInternal> restoreParsedStyleSheet(const CSSParserContext&);
+ void saveParsedStyleSheet(PassRefPtr<StyleSheetInternal>);
private:
bool canUseSheet(bool enforceMIMEType, bool* hasValidMIMEType) const;
@@ -60,6 +67,8 @@ namespace WebCore {
protected:
RefPtr<TextResourceDecoder> m_decoder;
String m_decodedSheetText;
+
+ RefPtr<StyleSheetInternal> m_parsedStyleSheetCache;
};
}
diff --git a/Source/WebCore/loader/cache/CachedFont.cpp b/Source/WebCore/loader/cache/CachedFont.cpp
index dc8567fb3..fddd79d47 100644
--- a/Source/WebCore/loader/cache/CachedFont.cpp
+++ b/Source/WebCore/loader/cache/CachedFont.cpp
@@ -27,8 +27,7 @@
#include "config.h"
#include "CachedFont.h"
-// FIXME: This should really be a blacklist instead of a whitelist
-#if USE(CG) || PLATFORM(QT) || PLATFORM(GTK) || (PLATFORM(CHROMIUM) && (!OS(DARWIN) || USE(SKIA_ON_MAC_CHROMIUM))) || OS(WINCE)
+#if !PLATFORM(WIN_CAIRO) && !PLATFORM(WX)
#define STORE_FONT_CUSTOM_PLATFORM_DATA
#endif
diff --git a/Source/WebCore/loader/cache/CachedImage.cpp b/Source/WebCore/loader/cache/CachedImage.cpp
index 5b77301ef..33a401570 100644
--- a/Source/WebCore/loader/cache/CachedImage.cpp
+++ b/Source/WebCore/loader/cache/CachedImage.cpp
@@ -33,6 +33,7 @@
#include "FrameLoaderClient.h"
#include "FrameLoaderTypes.h"
#include "FrameView.h"
+#include "Page.h"
#include "RenderObject.h"
#include "Settings.h"
#include "SharedBuffer.h"
@@ -202,7 +203,11 @@ void CachedImage::setContainerSizeForRenderer(const RenderObject* renderer, cons
m_image->setContainerSize(containerSize);
return;
}
- m_svgImageCache->setRequestedSizeAndZoom(renderer, SVGImageCache::SizeAndZoom(containerSize, containerZoom));
+
+ // FIXME (85335): This needs to take CSS transform scale into account as well.
+ float containerScale = renderer->document()->page()->deviceScaleFactor() * renderer->document()->page()->pageScaleFactor();
+
+ m_svgImageCache->setRequestedSizeAndScales(renderer, SVGImageCache::SizeAndScales(containerSize, containerZoom, containerScale));
#else
UNUSED_PARAM(renderer);
UNUSED_PARAM(containerZoom);
@@ -240,39 +245,34 @@ IntSize CachedImage::imageSizeForRenderer(const RenderObject* renderer, float mu
if (!m_image)
return IntSize();
+
+ IntSize imageSize;
+
+ if (m_image->isBitmapImage() && (renderer && renderer->shouldRespectImageOrientation() == RespectImageOrientation))
+ imageSize = static_cast<BitmapImage*>(m_image.get())->sizeRespectingOrientation();
+ else
+ imageSize = m_image->size();
+
#if ENABLE(SVG)
if (m_image->isSVGImage()) {
- // SVGImages already includes the zooming in its intrinsic size.
- SVGImageCache::SizeAndZoom sizeAndZoom = m_svgImageCache->requestedSizeAndZoom(renderer);
- if (sizeAndZoom.size.isEmpty())
- return m_image->size();
- if (sizeAndZoom.zoom == 1)
- return sizeAndZoom.size;
- if (multiplier == 1) {
- // Consumer wants unscaled coordinates.
- sizeAndZoom.size.setWidth(sizeAndZoom.size.width() / sizeAndZoom.zoom);
- sizeAndZoom.size.setHeight(sizeAndZoom.size.height() / sizeAndZoom.zoom);
- return sizeAndZoom.size;
+ SVGImageCache::SizeAndScales sizeAndScales = m_svgImageCache->requestedSizeAndScales(renderer);
+ if (!sizeAndScales.size.isEmpty()) {
+ imageSize.setWidth(sizeAndScales.size.width() / sizeAndScales.zoom);
+ imageSize.setHeight(sizeAndScales.size.height() / sizeAndScales.zoom);
}
- return sizeAndZoom.size;
}
-#else
- UNUSED_PARAM(renderer);
#endif
if (multiplier == 1.0f)
- return m_image->size();
+ return imageSize;
// Don't let images that have a width/height >= 1 shrink below 1 when zoomed.
- bool hasWidth = m_image->size().width() > 0;
- bool hasHeight = m_image->size().height() > 0;
- int width = m_image->size().width() * (m_image->hasRelativeWidth() ? 1.0f : multiplier);
- int height = m_image->size().height() * (m_image->hasRelativeHeight() ? 1.0f : multiplier);
- if (hasWidth)
- width = max(1, width);
- if (hasHeight)
- height = max(1, height);
- return IntSize(width, height);
+ float widthScale = m_image->hasRelativeWidth() ? 1.0f : multiplier;
+ float heightScale = m_image->hasRelativeHeight() ? 1.0f : multiplier;
+ IntSize minimumSize(imageSize.width() > 0 ? 1 : 0, imageSize.height() > 0 ? 1 : 0);
+ imageSize.scale(widthScale, heightScale);
+ imageSize.clampToMinimumSize(minimumSize);
+ return imageSize;
}
void CachedImage::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio)
diff --git a/Source/WebCore/loader/cache/CachedRawResource.cpp b/Source/WebCore/loader/cache/CachedRawResource.cpp
index 8df8fb61c..b0a703304 100644
--- a/Source/WebCore/loader/cache/CachedRawResource.cpp
+++ b/Source/WebCore/loader/cache/CachedRawResource.cpp
@@ -72,6 +72,10 @@ void CachedRawResource::didAddClient(CachedResourceClient* c)
{
if (m_response.isNull() || !hasClient(c))
return;
+ // The calls to the client can result in events running, potentially causing
+ // this resource to be evicted from the cache and all clients to be removed,
+ // so a protector is necessary.
+ CachedResourceHandle<CachedRawResource> protect(this);
CachedRawResourceClient* client = static_cast<CachedRawResourceClient*>(c);
client->responseReceived(this, m_response);
if (!hasClient(c))
@@ -122,14 +126,36 @@ void CachedRawResource::setDefersLoading(bool defers)
m_loader->setDefersLoading(defers);
}
-bool CachedRawResource::canReuse() const
+bool CachedRawResource::canReuse(const ResourceRequest& newRequest) const
{
if (m_options.shouldBufferData == DoNotBufferData)
return false;
- if (m_resourceRequest.httpMethod() != "GET")
+ if (m_resourceRequest.httpMethod() != newRequest.httpMethod())
+ return false;
+
+ if (m_resourceRequest.httpBody() != newRequest.httpBody())
+ return false;
+
+ if (m_resourceRequest.allowCookies() != newRequest.allowCookies())
+ return false;
+
+ // Ensure all headers match the existing headers before continuing.
+ // Note that only headers set by our client will be present in either
+ // ResourceRequest, since SubresourceLoader creates a separate copy
+ // for its purposes.
+ // FIXME: There might be some headers that shouldn't block reuse.
+ const HTTPHeaderMap& newHeaders = newRequest.httpHeaderFields();
+ const HTTPHeaderMap& oldHeaders = m_resourceRequest.httpHeaderFields();
+ if (newHeaders.size() != oldHeaders.size())
return false;
+ HTTPHeaderMap::const_iterator end = newHeaders.end();
+ for (HTTPHeaderMap::const_iterator i = newHeaders.begin(); i != end; ++i) {
+ AtomicString headerName = i->first;
+ if (i->second != oldHeaders.get(headerName))
+ return false;
+ }
return true;
}
diff --git a/Source/WebCore/loader/cache/CachedRawResource.h b/Source/WebCore/loader/cache/CachedRawResource.h
index f6eeb839e..ed0ff955f 100644
--- a/Source/WebCore/loader/cache/CachedRawResource.h
+++ b/Source/WebCore/loader/cache/CachedRawResource.h
@@ -42,7 +42,7 @@ public:
// FIXME: This is exposed for the InpsectorInstrumentation for preflights in DocumentThreadableLoader. It's also really lame.
unsigned long identifier() const { return m_identifier; }
- bool canReuse() const;
+ bool canReuse(const ResourceRequest&) const;
private:
virtual void didAddClient(CachedResourceClient*);
diff --git a/Source/WebCore/loader/cache/CachedResource.cpp b/Source/WebCore/loader/cache/CachedResource.cpp
index a74dbd6aa..0368a7245 100755
--- a/Source/WebCore/loader/cache/CachedResource.cpp
+++ b/Source/WebCore/loader/cache/CachedResource.cpp
@@ -106,6 +106,9 @@ static ResourceRequest::TargetType cachedResourceTypeToTargetType(CachedResource
return ResourceRequest::TargetIsFontResource;
case CachedResource::ImageResource:
return ResourceRequest::TargetIsImage;
+#if ENABLE(CSS_SHADERS)
+ case CachedResource::ShaderResource:
+#endif
case CachedResource::RawResource:
return ResourceRequest::TargetIsSubresource;
#if ENABLE(LINK_PREFETCH)
diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.cpp b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
index 7dc24f9c4..846f3a739 100644
--- a/Source/WebCore/loader/cache/CachedResourceLoader.cpp
+++ b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
@@ -117,7 +117,6 @@ CachedResourceLoader::CachedResourceLoader(Document* document)
, m_requestCount(0)
, m_garbageCollectDocumentResourcesTimer(this, &CachedResourceLoader::garbageCollectDocumentResourcesTimerFired)
, m_autoLoadImages(true)
- , m_loadFinishing(false)
, m_allowStaleResources(false)
{
}
@@ -230,6 +229,13 @@ CachedXSLStyleSheet* CachedResourceLoader::requestXSLStyleSheet(ResourceRequest&
}
#endif
+#if ENABLE(SVG)
+CachedSVGDocument* CachedResourceLoader::requestSVGDocument(ResourceRequest& request)
+{
+ return static_cast<CachedSVGDocument*>(requestResource(CachedResource::SVGDocumentResource, request, request.url(), defaultCachedResourceOptions()));
+}
+#endif
+
#if ENABLE(LINK_PREFETCH)
CachedResource* CachedResourceLoader::requestLinkResource(CachedResource::Type type, ResourceRequest& request, ResourceLoadPriority priority)
{
@@ -501,7 +507,11 @@ CachedResource* CachedResourceLoader::loadResource(CachedResource::Type type, Re
resource->setInCache(true);
resource->setLoadPriority(priority);
+
+ bool wasPruneEnabled = memoryCache()->pruneEnabled();
+ memoryCache()->setPruneEnabled(false);
resource->load(this, options);
+ memoryCache()->setPruneEnabled(wasPruneEnabled);
if (!inCache) {
resource->setOwningCachedResourceLoader(this);
@@ -537,7 +547,7 @@ CachedResourceLoader::RevalidationPolicy CachedResourceLoader::determineRevalida
return Reload;
}
- if (existingResource->type() == CachedResource::RawResource && !static_cast<CachedRawResource*>(existingResource)->canReuse())
+ if (existingResource->type() == CachedResource::RawResource && !static_cast<CachedRawResource*>(existingResource)->canReuse(request))
return Reload;
// Certain requests (e.g., XHRs) might have manually set headers that require revalidation.
@@ -545,11 +555,6 @@ CachedResourceLoader::RevalidationPolicy CachedResourceLoader::determineRevalida
// of things about how revalidation works that manual headers violate, so punt to Reload instead.
if (request.isConditional())
return Reload;
-
- // Re-using resources in the case of a Range header is very simple if the headers are identical and
- // much tougher if they aren't.
- if (existingResource->resourceRequest().httpHeaderField("Range") != request.httpHeaderField("Range"))
- return Reload;
// Don't reload resources while pasting.
if (m_allowStaleResources)
@@ -675,8 +680,6 @@ void CachedResourceLoader::removeCachedResource(CachedResource* resource) const
void CachedResourceLoader::loadDone()
{
- m_loadFinishing = false;
-
RefPtr<Document> protect(m_document);
if (frame())
frame()->loader()->loadDone();
@@ -741,13 +744,6 @@ void CachedResourceLoader::decrementRequestCount(const CachedResource* res)
--m_requestCount;
ASSERT(m_requestCount > -1);
}
-
-int CachedResourceLoader::requestCount()
-{
- if (m_loadFinishing)
- return m_requestCount + 1;
- return m_requestCount;
-}
void CachedResourceLoader::preload(CachedResource::Type type, ResourceRequest& request, const String& charset, bool referencedFromBody)
{
diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.h b/Source/WebCore/loader/cache/CachedResourceLoader.h
index 86dca0e1e..b8bdacac2 100644
--- a/Source/WebCore/loader/cache/CachedResourceLoader.h
+++ b/Source/WebCore/loader/cache/CachedResourceLoader.h
@@ -40,6 +40,7 @@
namespace WebCore {
class CachedCSSStyleSheet;
+class CachedSVGDocument;
class CachedFont;
class CachedImage;
class CachedRawResource;
@@ -69,6 +70,9 @@ public:
CachedFont* requestFont(ResourceRequest&);
CachedRawResource* requestRawResource(ResourceRequest&, const ResourceLoaderOptions&);
+#if ENABLE(SVG)
+ CachedSVGDocument* requestSVGDocument(ResourceRequest&);
+#endif
#if ENABLE(XSLT)
CachedXSLStyleSheet* requestXSLStyleSheet(ResourceRequest&);
#endif
@@ -100,13 +104,11 @@ public:
Document* document() const { return m_document; }
void removeCachedResource(CachedResource*) const;
-
- void loadFinishing() { m_loadFinishing = true; }
void loadDone();
void incrementRequestCount(const CachedResource*);
void decrementRequestCount(const CachedResource*);
- int requestCount();
+ int requestCount() const { return m_requestCount; }
bool isPreloaded(const String& urlString) const;
void clearPreloads();
@@ -147,9 +149,8 @@ private:
Timer<CachedResourceLoader> m_garbageCollectDocumentResourcesTimer;
- //29 bits left
+ // 30 bits left
bool m_autoLoadImages : 1;
- bool m_loadFinishing : 1;
bool m_allowStaleResources : 1;
};
diff --git a/Source/WebCore/loader/cache/MemoryCache.cpp b/Source/WebCore/loader/cache/MemoryCache.cpp
index 6796c12fb..eea759331 100644
--- a/Source/WebCore/loader/cache/MemoryCache.cpp
+++ b/Source/WebCore/loader/cache/MemoryCache.cpp
@@ -29,6 +29,7 @@
#include "CachedScript.h"
#include "CachedXSLStyleSheet.h"
#include "CachedResourceLoader.h"
+#include "CrossThreadTask.h"
#include "Document.h"
#include "FrameLoader.h"
#include "FrameLoaderTypes.h"
@@ -38,8 +39,12 @@
#include "ResourceHandle.h"
#include "SecurityOrigin.h"
#include "SecurityOriginHash.h"
+#include "WorkerContext.h"
+#include "WorkerLoaderProxy.h"
+#include "WorkerThread.h"
#include <stdio.h>
#include <wtf/CurrentTime.h>
+#include <wtf/TemporaryChange.h>
#include <wtf/text/CString.h>
using namespace std;
@@ -54,13 +59,15 @@ static const double cDefaultDecodedDataDeletionInterval = 0;
MemoryCache* memoryCache()
{
static MemoryCache* staticCache = new MemoryCache;
+ ASSERT(WTF::isMainThread());
+
return staticCache;
}
MemoryCache::MemoryCache()
: m_disabled(false)
, m_pruneEnabled(true)
- , m_inPruneDeadResources(false)
+ , m_inPruneResources(false)
, m_capacity(cDefaultCacheCapacity)
, m_minDeadCapacity(0)
, m_maxDeadCapacity(cDefaultCacheCapacity)
@@ -88,7 +95,9 @@ bool MemoryCache::add(CachedResource* resource)
{
if (disabled())
return false;
-
+
+ ASSERT(WTF::isMainThread());
+
m_resources.set(resource->url(), resource);
resource->setInCache(true);
@@ -132,6 +141,7 @@ void MemoryCache::revalidationSucceeded(CachedResource* revalidatingResource, co
void MemoryCache::revalidationFailed(CachedResource* revalidatingResource)
{
+ ASSERT(WTF::isMainThread());
LOG(ResourceLoading, "Revalidation failed for %p", revalidatingResource);
ASSERT(revalidatingResource->resourceToRevalidate());
revalidatingResource->clearResourceToRevalidate();
@@ -139,6 +149,7 @@ void MemoryCache::revalidationFailed(CachedResource* revalidatingResource)
CachedResource* MemoryCache::resourceForURL(const KURL& resourceURL)
{
+ ASSERT(WTF::isMainThread());
KURL url = removeFragmentIdentifierIfNeeded(resourceURL);
CachedResource* resource = m_resources.get(url);
bool wasPurgeable = MemoryCache::shouldMakeResourcePurgeableOnEviction() && resource && resource->isPurgeable();
@@ -198,6 +209,10 @@ void MemoryCache::pruneLiveResourcesToPercentage(float prunePercentage)
void MemoryCache::pruneLiveResourcesToSize(unsigned targetSize)
{
+ if (m_inPruneResources)
+ return;
+ TemporaryChange<bool> reentrancyProtector(m_inPruneResources, true);
+
double currentTime = FrameView::currentPaintTimeStamp();
if (!currentTime) // In case prune is called directly, outside of a Frame paint.
currentTime = WTF::currentTime();
@@ -260,29 +275,30 @@ void MemoryCache::pruneDeadResourcesToPercentage(float prunePercentage)
}
void MemoryCache::pruneDeadResourcesToSize(unsigned targetSize)
-{
+{
+ if (m_inPruneResources)
+ return;
+ TemporaryChange<bool> reentrancyProtector(m_inPruneResources, true);
+
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;
+ // 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;
}
-
+ if (targetSize && m_deadSize <= targetSize)
+ return;
+
bool canShrinkLRULists = true;
- m_inPruneDeadResources = true;
for (int i = size - 1; i >= 0; i--) {
// Remove from the tail, since this is the least frequently accessed of the objects.
CachedResource* current = m_allResources[i].m_tail;
@@ -296,10 +312,8 @@ void MemoryCache::pruneDeadResourcesToSize(unsigned targetSize)
// LRU list in m_allResources.
current->destroyDecodedData();
- if (targetSize && m_deadSize <= targetSize) {
- m_inPruneDeadResources = false;
+ if (targetSize && m_deadSize <= targetSize)
return;
- }
}
current = prev;
}
@@ -312,15 +326,8 @@ void MemoryCache::pruneDeadResourcesToSize(unsigned targetSize)
if (!makeResourcePurgeable(current))
evict(current);
- // If evict() caused pruneDeadResources() to be re-entered, bail out. This can happen when removing an
- // SVG CachedImage that has subresources.
- if (!m_inPruneDeadResources)
- return;
-
- if (targetSize && m_deadSize <= targetSize) {
- m_inPruneDeadResources = false;
+ if (targetSize && m_deadSize <= targetSize)
return;
- }
}
current = prev;
}
@@ -332,7 +339,6 @@ void MemoryCache::pruneDeadResourcesToSize(unsigned targetSize)
else if (canShrinkLRULists)
m_allResources.resize(i);
}
- m_inPruneDeadResources = false;
}
void MemoryCache::setCapacities(unsigned minDeadBytes, unsigned maxDeadBytes, unsigned totalBytes)
@@ -369,6 +375,7 @@ bool MemoryCache::makeResourcePurgeable(CachedResource* resource)
void MemoryCache::evict(CachedResource* resource)
{
+ ASSERT(WTF::isMainThread());
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,
// who needed a fresh copy for a reload. See <http://bugs.webkit.org/show_bug.cgi?id=12479#c6>.
@@ -636,6 +643,28 @@ void MemoryCache::adjustSize(bool live, int delta)
}
}
+
+void MemoryCache::removeUrlFromCache(ScriptExecutionContext* context, const String& urlString)
+{
+#if ENABLE(WORKERS)
+ if (context->isWorkerContext()) {
+ WorkerContext* workerContext = static_cast<WorkerContext*>(context);
+ workerContext->thread()->workerLoaderProxy().postTaskToLoader(
+ createCallbackTask(&removeUrlFromCacheImpl, urlString));
+ return;
+ }
+#endif
+ removeUrlFromCacheImpl(context, urlString);
+}
+
+void MemoryCache::removeUrlFromCacheImpl(ScriptExecutionContext*, const String& urlString)
+{
+ KURL url(KURL(), urlString);
+
+ if (CachedResource* resource = memoryCache()->resourceForURL(url))
+ memoryCache()->remove(resource);
+}
+
void MemoryCache::TypeStatistic::addResource(CachedResource* o)
{
bool purged = o->wasPurged();
diff --git a/Source/WebCore/loader/cache/MemoryCache.h b/Source/WebCore/loader/cache/MemoryCache.h
index 0ad79fce9..477d778e1 100644
--- a/Source/WebCore/loader/cache/MemoryCache.h
+++ b/Source/WebCore/loader/cache/MemoryCache.h
@@ -39,6 +39,7 @@ class CachedCSSStyleSheet;
class CachedResource;
class CachedResourceLoader;
class KURL;
+class ScriptExecutionContext;
class SecurityOrigin;
struct SecurityOriginHash;
@@ -128,6 +129,7 @@ public:
void evictResources();
void setPruneEnabled(bool enabled) { m_pruneEnabled = enabled; }
+ bool pruneEnabled() const { return m_pruneEnabled; }
void prune();
void pruneToPercentage(float targetPercentLive);
@@ -153,6 +155,8 @@ public:
static bool shouldMakeResourcePurgeableOnEviction();
+ static void removeUrlFromCache(ScriptExecutionContext*, const String& urlString);
+
// Function to collect cache statistics for the caches window in the Safari Debug menu.
Statistics getStatistics();
@@ -193,9 +197,11 @@ private:
bool makeResourcePurgeable(CachedResource*);
void evict(CachedResource*);
+ static void removeUrlFromCacheImpl(ScriptExecutionContext*, const String& urlString);
+
bool m_disabled; // Whether or not the cache is enabled.
bool m_pruneEnabled;
- bool m_inPruneDeadResources;
+ bool m_inPruneResources;
unsigned m_capacity;
unsigned m_minDeadCapacity;