Index: Source/WebCore/loader/cache/CachedResourceLoader.cpp |
=================================================================== |
--- Source/WebCore/loader/cache/CachedResourceLoader.cpp (revision 92202) |
+++ Source/WebCore/loader/cache/CachedResourceLoader.cpp (working copy) |
@@ -86,6 +86,7 @@ |
CachedResourceLoader::CachedResourceLoader(Document* document) |
: m_document(document) |
, m_requestCount(0) |
+ , m_garbageCollectDocumentResourcesTimer(this, &CachedResourceLoader::garbageCollectDocumentResourcesTimerFired) |
, m_autoLoadImages(true) |
, m_loadFinishing(false) |
, m_allowStaleResources(false) |
@@ -572,8 +573,35 @@ |
if (frame()) |
frame()->loader()->loadDone(); |
performPostLoadActions(); |
+ |
+ if (!m_garbageCollectDocumentResourcesTimer.isActive()) |
+ m_garbageCollectDocumentResourcesTimer.startOneShot(0); |
} |
+// Garbage collecting m_documentResources is a workaround for the |
+// CachedResourceHandles on the RHS being strong references. Ideally this |
+// would be a weak map, however CachedResourceHandles perform additional |
+// bookkeeping on CachedResources, so instead pseudo-GC them -- when the |
+// reference count reaches 1, m_documentResources is the only reference, so |
+// remove it from the map. |
+void CachedResourceLoader::garbageCollectDocumentResourcesTimerFired(Timer<CachedResourceLoader>* timer) |
+{ |
+ ASSERT_UNUSED(timer, timer == &m_garbageCollectDocumentResourcesTimer); |
+ |
+ typedef Vector<String, 10> StringVector; |
+ StringVector resourcesToDelete; |
+ |
+ for (DocumentResourceMap::iterator it = m_documentResources.begin(); it != m_documentResources.end(); ++it) { |
+ if (it->second->hasOneHandle()) { |
+ resourcesToDelete.append(it->first); |
+ it->second->setOwningCachedResourceLoader(0); |
+ } |
+ } |
+ |
+ for (StringVector::const_iterator it = resourcesToDelete.begin(); it != resourcesToDelete.end(); ++it) |
+ m_documentResources.remove(*it); |
+} |
+ |
void CachedResourceLoader::performPostLoadActions() |
{ |
checkForPendingPreloads(); |