Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Side by Side Diff: Source/core/fetch/MemoryCache.cpp

Issue 640463003: MemoryCache: Enable MemoryCache to have multiple isolated resource maps (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: tweak variable names Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/fetch/MemoryCache.h ('k') | Source/core/fetch/MemoryCacheTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) 3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org)
4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) 4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org)
5 Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 5 Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
6 6
7 This library is free software; you can redistribute it and/or 7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public 8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either 9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version. 10 version 2 of the License, or (at your option) any later version.
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 if (m_prunePending) 127 if (m_prunePending)
128 blink::Platform::current()->currentThread()->removeTaskObserver(this); 128 blink::Platform::current()->currentThread()->removeTaskObserver(this);
129 } 129 }
130 130
131 void MemoryCache::trace(Visitor* visitor) 131 void MemoryCache::trace(Visitor* visitor)
132 { 132 {
133 #if ENABLE(OILPAN) 133 #if ENABLE(OILPAN)
134 visitor->trace(m_allResources); 134 visitor->trace(m_allResources);
135 for (size_t i = 0; i < WTF_ARRAY_LENGTH(m_liveDecodedResources); ++i) 135 for (size_t i = 0; i < WTF_ARRAY_LENGTH(m_liveDecodedResources); ++i)
136 visitor->trace(m_liveDecodedResources[i]); 136 visitor->trace(m_liveDecodedResources[i]);
137 visitor->trace(m_resources); 137 visitor->trace(m_resourceMaps);
138 visitor->trace(m_liveResources); 138 visitor->trace(m_liveResources);
139 #endif 139 #endif
140 } 140 }
141 141
142 KURL MemoryCache::removeFragmentIdentifierIfNeeded(const KURL& originalURL) 142 KURL MemoryCache::removeFragmentIdentifierIfNeeded(const KURL& originalURL)
143 { 143 {
144 if (!originalURL.hasFragmentIdentifier()) 144 if (!originalURL.hasFragmentIdentifier())
145 return originalURL; 145 return originalURL;
146 // Strip away fragment identifier from HTTP URLs. 146 // Strip away fragment identifier from HTTP URLs.
147 // Data URLs must be unmodified. For file and custom URLs clients may expect resources 147 // Data URLs must be unmodified. For file and custom URLs clients may expect resources
148 // to be unique even when they differ by the fragment identifier only. 148 // to be unique even when they differ by the fragment identifier only.
149 if (!originalURL.protocolIsInHTTPFamily()) 149 if (!originalURL.protocolIsInHTTPFamily())
150 return originalURL; 150 return originalURL;
151 KURL url = originalURL; 151 KURL url = originalURL;
152 url.removeFragmentIdentifier(); 152 url.removeFragmentIdentifier();
153 return url; 153 return url;
154 } 154 }
155 155
156 String MemoryCache::defaultCacheIdentifier()
157 {
158 return emptyString();
159 }
160
161 MemoryCache::ResourceMap* MemoryCache::ensureResourceMap(const String& cacheIden tifier)
162 {
163 if (!m_resourceMaps.contains(cacheIdentifier)) {
164 ResourceMapIndex::AddResult result = m_resourceMaps.add(cacheIdentifier, adoptPtrWillBeNoop(new ResourceMap()));
165 RELEASE_ASSERT(result.isNewEntry);
166 }
167 return m_resourceMaps.get(cacheIdentifier);
168 }
169
156 void MemoryCache::add(Resource* resource) 170 void MemoryCache::add(Resource* resource)
157 { 171 {
158 ASSERT(WTF::isMainThread()); 172 ASSERT(WTF::isMainThread());
159 ASSERT(resource->url().isValid()); 173 ASSERT(resource->url().isValid());
160 RELEASE_ASSERT(!m_resources.contains(resource->url())); 174 ResourceMap* resources = ensureResourceMap(resource->cacheIdentifier());
161 m_resources.set(resource->url().string(), MemoryCacheEntry::create(resource) ); 175 RELEASE_ASSERT(!resources->contains(resource->url()));
176 resources->set(resource->url(), MemoryCacheEntry::create(resource));
162 update(resource, 0, resource->size(), true); 177 update(resource, 0, resource->size(), true);
163 178
164 WTF_LOG(ResourceLoading, "MemoryCache::add Added '%s', resource %p\n", resou rce->url().string().latin1().data(), resource); 179 WTF_LOG(ResourceLoading, "MemoryCache::add Added '%s', resource %p\n", resou rce->url().string().latin1().data(), resource);
165 } 180 }
166 181
167 void MemoryCache::replace(Resource* newResource, Resource* oldResource) 182 void MemoryCache::replace(Resource* newResource, Resource* oldResource)
168 { 183 {
169 if (MemoryCacheEntry* oldEntry = m_resources.get(oldResource->url())) 184 ASSERT(newResource->cacheIdentifier() == oldResource->cacheIdentifier());
185 ResourceMap* resources = ensureResourceMap(oldResource->cacheIdentifier());
186 if (MemoryCacheEntry* oldEntry = resources->get(oldResource->url()))
170 evict(oldEntry); 187 evict(oldEntry);
171 add(newResource); 188 add(newResource);
172 if (newResource->decodedSize() && newResource->hasClients()) 189 if (newResource->decodedSize() && newResource->hasClients())
173 insertInLiveDecodedResourcesList(m_resources.get(newResource->url())); 190 insertInLiveDecodedResourcesList(resources->get(newResource->url()));
174 } 191 }
175 192
176 void MemoryCache::remove(Resource* resource) 193 void MemoryCache::remove(Resource* resource)
177 { 194 {
178 // The resource may have already been removed by someone other than our call er, 195 // The resource may have already been removed by someone other than our call er,
179 // who needed a fresh copy for a reload. 196 // who needed a fresh copy for a reload.
180 if (!contains(resource)) 197 if (MemoryCacheEntry* entry = getEntryForResource(resource))
181 return; 198 evict(entry);
182 evict(m_resources.get(resource->url()));
183 } 199 }
184 200
185 bool MemoryCache::contains(const Resource* resource) const 201 bool MemoryCache::contains(const Resource* resource) const
186 { 202 {
187 if (resource->url().isNull()) 203 return getEntryForResource(resource);
188 return false;
189 const MemoryCacheEntry* entry = m_resources.get(resource->url());
190 return entry && entry->m_resource == resource;
191 } 204 }
192 205
193 Resource* MemoryCache::resourceForURL(const KURL& resourceURL) 206 Resource* MemoryCache::resourceForURL(const KURL& resourceURL)
194 { 207 {
208 return resourceForURL(resourceURL, defaultCacheIdentifier());
209 }
210
211 Resource* MemoryCache::resourceForURL(const KURL& resourceURL, const String& cac heIdentifier)
212 {
195 ASSERT(WTF::isMainThread()); 213 ASSERT(WTF::isMainThread());
214 ResourceMap* resources = m_resourceMaps.get(cacheIdentifier);
215 if (!resources)
216 return nullptr;
196 KURL url = removeFragmentIdentifierIfNeeded(resourceURL); 217 KURL url = removeFragmentIdentifierIfNeeded(resourceURL);
197 MemoryCacheEntry* entry = m_resources.get(url); 218 MemoryCacheEntry* entry = resources->get(url);
198 if (!entry) 219 if (!entry)
199 return 0; 220 return nullptr;
200 Resource* resource = entry->m_resource.get(); 221 Resource* resource = entry->m_resource.get();
201 if (resource && !resource->lock()) { 222 if (resource && !resource->lock()) {
202 ASSERT(!resource->hasClients()); 223 ASSERT(!resource->hasClients());
203 bool didEvict = evict(entry); 224 bool didEvict = evict(entry);
204 ASSERT_UNUSED(didEvict, didEvict); 225 ASSERT_UNUSED(didEvict, didEvict);
205 return 0; 226 return nullptr;
206 } 227 }
207 return resource; 228 return resource;
208 } 229 }
209 230
231 WillBeHeapVector<Member<Resource>> MemoryCache::resourcesForURL(const KURL& reso urceURL)
232 {
233 ASSERT(WTF::isMainThread());
234 KURL url = removeFragmentIdentifierIfNeeded(resourceURL);
235 WillBeHeapVector<Member<Resource>> results;
236 for (const auto& resourceMapIter : m_resourceMaps) {
237 if (MemoryCacheEntry* entry = resourceMapIter.value->get(url))
238 results.append(entry->m_resource.get());
239 }
240 return results;
241 }
242
210 size_t MemoryCache::deadCapacity() const 243 size_t MemoryCache::deadCapacity() const
211 { 244 {
212 // Dead resource capacity is whatever space is not occupied by live resource s, bounded by an independent minimum and maximum. 245 // Dead resource capacity is whatever space is not occupied by live resource s, bounded by an independent minimum and maximum.
213 size_t capacity = m_capacity - std::min(m_liveSize, m_capacity); // Start wi th available capacity. 246 size_t capacity = m_capacity - std::min(m_liveSize, m_capacity); // Start wi th available capacity.
214 capacity = std::max(capacity, m_minDeadCapacity); // Make sure it's above th e minimum. 247 capacity = std::max(capacity, m_minDeadCapacity); // Make sure it's above th e minimum.
215 capacity = std::min(capacity, m_maxDeadCapacity); // Make sure it's below th e maximum. 248 capacity = std::min(capacity, m_maxDeadCapacity); // Make sure it's below th e maximum.
216 return capacity; 249 return capacity;
217 } 250 }
218 251
219 size_t MemoryCache::liveCapacity() const 252 size_t MemoryCache::liveCapacity() const
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 ASSERT(WTF::isMainThread()); 400 ASSERT(WTF::isMainThread());
368 401
369 Resource* resource = entry->m_resource.get(); 402 Resource* resource = entry->m_resource.get();
370 bool canDelete = resource->canDelete(); 403 bool canDelete = resource->canDelete();
371 WTF_LOG(ResourceLoading, "Evicting resource %p for '%s' from cache", resourc e, resource->url().string().latin1().data()); 404 WTF_LOG(ResourceLoading, "Evicting resource %p for '%s' from cache", resourc e, resource->url().string().latin1().data());
372 // The resource may have already been removed by someone other than our call er, 405 // The resource may have already been removed by someone other than our call er,
373 // who needed a fresh copy for a reload. See <http://bugs.webkit.org/show_bu g.cgi?id=12479#c6>. 406 // who needed a fresh copy for a reload. See <http://bugs.webkit.org/show_bu g.cgi?id=12479#c6>.
374 update(resource, resource->size(), 0, false); 407 update(resource, resource->size(), 0, false);
375 removeFromLiveDecodedResourcesList(entry); 408 removeFromLiveDecodedResourcesList(entry);
376 409
377 ResourceMap::iterator it = m_resources.find(resource->url()); 410 ResourceMap* resources = m_resourceMaps.get(resource->cacheIdentifier());
378 ASSERT(it != m_resources.end()); 411 ASSERT(resources);
412 ResourceMap::iterator it = resources->find(resource->url());
413 ASSERT(it != resources->end());
379 #if ENABLE(OILPAN) 414 #if ENABLE(OILPAN)
380 MemoryCacheEntry* entryPtr = it->value; 415 MemoryCacheEntry* entryPtr = it->value;
381 #else 416 #else
382 OwnPtr<MemoryCacheEntry> entryPtr; 417 OwnPtr<MemoryCacheEntry> entryPtr;
383 entryPtr.swap(it->value); 418 entryPtr.swap(it->value);
384 #endif 419 #endif
385 m_resources.remove(it); 420 resources->remove(it);
386 #if ENABLE(OILPAN) 421 #if ENABLE(OILPAN)
387 if (entryPtr) 422 if (entryPtr)
388 entryPtr->dispose(); 423 entryPtr->dispose();
389 #endif 424 #endif
390 return canDelete; 425 return canDelete;
391 } 426 }
392 427
428 MemoryCacheEntry* MemoryCache::getEntryForResource(const Resource* resource) con st
429 {
430 if (resource->url().isNull() || resource->url().isEmpty())
431 return nullptr;
432 ResourceMap* resources = m_resourceMaps.get(resource->cacheIdentifier());
433 if (!resources)
434 return nullptr;
435 MemoryCacheEntry* entry = resources->get(resource->url());
436 if (!entry || entry->m_resource != resource)
437 return nullptr;
438 return entry;
439 }
440
393 MemoryCacheLRUList* MemoryCache::lruListFor(unsigned accessCount, size_t size) 441 MemoryCacheLRUList* MemoryCache::lruListFor(unsigned accessCount, size_t size)
394 { 442 {
395 ASSERT(accessCount > 0); 443 ASSERT(accessCount > 0);
396 unsigned queueIndex = WTF::fastLog2(size / accessCount); 444 unsigned queueIndex = WTF::fastLog2(size / accessCount);
397 if (m_allResources.size() <= queueIndex) 445 if (m_allResources.size() <= queueIndex)
398 m_allResources.grow(queueIndex + 1); 446 m_allResources.grow(queueIndex + 1);
399 return &m_allResources[queueIndex]; 447 return &m_allResources[queueIndex];
400 } 448 }
401 449
402 void MemoryCache::removeFromLRUList(MemoryCacheEntry* entry, MemoryCacheLRUList* list) 450 void MemoryCache::removeFromLRUList(MemoryCacheEntry* entry, MemoryCacheLRUList* list)
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 m_liveSize += resource->size(); 563 m_liveSize += resource->size();
516 m_deadSize -= resource->size(); 564 m_deadSize -= resource->size();
517 } 565 }
518 566
519 void MemoryCache::makeDead(Resource* resource) 567 void MemoryCache::makeDead(Resource* resource)
520 { 568 {
521 if (!contains(resource)) 569 if (!contains(resource))
522 return; 570 return;
523 m_liveSize -= resource->size(); 571 m_liveSize -= resource->size();
524 m_deadSize += resource->size(); 572 m_deadSize += resource->size();
525 removeFromLiveDecodedResourcesList(m_resources.get(resource->url())); 573 removeFromLiveDecodedResourcesList(getEntryForResource(resource));
526 } 574 }
527 575
528 void MemoryCache::update(Resource* resource, size_t oldSize, size_t newSize, boo l wasAccessed) 576 void MemoryCache::update(Resource* resource, size_t oldSize, size_t newSize, boo l wasAccessed)
529 { 577 {
530 if (!contains(resource)) 578 MemoryCacheEntry* entry = getEntryForResource(resource);
579 if (!entry)
531 return; 580 return;
532 MemoryCacheEntry* entry = m_resources.get(resource->url());
533 581
534 // The object must now be moved to a different queue, since either its size or its accessCount has been changed, 582 // The object must now be moved to a different queue, since either its size or its accessCount has been changed,
535 // and both of those are used to determine which LRU queue the resource shou ld be in. 583 // and both of those are used to determine which LRU queue the resource shou ld be in.
536 if (oldSize) 584 if (oldSize)
537 removeFromLRUList(entry, lruListFor(entry->m_accessCount, oldSize)); 585 removeFromLRUList(entry, lruListFor(entry->m_accessCount, oldSize));
538 if (wasAccessed) 586 if (wasAccessed)
539 entry->m_accessCount++; 587 entry->m_accessCount++;
540 if (newSize) 588 if (newSize)
541 insertInLRUList(entry, lruListFor(entry->m_accessCount, newSize)); 589 insertInLRUList(entry, lruListFor(entry->m_accessCount, newSize));
542 590
543 ptrdiff_t delta = newSize - oldSize; 591 ptrdiff_t delta = newSize - oldSize;
544 if (resource->hasClients()) { 592 if (resource->hasClients()) {
545 ASSERT(delta >= 0 || m_liveSize >= static_cast<size_t>(-delta) ); 593 ASSERT(delta >= 0 || m_liveSize >= static_cast<size_t>(-delta) );
546 m_liveSize += delta; 594 m_liveSize += delta;
547 } else { 595 } else {
548 ASSERT(delta >= 0 || m_deadSize >= static_cast<size_t>(-delta) ); 596 ASSERT(delta >= 0 || m_deadSize >= static_cast<size_t>(-delta) );
549 m_deadSize += delta; 597 m_deadSize += delta;
550 } 598 }
551 } 599 }
552 600
553 void MemoryCache::updateDecodedResource(Resource* resource, UpdateReason reason, MemoryCacheLiveResourcePriority priority) 601 void MemoryCache::updateDecodedResource(Resource* resource, UpdateReason reason, MemoryCacheLiveResourcePriority priority)
554 { 602 {
555 if (!contains(resource)) 603 MemoryCacheEntry* entry = getEntryForResource(resource);
604 if (!entry)
556 return; 605 return;
557 MemoryCacheEntry* entry = m_resources.get(resource->url());
558 606
559 removeFromLiveDecodedResourcesList(entry); 607 removeFromLiveDecodedResourcesList(entry);
560 if (priority != MemoryCacheLiveResourcePriorityUnknown && priority != entry- >m_liveResourcePriority) 608 if (priority != MemoryCacheLiveResourcePriorityUnknown && priority != entry- >m_liveResourcePriority)
561 entry->m_liveResourcePriority = priority; 609 entry->m_liveResourcePriority = priority;
562 if (resource->decodedSize() && resource->hasClients()) 610 if (resource->decodedSize() && resource->hasClients())
563 insertInLiveDecodedResourcesList(entry); 611 insertInLiveDecodedResourcesList(entry);
564 612
565 if (reason != UpdateForAccess) 613 if (reason != UpdateForAccess)
566 return; 614 return;
567 615
568 double timestamp = resource->isImage() ? FrameView::currentFrameTimeStamp() : 0.0; 616 double timestamp = resource->isImage() ? FrameView::currentFrameTimeStamp() : 0.0;
569 if (!timestamp) 617 if (!timestamp)
570 timestamp = currentTime(); 618 timestamp = currentTime();
571 entry->m_lastDecodedAccessTime = timestamp; 619 entry->m_lastDecodedAccessTime = timestamp;
572 } 620 }
573 621
574 MemoryCacheLiveResourcePriority MemoryCache::priority(Resource* resource) const 622 MemoryCacheLiveResourcePriority MemoryCache::priority(Resource* resource) const
575 { 623 {
576 if (!contains(resource)) 624 MemoryCacheEntry* entry = getEntryForResource(resource);
625 if (!entry)
577 return MemoryCacheLiveResourcePriorityUnknown; 626 return MemoryCacheLiveResourcePriorityUnknown;
578 MemoryCacheEntry* entry = m_resources.get(resource->url());
579 return entry->m_liveResourcePriority; 627 return entry->m_liveResourcePriority;
580 } 628 }
581 629
582 void MemoryCache::removeURLFromCache(ExecutionContext* context, const KURL& url) 630 void MemoryCache::removeURLFromCache(ExecutionContext* context, const KURL& url)
583 { 631 {
584 if (context->isWorkerGlobalScope()) { 632 if (context->isWorkerGlobalScope()) {
585 WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); 633 WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context);
586 workerGlobalScope->thread()->workerLoaderProxy().postTaskToLoader(create CrossThreadTask(&removeURLFromCacheInternal, url)); 634 workerGlobalScope->thread()->workerLoaderProxy().postTaskToLoader(create CrossThreadTask(&removeURLFromCacheInternal, url));
587 return; 635 return;
588 } 636 }
589 removeURLFromCacheInternal(context, url); 637 removeURLFromCacheInternal(context, url);
590 } 638 }
591 639
592 void MemoryCache::removeURLFromCacheInternal(ExecutionContext*, const KURL& url) 640 void MemoryCache::removeURLFromCacheInternal(ExecutionContext*, const KURL& url)
593 { 641 {
594 if (Resource* resource = memoryCache()->resourceForURL(url)) 642 WillBeHeapVector<Member<Resource>> resources = memoryCache()->resourcesForUR L(url);
643 for (Resource* resource : resources)
595 memoryCache()->remove(resource); 644 memoryCache()->remove(resource);
596 } 645 }
597 646
598 void MemoryCache::TypeStatistic::addResource(Resource* o) 647 void MemoryCache::TypeStatistic::addResource(Resource* o)
599 { 648 {
600 bool purged = o->wasPurged(); 649 bool purged = o->wasPurged();
601 bool purgeable = o->isPurgeable() && !purged; 650 bool purgeable = o->isPurgeable() && !purged;
602 size_t pageSize = (o->encodedSize() + o->overheadSize() + 4095) & ~4095; 651 size_t pageSize = (o->encodedSize() + o->overheadSize() + 4095) & ~4095;
603 count++; 652 count++;
604 size += purged ? 0 : o->size(); 653 size += purged ? 0 : o->size();
605 liveSize += o->hasClients() ? o->size() : 0; 654 liveSize += o->hasClients() ? o->size() : 0;
606 decodedSize += o->decodedSize(); 655 decodedSize += o->decodedSize();
607 encodedSize += o->encodedSize(); 656 encodedSize += o->encodedSize();
608 encodedSizeDuplicatedInDataURLs += o->url().protocolIsData() ? o->encodedSiz e() : 0; 657 encodedSizeDuplicatedInDataURLs += o->url().protocolIsData() ? o->encodedSiz e() : 0;
609 purgeableSize += purgeable ? pageSize : 0; 658 purgeableSize += purgeable ? pageSize : 0;
610 purgedSize += purged ? pageSize : 0; 659 purgedSize += purged ? pageSize : 0;
611 } 660 }
612 661
613 MemoryCache::Statistics MemoryCache::getStatistics() 662 MemoryCache::Statistics MemoryCache::getStatistics()
614 { 663 {
615 Statistics stats; 664 Statistics stats;
616 for (const auto& resourceIter : m_resources) { 665 for (const auto& resourceMapIter : m_resourceMaps) {
617 Resource* resource = resourceIter.value->m_resource.get(); 666 for (const auto& resourceIter : *resourceMapIter.value) {
618 switch (resource->type()) { 667 Resource* resource = resourceIter.value->m_resource.get();
619 case Resource::Image: 668 switch (resource->type()) {
620 stats.images.addResource(resource); 669 case Resource::Image:
621 break; 670 stats.images.addResource(resource);
622 case Resource::CSSStyleSheet: 671 break;
623 stats.cssStyleSheets.addResource(resource); 672 case Resource::CSSStyleSheet:
624 break; 673 stats.cssStyleSheets.addResource(resource);
625 case Resource::Script: 674 break;
626 stats.scripts.addResource(resource); 675 case Resource::Script:
627 break; 676 stats.scripts.addResource(resource);
628 case Resource::XSLStyleSheet: 677 break;
629 stats.xslStyleSheets.addResource(resource); 678 case Resource::XSLStyleSheet:
630 break; 679 stats.xslStyleSheets.addResource(resource);
631 case Resource::Font: 680 break;
632 stats.fonts.addResource(resource); 681 case Resource::Font:
633 break; 682 stats.fonts.addResource(resource);
634 default: 683 break;
635 stats.other.addResource(resource); 684 default:
636 break; 685 stats.other.addResource(resource);
686 break;
687 }
637 } 688 }
638 } 689 }
639 return stats; 690 return stats;
640 } 691 }
641 692
642 void MemoryCache::evictResources() 693 void MemoryCache::evictResources()
643 { 694 {
644 for (;;) { 695 while (true) {
645 ResourceMap::iterator i = m_resources.begin(); 696 ResourceMapIndex::iterator resourceMapIter = m_resourceMaps.begin();
646 if (i == m_resources.end()) 697 if (resourceMapIter == m_resourceMaps.end())
647 break; 698 break;
648 evict(i->value.get()); 699 ResourceMap* resources = resourceMapIter->value.get();
700 while (true) {
701 ResourceMap::iterator resourceIter = resources->begin();
702 if (resourceIter == resources->end())
703 break;
704 evict(resourceIter->value.get());
705 }
706 m_resourceMaps.remove(resourceMapIter);
649 } 707 }
650 } 708 }
651 709
652 void MemoryCache::prune(Resource* justReleasedResource) 710 void MemoryCache::prune(Resource* justReleasedResource)
653 { 711 {
654 TRACE_EVENT0("renderer", "MemoryCache::prune()"); 712 TRACE_EVENT0("renderer", "MemoryCache::prune()");
655 713
656 if (m_inPruneResources) 714 if (m_inPruneResources)
657 return; 715 return;
658 if (m_liveSize + m_deadSize <= m_capacity && m_maxDeadCapacity && m_deadSize <= m_maxDeadCapacity) // Fast path. 716 if (m_liveSize + m_deadSize <= m_capacity && m_maxDeadCapacity && m_deadSize <= m_maxDeadCapacity) // Fast path.
(...skipping 23 matching lines...) Expand all
682 740
683 if (m_prunePending && m_deadSize > m_maxDeferredPruneDeadCapacity && justRel easedResource) { 741 if (m_prunePending && m_deadSize > m_maxDeferredPruneDeadCapacity && justRel easedResource) {
684 // The following eviction does not respect LRU order, but it can be done 742 // The following eviction does not respect LRU order, but it can be done
685 // immediately in constant time, as opposed to pruneDeadResources, which 743 // immediately in constant time, as opposed to pruneDeadResources, which
686 // we would rather defer because it is O(N), which would make tear-down of N 744 // we would rather defer because it is O(N), which would make tear-down of N
687 // objects O(N^2) if we pruned immediately. This immediate eviction is a 745 // objects O(N^2) if we pruned immediately. This immediate eviction is a
688 // safeguard against runaway memory consumption by dead resources 746 // safeguard against runaway memory consumption by dead resources
689 // while a prune is pending. 747 // while a prune is pending.
690 // Main Resources in the cache are only substitue data that was 748 // Main Resources in the cache are only substitue data that was
691 // precached and should not be evicted. 749 // precached and should not be evicted.
692 if (contains(justReleasedResource) && justReleasedResource->type() != Re source::MainResource) 750 if (justReleasedResource->type() != Resource::MainResource) {
693 evict(m_resources.get(justReleasedResource->url())); 751 if (MemoryCacheEntry* entry = getEntryForResource(justReleasedResour ce))
752 evict(entry);
753 }
694 754
695 // As a last resort, prune immediately 755 // As a last resort, prune immediately
696 if (m_deadSize > m_maxDeferredPruneDeadCapacity) 756 if (m_deadSize > m_maxDeferredPruneDeadCapacity)
697 pruneNow(currentTime); 757 pruneNow(currentTime);
698 } 758 }
699 } 759 }
700 760
701 void MemoryCache::willProcessTask() 761 void MemoryCache::willProcessTask()
702 { 762 {
703 } 763 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 printf("(%.1fK, %.1fK, %uA, %dR, %d, %d); ", current->decodedSiz e() / 1024.0f, (current->encodedSize() + current->overheadSize()) / 1024.0f, cur rent->accessCount(), current->hasClients(), current->isPurgeable(), current->was Purged()); 845 printf("(%.1fK, %.1fK, %uA, %dR, %d, %d); ", current->decodedSiz e() / 1024.0f, (current->encodedSize() + current->overheadSize()) / 1024.0f, cur rent->accessCount(), current->hasClients(), current->isPurgeable(), current->was Purged());
786 846
787 current = prev; 847 current = prev;
788 } 848 }
789 } 849 }
790 } 850 }
791 851
792 #endif // MEMORY_CACHE_STATS 852 #endif // MEMORY_CACHE_STATS
793 853
794 } // namespace blink 854 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/fetch/MemoryCache.h ('k') | Source/core/fetch/MemoryCacheTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698