[SCM] WebKit Debian packaging branch, debian/experimental, updated. debian/1.3.8-1-1049-g2e11a8e
antti at apple.com
antti at apple.com
Fri Jan 21 14:48:40 UTC 2011
The following commit has been merged in the debian/experimental branch:
commit f73108e259ae49784cb03b6e2f23b73f76449c2e
Author: antti at apple.com <antti at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Thu Dec 30 20:57:02 2010 +0000
https://bugs.webkit.org/show_bug.cgi?id=51134
Move loading related code from MemoryCache to CachedResourceLoader
Reviewed by Darin Adler.
- Merge MemoryCache::requestResource to CachedResourceLoader::requestResource
- Merge MemoryCache::requestUserCSSStyleSheet to CachedResourceLoader::requestUserCSSStyleSheet
- Move MemoryCache::revalidateResource to CachedResourceLoader::revalidateResource
- Add MemoryCache::add
- Refactor the decision on whether to reload, revalidate or use the existing resource to
a single function, CachedResourceLoader::determineRevalidationPolicy
* css/CSSImageValue.cpp:
(WebCore::CSSImageValue::cachedImage):
Remove a code path that called MemoryCache::requestResource directly. This code path would have crashed
if ever taken (since it passes null CachedResourceLoader pointer).
* loader/ImageLoader.cpp:
(WebCore::ImageLoader::updateFromElement):
* loader/cache/CachedImage.cpp:
* loader/cache/CachedResource.cpp:
(WebCore::CachedResource::CachedResource):
(WebCore::CachedResource::~CachedResource):
(WebCore::CachedResource::mustRevalidateDueToCacheHeaders):
Moved tests that were not about cache headers to CachedResourceLoader::determineRevalidationPolicy and renamed.
(WebCore::CachedResource::setLoadPriority):
Check for Unresolved value before setting.
* loader/cache/CachedResource.h:
(WebCore::CachedResource::setOwningCachedResourceLoader):
Rename to be bit less mysterious.
* loader/cache/CachedResourceLoader.cpp:
(WebCore::createResource):
This was moved from MemoryCache.
(WebCore::CachedResourceLoader::~CachedResourceLoader):
(WebCore::CachedResourceLoader::determineRevalidationPolicy):
(WebCore::CachedResourceLoader::requestUserCSSStyleSheet):
This was moved/merged from MemoryCache.
(WebCore::CachedResourceLoader::canRequest):
(WebCore::CachedResourceLoader::requestResource):
This combines MemoryCache::requestResource and the existing method.
(WebCore::CachedResourceLoader::revalidateResource):
This was moved from MemoryCache.
(WebCore::CachedResourceLoader::loadResource):
New method for initiating loading.
(WebCore::CachedResourceLoader::notifyLoadedFromMemoryCache):
Renamed the mysterious CachedResourceLoader::checkCacheObjectStatus
* loader/cache/CachedResourceLoader.h:
* loader/cache/MemoryCache.cpp:
(WebCore::MemoryCache::add):
* loader/cache/MemoryCache.h:
(WebCore::MemoryCache::remove):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@74807 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 071a4a4..51bfc5a 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,76 @@
+2010-12-30 Antti Koivisto <antti at apple.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=51134
+ Move loading related code from MemoryCache to CachedResourceLoader
+
+ - Merge MemoryCache::requestResource to CachedResourceLoader::requestResource
+ - Merge MemoryCache::requestUserCSSStyleSheet to CachedResourceLoader::requestUserCSSStyleSheet
+ - Move MemoryCache::revalidateResource to CachedResourceLoader::revalidateResource
+ - Add MemoryCache::add
+ - Refactor the decision on whether to reload, revalidate or use the existing resource to
+ a single function, CachedResourceLoader::determineRevalidationPolicy
+
+ * css/CSSImageValue.cpp:
+ (WebCore::CSSImageValue::cachedImage):
+
+ Remove a code path that called MemoryCache::requestResource directly. This code path would have crashed
+ if ever taken (since it passes null CachedResourceLoader pointer).
+
+ * loader/ImageLoader.cpp:
+ (WebCore::ImageLoader::updateFromElement):
+ * loader/cache/CachedImage.cpp:
+ * loader/cache/CachedResource.cpp:
+ (WebCore::CachedResource::CachedResource):
+ (WebCore::CachedResource::~CachedResource):
+ (WebCore::CachedResource::mustRevalidateDueToCacheHeaders):
+
+ Moved tests that were not about cache headers to CachedResourceLoader::determineRevalidationPolicy and renamed.
+
+ (WebCore::CachedResource::setLoadPriority):
+
+ Check for Unresolved value before setting.
+
+ * loader/cache/CachedResource.h:
+ (WebCore::CachedResource::setOwningCachedResourceLoader):
+
+ Rename to be bit less mysterious.
+
+ * loader/cache/CachedResourceLoader.cpp:
+ (WebCore::createResource):
+
+ This was moved from MemoryCache.
+
+ (WebCore::CachedResourceLoader::~CachedResourceLoader):
+ (WebCore::CachedResourceLoader::determineRevalidationPolicy):
+ (WebCore::CachedResourceLoader::requestUserCSSStyleSheet):
+
+ This was moved/merged from MemoryCache.
+
+ (WebCore::CachedResourceLoader::canRequest):
+ (WebCore::CachedResourceLoader::requestResource):
+
+ This combines MemoryCache::requestResource and the existing method.
+
+ (WebCore::CachedResourceLoader::revalidateResource):
+
+ This was moved from MemoryCache.
+
+ (WebCore::CachedResourceLoader::loadResource):
+
+ New method for initiating loading.
+
+ (WebCore::CachedResourceLoader::notifyLoadedFromMemoryCache):
+
+ Renamed the mysterious CachedResourceLoader::checkCacheObjectStatus
+
+ * loader/cache/CachedResourceLoader.h:
+ * loader/cache/MemoryCache.cpp:
+ (WebCore::MemoryCache::add):
+ * loader/cache/MemoryCache.h:
+ (WebCore::MemoryCache::remove):
+
2010-12-30 Steve Block <steveblock at google.com>
Reviewed by Gavin Barraclough.
diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj
index 1f8afcb..dc0fd2f 100644
--- a/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -22266,6 +22266,7 @@
isa = PBXProject;
buildConfigurationList = 149C284308902B11008A9EFC /* Build configuration list for PBXProject "WebCore" */;
compatibilityVersion = "Xcode 2.4";
+ developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
diff --git a/WebCore/css/CSSImageValue.cpp b/WebCore/css/CSSImageValue.cpp
index 2155eea..a9038b9 100644
--- a/WebCore/css/CSSImageValue.cpp
+++ b/WebCore/css/CSSImageValue.cpp
@@ -66,24 +66,18 @@ StyleCachedImage* CSSImageValue::cachedImage(CachedResourceLoader* loader)
StyleCachedImage* CSSImageValue::cachedImage(CachedResourceLoader* loader, const String& url)
{
+ ASSERT(loader);
+
if (!m_accessedImage) {
m_accessedImage = true;
- CachedImage* cachedImage = 0;
- if (loader)
- cachedImage = loader->requestImage(url);
- else {
- // FIXME: Should find a way to make these images sit in their own memory partition, since they are user agent images.
- cachedImage = static_cast<CachedImage*>(cache()->requestResource(0, CachedResource::ImageResource, KURL(ParsedURLString, url), String(), ResourceLoadPriorityUnresolved));
- }
-
- if (cachedImage) {
+ if (CachedImage* cachedImage = loader->requestImage(url)) {
cachedImage->addClient(this);
m_image = StyleCachedImage::create(cachedImage);
}
}
- return m_image->isCachedImage() ? static_cast<StyleCachedImage*>(m_image.get()) : 0;
+ return (m_image && m_image->isCachedImage()) ? static_cast<StyleCachedImage*>(m_image.get()) : 0;
}
String CSSImageValue::cachedImageURL()
diff --git a/WebCore/loader/ImageLoader.cpp b/WebCore/loader/ImageLoader.cpp
index 94a21a4..a77e8c0 100644
--- a/WebCore/loader/ImageLoader.cpp
+++ b/WebCore/loader/ImageLoader.cpp
@@ -164,7 +164,7 @@ void ImageLoader::updateFromElement()
document->cachedResourceLoader()->setAutoLoadImages(false);
newImage = new CachedImage(sourceURI(attr));
newImage->setLoading(true);
- newImage->setCachedResourceLoader(document->cachedResourceLoader());
+ newImage->setOwningCachedResourceLoader(document->cachedResourceLoader());
document->cachedResourceLoader()->m_documentResources.set(newImage->url(), newImage);
document->cachedResourceLoader()->setAutoLoadImages(autoLoadOtherImages);
} else
diff --git a/WebCore/loader/cache/CachedImage.cpp b/WebCore/loader/cache/CachedImage.cpp
index e543a14..39462b6 100644
--- a/WebCore/loader/cache/CachedImage.cpp
+++ b/WebCore/loader/cache/CachedImage.cpp
@@ -29,6 +29,7 @@
#include "CachedResourceClient.h"
#include "CachedResourceClientWalker.h"
#include "CachedResourceLoader.h"
+#include "CachedResourceRequest.h"
#include "Frame.h"
#include "FrameLoaderTypes.h"
#include "FrameView.h"
diff --git a/WebCore/loader/cache/CachedResource.cpp b/WebCore/loader/cache/CachedResource.cpp
index 19e535f..a9d9b0a 100644
--- a/WebCore/loader/cache/CachedResource.cpp
+++ b/WebCore/loader/cache/CachedResource.cpp
@@ -101,7 +101,7 @@ CachedResource::CachedResource(const String& url, Type type)
, m_prevInAllResourcesList(0)
, m_nextInLiveResourcesList(0)
, m_prevInLiveResourcesList(0)
- , m_cachedResourceLoader(0)
+ , m_owningCachedResourceLoader(0)
, m_resourceToRevalidate(0)
, m_proxyResource(0)
{
@@ -122,8 +122,8 @@ CachedResource::~CachedResource()
cachedResourceLeakCounter.decrement();
#endif
- if (m_cachedResourceLoader)
- m_cachedResourceLoader->removeCachedResource(this);
+ if (m_owningCachedResourceLoader)
+ m_owningCachedResourceLoader->removeCachedResource(this);
}
void CachedResource::load(CachedResourceLoader* cachedResourceLoader, bool incremental, SecurityCheckPolicy securityCheck, bool sendResourceLoadCallbacks)
@@ -490,17 +490,14 @@ bool CachedResource::canUseCacheValidator() const
DEFINE_STATIC_LOCAL(const AtomicString, eTagHeader, ("etag"));
return !m_response.httpHeaderField(lastModifiedHeader).isEmpty() || !m_response.httpHeaderField(eTagHeader).isEmpty();
}
-
-bool CachedResource::mustRevalidate(CachePolicy cachePolicy) const
-{
- if (errorOccurred()) {
- LOG(ResourceLoading, "CachedResource %p mustRevalidate because of m_errorOccurred\n", this);
+
+bool CachedResource::mustRevalidateDueToCacheHeaders(CachePolicy cachePolicy) const
+{
+ ASSERT(cachePolicy == CachePolicyRevalidate || cachePolicy == CachePolicyCache || cachePolicy == CachePolicyVerify);
+
+ if (cachePolicy == CachePolicyRevalidate)
return true;
- }
- if (m_loading)
- return false;
-
if (m_response.cacheControlContainsNoCache() || m_response.cacheControlContainsNoStore()) {
LOG(ResourceLoading, "CachedResource %p mustRevalidate because of m_response.cacheControlContainsNoCache() || m_response.cacheControlContainsNoStore()\n", this);
return true;
@@ -514,6 +511,7 @@ bool CachedResource::mustRevalidate(CachePolicy cachePolicy) const
return false;
}
+ // CachePolicyVerify
if (isExpired()) {
LOG(ResourceLoading, "CachedResource %p mustRevalidate because of isExpired()\n", this);
return true;
@@ -587,5 +585,12 @@ unsigned CachedResource::overheadSize() const
384; // average size of m_clients hash map
*/
}
+
+void CachedResource::setLoadPriority(ResourceLoadPriority loadPriority)
+{
+ if (loadPriority == ResourceLoadPriorityUnresolved)
+ return;
+ m_loadPriority = loadPriority;
+}
}
diff --git a/WebCore/loader/cache/CachedResource.h b/WebCore/loader/cache/CachedResource.h
index 9defc16..3600a02 100644
--- a/WebCore/loader/cache/CachedResource.h
+++ b/WebCore/loader/cache/CachedResource.h
@@ -93,6 +93,7 @@ public:
Type type() const { return static_cast<Type>(m_type); }
ResourceLoadPriority loadPriority() const { return m_loadPriority; }
+ void setLoadPriority(ResourceLoadPriority);
void addClient(CachedResourceClient*);
void removeClient(CachedResourceClient*);
@@ -186,7 +187,7 @@ public:
virtual void destroyDecodedData() { }
- void setCachedResourceLoader(CachedResourceLoader* cachedResourceLoader) { m_cachedResourceLoader = cachedResourceLoader; }
+ void setOwningCachedResourceLoader(CachedResourceLoader* cachedResourceLoader) { m_owningCachedResourceLoader = cachedResourceLoader; }
bool isPreloaded() const { return m_preloadCount; }
void increasePreloadCount() { ++m_preloadCount; }
@@ -196,7 +197,7 @@ public:
void unregisterHandle(CachedResourceHandleBase* h);
bool canUseCacheValidator() const;
- bool mustRevalidate(CachePolicy) const;
+ bool mustRevalidateDueToCacheHeaders(CachePolicy) const;
bool isCacheValidator() const { return m_resourceToRevalidate; }
CachedResource* resourceToRevalidate() const { return m_resourceToRevalidate; }
@@ -207,6 +208,12 @@ public:
// triggering a load. We should make it protected again if we can find a
// better way to handle the archive case.
bool makePurgeable(bool purgeable);
+
+ // HTTP revalidation support methods for CachedResourceLoader.
+ void setResourceToRevalidate(CachedResource*);
+ void switchClientsToRevalidatedResource();
+ void clearResourceToRevalidate();
+ void updateResponseAfterRevalidation(const ResourceResponse& validatingResponse);
protected:
void setEncodedSize(unsigned);
@@ -230,14 +237,8 @@ protected:
private:
void addClientToSet(CachedResourceClient*);
-
- // These are called by the friendly MemoryCache only
- void setResourceToRevalidate(CachedResource*);
- void switchClientsToRevalidatedResource();
- void clearResourceToRevalidate();
- void updateResponseAfterRevalidation(const ResourceResponse& validatingResponse);
+
virtual PurgePriority purgePriority() const { return PurgeDefault; }
- void setLoadPriority(ResourceLoadPriority loadPriority) { m_loadPriority = loadPriority; }
double currentAge() const;
double freshnessLifetime() const;
@@ -275,7 +276,7 @@ private:
CachedResource* m_nextInLiveResourcesList;
CachedResource* m_prevInLiveResourcesList;
- CachedResourceLoader* m_cachedResourceLoader; // only non-0 for resources that are not in the cache
+ CachedResourceLoader* m_owningCachedResourceLoader; // only non-0 for resources that are not in the cache
// If this field is non-null we are using the resource as a proxy for checking whether an existing resource is still up to date
// using HTTP If-Modified-Since/If-None-Match headers. If the response is 304 all clients of this resource are moved
diff --git a/WebCore/loader/cache/CachedResourceLoader.cpp b/WebCore/loader/cache/CachedResourceLoader.cpp
index 5443815..b7060a8 100644
--- a/WebCore/loader/cache/CachedResourceLoader.cpp
+++ b/WebCore/loader/cache/CachedResourceLoader.cpp
@@ -30,6 +30,7 @@
#include "CachedCSSStyleSheet.h"
#include "CachedFont.h"
#include "CachedImage.h"
+#include "CachedResourceRequest.h"
#include "CachedScript.h"
#include "CachedXSLStyleSheet.h"
#include "Console.h"
@@ -39,6 +40,7 @@
#include "FrameLoader.h"
#include "FrameLoaderClient.h"
#include "HTMLElement.h"
+#include "Logging.h"
#include "MemoryCache.h"
#include "PingLoader.h"
#include "SecurityOrigin.h"
@@ -49,6 +51,30 @@
namespace WebCore {
+static CachedResource* createResource(CachedResource::Type type, const KURL& url, const String& charset)
+{
+ switch (type) {
+ case CachedResource::ImageResource:
+ return new CachedImage(url.string());
+ case CachedResource::CSSStyleSheet:
+ return new CachedCSSStyleSheet(url.string(), charset);
+ case CachedResource::Script:
+ return new CachedScript(url.string(), charset);
+ case CachedResource::FontResource:
+ return new CachedFont(url.string());
+#if ENABLE(XSLT)
+ case CachedResource::XSLStyleSheet:
+ return new CachedXSLStyleSheet(url.string());
+#endif
+#if ENABLE(LINK_PREFETCH)
+ case CachedResource::LinkPrefetch:
+ return new CachedResource(url.string(), CachedResource::LinkPrefetch);
+#endif
+ }
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
CachedResourceLoader::CachedResourceLoader(Document* document)
: m_cache(cache())
, m_document(document)
@@ -66,7 +92,7 @@ CachedResourceLoader::~CachedResourceLoader()
clearPreloads();
DocumentResourceMap::iterator end = m_documentResources.end();
for (DocumentResourceMap::iterator it = m_documentResources.begin(); it != end; ++it)
- it->second->setCachedResourceLoader(0);
+ it->second->setOwningCachedResourceLoader(0);
m_cache->removeCachedResourceLoader(this);
// Make sure no requests still point to this CachedResourceLoader
@@ -90,45 +116,6 @@ Frame* CachedResourceLoader::frame() const
return m_document->frame();
}
-void CachedResourceLoader::checkForReload(const KURL& fullURL)
-{
- if (m_allowStaleResources)
- return; // Don't reload resources while pasting
-
- if (fullURL.isEmpty())
- return;
-
- if (m_reloadedURLs.contains(fullURL.string()))
- return;
-
- CachedResource* existing = cache()->resourceForURL(fullURL);
- if (!existing || existing->isPreloaded())
- return;
-
- switch (cachePolicy()) {
- case CachePolicyVerify:
- if (!existing->mustRevalidate(CachePolicyVerify))
- return;
- cache()->revalidateResource(existing, this);
- break;
- case CachePolicyCache:
- if (!existing->mustRevalidate(CachePolicyCache))
- return;
- cache()->revalidateResource(existing, this);
- break;
- case CachePolicyReload:
- cache()->remove(existing);
- break;
- case CachePolicyRevalidate:
- cache()->revalidateResource(existing, this);
- break;
- case CachePolicyHistoryBuffer:
- return;
- }
-
- m_reloadedURLs.add(fullURL.string());
-}
-
CachedImage* CachedResourceLoader::requestImage(const String& url)
{
if (Frame* f = frame()) {
@@ -161,9 +148,27 @@ CachedCSSStyleSheet* CachedResourceLoader::requestCSSStyleSheet(const String& ur
return static_cast<CachedCSSStyleSheet*>(requestResource(CachedResource::CSSStyleSheet, url, charset, priority));
}
-CachedCSSStyleSheet* CachedResourceLoader::requestUserCSSStyleSheet(const String& url, const String& charset)
+CachedCSSStyleSheet* CachedResourceLoader::requestUserCSSStyleSheet(const String& requestURL, const String& charset)
{
- return cache()->requestUserCSSStyleSheet(this, KURL(KURL(), url), charset);
+ KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(KURL(KURL(), requestURL));
+
+ if (CachedResource* existing = cache()->resourceForURL(url)) {
+ if (existing->type() == CachedResource::CSSStyleSheet)
+ return static_cast<CachedCSSStyleSheet*>(existing);
+ cache()->remove(existing);
+ }
+ CachedCSSStyleSheet* userSheet = new CachedCSSStyleSheet(url, charset);
+
+ bool inCache = cache()->add(userSheet);
+ if (!inCache)
+ userSheet->setInCache(true);
+
+ userSheet->load(this, /*incremental*/ false, SkipSecurityCheck, /*sendResourceLoadCallbacks*/ false);
+
+ if (!inCache)
+ userSheet->setInCache(false);
+
+ return userSheet;
}
CachedScript* CachedResourceLoader::requestScript(const String& url, const String& charset)
@@ -254,41 +259,187 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url
return true;
}
-CachedResource* CachedResourceLoader::requestResource(CachedResource::Type type, const String& url, const String& charset, ResourceLoadPriority priority, bool isPreload)
+CachedResource* CachedResourceLoader::requestResource(CachedResource::Type type, const String& resourceURL, const String& charset, ResourceLoadPriority priority, bool forPreload)
{
- KURL fullURL = m_document->completeURL(url);
+ 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);
// If only the fragment identifiers differ, it is the same resource.
- fullURL = MemoryCache::removeFragmentIdentifierIfNeeded(fullURL);
+ url = MemoryCache::removeFragmentIdentifierIfNeeded(url);
+
+ if (!url.isValid())
+ return 0;
+
+ if (!canRequest(type, url))
+ return 0;
- if (!fullURL.isValid() || !canRequest(type, fullURL))
+ // FIXME: Figure out what is the correct way to merge this security check with the one above.
+ if (!document()->securityOrigin()->canDisplay(url)) {
+ if (!forPreload)
+ FrameLoader::reportLocalLoadFailed(document()->frame(), url.string());
+ LOG(ResourceLoading, "CachedResourceLoader::requestResource URL was not allowed by SecurityOrigin::canDisplay");
return 0;
+ }
if (cache()->disabled()) {
- DocumentResourceMap::iterator it = m_documentResources.find(fullURL.string());
-
+ DocumentResourceMap::iterator it = m_documentResources.find(url.string());
if (it != m_documentResources.end()) {
- it->second->setCachedResourceLoader(0);
+ it->second->setOwningCachedResourceLoader(0);
m_documentResources.remove(it);
}
}
- checkForReload(fullURL);
+ // See if we can use an existing resource from the cache.
+ CachedResource* resource = cache()->resourceForURL(url);
- bool allowForHistoryOnlyResources = cachePolicy() == CachePolicyHistoryBuffer;
- CachedResource* resource = cache()->requestResource(this, type, fullURL, charset, priority, isPreload, allowForHistoryOnlyResources);
- if (resource) {
- // Check final URL of resource to catch redirects.
- // See <https://bugs.webkit.org/show_bug.cgi?id=21963>.
- if (fullURL != resource->url() && !canRequest(type, KURL(ParsedURLString, resource->url())))
- return 0;
+ switch (determineRevalidationPolicy(type, forPreload, resource)) {
+ case Load:
+ resource = loadResource(type, url, charset, priority);
+ break;
+ case Reload:
+ cache()->remove(resource);
+ resource = loadResource(type, url, charset, priority);
+ break;
+ case Revalidate:
+ resource = revalidateResource(resource, priority);
+ break;
+ case Use:
+ cache()->resourceAccessed(resource);
+ notifyLoadedFromMemoryCache(resource);
+ break;
+ }
+
+ if (!resource)
+ return 0;
+
+ ASSERT(resource->url() == url.string());
+ m_documentResources.set(resource->url(), resource);
+
+ return resource;
+}
+
+CachedResource* CachedResourceLoader::revalidateResource(CachedResource* resource, ResourceLoadPriority priority)
+{
+ ASSERT(resource);
+ ASSERT(resource->inCache());
+ ASSERT(!cache()->disabled());
+ ASSERT(resource->canUseCacheValidator());
+ ASSERT(!resource->resourceToRevalidate());
+
+ const String& url = resource->url();
+ CachedResource* newResource = createResource(resource->type(), KURL(ParsedURLString, url), resource->encoding());
+
+ LOG(ResourceLoading, "Resource %p created to revalidate %p", newResource, resource);
+ newResource->setResourceToRevalidate(resource);
+
+ cache()->remove(resource);
+ cache()->add(newResource);
+
+ newResource->setLoadPriority(priority);
+ newResource->load(this);
+
+ m_validatedURLs.add(url);
+ return newResource;
+}
+
+CachedResource* CachedResourceLoader::loadResource(CachedResource::Type type, const KURL& url, const String& charset, ResourceLoadPriority priority)
+{
+ ASSERT(!cache()->resourceForURL(url));
+
+ LOG(ResourceLoading, "Loading CachedResource for '%s'.", url.string().latin1().data());
+
+ CachedResource* resource = createResource(type, url, charset);
+
+ bool inCache = cache()->add(resource);
+
+ // Pretend the resource is in the cache, to prevent it from being deleted during the load() call.
+ // FIXME: CachedResource should just use normal refcounting instead.
+ if (!inCache)
+ resource->setInCache(true);
+
+ resource->setLoadPriority(priority);
+ resource->load(this);
+
+ if (!inCache) {
+ resource->setOwningCachedResourceLoader(this);
+ resource->setInCache(false);
+ }
- m_documentResources.set(resource->url(), resource);
- checkCacheObjectStatus(resource);
+ // We don't support immediate loads, but we do support immediate failure.
+ if (resource->errorOccurred()) {
+ if (inCache)
+ cache()->remove(resource);
+ else
+ delete resource;
+ return 0;
}
+
+ m_validatedURLs.add(url.string());
return resource;
}
+CachedResourceLoader::RevalidationPolicy CachedResourceLoader::determineRevalidationPolicy(CachedResource::Type type, bool forPreload, CachedResource* existingResource) const
+{
+ if (!existingResource)
+ return Load;
+
+ // We already have a preload going for this URL.
+ if (forPreload && existingResource->isPreloaded())
+ return Use;
+
+ // If the same URL has been loaded as a different type, we need to reload.
+ if (existingResource->type() != type) {
+ LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicy reloading due to type mismatch.");
+ return Reload;
+ }
+
+ // Don't reload resources while pasting.
+ if (m_allowStaleResources)
+ return Use;
+
+ // Alwaus use preloads.
+ if (existingResource->isPreloaded())
+ return Use;
+
+ // Avoid loading the same resource multiple times for a single document, even if the cache policies would tell us to.
+ if (m_validatedURLs.contains(existingResource->url()))
+ return Use;
+
+ // CachePolicyReload always reloads
+ if (cachePolicy() == CachePolicyReload) {
+ LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicy reloading due to CachePolicyReload.");
+ return Reload;
+ }
+
+ // CachePolicyHistoryBuffer uses the cache no matter what.
+ if (cachePolicy() == CachePolicyHistoryBuffer)
+ return Use;
+
+ // We'll try to reload the resource if it failed last time.
+ if (existingResource->errorOccurred()) {
+ LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicye reloading due to resource being in the error state");
+ return Reload;
+ }
+
+ // For resources that are not yet loaded we ignore the cache policy.
+ if (existingResource->isLoading())
+ return Use;
+
+ // Check if the cache headers requires us to revalidate (cache expiration for example).
+ if (existingResource->mustRevalidateDueToCacheHeaders(cachePolicy())) {
+ // See if the resource has usable ETag or Last-modified headers.
+ if (existingResource->canUseCacheValidator())
+ return Revalidate;
+
+ // No, must reload.
+ LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicy reloading due to missing cache validators.");
+ return Reload;
+ }
+
+ return Use;
+}
+
void CachedResourceLoader::printAccessDeniedMessage(const KURL& url) const
{
if (url.isNull())
@@ -378,9 +529,8 @@ void CachedResourceLoader::cancelRequests()
requestsToCancel[i]->didFail(true);
}
-void CachedResourceLoader::checkCacheObjectStatus(CachedResource* resource)
+void CachedResourceLoader::notifyLoadedFromMemoryCache(CachedResource* resource)
{
- // Return from the function for objects that we didn't load from the cache or if we don't have a frame.
if (!resource || !frame() || resource->status() != CachedResource::Cached)
return;
diff --git a/WebCore/loader/cache/CachedResourceLoader.h b/WebCore/loader/cache/CachedResourceLoader.h
index 0a44f73..2b90611 100644
--- a/WebCore/loader/cache/CachedResourceLoader.h
+++ b/WebCore/loader/cache/CachedResourceLoader.h
@@ -28,7 +28,6 @@
#include "CachedResource.h"
#include "CachedResourceHandle.h"
-#include "CachedResourceRequest.h"
#include "CachePolicy.h"
#include "ResourceLoadPriority.h"
#include <wtf/HashMap.h>
@@ -41,6 +40,7 @@ namespace WebCore {
class CachedCSSStyleSheet;
class CachedFont;
class CachedImage;
+class CachedResourceRequest;
class CachedScript;
class CachedXSLStyleSheet;
class Document;
@@ -108,14 +108,18 @@ public:
private:
CachedResource* requestResource(CachedResource::Type, const String& url, const String& charset, ResourceLoadPriority priority = ResourceLoadPriorityUnresolved, bool isPreload = false);
+ CachedResource* revalidateResource(CachedResource*, ResourceLoadPriority priority);
+ CachedResource* loadResource(CachedResource::Type, const KURL&, const String& charset, ResourceLoadPriority priority);
void requestPreload(CachedResource::Type, const String& url, const String& charset);
- void checkForReload(const KURL&);
- void checkCacheObjectStatus(CachedResource*);
+ enum RevalidationPolicy { Use, Revalidate, Reload, Load };
+ RevalidationPolicy determineRevalidationPolicy(CachedResource::Type, bool forPreload, CachedResource* existingResource) const;
+
+ void notifyLoadedFromMemoryCache(CachedResource*);
bool canRequest(CachedResource::Type, const KURL&);
MemoryCache* m_cache;
- HashSet<String> m_reloadedURLs;
+ HashSet<String> m_validatedURLs;
mutable DocumentResourceMap m_documentResources;
Document* m_document;
diff --git a/WebCore/loader/cache/MemoryCache.cpp b/WebCore/loader/cache/MemoryCache.cpp
index 8826cec..930033a 100644
--- a/WebCore/loader/cache/MemoryCache.cpp
+++ b/WebCore/loader/cache/MemoryCache.cpp
@@ -69,156 +69,6 @@ MemoryCache::MemoryCache()
{
}
-static CachedResource* createResource(CachedResource::Type type, const KURL& url, const String& charset)
-{
- switch (type) {
- case CachedResource::ImageResource:
- return new CachedImage(url.string());
- case CachedResource::CSSStyleSheet:
- return new CachedCSSStyleSheet(url.string(), charset);
- case CachedResource::Script:
- return new CachedScript(url.string(), charset);
- case CachedResource::FontResource:
- return new CachedFont(url.string());
-#if ENABLE(XSLT)
- case CachedResource::XSLStyleSheet:
- return new CachedXSLStyleSheet(url.string());
-#endif
-#if ENABLE(LINK_PREFETCH)
- case CachedResource::LinkPrefetch:
- return new CachedResource(url.string(), CachedResource::LinkPrefetch);
-#endif
- default:
- break;
- }
-
- return 0;
-}
-
-CachedResource* MemoryCache::requestResource(CachedResourceLoader* cachedResourceLoader, CachedResource::Type type, const KURL& requestURL, const String& charset, ResourceLoadPriority priority, bool requestIsPreload, bool forHistory)
-{
- LOG(ResourceLoading, "MemoryCache::requestResource '%s', charset '%s', priority=%d, preload=%u, forHistory=%u", requestURL.string().latin1().data(), charset.latin1().data(), priority, requestIsPreload, forHistory);
-
- // 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?
- if (requestURL.isEmpty())
- return 0;
-
- // Ensure this is the pure primary resource URL.
- KURL url = removeFragmentIdentifierIfNeeded(requestURL);
-
- // Look up the resource in our map.
- CachedResource* resource = resourceForURL(url);
-
- // Non https "no-store" resources are left in the cache to be used for back/forward navigation only.
- // If this is not a request forHistory and the resource was served with "no-store" we should evict
- // it here and make a fresh request.
- if (!forHistory && resource && resource->response().cacheControlContainsNoStore()) {
- LOG(ResourceLoading, "MemoryCache::requestResource cleared a for history only resource due to a non-history request for the resource");
- evict(resource);
- resource = 0;
- }
-
- if (resource && requestIsPreload && !resource->isPreloaded()) {
- LOG(ResourceLoading, "MemoryCache::requestResource already has a preload request for this request, and it hasn't been preloaded yet");
- return 0;
- }
-
- if (!cachedResourceLoader->document()->securityOrigin()->canDisplay(url)) {
- LOG(ResourceLoading, "...URL was not allowed by SecurityOrigin");
- if (!requestIsPreload)
- FrameLoader::reportLocalLoadFailed(cachedResourceLoader->document()->frame(), url.string());
- return 0;
- }
-
- if (resource && resource->type() != type) {
- LOG(ResourceLoading, "Cache::requestResource found a cache resource with matching url but different type, evicting and loading with new type.");
- evict(resource);
- resource = 0;
- }
-
- if (!resource) {
- LOG(ResourceLoading, "CachedResource for '%s' wasn't found in cache. Creating it", url.string().latin1().data());
- // The resource does not exist. Create it.
- resource = createResource(type, url, charset);
- ASSERT(resource);
-
- // Pretend the resource is in the cache, to prevent it from being deleted during the load() call.
- // FIXME: CachedResource should just use normal refcounting instead.
- resource->setInCache(true);
-
- // Default priority based on resource type is used if the request did not specify one.
- if (priority != ResourceLoadPriorityUnresolved)
- resource->setLoadPriority(priority);
-
- resource->load(cachedResourceLoader);
-
- if (resource->errorOccurred()) {
- // We don't support immediate loads, but we do support immediate failure.
- // In that case we should to delete the resource now and return 0 because otherwise
- // it would leak if no ref/deref was ever done on it.
- resource->setInCache(false);
- delete resource;
- return 0;
- }
-
- if (!disabled())
- m_resources.set(url.string(), resource); // The size will be added in later once the resource is loaded and calls back to us with the new size.
- else {
- // Kick the resource out of the cache, because the cache is disabled.
- resource->setInCache(false);
- resource->setCachedResourceLoader(cachedResourceLoader);
- }
- } else {
- // FIXME: Upgrading the priority doesn't really do much since the ResourceLoadScheduler does not currently
- // allow changing priorities. This might become important if we make scheduling priorities
- // more dynamic.
- if (priority != ResourceLoadPriorityUnresolved && resource->loadPriority() < priority)
- resource->setLoadPriority(priority);
- }
-
- if (!disabled()) {
- // This will move the resource to the front of its LRU list and increase its access count.
- resourceAccessed(resource);
- }
-
- LOG(ResourceLoading, "MemoryCache::requestResource for '%s' returning resource %p\n", url.string().latin1().data(), resource);
-
- return resource;
-}
-
-CachedCSSStyleSheet* MemoryCache::requestUserCSSStyleSheet(CachedResourceLoader* cachedResourceLoader, const KURL& requestURL, const String& charset)
-{
- // Ensure this is the pure primary resource URL.
- KURL url = removeFragmentIdentifierIfNeeded(requestURL);
-
- CachedCSSStyleSheet* userSheet;
- if (CachedResource* existing = resourceForURL(url)) {
- if (existing->type() != CachedResource::CSSStyleSheet)
- return 0;
- userSheet = static_cast<CachedCSSStyleSheet*>(existing);
- } else {
- userSheet = new CachedCSSStyleSheet(url, charset);
-
- // Pretend the resource is in the cache, to prevent it from being deleted during the load() call.
- // FIXME: CachedResource should just use normal refcounting instead.
- userSheet->setInCache(true);
- // Don't load incrementally, skip load checks, don't send resource load callbacks.
- userSheet->load(cachedResourceLoader, false, SkipSecurityCheck, false);
- if (!disabled())
- m_resources.set(url, userSheet);
- else
- userSheet->setInCache(false);
- }
-
- if (!disabled()) {
- // This will move the resource to the front of its LRU list and increase its access count.
- resourceAccessed(userSheet);
- }
-
- return userSheet;
-}
-
KURL MemoryCache::removeFragmentIdentifierIfNeeded(const KURL& originalURL)
{
if (!originalURL.hasFragmentIdentifier())
@@ -232,29 +82,20 @@ KURL MemoryCache::removeFragmentIdentifierIfNeeded(const KURL& originalURL)
return url;
}
-void MemoryCache::revalidateResource(CachedResource* resource, CachedResourceLoader* cachedResourceLoader)
+bool MemoryCache::add(CachedResource* resource)
{
- ASSERT(resource);
- ASSERT(resource->inCache());
- ASSERT(resource == m_resources.get(resource->url()));
- ASSERT(!disabled());
- if (resource->resourceToRevalidate())
- return;
- if (!resource->canUseCacheValidator()) {
- evict(resource);
- return;
- }
- const String& url = resource->url();
- CachedResource* newResource = createResource(resource->type(), KURL(ParsedURLString, url), resource->encoding());
- LOG(ResourceLoading, "Resource %p created to revalidate %p", newResource, resource);
- newResource->setResourceToRevalidate(resource);
- evict(resource);
- m_resources.set(url, newResource);
- newResource->setInCache(true);
- resourceAccessed(newResource);
- newResource->load(cachedResourceLoader);
-}
+ if (disabled())
+ return false;
+
+ m_resources.set(resource->url(), resource);
+ resource->setInCache(true);
+ resourceAccessed(resource);
+
+ LOG(ResourceLoading, "MemoryCache::add Added '%s', resource %p\n", resource->url().latin1().data(), resource);
+ return true;
+}
+
void MemoryCache::revalidationSucceeded(CachedResource* revalidatingResource, const ResourceResponse& response)
{
CachedResource* resource = revalidatingResource->resourceToRevalidate();
diff --git a/WebCore/loader/cache/MemoryCache.h b/WebCore/loader/cache/MemoryCache.h
index 15f4014..2798fba 100644
--- a/WebCore/loader/cache/MemoryCache.h
+++ b/WebCore/loader/cache/MemoryCache.h
@@ -102,16 +102,14 @@ public:
#endif
TypeStatistic fonts;
};
-
- // Request resources from the cache. A load will be initiated and a cache object created if the object is not
- // found in the cache.
- CachedResource* requestResource(CachedResourceLoader*, CachedResource::Type, const KURL& url, const String& charset, ResourceLoadPriority, bool isPreload = false, bool forHistory = false);
-
- CachedCSSStyleSheet* requestUserCSSStyleSheet(CachedResourceLoader*, const KURL& url, const String& charset);
+ CachedResource* resourceForURL(const KURL&);
+
+ bool add(CachedResource* resource);
+ void remove(CachedResource* resource) { evict(resource); }
+
static KURL removeFragmentIdentifierIfNeeded(const KURL& originalURL);
- void revalidateResource(CachedResource*, CachedResourceLoader*);
void revalidationSucceeded(CachedResource* revalidatingResource, const ResourceResponse&);
void revalidationFailed(CachedResource* revalidatingResource);
@@ -140,14 +138,9 @@ public:
void setDeadDecodedDataDeletionInterval(double interval) { m_deadDecodedDataDeletionInterval = interval; }
double deadDecodedDataDeletionInterval() const { return m_deadDecodedDataDeletionInterval; }
- // Remove an existing cache entry from both the resource map and from the LRU list.
- void remove(CachedResource* resource) { evict(resource); }
-
void addCachedResourceLoader(CachedResourceLoader*);
void removeCachedResourceLoader(CachedResourceLoader*);
- CachedResource* resourceForURL(const KURL&);
-
// Calls to put the cached resource into and out of LRU lists.
void insertInLRUList(CachedResource*);
void removeFromLRUList(CachedResource*);
@@ -166,13 +159,14 @@ public:
// Function to collect cache statistics for the caches window in the Safari Debug menu.
Statistics getStatistics();
+
+ void resourceAccessed(CachedResource*);
private:
MemoryCache();
~MemoryCache(); // Not implemented to make sure nobody accidentally calls delete -- WebCore does not delete singletons.
LRUList* lruListFor(CachedResource*);
- void resourceAccessed(CachedResource*);
#ifndef NDEBUG
void dumpStats();
void dumpLRULists(bool includeLive) const;
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list