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

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

Issue 174523002: Reland "Move MemoryCache implementation details out of Resource" (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase Created 6 years, 9 months 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 | Annotate | Revision Log
« 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 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 if (!originalURL.protocolIsInHTTPFamily()) 102 if (!originalURL.protocolIsInHTTPFamily())
103 return originalURL; 103 return originalURL;
104 KURL url = originalURL; 104 KURL url = originalURL;
105 url.removeFragmentIdentifier(); 105 url.removeFragmentIdentifier();
106 return url; 106 return url;
107 } 107 }
108 108
109 void MemoryCache::add(Resource* resource) 109 void MemoryCache::add(Resource* resource)
110 { 110 {
111 ASSERT(WTF::isMainThread()); 111 ASSERT(WTF::isMainThread());
112 m_resources.set(resource->url(), resource); 112 ASSERT(!m_resources.contains(resource->url()));
113 m_resources.set(resource->url(), MemoryCacheEntry::create(resource));
113 resource->setInCache(true); 114 resource->setInCache(true);
114 resource->updateForAccess(); 115 resource->updateForAccess();
115 116
116 WTF_LOG(ResourceLoading, "MemoryCache::add Added '%s', resource %p\n", resou rce->url().string().latin1().data(), resource); 117 WTF_LOG(ResourceLoading, "MemoryCache::add Added '%s', resource %p\n", resou rce->url().string().latin1().data(), resource);
117 } 118 }
118 119
119 void MemoryCache::replace(Resource* newResource, Resource* oldResource) 120 void MemoryCache::replace(Resource* newResource, Resource* oldResource)
120 { 121 {
121 evict(oldResource); 122 evict(oldResource);
122 ASSERT(!m_resources.get(newResource->url())); 123 ASSERT(!m_resources.contains(newResource->url()));
123 m_resources.set(newResource->url(), newResource); 124 m_resources.set(newResource->url(), MemoryCacheEntry::create(newResource));
124 newResource->setInCache(true); 125 newResource->setInCache(true);
125 insertInLRUList(newResource); 126 insertInLRUList(newResource);
126 int delta = newResource->size(); 127 int delta = newResource->size();
127 if (newResource->decodedSize() && newResource->hasClients()) 128 if (newResource->decodedSize() && newResource->hasClients())
128 insertInLiveDecodedResourcesList(newResource); 129 insertInLiveDecodedResourcesList(newResource);
129 if (delta) 130 if (delta)
130 adjustSize(newResource->hasClients(), delta); 131 adjustSize(newResource->hasClients(), delta);
131 } 132 }
132 133
133 Resource* MemoryCache::resourceForURL(const KURL& resourceURL) 134 Resource* MemoryCache::resourceForURL(const KURL& resourceURL)
134 { 135 {
135 ASSERT(WTF::isMainThread()); 136 ASSERT(WTF::isMainThread());
136 KURL url = removeFragmentIdentifierIfNeeded(resourceURL); 137 KURL url = removeFragmentIdentifierIfNeeded(resourceURL);
137 Resource* resource = m_resources.get(url); 138 MemoryCacheEntry* entry = m_resources.get(url);
139 if (!entry)
140 return 0;
141 Resource* resource = entry->m_resource.get();
138 if (resource && !resource->lock()) { 142 if (resource && !resource->lock()) {
139 ASSERT(!resource->hasClients()); 143 ASSERT(!resource->hasClients());
140 bool didEvict = evict(resource); 144 bool didEvict = evict(resource);
141 ASSERT_UNUSED(didEvict, didEvict); 145 ASSERT_UNUSED(didEvict, didEvict);
142 return 0; 146 return 0;
143 } 147 }
144 return resource; 148 return resource;
145 } 149 }
146 150
147 size_t MemoryCache::deadCapacity() const 151 size_t MemoryCache::deadCapacity() const
(...skipping 25 matching lines...) Expand all
173 // and least recently accessed of the objects. 177 // and least recently accessed of the objects.
174 178
175 // The list might not be sorted by the m_lastDecodedFrameTimeStamp. The impa ct 179 // The list might not be sorted by the m_lastDecodedFrameTimeStamp. The impa ct
176 // of this weaker invariant is minor as the below if statement to check the 180 // of this weaker invariant is minor as the below if statement to check the
177 // elapsedTime will evaluate to false as the current time will be a lot 181 // elapsedTime will evaluate to false as the current time will be a lot
178 // greater than the current->m_lastDecodedFrameTimeStamp. 182 // greater than the current->m_lastDecodedFrameTimeStamp.
179 // For more details see: https://bugs.webkit.org/show_bug.cgi?id=30209 183 // For more details see: https://bugs.webkit.org/show_bug.cgi?id=30209
180 184
181 // Start pruning from the lowest priority list. 185 // Start pruning from the lowest priority list.
182 for (int priority = Resource::CacheLiveResourcePriorityLow; priority <= Reso urce::CacheLiveResourcePriorityHigh; ++priority) { 186 for (int priority = Resource::CacheLiveResourcePriorityLow; priority <= Reso urce::CacheLiveResourcePriorityHigh; ++priority) {
183 Resource* current = m_liveDecodedResources[priority].m_tail; 187 MemoryCacheEntry* current = m_liveDecodedResources[priority].m_tail;
184 while (current) { 188 while (current) {
185 Resource* prev = current->m_prevInLiveResourcesList; 189 MemoryCacheEntry* previous = current->m_previousInLiveResourcesList;
186 ASSERT(current->hasClients()); 190 ASSERT(current->m_resource->hasClients());
187 if (current->isLoaded() && current->decodedSize()) { 191 if (current->m_resource->isLoaded() && current->m_resource->decodedS ize()) {
188 // Check to see if the remaining resources are too new to prune. 192 // Check to see if the remaining resources are too new to prune.
189 double elapsedTime = m_pruneFrameTimeStamp - current->m_lastDeco dedAccessTime; 193 double elapsedTime = m_pruneFrameTimeStamp - current->m_resource ->m_lastDecodedAccessTime;
190 if (elapsedTime < m_delayBeforeLiveDecodedPrune) 194 if (elapsedTime < m_delayBeforeLiveDecodedPrune)
191 return; 195 return;
192 196
193 // Destroy our decoded data if possible. This will remove us 197 // Destroy our decoded data if possible. This will remove us
194 // from m_liveDecodedResources, and possibly move us to a 198 // from m_liveDecodedResources, and possibly move us to a
195 // different LRU list in m_allResources. 199 // different LRU list in m_allResources.
196 current->prune(); 200 current->m_resource->prune();
197 201
198 if (targetSize && m_liveSize <= targetSize) 202 if (targetSize && m_liveSize <= targetSize)
199 return; 203 return;
200 } 204 }
201 current = prev; 205 current = previous;
202 } 206 }
203 } 207 }
204 } 208 }
205 209
206 void MemoryCache::pruneDeadResources() 210 void MemoryCache::pruneDeadResources()
207 { 211 {
208 size_t capacity = deadCapacity(); 212 size_t capacity = deadCapacity();
209 if (!m_deadSize || (capacity && m_deadSize <= capacity)) 213 if (!m_deadSize || (capacity && m_deadSize <= capacity))
210 return; 214 return;
211 215
212 size_t targetSize = static_cast<size_t>(capacity * cTargetPrunePercentage); // Cut by a percentage to avoid immediately pruning again. 216 size_t targetSize = static_cast<size_t>(capacity * cTargetPrunePercentage); // Cut by a percentage to avoid immediately pruning again.
213 217
214 int size = m_allResources.size(); 218 int size = m_allResources.size();
215 219
216 // See if we have any purged resources we can evict. 220 // See if we have any purged resources we can evict.
217 for (int i = 0; i < size; i++) { 221 for (int i = 0; i < size; i++) {
218 Resource* current = m_allResources[i].m_tail; 222 MemoryCacheEntry* current = m_allResources[i].m_tail;
219 while (current) { 223 while (current) {
220 Resource* prev = current->m_prevInAllResourcesList; 224 MemoryCacheEntry* previous = current->m_previousInAllResourcesList;
221 if (current->wasPurged()) { 225 if (current->m_resource->wasPurged()) {
222 ASSERT(!current->hasClients()); 226 ASSERT(!current->m_resource->hasClients());
223 ASSERT(!current->isPreloaded()); 227 ASSERT(!current->m_resource->isPreloaded());
224 evict(current); 228 evict(current->m_resource.get());
225 } 229 }
226 current = prev; 230 current = previous;
227 } 231 }
228 } 232 }
229 if (targetSize && m_deadSize <= targetSize) 233 if (targetSize && m_deadSize <= targetSize)
230 return; 234 return;
231 235
232 bool canShrinkLRULists = true; 236 bool canShrinkLRULists = true;
233 for (int i = size - 1; i >= 0; i--) { 237 for (int i = size - 1; i >= 0; i--) {
234 // Remove from the tail, since this is the least frequently accessed of the objects. 238 // Remove from the tail, since this is the least frequently accessed of the objects.
235 Resource* current = m_allResources[i].m_tail; 239 MemoryCacheEntry* current = m_allResources[i].m_tail;
236 240
237 // First flush all the decoded data in this queue. 241 // First flush all the decoded data in this queue.
238 while (current) { 242 while (current) {
239 // Protect 'previous' so it can't get deleted during destroyDecodedD ata(). 243 // Protect 'previous' so it can't get deleted during destroyDecodedD ata().
240 ResourcePtr<Resource> previous = current->m_prevInAllResourcesList; 244 MemoryCacheEntry* previous = current->m_previousInAllResourcesList;
241 ASSERT(!previous || previous->inCache()); 245 ASSERT(!previous || previous->m_resource->inCache());
242 if (!current->hasClients() && !current->isPreloaded() && current->is Loaded()) { 246 if (!current->m_resource->hasClients() && !current->m_resource->isPr eloaded() && current->m_resource->isLoaded()) {
243 // Destroy our decoded data if possible. This will remove us 247 // Destroy our decoded data. This will remove us from
244 // from m_liveDecodedResources, and possibly move us to a 248 // m_liveDecodedResources, and possibly move us to a different
245 // different LRU list in m_allResources. 249 // LRU list in m_allResources.
246 current->prune(); 250 current->m_resource->prune();
247 251
248 if (targetSize && m_deadSize <= targetSize) 252 if (targetSize && m_deadSize <= targetSize)
249 return; 253 return;
250 } 254 }
251 // Decoded data may reference other resources. Stop iterating if 'pr evious' somehow got 255 // Decoded data may reference other resources. Stop iterating if 'pr evious' somehow got
252 // kicked out of cache during destroyDecodedData(). 256 // kicked out of cache during destroyDecodedData().
253 if (previous && !previous->inCache()) 257 if (previous && !previous->m_resource->inCache())
254 break; 258 break;
255 current = previous.get(); 259 current = previous;
256 } 260 }
257 261
258 // Now evict objects from this queue. 262 // Now evict objects from this queue.
259 current = m_allResources[i].m_tail; 263 current = m_allResources[i].m_tail;
260 while (current) { 264 while (current) {
261 ResourcePtr<Resource> previous = current->m_prevInAllResourcesList; 265 MemoryCacheEntry* previous = current->m_previousInAllResourcesList;
262 ASSERT(!previous || previous->inCache()); 266 ASSERT(!previous || previous->m_resource->inCache());
263 if (!current->hasClients() && !current->isPreloaded() && !current->i sCacheValidator()) { 267 if (!current->m_resource->hasClients() && !current->m_resource->isPr eloaded() && !current->m_resource->isCacheValidator()) {
264 evict(current); 268 evict(current->m_resource.get());
265 if (targetSize && m_deadSize <= targetSize) 269 if (targetSize && m_deadSize <= targetSize)
266 return; 270 return;
267 } 271 }
268 if (previous && !previous->inCache()) 272 if (previous && !previous->m_resource->inCache())
269 break; 273 break;
270 current = previous.get(); 274 current = previous;
271 } 275 }
272 276
273 // Shrink the vector back down so we don't waste time inspecting 277 // Shrink the vector back down so we don't waste time inspecting
274 // empty LRU lists on future prunes. 278 // empty LRU lists on future prunes.
275 if (m_allResources[i].m_head) 279 if (m_allResources[i].m_head)
276 canShrinkLRULists = false; 280 canShrinkLRULists = false;
277 else if (canShrinkLRULists) 281 else if (canShrinkLRULists)
278 m_allResources.resize(i); 282 m_allResources.resize(i);
279 } 283 }
280 } 284 }
281 285
282 void MemoryCache::setCapacities(size_t minDeadBytes, size_t maxDeadBytes, size_t totalBytes) 286 void MemoryCache::setCapacities(size_t minDeadBytes, size_t maxDeadBytes, size_t totalBytes)
283 { 287 {
284 ASSERT(minDeadBytes <= maxDeadBytes); 288 ASSERT(minDeadBytes <= maxDeadBytes);
285 ASSERT(maxDeadBytes <= totalBytes); 289 ASSERT(maxDeadBytes <= totalBytes);
286 m_minDeadCapacity = minDeadBytes; 290 m_minDeadCapacity = minDeadBytes;
287 m_maxDeadCapacity = maxDeadBytes; 291 m_maxDeadCapacity = maxDeadBytes;
288 m_maxDeferredPruneDeadCapacity = cDeferredPruneDeadCapacityFactor * maxDeadB ytes; 292 m_maxDeferredPruneDeadCapacity = cDeferredPruneDeadCapacityFactor * maxDeadB ytes;
289 m_capacity = totalBytes; 293 m_capacity = totalBytes;
290 prune(); 294 prune();
291 } 295 }
292 296
293 bool MemoryCache::evict(Resource* resource) 297 bool MemoryCache::evict(Resource* resource)
294 { 298 {
295 ASSERT(WTF::isMainThread()); 299 ASSERT(WTF::isMainThread());
296 WTF_LOG(ResourceLoading, "Evicting resource %p for '%s' from cache", resourc e, resource->url().string().latin1().data()); 300 WTF_LOG(ResourceLoading, "Evicting resource %p for '%s' from cache", resourc e, resource->url().string().latin1().data());
297 // The resource may have already been removed by someone other than our call er, 301 // The resource may have already been removed by someone other than our call er,
298 // who needed a fresh copy for a reload. See <http://bugs.webkit.org/show_bu g.cgi?id=12479#c6>. 302 // who needed a fresh copy for a reload. See <http://bugs.webkit.org/show_bu g.cgi?id=12479#c6>.
299 if (resource->inCache()) { 303 if (resource->inCache()) {
300 // Remove from the resource map.
301 m_resources.remove(resource->url());
302 resource->setInCache(false);
303
304 // Remove from the appropriate LRU list. 304 // Remove from the appropriate LRU list.
305 removeFromLRUList(resource); 305 removeFromLRUList(resource);
306 removeFromLiveDecodedResourcesList(resource); 306 removeFromLiveDecodedResourcesList(resource);
307 adjustSize(resource->hasClients(), -static_cast<ptrdiff_t>(resource->siz e())); 307 adjustSize(resource->hasClients(), -static_cast<ptrdiff_t>(resource->siz e()));
308
309 // Remove from the resource map.
310 m_resources.remove(resource->url());
311 resource->setInCache(false);
308 } else { 312 } else {
309 ASSERT(m_resources.get(resource->url()) != resource); 313 ASSERT(!m_resources.get(resource->url()) || m_resources.get(resource->ur l())->m_resource != resource);
310 } 314 }
311 315
312 return resource->deleteIfPossible(); 316 return resource->deleteIfPossible();
313 } 317 }
314 318
315 MemoryCache::LRUList* MemoryCache::lruListFor(Resource* resource) 319 MemoryCache::LRUList* MemoryCache::lruListFor(MemoryCacheEntry* entry)
316 { 320 {
317 unsigned accessCount = std::max(resource->accessCount(), 1U); 321 unsigned accessCount = std::max(entry->m_resource->accessCount(), 1U);
318 unsigned queueIndex = WTF::fastLog2(resource->size() / accessCount); 322 unsigned queueIndex = WTF::fastLog2(entry->m_resource->size() / accessCount) ;
319 #ifndef NDEBUG
320 resource->m_lruIndex = queueIndex;
321 #endif
322 if (m_allResources.size() <= queueIndex) 323 if (m_allResources.size() <= queueIndex)
323 m_allResources.grow(queueIndex + 1); 324 m_allResources.grow(queueIndex + 1);
324 return &m_allResources[queueIndex]; 325 return &m_allResources[queueIndex];
325 } 326 }
326 327
327 void MemoryCache::removeFromLRUList(Resource* resource) 328 void MemoryCache::removeFromLRUList(Resource* resource)
328 { 329 {
329 // If we've never been accessed, then we're brand new and not in any list. 330 // If we've never been accessed, then we're brand new and not in any list.
330 if (!resource->accessCount()) 331 if (!resource->accessCount())
331 return; 332 return;
332 333
333 #if !ASSERT_DISABLED 334 MemoryCacheEntry* entry = m_resources.get(resource->url());
334 unsigned oldListIndex = resource->m_lruIndex; 335 ASSERT(entry->m_resource == resource);
335 #endif 336 LRUList* list = lruListFor(entry);
336
337 LRUList* list = lruListFor(resource);
338 337
339 #if !ASSERT_DISABLED 338 #if !ASSERT_DISABLED
340 // Verify that the list we got is the list we want.
341 ASSERT(resource->m_lruIndex == oldListIndex);
342
343 // Verify that we are in fact in this list. 339 // Verify that we are in fact in this list.
344 bool found = false; 340 bool found = false;
345 for (Resource* current = list->m_head; current; current = current->m_nextInA llResourcesList) { 341 for (MemoryCacheEntry* current = list->m_head; current; current = current->m _nextInAllResourcesList) {
346 if (current == resource) { 342 if (current == entry) {
347 found = true; 343 found = true;
348 break; 344 break;
349 } 345 }
350 } 346 }
351 ASSERT(found); 347 ASSERT(found);
352 #endif 348 #endif
353 349
354 Resource* next = resource->m_nextInAllResourcesList; 350 MemoryCacheEntry* next = entry->m_nextInAllResourcesList;
355 Resource* prev = resource->m_prevInAllResourcesList; 351 MemoryCacheEntry* previous = entry->m_previousInAllResourcesList;
356 352
357 if (!next && !prev && list->m_head != resource) 353 entry->m_nextInAllResourcesList = 0;
358 return; 354 entry->m_previousInAllResourcesList = 0;
359
360 resource->m_nextInAllResourcesList = 0;
361 resource->m_prevInAllResourcesList = 0;
362 355
363 if (next) 356 if (next)
364 next->m_prevInAllResourcesList = prev; 357 next->m_previousInAllResourcesList = previous;
365 else if (list->m_tail == resource) 358 else
366 list->m_tail = prev; 359 list->m_tail = previous;
367 360
368 if (prev) 361 if (previous)
369 prev->m_nextInAllResourcesList = next; 362 previous->m_nextInAllResourcesList = next;
370 else if (list->m_head == resource) 363 else
371 list->m_head = next; 364 list->m_head = next;
372 } 365 }
373 366
374 void MemoryCache::insertInLRUList(Resource* resource) 367 void MemoryCache::insertInLRUList(Resource* resource)
375 { 368 {
369 MemoryCacheEntry* entry = m_resources.get(resource->url());
370 ASSERT(entry->m_resource == resource);
371
376 // Make sure we aren't in some list already. 372 // Make sure we aren't in some list already.
377 ASSERT(!resource->m_nextInAllResourcesList && !resource->m_prevInAllResource sList); 373 ASSERT(!entry->m_nextInAllResourcesList && !entry->m_previousInAllResourcesL ist);
378 ASSERT(resource->inCache()); 374 ASSERT(resource->inCache());
379 ASSERT(resource->accessCount() > 0); 375 ASSERT(resource->accessCount() > 0);
380 376
381 LRUList* list = lruListFor(resource); 377 LRUList* list = lruListFor(entry);
382 378
383 resource->m_nextInAllResourcesList = list->m_head; 379 entry->m_nextInAllResourcesList = list->m_head;
384 if (list->m_head) 380 if (list->m_head)
385 list->m_head->m_prevInAllResourcesList = resource; 381 list->m_head->m_previousInAllResourcesList = entry;
386 list->m_head = resource; 382 list->m_head = entry;
387 383
388 if (!resource->m_nextInAllResourcesList) 384 if (!entry->m_nextInAllResourcesList)
389 list->m_tail = resource; 385 list->m_tail = entry;
390 386
391 #if !ASSERT_DISABLED 387 #if !ASSERT_DISABLED
392 // Verify that we are in now in the list like we should be. 388 // Verify that we are in now in the list like we should be.
393 list = lruListFor(resource); 389 list = lruListFor(entry);
394 bool found = false; 390 bool found = false;
395 for (Resource* current = list->m_head; current; current = current->m_nextInA llResourcesList) { 391 for (MemoryCacheEntry* current = list->m_head; current; current = current->m _nextInAllResourcesList) {
396 if (current == resource) { 392 if (current == entry) {
397 found = true; 393 found = true;
398 break; 394 break;
399 } 395 }
400 } 396 }
401 ASSERT(found); 397 ASSERT(found);
402 #endif 398 #endif
403
404 } 399 }
405 400
406 void MemoryCache::removeFromLiveDecodedResourcesList(Resource* resource) 401 void MemoryCache::removeFromLiveDecodedResourcesList(Resource* resource)
407 { 402 {
403 MemoryCacheEntry* entry = m_resources.get(resource->url());
404 ASSERT(entry->m_resource == resource);
405
408 // If we've never been accessed, then we're brand new and not in any list. 406 // If we've never been accessed, then we're brand new and not in any list.
409 if (!resource->m_inLiveDecodedResourcesList) 407 if (!entry->m_inLiveDecodedResourcesList)
410 return; 408 return;
411 resource->m_inLiveDecodedResourcesList = false; 409 entry->m_inLiveDecodedResourcesList = false;
412 410
413 LRUList* list = &m_liveDecodedResources[resource->cacheLiveResourcePriority( )]; 411 LRUList* list = &m_liveDecodedResources[resource->cacheLiveResourcePriority( )];
414 412
415 #if !ASSERT_DISABLED 413 #if !ASSERT_DISABLED
416 // Verify that we are in fact in this list. 414 // Verify that we are in fact in this list.
417 bool found = false; 415 bool found = false;
418 for (Resource* current = list->m_head; current; current = current->m_nextInL iveResourcesList) { 416 for (MemoryCacheEntry* current = list->m_head; current; current = current->m _nextInLiveResourcesList) {
419 if (current == resource) { 417 if (current == entry) {
420 found = true; 418 found = true;
421 break; 419 break;
422 } 420 }
423 } 421 }
424 ASSERT(found); 422 ASSERT(found);
425 #endif 423 #endif
426 424
427 Resource* next = resource->m_nextInLiveResourcesList; 425 MemoryCacheEntry* next = entry->m_nextInLiveResourcesList;
428 Resource* prev = resource->m_prevInLiveResourcesList; 426 MemoryCacheEntry* previous = entry->m_previousInLiveResourcesList;
429 427
430 if (!next && !prev && list->m_head != resource) 428 entry->m_nextInLiveResourcesList = 0;
431 return; 429 entry->m_previousInLiveResourcesList = 0;
432
433 resource->m_nextInLiveResourcesList = 0;
434 resource->m_prevInLiveResourcesList = 0;
435 430
436 if (next) 431 if (next)
437 next->m_prevInLiveResourcesList = prev; 432 next->m_previousInLiveResourcesList = previous;
438 else if (list->m_tail == resource) 433 else
439 list->m_tail = prev; 434 list->m_tail = previous;
440 435
441 if (prev) 436 if (previous)
442 prev->m_nextInLiveResourcesList = next; 437 previous->m_nextInLiveResourcesList = next;
443 else if (list->m_head == resource) 438 else
444 list->m_head = next; 439 list->m_head = next;
445 } 440 }
446 441
447 void MemoryCache::insertInLiveDecodedResourcesList(Resource* resource) 442 void MemoryCache::insertInLiveDecodedResourcesList(Resource* resource)
448 { 443 {
444 MemoryCacheEntry* entry = m_resources.get(resource->url());
445 ASSERT(entry->m_resource == resource);
446
449 // Make sure we aren't in the list already. 447 // Make sure we aren't in the list already.
450 ASSERT(!resource->m_nextInLiveResourcesList && !resource->m_prevInLiveResour cesList && !resource->m_inLiveDecodedResourcesList); 448 ASSERT(!entry->m_nextInLiveResourcesList && !entry->m_previousInLiveResource sList && !entry->m_inLiveDecodedResourcesList);
451 resource->m_inLiveDecodedResourcesList = true; 449 entry->m_inLiveDecodedResourcesList = true;
452 450
453 LRUList* list = &m_liveDecodedResources[resource->cacheLiveResourcePriority( )]; 451 LRUList* list = &m_liveDecodedResources[resource->cacheLiveResourcePriority( )];
454 resource->m_nextInLiveResourcesList = list->m_head; 452 entry->m_nextInLiveResourcesList = list->m_head;
455 if (list->m_head) 453 if (list->m_head)
456 list->m_head->m_prevInLiveResourcesList = resource; 454 list->m_head->m_previousInLiveResourcesList = entry;
457 list->m_head = resource; 455 list->m_head = entry;
458 456
459 if (!resource->m_nextInLiveResourcesList) 457 if (!entry->m_nextInLiveResourcesList)
460 list->m_tail = resource; 458 list->m_tail = entry;
461 459
462 #if !ASSERT_DISABLED 460 #if !ASSERT_DISABLED
463 // Verify that we are in now in the list like we should be. 461 // Verify that we are in now in the list like we should be.
464 bool found = false; 462 bool found = false;
465 for (Resource* current = list->m_head; current; current = current->m_nextInL iveResourcesList) { 463 for (MemoryCacheEntry* current = list->m_head; current; current = current->m _nextInLiveResourcesList) {
466 if (current == resource) { 464 if (current == entry) {
467 found = true; 465 found = true;
468 break; 466 break;
469 } 467 }
470 } 468 }
471 ASSERT(found); 469 ASSERT(found);
472 #endif 470 #endif
471 }
473 472
473 bool MemoryCache::isInLiveDecodedResourcesList(Resource* resource)
474 {
475 MemoryCacheEntry* entry = m_resources.get(resource->url());
476 ASSERT(entry->m_resource == resource);
477 return entry ? entry->m_inLiveDecodedResourcesList : false;
474 } 478 }
475 479
476 void MemoryCache::addToLiveResourcesSize(Resource* resource) 480 void MemoryCache::addToLiveResourcesSize(Resource* resource)
477 { 481 {
478 ASSERT(m_deadSize >= resource->size()); 482 ASSERT(m_deadSize >= resource->size());
479 m_liveSize += resource->size(); 483 m_liveSize += resource->size();
480 m_deadSize -= resource->size(); 484 m_deadSize -= resource->size();
481 } 485 }
482 486
483 void MemoryCache::removeFromLiveResourcesSize(Resource* resource) 487 void MemoryCache::removeFromLiveResourcesSize(Resource* resource)
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 encodedSizeDuplicatedInDataURLs += o->url().protocolIsData() ? o->encodedSiz e() : 0; 531 encodedSizeDuplicatedInDataURLs += o->url().protocolIsData() ? o->encodedSiz e() : 0;
528 purgeableSize += purgeable ? pageSize : 0; 532 purgeableSize += purgeable ? pageSize : 0;
529 purgedSize += purged ? pageSize : 0; 533 purgedSize += purged ? pageSize : 0;
530 } 534 }
531 535
532 MemoryCache::Statistics MemoryCache::getStatistics() 536 MemoryCache::Statistics MemoryCache::getStatistics()
533 { 537 {
534 Statistics stats; 538 Statistics stats;
535 ResourceMap::iterator e = m_resources.end(); 539 ResourceMap::iterator e = m_resources.end();
536 for (ResourceMap::iterator i = m_resources.begin(); i != e; ++i) { 540 for (ResourceMap::iterator i = m_resources.begin(); i != e; ++i) {
537 Resource* resource = i->value; 541 Resource* resource = i->value->m_resource.get();
538 switch (resource->type()) { 542 switch (resource->type()) {
539 case Resource::Image: 543 case Resource::Image:
540 stats.images.addResource(resource); 544 stats.images.addResource(resource);
541 break; 545 break;
542 case Resource::CSSStyleSheet: 546 case Resource::CSSStyleSheet:
543 stats.cssStyleSheets.addResource(resource); 547 stats.cssStyleSheets.addResource(resource);
544 break; 548 break;
545 case Resource::Script: 549 case Resource::Script:
546 stats.scripts.addResource(resource); 550 stats.scripts.addResource(resource);
547 break; 551 break;
(...skipping 10 matching lines...) Expand all
558 } 562 }
559 return stats; 563 return stats;
560 } 564 }
561 565
562 void MemoryCache::evictResources() 566 void MemoryCache::evictResources()
563 { 567 {
564 for (;;) { 568 for (;;) {
565 ResourceMap::iterator i = m_resources.begin(); 569 ResourceMap::iterator i = m_resources.begin();
566 if (i == m_resources.end()) 570 if (i == m_resources.end())
567 break; 571 break;
568 evict(i->value); 572 evict(i->value->m_resource.get());
569 } 573 }
570 } 574 }
571 575
572 void MemoryCache::prune(Resource* justReleasedResource) 576 void MemoryCache::prune(Resource* justReleasedResource)
573 { 577 {
574 TRACE_EVENT0("renderer", "MemoryCache::prune()"); 578 TRACE_EVENT0("renderer", "MemoryCache::prune()");
575 579
576 if (m_inPruneResources) 580 if (m_inPruneResources)
577 return; 581 return;
578 if (m_liveSize + m_deadSize <= m_capacity && m_maxDeadCapacity && m_deadSize <= m_maxDeadCapacity) // Fast path. 582 if (m_liveSize + m_deadSize <= m_capacity && m_maxDeadCapacity && m_deadSize <= m_maxDeadCapacity) // Fast path.
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 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()); 682 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());
679 683
680 current = prev; 684 current = prev;
681 } 685 }
682 } 686 }
683 } 687 }
684 688
685 #endif // MEMORY_CACHE_STATS 689 #endif // MEMORY_CACHE_STATS
686 690
687 } // namespace WebCore 691 } // namespace WebCore
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