Changeset 74807 in webkit
- Timestamp:
- Dec 30, 2010 12:57:02 PM (13 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r74806 r74807 1 2010-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 1 74 2010-12-30 Steve Block <steveblock@google.com> 2 75 -
trunk/WebCore/WebCore.xcodeproj/project.pbxproj
r74800 r74807 22267 22267 buildConfigurationList = 149C284308902B11008A9EFC /* Build configuration list for PBXProject "WebCore" */; 22268 22268 compatibilityVersion = "Xcode 2.4"; 22269 developmentRegion = English; 22269 22270 hasScannedForEncodings = 1; 22270 22271 knownRegions = ( -
trunk/WebCore/css/CSSImageValue.cpp
r73938 r74807 67 67 StyleCachedImage* CSSImageValue::cachedImage(CachedResourceLoader* loader, const String& url) 68 68 { 69 ASSERT(loader); 70 69 71 if (!m_accessedImage) { 70 72 m_accessedImage = true; 71 73 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)) { 81 75 cachedImage->addClient(this); 82 76 m_image = StyleCachedImage::create(cachedImage); … … 84 78 } 85 79 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; 87 81 } 88 82 -
trunk/WebCore/loader/ImageLoader.cpp
r68854 r74807 165 165 newImage = new CachedImage(sourceURI(attr)); 166 166 newImage->setLoading(true); 167 newImage->set CachedResourceLoader(document->cachedResourceLoader());167 newImage->setOwningCachedResourceLoader(document->cachedResourceLoader()); 168 168 document->cachedResourceLoader()->m_documentResources.set(newImage->url(), newImage); 169 169 document->cachedResourceLoader()->setAutoLoadImages(autoLoadOtherImages); -
trunk/WebCore/loader/cache/CachedImage.cpp
r73749 r74807 30 30 #include "CachedResourceClientWalker.h" 31 31 #include "CachedResourceLoader.h" 32 #include "CachedResourceRequest.h" 32 33 #include "Frame.h" 33 34 #include "FrameLoaderTypes.h" -
trunk/WebCore/loader/cache/CachedResource.cpp
r74107 r74807 102 102 , m_nextInLiveResourcesList(0) 103 103 , m_prevInLiveResourcesList(0) 104 , m_ cachedResourceLoader(0)104 , m_owningCachedResourceLoader(0) 105 105 , m_resourceToRevalidate(0) 106 106 , m_proxyResource(0) … … 123 123 #endif 124 124 125 if (m_ cachedResourceLoader)126 m_ cachedResourceLoader->removeCachedResource(this);125 if (m_owningCachedResourceLoader) 126 m_owningCachedResourceLoader->removeCachedResource(this); 127 127 } 128 128 … … 491 491 return !m_response.httpHeaderField(lastModifiedHeader).isEmpty() || !m_response.httpHeaderField(eTagHeader).isEmpty(); 492 492 } 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 494 bool CachedResource::mustRevalidateDueToCacheHeaders(CachePolicy cachePolicy) const 495 { 496 ASSERT(cachePolicy == CachePolicyRevalidate || cachePolicy == CachePolicyCache || cachePolicy == CachePolicyVerify); 497 498 if (cachePolicy == CachePolicyRevalidate) 498 499 return true; 499 } 500 501 if (m_loading) 502 return false; 503 500 504 501 if (m_response.cacheControlContainsNoCache() || m_response.cacheControlContainsNoStore()) { 505 502 LOG(ResourceLoading, "CachedResource %p mustRevalidate because of m_response.cacheControlContainsNoCache() || m_response.cacheControlContainsNoStore()\n", this); … … 515 512 } 516 513 514 // CachePolicyVerify 517 515 if (isExpired()) { 518 516 LOG(ResourceLoading, "CachedResource %p mustRevalidate because of isExpired()\n", this); … … 588 586 */ 589 587 } 590 591 } 588 589 void 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 94 94 95 95 ResourceLoadPriority loadPriority() const { return m_loadPriority; } 96 void setLoadPriority(ResourceLoadPriority); 96 97 97 98 void addClient(CachedResourceClient*); … … 187 188 virtual void destroyDecodedData() { } 188 189 189 void set CachedResourceLoader(CachedResourceLoader* cachedResourceLoader) { m_cachedResourceLoader = cachedResourceLoader; }190 void setOwningCachedResourceLoader(CachedResourceLoader* cachedResourceLoader) { m_owningCachedResourceLoader = cachedResourceLoader; } 190 191 191 192 bool isPreloaded() const { return m_preloadCount; } … … 197 198 198 199 bool canUseCacheValidator() const; 199 bool mustRevalidate (CachePolicy) const;200 bool mustRevalidateDueToCacheHeaders(CachePolicy) const; 200 201 bool isCacheValidator() const { return m_resourceToRevalidate; } 201 202 CachedResource* resourceToRevalidate() const { return m_resourceToRevalidate; } … … 208 209 // better way to handle the archive case. 209 210 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); 210 217 211 218 protected: … … 231 238 private: 232 239 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 239 241 virtual PurgePriority purgePriority() const { return PurgeDefault; } 240 void setLoadPriority(ResourceLoadPriority loadPriority) { m_loadPriority = loadPriority; }241 242 242 243 double currentAge() const; … … 276 277 CachedResource* m_prevInLiveResourcesList; 277 278 278 CachedResourceLoader* m_ cachedResourceLoader; // only non-0 for resources that are not in the cache279 CachedResourceLoader* m_owningCachedResourceLoader; // only non-0 for resources that are not in the cache 279 280 280 281 // 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 31 31 #include "CachedFont.h" 32 32 #include "CachedImage.h" 33 #include "CachedResourceRequest.h" 33 34 #include "CachedScript.h" 34 35 #include "CachedXSLStyleSheet.h" … … 40 41 #include "FrameLoaderClient.h" 41 42 #include "HTMLElement.h" 43 #include "Logging.h" 42 44 #include "MemoryCache.h" 43 45 #include "PingLoader.h" … … 49 51 50 52 namespace WebCore { 53 54 static 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 } 51 77 52 78 CachedResourceLoader::CachedResourceLoader(Document* document) … … 67 93 DocumentResourceMap::iterator end = m_documentResources.end(); 68 94 for (DocumentResourceMap::iterator it = m_documentResources.begin(); it != end; ++it) 69 it->second->set CachedResourceLoader(0);95 it->second->setOwningCachedResourceLoader(0); 70 96 m_cache->removeCachedResourceLoader(this); 71 97 … … 89 115 { 90 116 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 pasting97 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());130 117 } 131 118 … … 162 149 } 163 150 164 CachedCSSStyleSheet* CachedResourceLoader::requestUserCSSStyleSheet(const String& url, const String& charset) 165 { 166 return cache()->requestUserCSSStyleSheet(this, KURL(KURL(), url), charset); 151 CachedCSSStyleSheet* 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; 167 172 } 168 173 … … 255 260 } 256 261 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); 262 CachedResource* 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); 260 267 261 268 // 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()) 265 272 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 } 266 284 267 285 if (cache()->disabled()) { 268 DocumentResourceMap::iterator it = m_documentResources.find(fullURL.string()); 269 286 DocumentResourceMap::iterator it = m_documentResources.find(url.string()); 270 287 if (it != m_documentResources.end()) { 271 it->second->set CachedResourceLoader(0);288 it->second->setOwningCachedResourceLoader(0); 272 289 m_documentResources.remove(it); 273 290 } 274 291 } 275 292 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 289 319 return resource; 320 } 321 322 CachedResource* 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 346 CachedResource* 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 382 CachedResourceLoader::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; 290 441 } 291 442 … … 379 530 } 380 531 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. 532 void CachedResourceLoader::notifyLoadedFromMemoryCache(CachedResource* resource) 533 { 384 534 if (!resource || !frame() || resource->status() != CachedResource::Cached) 385 535 return; -
trunk/WebCore/loader/cache/CachedResourceLoader.h
r74107 r74807 29 29 #include "CachedResource.h" 30 30 #include "CachedResourceHandle.h" 31 #include "CachedResourceRequest.h"32 31 #include "CachePolicy.h" 33 32 #include "ResourceLoadPriority.h" … … 42 41 class CachedFont; 43 42 class CachedImage; 43 class CachedResourceRequest; 44 44 class CachedScript; 45 45 class CachedXSLStyleSheet; … … 109 109 private: 110 110 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); 111 113 void requestPreload(CachedResource::Type, const String& url, const String& charset); 112 114 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*); 115 119 bool canRequest(CachedResource::Type, const KURL&); 116 120 117 121 MemoryCache* m_cache; 118 HashSet<String> m_ reloadedURLs;122 HashSet<String> m_validatedURLs; 119 123 mutable DocumentResourceMap m_documentResources; 120 124 Document* m_document; -
trunk/WebCore/loader/cache/MemoryCache.cpp
r74107 r74807 70 70 } 71 71 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 #endif87 #if ENABLE(LINK_PREFETCH)88 case CachedResource::LinkPrefetch:89 return new CachedResource(url.string(), CachedResource::LinkPrefetch);90 #endif91 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 evict115 // 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 otherwise159 // 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 currently174 // allow changing priorities. This might become important if we make scheduling priorities175 // 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 else211 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 222 72 KURL MemoryCache::removeFragmentIdentifierIfNeeded(const KURL& originalURL) 223 73 { … … 233 83 } 234 84 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 85 bool 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 258 99 void MemoryCache::revalidationSucceeded(CachedResource* revalidatingResource, const ResourceResponse& response) 259 100 { -
trunk/WebCore/loader/cache/MemoryCache.h
r74107 r74807 103 103 TypeStatistic fonts; 104 104 }; 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 112 111 static KURL removeFragmentIdentifierIfNeeded(const KURL& originalURL); 113 112 114 void revalidateResource(CachedResource*, CachedResourceLoader*);115 113 void revalidationSucceeded(CachedResource* revalidatingResource, const ResourceResponse&); 116 114 void revalidationFailed(CachedResource* revalidatingResource); … … 141 139 double deadDecodedDataDeletionInterval() const { return m_deadDecodedDataDeletionInterval; } 142 140 143 // Remove an existing cache entry from both the resource map and from the LRU list.144 void remove(CachedResource* resource) { evict(resource); }145 146 141 void addCachedResourceLoader(CachedResourceLoader*); 147 142 void removeCachedResourceLoader(CachedResourceLoader*); 148 149 CachedResource* resourceForURL(const KURL&);150 143 151 144 // Calls to put the cached resource into and out of LRU lists. … … 167 160 // Function to collect cache statistics for the caches window in the Safari Debug menu. 168 161 Statistics getStatistics(); 162 163 void resourceAccessed(CachedResource*); 169 164 170 165 private: … … 173 168 174 169 LRUList* lruListFor(CachedResource*); 175 void resourceAccessed(CachedResource*);176 170 #ifndef NDEBUG 177 171 void dumpStats();
Note: See TracChangeset
for help on using the changeset viewer.