Bug 737075 - unmark gray strongly held observers implemented in JS. r=bsmedberg, smaug

This commit is contained in:
Andrew McCreight 2012-04-30 12:01:11 -07:00
parent 7e14831de1
commit c7b15dad64
6 changed files with 43 additions and 0 deletions

View File

@ -62,6 +62,7 @@
#include "nsFrameLoader.h"
#include "nsGenericElement.h"
#include "xpcpublic.h"
#include "nsObserverService.h"
static bool sInited = 0;
PRUint32 nsCCUncollectableMarker::sGeneration = 0;
@ -373,6 +374,10 @@ nsCCUncollectableMarker::Observe(nsISupports* aSubject, const char* aTopic,
if (cleanupJS) {
nsContentUtils::UnmarkGrayJSListenersInCCGenerationDocuments(sGeneration);
MarkMessageManagers();
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
static_cast<nsObserverService *>(obs.get())->UnmarkGrayStrongObservers();
previousWasJSCleanup = true;
} else if (previousWasJSCleanup) {
previousWasJSCleanup = false;

View File

@ -101,6 +101,7 @@ EXPORTS = \
nsIByteBuffer.h \
nsIUnicharBuffer.h \
nsMathUtils.h \
nsObserverList.h \
nsObserverService.h \
nsStaticNameTable.h \
nsStaticAtom.h \

View File

@ -40,6 +40,7 @@
#include "nsAutoPtr.h"
#include "nsCOMArray.h"
#include "nsISimpleEnumerator.h"
#include "xpcpublic.h"
nsresult
nsObserverList::AddObserver(nsIObserver* anObserver, bool ownsWeak)
@ -131,6 +132,16 @@ nsObserverList::NotifyObservers(nsISupports *aSubject,
}
}
void
nsObserverList::UnmarkGrayStrongObservers()
{
for (PRUint32 i = 0; i < mObservers.Length(); ++i) {
if (!mObservers[i].isWeakRef) {
xpc_TryUnmarkWrappedGrayObject(mObservers[i].asObserver());
}
}
}
NS_IMPL_ISUPPORTS1(nsObserverEnumerator, nsISimpleEnumerator)
nsObserverEnumerator::nsObserverEnumerator(nsObserverList* aObserverList)

View File

@ -91,6 +91,10 @@ public:
// The array is filled in last-added-first order.
void FillObserverArray(nsCOMArray<nsIObserver> &aArray);
// Unmark any strongly held observers implemented in JS so the cycle
// collector will not traverse them.
void UnmarkGrayStrongObservers();
private:
nsTArray<ObserverRef> mObservers;
};

View File

@ -190,3 +190,21 @@ NS_IMETHODIMP nsObserverService::NotifyObservers(nsISupports *aSubject,
return NS_OK;
}
static PLDHashOperator
UnmarkGrayObserverEntry(nsObserverList* aObserverList, void* aClosure)
{
if (aObserverList) {
aObserverList->UnmarkGrayStrongObservers();
}
return PL_DHASH_NEXT;
}
NS_IMETHODIMP
nsObserverService::UnmarkGrayStrongObservers()
{
NS_ENSURE_VALIDCALL
mObserverTopicTable.EnumerateEntries(UnmarkGrayObserverEntry, nsnull);
return NS_OK;
}

View File

@ -62,6 +62,10 @@ public:
static nsresult
Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr);
// Unmark any strongly held observers implemented in JS so the cycle
// collector will not traverse them.
NS_IMETHOD UnmarkGrayStrongObservers();
private:
~nsObserverService(void);