OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |