[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