From 996c02e7e2de9bcdbcc23fc3dae6bd8b73a9cd47 Mon Sep 17 00:00:00 2001 From: Justin Lebar Date: Fri, 9 Mar 2012 17:21:01 -0500 Subject: [PATCH] Bug 731419 - Part 2: Discard image data immediately on tab close, DOM changes. r=bz --- content/base/src/nsDocument.cpp | 37 +++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index 9cbbd96a346c..ed5066747c2c 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -3247,6 +3247,14 @@ nsIDocument::TakeFrameRequestCallbacks(FrameRequestCallbackList& aCallbacks) mFrameRequestCallbacks.Clear(); } +PLDHashOperator RequestDiscardEnumerator(imgIRequest* aKey, + PRUint32 aData, + void* userArg) +{ + aKey->RequestDiscard(); + return PL_DHASH_NEXT; +} + void nsDocument::DeleteShell() { @@ -3255,6 +3263,11 @@ nsDocument::DeleteShell() RevokeAnimationFrameNotifications(); } + // When our shell goes away, request that all our images be immediately + // discarded, so we don't carry around decoded image data for a document we + // no longer intend to paint. + mImageTracker.EnumerateRead(RequestDiscardEnumerator, nsnull); + mPresShell = nsnull; } @@ -8309,26 +8322,32 @@ nsDocument::RemoveImage(imgIRequest* aImage) // If the count is now zero, remove from the tracker. // Otherwise, set the new value. - if (count == 0) { - mImageTracker.Remove(aImage); - } else { + if (count != 0) { mImageTracker.Put(aImage, count); + return NS_OK; } + mImageTracker.Remove(aImage); + nsresult rv = NS_OK; - // If we removed the image from the tracker and we're locking images, unlock - // this image. - if (count == 0 && mLockingImages) + // Now that we're no longer tracking this image, unlock it if we'd + // previously locked it. + if (mLockingImages) { rv = aImage->UnlockImage(); + } - // If we removed the image from the tracker and we're animating images, - // remove our request to animate this image. - if (count == 0 && mAnimatingImages) { + // If we're animating images, remove our request to animate this one. + if (mAnimatingImages) { nsresult rv2 = aImage->DecrementAnimationConsumers(); rv = NS_SUCCEEDED(rv) ? rv2 : rv; } + // Request that the image be discarded if nobody else holds a lock on it. + // Do this even if !mLockingImages, because even if we didn't just unlock + // this image, it might still be a candidate for discarding. + aImage->RequestDiscard(); + return rv; }