Skip to content

Commit 05fb8bb

Browse files
committed
Bug 737075 - unmark gray strongly held observers implemented in JS. r=bsmedberg, smaug
1 parent 4b321f4 commit 05fb8bb

File tree

6 files changed

+43
-0
lines changed

6 files changed

+43
-0
lines changed

content/base/src/nsCCUncollectableMarker.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
#include "nsFrameLoader.h"
6363
#include "nsGenericElement.h"
6464
#include "xpcpublic.h"
65+
#include "nsObserverService.h"
6566

6667
static bool sInited = 0;
6768
PRUint32 nsCCUncollectableMarker::sGeneration = 0;
@@ -373,6 +374,10 @@ nsCCUncollectableMarker::Observe(nsISupports* aSubject, const char* aTopic,
373374
if (cleanupJS) {
374375
nsContentUtils::UnmarkGrayJSListenersInCCGenerationDocuments(sGeneration);
375376
MarkMessageManagers();
377+
378+
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
379+
static_cast<nsObserverService *>(obs.get())->UnmarkGrayStrongObservers();
380+
376381
previousWasJSCleanup = true;
377382
} else if (previousWasJSCleanup) {
378383
previousWasJSCleanup = false;

xpcom/ds/Makefile.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ EXPORTS = \
101101
nsIByteBuffer.h \
102102
nsIUnicharBuffer.h \
103103
nsMathUtils.h \
104+
nsObserverList.h \
104105
nsObserverService.h \
105106
nsStaticNameTable.h \
106107
nsStaticAtom.h \

xpcom/ds/nsObserverList.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "nsAutoPtr.h"
4141
#include "nsCOMArray.h"
4242
#include "nsISimpleEnumerator.h"
43+
#include "xpcpublic.h"
4344

4445
nsresult
4546
nsObserverList::AddObserver(nsIObserver* anObserver, bool ownsWeak)
@@ -131,6 +132,16 @@ nsObserverList::NotifyObservers(nsISupports *aSubject,
131132
}
132133
}
133134

135+
void
136+
nsObserverList::UnmarkGrayStrongObservers()
137+
{
138+
for (PRUint32 i = 0; i < mObservers.Length(); ++i) {
139+
if (!mObservers[i].isWeakRef) {
140+
xpc_TryUnmarkWrappedGrayObject(mObservers[i].asObserver());
141+
}
142+
}
143+
}
144+
134145
NS_IMPL_ISUPPORTS1(nsObserverEnumerator, nsISimpleEnumerator)
135146

136147
nsObserverEnumerator::nsObserverEnumerator(nsObserverList* aObserverList)

xpcom/ds/nsObserverList.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ class nsObserverList : public nsCharPtrHashKey
9191
// The array is filled in last-added-first order.
9292
void FillObserverArray(nsCOMArray<nsIObserver> &aArray);
9393

94+
// Unmark any strongly held observers implemented in JS so the cycle
95+
// collector will not traverse them.
96+
void UnmarkGrayStrongObservers();
97+
9498
private:
9599
nsTArray<ObserverRef> mObservers;
96100
};

xpcom/ds/nsObserverService.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,3 +190,21 @@ NS_IMETHODIMP nsObserverService::NotifyObservers(nsISupports *aSubject,
190190
return NS_OK;
191191
}
192192

193+
static PLDHashOperator
194+
UnmarkGrayObserverEntry(nsObserverList* aObserverList, void* aClosure)
195+
{
196+
if (aObserverList) {
197+
aObserverList->UnmarkGrayStrongObservers();
198+
}
199+
return PL_DHASH_NEXT;
200+
}
201+
202+
NS_IMETHODIMP
203+
nsObserverService::UnmarkGrayStrongObservers()
204+
{
205+
NS_ENSURE_VALIDCALL
206+
207+
mObserverTopicTable.EnumerateEntries(UnmarkGrayObserverEntry, nsnull);
208+
209+
return NS_OK;
210+
}

xpcom/ds/nsObserverService.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ class nsObserverService : public nsIObserverService {
6262
static nsresult
6363
Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr);
6464

65+
// Unmark any strongly held observers implemented in JS so the cycle
66+
// collector will not traverse them.
67+
NS_IMETHOD UnmarkGrayStrongObservers();
68+
6569
private:
6670
~nsObserverService(void);
6771

0 commit comments

Comments
 (0)