Changeset 74807 in webkit


Ignore:
Timestamp:
Dec 30, 2010 12:57:02 PM (13 years ago)
Author:
Antti Koivisto
Message:

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):

Location:
trunk/WebCore
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r74806 r74807  
     12010-12-30  Antti Koivisto  <antti@apple.com>
     2
     3        Reviewed by Darin Adler.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=51134
     6        Move loading related code from MemoryCache to CachedResourceLoader
     7
     8        - Merge MemoryCache::requestResource to CachedResourceLoader::requestResource
     9        - Merge MemoryCache::requestUserCSSStyleSheet to CachedResourceLoader::requestUserCSSStyleSheet
     10        - Move MemoryCache::revalidateResource to CachedResourceLoader::revalidateResource
     11        - Add MemoryCache::add
     12        - Refactor the decision on whether to reload, revalidate or use the existing resource to
     13          a single function, CachedResourceLoader::determineRevalidationPolicy
     14
     15        * css/CSSImageValue.cpp:
     16        (WebCore::CSSImageValue::cachedImage):
     17           
     18            Remove a code path that called MemoryCache::requestResource directly. This code path would have crashed
     19            if ever taken (since it passes null CachedResourceLoader pointer).
     20           
     21        * loader/ImageLoader.cpp:
     22        (WebCore::ImageLoader::updateFromElement):
     23        * loader/cache/CachedImage.cpp:
     24        * loader/cache/CachedResource.cpp:
     25        (WebCore::CachedResource::CachedResource):
     26        (WebCore::CachedResource::~CachedResource):
     27        (WebCore::CachedResource::mustRevalidateDueToCacheHeaders):
     28       
     29            Moved tests that were not about cache headers to CachedResourceLoader::determineRevalidationPolicy and renamed.
     30       
     31        (WebCore::CachedResource::setLoadPriority):
     32       
     33            Check for Unresolved value before setting.
     34       
     35        * loader/cache/CachedResource.h:
     36        (WebCore::CachedResource::setOwningCachedResourceLoader):
     37       
     38            Rename to be bit less mysterious.
     39       
     40        * loader/cache/CachedResourceLoader.cpp:
     41        (WebCore::createResource):
     42       
     43            This was moved from MemoryCache.
     44       
     45        (WebCore::CachedResourceLoader::~CachedResourceLoader):
     46        (WebCore::CachedResourceLoader::determineRevalidationPolicy):
     47        (WebCore::CachedResourceLoader::requestUserCSSStyleSheet):
     48       
     49            This was moved/merged from MemoryCache.
     50       
     51        (WebCore::CachedResourceLoader::canRequest):
     52        (WebCore::CachedResourceLoader::requestResource):
     53       
     54            This combines MemoryCache::requestResource and the existing method.
     55       
     56        (WebCore::CachedResourceLoader::revalidateResource):
     57       
     58            This was moved from MemoryCache.
     59       
     60        (WebCore::CachedResourceLoader::loadResource):
     61       
     62            New method for initiating loading.
     63       
     64        (WebCore::CachedResourceLoader::notifyLoadedFromMemoryCache):
     65       
     66            Renamed the mysterious CachedResourceLoader::checkCacheObjectStatus
     67       
     68        * loader/cache/CachedResourceLoader.h:
     69        * loader/cache/MemoryCache.cpp:
     70        (WebCore::MemoryCache::add):
     71        * loader/cache/MemoryCache.h:
     72        (WebCore::MemoryCache::remove):
     73
    1742010-12-30  Steve Block  <steveblock@google.com>
    275
  • trunk/WebCore/WebCore.xcodeproj/project.pbxproj

    r74800 r74807  
    2226722267                        buildConfigurationList = 149C284308902B11008A9EFC /* Build configuration list for PBXProject "WebCore" */;
    2226822268                        compatibilityVersion = "Xcode 2.4";
     22269                        developmentRegion = English;
    2226922270                        hasScannedForEncodings = 1;
    2227022271                        knownRegions = (
  • trunk/WebCore/css/CSSImageValue.cpp

    r73938 r74807  
    6767StyleCachedImage* CSSImageValue::cachedImage(CachedResourceLoader* loader, const String& url)
    6868{
     69    ASSERT(loader);
     70
    6971    if (!m_accessedImage) {
    7072        m_accessedImage = true;
    7173
    72         CachedImage* cachedImage = 0;
    73         if (loader)
    74             cachedImage = loader->requestImage(url);
    75         else {
    76             // FIXME: Should find a way to make these images sit in their own memory partition, since they are user agent images.
    77             cachedImage = static_cast<CachedImage*>(cache()->requestResource(0, CachedResource::ImageResource, KURL(ParsedURLString, url), String(), ResourceLoadPriorityUnresolved));
    78         }
    79 
    80         if (cachedImage) {
     74        if (CachedImage* cachedImage = loader->requestImage(url)) {
    8175            cachedImage->addClient(this);
    8276            m_image = StyleCachedImage::create(cachedImage);
     
    8478    }
    8579   
    86     return m_image->isCachedImage() ? static_cast<StyleCachedImage*>(m_image.get()) : 0;
     80    return (m_image && m_image->isCachedImage()) ? static_cast<StyleCachedImage*>(m_image.get()) : 0;
    8781}
    8882
  • trunk/WebCore/loader/ImageLoader.cpp

    r68854 r74807  
    165165            newImage = new CachedImage(sourceURI(attr));
    166166            newImage->setLoading(true);
    167             newImage->setCachedResourceLoader(document->cachedResourceLoader());
     167            newImage->setOwningCachedResourceLoader(document->cachedResourceLoader());
    168168            document->cachedResourceLoader()->m_documentResources.set(newImage->url(), newImage);
    169169            document->cachedResourceLoader()->setAutoLoadImages(autoLoadOtherImages);
  • trunk/WebCore/loader/cache/CachedImage.cpp

    r73749 r74807  
    3030#include "CachedResourceClientWalker.h"
    3131#include "CachedResourceLoader.h"
     32#include "CachedResourceRequest.h"
    3233#include "Frame.h"
    3334#include "FrameLoaderTypes.h"
  • trunk/WebCore/loader/cache/CachedResource.cpp

    r74107 r74807  
    102102    , m_nextInLiveResourcesList(0)
    103103    , m_prevInLiveResourcesList(0)
    104     , m_cachedResourceLoader(0)
     104    , m_owningCachedResourceLoader(0)
    105105    , m_resourceToRevalidate(0)
    106106    , m_proxyResource(0)
     
    123123#endif
    124124
    125     if (m_cachedResourceLoader)
    126         m_cachedResourceLoader->removeCachedResource(this);
     125    if (m_owningCachedResourceLoader)
     126        m_owningCachedResourceLoader->removeCachedResource(this);
    127127}
    128128
     
    491491    return !m_response.httpHeaderField(lastModifiedHeader).isEmpty() || !m_response.httpHeaderField(eTagHeader).isEmpty();
    492492}
    493    
    494 bool CachedResource::mustRevalidate(CachePolicy cachePolicy) const
    495 {
    496     if (errorOccurred()) {
    497         LOG(ResourceLoading, "CachedResource %p mustRevalidate because of m_errorOccurred\n", this);
     493
     494bool CachedResource::mustRevalidateDueToCacheHeaders(CachePolicy cachePolicy) const
     495{   
     496    ASSERT(cachePolicy == CachePolicyRevalidate || cachePolicy == CachePolicyCache || cachePolicy == CachePolicyVerify);
     497
     498    if (cachePolicy == CachePolicyRevalidate)
    498499        return true;
    499     }
    500 
    501     if (m_loading)
    502         return false;
    503    
     500
    504501    if (m_response.cacheControlContainsNoCache() || m_response.cacheControlContainsNoStore()) {
    505502        LOG(ResourceLoading, "CachedResource %p mustRevalidate because of m_response.cacheControlContainsNoCache() || m_response.cacheControlContainsNoStore()\n", this);
     
    515512    }
    516513
     514    // CachePolicyVerify
    517515    if (isExpired()) {
    518516        LOG(ResourceLoading, "CachedResource %p mustRevalidate because of isExpired()\n", this);
     
    588586    */
    589587}
    590 
    591 }
     588   
     589void CachedResource::setLoadPriority(ResourceLoadPriority loadPriority)
     590{
     591    if (loadPriority == ResourceLoadPriorityUnresolved)
     592        return;
     593    m_loadPriority = loadPriority;
     594}
     595
     596}
  • trunk/WebCore/loader/cache/CachedResource.h

    r74049 r74807  
    9494   
    9595    ResourceLoadPriority loadPriority() const { return m_loadPriority; }
     96    void setLoadPriority(ResourceLoadPriority);
    9697
    9798    void addClient(CachedResourceClient*);
     
    187188    virtual void destroyDecodedData() { }
    188189
    189     void setCachedResourceLoader(CachedResourceLoader* cachedResourceLoader) { m_cachedResourceLoader = cachedResourceLoader; }
     190    void setOwningCachedResourceLoader(CachedResourceLoader* cachedResourceLoader) { m_owningCachedResourceLoader = cachedResourceLoader; }
    190191   
    191192    bool isPreloaded() const { return m_preloadCount; }
     
    197198   
    198199    bool canUseCacheValidator() const;
    199     bool mustRevalidate(CachePolicy) const;
     200    bool mustRevalidateDueToCacheHeaders(CachePolicy) const;
    200201    bool isCacheValidator() const { return m_resourceToRevalidate; }
    201202    CachedResource* resourceToRevalidate() const { return m_resourceToRevalidate; }
     
    208209    // better way to handle the archive case.
    209210    bool makePurgeable(bool purgeable);
     211   
     212    // HTTP revalidation support methods for CachedResourceLoader.
     213    void setResourceToRevalidate(CachedResource*);
     214    void switchClientsToRevalidatedResource();
     215    void clearResourceToRevalidate();
     216    void updateResponseAfterRevalidation(const ResourceResponse& validatingResponse);
    210217
    211218protected:
     
    231238private:
    232239    void addClientToSet(CachedResourceClient*);
    233                                        
    234     // These are called by the friendly MemoryCache only
    235     void setResourceToRevalidate(CachedResource*);
    236     void switchClientsToRevalidatedResource();
    237     void clearResourceToRevalidate();
    238     void updateResponseAfterRevalidation(const ResourceResponse& validatingResponse);
     240
    239241    virtual PurgePriority purgePriority() const { return PurgeDefault; }
    240     void setLoadPriority(ResourceLoadPriority loadPriority) { m_loadPriority = loadPriority; }
    241242
    242243    double currentAge() const;
     
    276277    CachedResource* m_prevInLiveResourcesList;
    277278
    278     CachedResourceLoader* m_cachedResourceLoader; // only non-0 for resources that are not in the cache
     279    CachedResourceLoader* m_owningCachedResourceLoader; // only non-0 for resources that are not in the cache
    279280   
    280281    // 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
  • trunk/WebCore/loader/cache/CachedResourceLoader.cpp

    r74107 r74807  
    3131#include "CachedFont.h"
    3232#include "CachedImage.h"
     33#include "CachedResourceRequest.h"
    3334#include "CachedScript.h"
    3435#include "CachedXSLStyleSheet.h"
     
    4041#include "FrameLoaderClient.h"
    4142#include "HTMLElement.h"
     43#include "Logging.h"
    4244#include "MemoryCache.h"
    4345#include "PingLoader.h"
     
    4951
    5052namespace WebCore {
     53
     54static CachedResource* createResource(CachedResource::Type type, const KURL& url, const String& charset)
     55{
     56    switch (type) {
     57    case CachedResource::ImageResource:
     58        return new CachedImage(url.string());
     59    case CachedResource::CSSStyleSheet:
     60        return new CachedCSSStyleSheet(url.string(), charset);
     61    case CachedResource::Script:
     62        return new CachedScript(url.string(), charset);
     63    case CachedResource::FontResource:
     64        return new CachedFont(url.string());
     65#if ENABLE(XSLT)
     66    case CachedResource::XSLStyleSheet:
     67        return new CachedXSLStyleSheet(url.string());
     68#endif
     69#if ENABLE(LINK_PREFETCH)
     70    case CachedResource::LinkPrefetch:
     71        return new CachedResource(url.string(), CachedResource::LinkPrefetch);
     72#endif
     73    }
     74    ASSERT_NOT_REACHED();
     75    return 0;
     76}
    5177
    5278CachedResourceLoader::CachedResourceLoader(Document* document)
     
    6793    DocumentResourceMap::iterator end = m_documentResources.end();
    6894    for (DocumentResourceMap::iterator it = m_documentResources.begin(); it != end; ++it)
    69         it->second->setCachedResourceLoader(0);
     95        it->second->setOwningCachedResourceLoader(0);
    7096    m_cache->removeCachedResourceLoader(this);
    7197
     
    89115{
    90116    return m_document->frame();
    91 }
    92 
    93 void CachedResourceLoader::checkForReload(const KURL& fullURL)
    94 {
    95     if (m_allowStaleResources)
    96         return; // Don't reload resources while pasting
    97 
    98     if (fullURL.isEmpty())
    99         return;
    100    
    101     if (m_reloadedURLs.contains(fullURL.string()))
    102         return;
    103    
    104     CachedResource* existing = cache()->resourceForURL(fullURL);
    105     if (!existing || existing->isPreloaded())
    106         return;
    107 
    108     switch (cachePolicy()) {
    109     case CachePolicyVerify:
    110         if (!existing->mustRevalidate(CachePolicyVerify))
    111             return;
    112         cache()->revalidateResource(existing, this);
    113         break;
    114     case CachePolicyCache:
    115         if (!existing->mustRevalidate(CachePolicyCache))
    116             return;
    117         cache()->revalidateResource(existing, this);
    118         break;
    119     case CachePolicyReload:
    120         cache()->remove(existing);       
    121         break;
    122     case CachePolicyRevalidate:
    123         cache()->revalidateResource(existing, this);
    124         break;
    125     case CachePolicyHistoryBuffer:
    126         return;
    127     }
    128 
    129     m_reloadedURLs.add(fullURL.string());
    130117}
    131118
     
    162149}
    163150
    164 CachedCSSStyleSheet* CachedResourceLoader::requestUserCSSStyleSheet(const String& url, const String& charset)
    165 {
    166     return cache()->requestUserCSSStyleSheet(this, KURL(KURL(), url), charset);
     151CachedCSSStyleSheet* CachedResourceLoader::requestUserCSSStyleSheet(const String& requestURL, const String& charset)
     152{
     153    KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(KURL(KURL(), requestURL));
     154
     155    if (CachedResource* existing = cache()->resourceForURL(url)) {
     156        if (existing->type() == CachedResource::CSSStyleSheet)
     157            return static_cast<CachedCSSStyleSheet*>(existing);
     158        cache()->remove(existing);
     159    }
     160    CachedCSSStyleSheet* userSheet = new CachedCSSStyleSheet(url, charset);
     161   
     162    bool inCache = cache()->add(userSheet);
     163    if (!inCache)
     164        userSheet->setInCache(true);
     165   
     166    userSheet->load(this, /*incremental*/ false, SkipSecurityCheck, /*sendResourceLoadCallbacks*/ false);
     167
     168    if (!inCache)
     169        userSheet->setInCache(false);
     170   
     171    return userSheet;
    167172}
    168173
     
    255260}
    256261
    257 CachedResource* CachedResourceLoader::requestResource(CachedResource::Type type, const String& url, const String& charset, ResourceLoadPriority priority, bool isPreload)
    258 {
    259     KURL fullURL = m_document->completeURL(url);
     262CachedResource* CachedResourceLoader::requestResource(CachedResource::Type type, const String& resourceURL, const String& charset, ResourceLoadPriority priority, bool forPreload)
     263{
     264    KURL url = m_document->completeURL(resourceURL);
     265   
     266    LOG(ResourceLoading, "CachedResourceLoader::requestResource '%s', charset '%s', priority=%d, forPreload=%u", url.string().latin1().data(), charset.latin1().data(), priority, forPreload);
    260267   
    261268    // If only the fragment identifiers differ, it is the same resource.
    262     fullURL = MemoryCache::removeFragmentIdentifierIfNeeded(fullURL);
    263 
    264     if (!fullURL.isValid() || !canRequest(type, fullURL))
     269    url = MemoryCache::removeFragmentIdentifierIfNeeded(url);
     270
     271    if (!url.isValid())
    265272        return 0;
     273   
     274    if (!canRequest(type, url))
     275        return 0;
     276
     277    // FIXME: Figure out what is the correct way to merge this security check with the one above.
     278    if (!document()->securityOrigin()->canDisplay(url)) {
     279        if (!forPreload)
     280            FrameLoader::reportLocalLoadFailed(document()->frame(), url.string());
     281        LOG(ResourceLoading, "CachedResourceLoader::requestResource URL was not allowed by SecurityOrigin::canDisplay");
     282        return 0;
     283    }
    266284
    267285    if (cache()->disabled()) {
    268         DocumentResourceMap::iterator it = m_documentResources.find(fullURL.string());
    269        
     286        DocumentResourceMap::iterator it = m_documentResources.find(url.string());
    270287        if (it != m_documentResources.end()) {
    271             it->second->setCachedResourceLoader(0);
     288            it->second->setOwningCachedResourceLoader(0);
    272289            m_documentResources.remove(it);
    273290        }
    274291    }
    275292
    276     checkForReload(fullURL);
    277 
    278     bool allowForHistoryOnlyResources = cachePolicy() == CachePolicyHistoryBuffer;
    279     CachedResource* resource = cache()->requestResource(this, type, fullURL, charset, priority, isPreload, allowForHistoryOnlyResources);
    280     if (resource) {
    281         // Check final URL of resource to catch redirects.
    282         // See <https://bugs.webkit.org/show_bug.cgi?id=21963>.
    283         if (fullURL != resource->url() && !canRequest(type, KURL(ParsedURLString, resource->url())))
    284             return 0;
    285 
    286         m_documentResources.set(resource->url(), resource);
    287         checkCacheObjectStatus(resource);
    288     }
     293    // See if we can use an existing resource from the cache.
     294    CachedResource* resource = cache()->resourceForURL(url);
     295
     296    switch (determineRevalidationPolicy(type, forPreload, resource)) {
     297    case Load:
     298        resource = loadResource(type, url, charset, priority);
     299        break;
     300    case Reload:
     301        cache()->remove(resource);
     302        resource = loadResource(type, url, charset, priority);
     303        break;
     304    case Revalidate:
     305        resource = revalidateResource(resource, priority);
     306        break;
     307    case Use:
     308        cache()->resourceAccessed(resource);
     309        notifyLoadedFromMemoryCache(resource);
     310        break;
     311    }
     312
     313    if (!resource)
     314        return 0;
     315
     316    ASSERT(resource->url() == url.string());
     317    m_documentResources.set(resource->url(), resource);
     318   
    289319    return resource;
     320}
     321   
     322CachedResource* CachedResourceLoader::revalidateResource(CachedResource* resource, ResourceLoadPriority priority)
     323{
     324    ASSERT(resource);
     325    ASSERT(resource->inCache());
     326    ASSERT(!cache()->disabled());
     327    ASSERT(resource->canUseCacheValidator());
     328    ASSERT(!resource->resourceToRevalidate());
     329   
     330    const String& url = resource->url();
     331    CachedResource* newResource = createResource(resource->type(), KURL(ParsedURLString, url), resource->encoding());
     332   
     333    LOG(ResourceLoading, "Resource %p created to revalidate %p", newResource, resource);
     334    newResource->setResourceToRevalidate(resource);
     335   
     336    cache()->remove(resource);
     337    cache()->add(newResource);
     338   
     339    newResource->setLoadPriority(priority);
     340    newResource->load(this);
     341   
     342    m_validatedURLs.add(url);
     343    return newResource;
     344}
     345
     346CachedResource* CachedResourceLoader::loadResource(CachedResource::Type type, const KURL& url, const String& charset, ResourceLoadPriority priority)
     347{
     348    ASSERT(!cache()->resourceForURL(url));
     349   
     350    LOG(ResourceLoading, "Loading CachedResource for '%s'.", url.string().latin1().data());
     351   
     352    CachedResource* resource = createResource(type, url, charset);
     353   
     354    bool inCache = cache()->add(resource);
     355   
     356    // Pretend the resource is in the cache, to prevent it from being deleted during the load() call.
     357    // FIXME: CachedResource should just use normal refcounting instead.
     358    if (!inCache)
     359        resource->setInCache(true);
     360   
     361    resource->setLoadPriority(priority);
     362    resource->load(this);
     363   
     364    if (!inCache) {
     365        resource->setOwningCachedResourceLoader(this);
     366        resource->setInCache(false);
     367    }
     368
     369    // We don't support immediate loads, but we do support immediate failure.
     370    if (resource->errorOccurred()) {
     371        if (inCache)
     372            cache()->remove(resource);
     373        else
     374            delete resource;
     375        return 0;
     376    }
     377
     378    m_validatedURLs.add(url.string());
     379    return resource;
     380}
     381
     382CachedResourceLoader::RevalidationPolicy CachedResourceLoader::determineRevalidationPolicy(CachedResource::Type type, bool forPreload, CachedResource* existingResource) const
     383{
     384    if (!existingResource)
     385        return Load;
     386   
     387    // We already have a preload going for this URL.
     388    if (forPreload && existingResource->isPreloaded())
     389        return Use;
     390   
     391    // If the same URL has been loaded as a different type, we need to reload.
     392    if (existingResource->type() != type) {
     393        LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicy reloading due to type mismatch.");
     394        return Reload;
     395    }
     396   
     397    // Don't reload resources while pasting.
     398    if (m_allowStaleResources)
     399        return Use;
     400   
     401    // Alwaus use preloads.
     402    if (existingResource->isPreloaded())
     403        return Use;
     404   
     405    // Avoid loading the same resource multiple times for a single document, even if the cache policies would tell us to.
     406    if (m_validatedURLs.contains(existingResource->url()))
     407        return Use;
     408   
     409    // CachePolicyReload always reloads
     410    if (cachePolicy() == CachePolicyReload) {
     411        LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicy reloading due to CachePolicyReload.");
     412        return Reload;
     413    }
     414   
     415    // CachePolicyHistoryBuffer uses the cache no matter what.
     416    if (cachePolicy() == CachePolicyHistoryBuffer)
     417        return Use;
     418   
     419    // We'll try to reload the resource if it failed last time.
     420    if (existingResource->errorOccurred()) {
     421        LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicye reloading due to resource being in the error state");
     422        return Reload;
     423    }
     424   
     425    // For resources that are not yet loaded we ignore the cache policy.
     426    if (existingResource->isLoading())
     427        return Use;
     428
     429    // Check if the cache headers requires us to revalidate (cache expiration for example).
     430    if (existingResource->mustRevalidateDueToCacheHeaders(cachePolicy())) {
     431        // See if the resource has usable ETag or Last-modified headers.
     432        if (existingResource->canUseCacheValidator())
     433            return Revalidate;
     434       
     435        // No, must reload.
     436        LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicy reloading due to missing cache validators.");           
     437        return Reload;
     438    }
     439
     440    return Use;
    290441}
    291442
     
    379530}
    380531
    381 void CachedResourceLoader::checkCacheObjectStatus(CachedResource* resource)
    382 {
    383     // Return from the function for objects that we didn't load from the cache or if we don't have a frame.
     532void CachedResourceLoader::notifyLoadedFromMemoryCache(CachedResource* resource)
     533{
    384534    if (!resource || !frame() || resource->status() != CachedResource::Cached)
    385535        return;
  • trunk/WebCore/loader/cache/CachedResourceLoader.h

    r74107 r74807  
    2929#include "CachedResource.h"
    3030#include "CachedResourceHandle.h"
    31 #include "CachedResourceRequest.h"
    3231#include "CachePolicy.h"
    3332#include "ResourceLoadPriority.h"
     
    4241class CachedFont;
    4342class CachedImage;
     43class CachedResourceRequest;
    4444class CachedScript;
    4545class CachedXSLStyleSheet;
     
    109109private:
    110110    CachedResource* requestResource(CachedResource::Type, const String& url, const String& charset, ResourceLoadPriority priority = ResourceLoadPriorityUnresolved, bool isPreload = false);
     111    CachedResource* revalidateResource(CachedResource*, ResourceLoadPriority priority);
     112    CachedResource* loadResource(CachedResource::Type, const KURL&, const String& charset, ResourceLoadPriority priority);
    111113    void requestPreload(CachedResource::Type, const String& url, const String& charset);
    112114
    113     void checkForReload(const KURL&);
    114     void checkCacheObjectStatus(CachedResource*);
     115    enum RevalidationPolicy { Use, Revalidate, Reload, Load };
     116    RevalidationPolicy determineRevalidationPolicy(CachedResource::Type, bool forPreload, CachedResource* existingResource) const;
     117   
     118    void notifyLoadedFromMemoryCache(CachedResource*);
    115119    bool canRequest(CachedResource::Type, const KURL&);
    116120   
    117121    MemoryCache* m_cache;
    118     HashSet<String> m_reloadedURLs;
     122    HashSet<String> m_validatedURLs;
    119123    mutable DocumentResourceMap m_documentResources;
    120124    Document* m_document;
  • trunk/WebCore/loader/cache/MemoryCache.cpp

    r74107 r74807  
    7070}
    7171
    72 static CachedResource* createResource(CachedResource::Type type, const KURL& url, const String& charset)
    73 {
    74     switch (type) {
    75     case CachedResource::ImageResource:
    76         return new CachedImage(url.string());
    77     case CachedResource::CSSStyleSheet:
    78         return new CachedCSSStyleSheet(url.string(), charset);
    79     case CachedResource::Script:
    80         return new CachedScript(url.string(), charset);
    81     case CachedResource::FontResource:
    82         return new CachedFont(url.string());
    83 #if ENABLE(XSLT)
    84     case CachedResource::XSLStyleSheet:
    85         return new CachedXSLStyleSheet(url.string());
    86 #endif
    87 #if ENABLE(LINK_PREFETCH)
    88     case CachedResource::LinkPrefetch:
    89         return new CachedResource(url.string(), CachedResource::LinkPrefetch);
    90 #endif
    91     default:
    92         break;
    93     }
    94 
    95     return 0;
    96 }
    97 
    98 CachedResource* MemoryCache::requestResource(CachedResourceLoader* cachedResourceLoader, CachedResource::Type type, const KURL& requestURL, const String& charset, ResourceLoadPriority priority, bool requestIsPreload, bool forHistory)
    99 {
    100     LOG(ResourceLoading, "MemoryCache::requestResource '%s', charset '%s', priority=%d, preload=%u, forHistory=%u", requestURL.string().latin1().data(), charset.latin1().data(), priority, requestIsPreload, forHistory);
    101    
    102     // FIXME: Do we really need to special-case an empty URL?
    103     // Would it be better to just go on with the cache code and let it fail later?
    104     if (requestURL.isEmpty())
    105         return 0;
    106    
    107     // Ensure this is the pure primary resource URL.
    108     KURL url = removeFragmentIdentifierIfNeeded(requestURL);
    109 
    110     // Look up the resource in our map.
    111     CachedResource* resource = resourceForURL(url);
    112 
    113     // Non https "no-store" resources are left in the cache to be used for back/forward navigation only.
    114     // If this is not a request forHistory and the resource was served with "no-store" we should evict
    115     // it here and make a fresh request.
    116     if (!forHistory && resource && resource->response().cacheControlContainsNoStore()) {
    117         LOG(ResourceLoading, "MemoryCache::requestResource cleared a for history only resource due to a non-history request for the resource");
    118         evict(resource);
    119         resource = 0;
    120     }
    121 
    122     if (resource && requestIsPreload && !resource->isPreloaded()) {
    123         LOG(ResourceLoading, "MemoryCache::requestResource already has a preload request for this request, and it hasn't been preloaded yet");
    124         return 0;
    125     }
    126 
    127     if (!cachedResourceLoader->document()->securityOrigin()->canDisplay(url)) {
    128         LOG(ResourceLoading, "...URL was not allowed by SecurityOrigin");
    129         if (!requestIsPreload)
    130             FrameLoader::reportLocalLoadFailed(cachedResourceLoader->document()->frame(), url.string());
    131         return 0;
    132     }
    133 
    134     if (resource && resource->type() != type) {
    135         LOG(ResourceLoading, "Cache::requestResource found a cache resource with matching url but different type, evicting and loading with new type.");
    136         evict(resource);
    137         resource = 0;
    138     }
    139 
    140     if (!resource) {
    141         LOG(ResourceLoading, "CachedResource for '%s' wasn't found in cache. Creating it", url.string().latin1().data());
    142         // The resource does not exist. Create it.
    143         resource = createResource(type, url, charset);
    144         ASSERT(resource);
    145 
    146         // Pretend the resource is in the cache, to prevent it from being deleted during the load() call.
    147         // FIXME: CachedResource should just use normal refcounting instead.
    148         resource->setInCache(true);
    149        
    150         // Default priority based on resource type is used if the request did not specify one.
    151         if (priority != ResourceLoadPriorityUnresolved)
    152             resource->setLoadPriority(priority);
    153 
    154         resource->load(cachedResourceLoader);
    155        
    156         if (resource->errorOccurred()) {
    157             // We don't support immediate loads, but we do support immediate failure.
    158             // In that case we should to delete the resource now and return 0 because otherwise
    159             // it would leak if no ref/deref was ever done on it.
    160             resource->setInCache(false);
    161             delete resource;
    162             return 0;
    163         }
    164 
    165         if (!disabled())
    166             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.
    167         else {
    168             // Kick the resource out of the cache, because the cache is disabled.
    169             resource->setInCache(false);
    170             resource->setCachedResourceLoader(cachedResourceLoader);
    171         }
    172     } else {
    173         // FIXME: Upgrading the priority doesn't really do much since the ResourceLoadScheduler does not currently
    174         // allow changing priorities. This might become important if we make scheduling priorities
    175         // more dynamic.
    176         if (priority != ResourceLoadPriorityUnresolved && resource->loadPriority() < priority)
    177             resource->setLoadPriority(priority);
    178     }
    179 
    180     if (!disabled()) {
    181         // This will move the resource to the front of its LRU list and increase its access count.
    182         resourceAccessed(resource);
    183     }
    184 
    185     LOG(ResourceLoading, "MemoryCache::requestResource for '%s' returning resource %p\n", url.string().latin1().data(), resource);
    186 
    187     return resource;
    188 }
    189    
    190 CachedCSSStyleSheet* MemoryCache::requestUserCSSStyleSheet(CachedResourceLoader* cachedResourceLoader, const KURL& requestURL, const String& charset)
    191 {
    192     // Ensure this is the pure primary resource URL.
    193     KURL url = removeFragmentIdentifierIfNeeded(requestURL);
    194 
    195     CachedCSSStyleSheet* userSheet;
    196     if (CachedResource* existing = resourceForURL(url)) {
    197         if (existing->type() != CachedResource::CSSStyleSheet)
    198             return 0;
    199         userSheet = static_cast<CachedCSSStyleSheet*>(existing);
    200     } else {
    201         userSheet = new CachedCSSStyleSheet(url, charset);
    202 
    203         // Pretend the resource is in the cache, to prevent it from being deleted during the load() call.
    204         // FIXME: CachedResource should just use normal refcounting instead.
    205         userSheet->setInCache(true);
    206         // Don't load incrementally, skip load checks, don't send resource load callbacks.
    207         userSheet->load(cachedResourceLoader, false, SkipSecurityCheck, false);
    208         if (!disabled())
    209             m_resources.set(url, userSheet);
    210         else
    211             userSheet->setInCache(false);
    212     }
    213 
    214     if (!disabled()) {
    215         // This will move the resource to the front of its LRU list and increase its access count.
    216         resourceAccessed(userSheet);
    217     }
    218 
    219     return userSheet;
    220 }
    221 
    22272KURL MemoryCache::removeFragmentIdentifierIfNeeded(const KURL& originalURL)
    22373{
     
    23383}
    23484
    235 void MemoryCache::revalidateResource(CachedResource* resource, CachedResourceLoader* cachedResourceLoader)
    236 {
    237     ASSERT(resource);
    238     ASSERT(resource->inCache());
    239     ASSERT(resource == m_resources.get(resource->url()));
    240     ASSERT(!disabled());
    241     if (resource->resourceToRevalidate())
    242         return;
    243     if (!resource->canUseCacheValidator()) {
    244         evict(resource);
    245         return;
    246     }
    247     const String& url = resource->url();
    248     CachedResource* newResource = createResource(resource->type(), KURL(ParsedURLString, url), resource->encoding());
    249     LOG(ResourceLoading, "Resource %p created to revalidate %p", newResource, resource);
    250     newResource->setResourceToRevalidate(resource);
    251     evict(resource);
    252     m_resources.set(url, newResource);
    253     newResource->setInCache(true);
    254     resourceAccessed(newResource);
    255     newResource->load(cachedResourceLoader);
    256 }
    257    
     85bool MemoryCache::add(CachedResource* resource)
     86{
     87    if (disabled())
     88        return false;
     89   
     90    m_resources.set(resource->url(), resource);
     91    resource->setInCache(true);
     92   
     93    resourceAccessed(resource);
     94   
     95    LOG(ResourceLoading, "MemoryCache::add Added '%s', resource %p\n", resource->url().latin1().data(), resource);
     96    return true;
     97}
     98
    25899void MemoryCache::revalidationSucceeded(CachedResource* revalidatingResource, const ResourceResponse& response)
    259100{
  • trunk/WebCore/loader/cache/MemoryCache.h

    r74107 r74807  
    103103        TypeStatistic fonts;
    104104    };
    105 
    106     // Request resources from the cache.  A load will be initiated and a cache object created if the object is not
    107     // found in the cache.
    108     CachedResource* requestResource(CachedResourceLoader*, CachedResource::Type, const KURL& url, const String& charset, ResourceLoadPriority, bool isPreload = false, bool forHistory = false);
    109 
    110     CachedCSSStyleSheet* requestUserCSSStyleSheet(CachedResourceLoader*, const KURL& url, const String& charset);
    111    
     105   
     106    CachedResource* resourceForURL(const KURL&);
     107   
     108    bool add(CachedResource* resource);
     109    void remove(CachedResource* resource) { evict(resource); }
     110
    112111    static KURL removeFragmentIdentifierIfNeeded(const KURL& originalURL);
    113112   
    114     void revalidateResource(CachedResource*, CachedResourceLoader*);
    115113    void revalidationSucceeded(CachedResource* revalidatingResource, const ResourceResponse&);
    116114    void revalidationFailed(CachedResource* revalidatingResource);
     
    141139    double deadDecodedDataDeletionInterval() const { return m_deadDecodedDataDeletionInterval; }
    142140
    143     // Remove an existing cache entry from both the resource map and from the LRU list.
    144     void remove(CachedResource* resource) { evict(resource); }
    145 
    146141    void addCachedResourceLoader(CachedResourceLoader*);
    147142    void removeCachedResourceLoader(CachedResourceLoader*);
    148 
    149     CachedResource* resourceForURL(const KURL&);
    150143
    151144    // Calls to put the cached resource into and out of LRU lists.
     
    167160    // Function to collect cache statistics for the caches window in the Safari Debug menu.
    168161    Statistics getStatistics();
     162   
     163    void resourceAccessed(CachedResource*);
    169164
    170165private:
     
    173168       
    174169    LRUList* lruListFor(CachedResource*);
    175     void resourceAccessed(CachedResource*);
    176170#ifndef NDEBUG
    177171    void dumpStats();
Note: See TracChangeset for help on using the changeset viewer.