Bug 1543537, part 1 - Add a NoteWeakMapping method to traversal callback. r=kmag

For nsXPCWrappedJS, we need to add an edge to the cycle collector graph
from the JS object to its WJS, even though the JS object does not actually
contain a pointer to the WJS object. We can (mis)use the weak mapping
interface for this purpose. The only difference is that we need it during
traversal instead of while adding roots. The API is fairly specialized to
the specific use case we need.

Differential Revision: https://phabricator.services.mozilla.com/D157529
This commit is contained in:
Andrew McCreight
2022-09-24 23:24:31 +00:00
parent 62f9f0eda3
commit 448c4376c2
3 changed files with 35 additions and 0 deletions

View File

@@ -89,6 +89,10 @@ class DebugWrapperTraversalCallback
NoteNativeChild(void* aChild,
nsCycleCollectionParticipant* aHelper) override {}
NS_IMETHOD_(void)
NoteWeakMapping(JSObject* aKey, nsISupports* aVal,
nsCycleCollectionParticipant* aValParticipant) override {}
NS_IMETHOD_(void) NoteNextEdgeName(const char* aName) override {}
bool mFound;

View File

@@ -12,6 +12,7 @@
class nsCycleCollectionParticipant;
class nsISupports;
class JSObject;
namespace JS {
class GCCellPtr;
@@ -35,6 +36,10 @@ class NS_NO_VTABLE nsCycleCollectionTraversalCallback {
NS_IMETHOD_(void)
NoteNativeChild(void* aChild, nsCycleCollectionParticipant* aHelper) = 0;
NS_IMETHOD_(void)
NoteWeakMapping(JSObject* aKey, nsISupports* aVal,
nsCycleCollectionParticipant* aValParticipant) = 0;
// Give a name to the edge associated with the next call to
// NoteXPCOMChild, NoteJSObject, NoteJSScript, or NoteNativeChild.
// Callbacks who care about this should set WANT_DEBUG_INFO in the

View File

@@ -1878,6 +1878,13 @@ class CCGraphBuilder final : public nsCycleCollectionTraversalCallback,
NS_IMETHOD_(void)
NoteWeakMapping(JSObject* aMap, JS::GCCellPtr aKey, JSObject* aKdelegate,
JS::GCCellPtr aVal) override;
// This is used to create synthetic non-refcounted references to
// nsXPCWrappedJS from their wrapped JS objects. No map is needed, because
// the SubjectToFinalization list is like a known-black weak map, and
// no delegate is needed because the keys are all unwrapped objects.
NS_IMETHOD_(void)
NoteWeakMapping(JSObject* aKey, nsISupports* aVal,
nsCycleCollectionParticipant* aValParticipant) override;
// nsCycleCollectionTraversalCallback methods.
NS_IMETHOD_(void)
@@ -2241,6 +2248,21 @@ CCGraphBuilder::NoteWeakMapping(JSObject* aMap, JS::GCCellPtr aKey,
}
}
NS_IMETHODIMP_(void)
CCGraphBuilder::NoteWeakMapping(JSObject* aKey, nsISupports* aVal,
nsCycleCollectionParticipant* aValParticipant) {
WeakMapping* mapping = mGraph.mWeakMaps.AppendElement();
mapping->mMap = nullptr;
mapping->mKey = aKey ? AddWeakMapNode(aKey) : nullptr;
mapping->mKeyDelegate = mapping->mKey;
MOZ_ASSERT(js::UncheckedUnwrapWithoutExpose(aKey) == aKey);
mapping->mVal = aVal ? AddNode(aVal, aValParticipant) : nullptr;
if (mLogger) {
mLogger->NoteWeakMapEntry(0, (uint64_t)aKey, 0, (uint64_t)aVal);
}
}
static bool AddPurpleRoot(CCGraphBuilder& aBuilder, void* aRoot,
nsCycleCollectionParticipant* aParti) {
return aBuilder.AddPurpleRoot(aRoot, aParti);
@@ -2259,6 +2281,10 @@ class ChildFinder : public nsCycleCollectionTraversalCallback {
NoteNativeChild(void* aChild, nsCycleCollectionParticipant* aHelper) override;
NS_IMETHOD_(void) NoteJSChild(JS::GCCellPtr aThing) override;
NS_IMETHOD_(void)
NoteWeakMapping(JSObject* aKey, nsISupports* aVal,
nsCycleCollectionParticipant* aValParticipant) override {}
NS_IMETHOD_(void)
DescribeRefCountedNode(nsrefcnt aRefcount, const char* aObjname) override {}
NS_IMETHOD_(void)