Bug 1744036 part 6 - Stop pinning atoms for XPCNativeInterface. r=mccr8,jonco

Replace the use of pinned atoms with code to trace all atoms stored in live
XPCNativeInterface instances. This means we stop 'leaking' those atoms after
releasing the XPCNativeInterface using them.

Differential Revision: https://phabricator.services.mozilla.com/D132693
This commit is contained in:
Jan de Mooij 2021-12-08 08:38:02 +00:00
parent 364cf1e480
commit f966d35ca2
5 changed files with 36 additions and 6 deletions

View File

@ -697,6 +697,10 @@ void XPCJSRuntime::TraceNativeBlackRoots(JSTracer* trc) {
}
}
if (mIID2NativeInterfaceMap) {
mIID2NativeInterfaceMap->Trace(trc);
}
dom::TraceBlackJS(trc);
}

View File

@ -181,6 +181,8 @@ class IID2NativeInterfaceMap {
size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
void Trace(JSTracer* trc);
private:
Map mMap;
};

View File

@ -281,12 +281,12 @@ already_AddRefed<XPCNativeInterface> XPCNativeInterface::NewInstance(
return nullptr;
}
RootedString str(cx, JS_AtomizeAndPinString(cx, namestr.get()));
RootedString str(cx, JS_AtomizeString(cx, namestr.get()));
if (!str) {
NS_ERROR("bad constant name");
return nullptr;
}
jsid name = PropertyKey::fromPinnedString(str);
jsid name = PropertyKey::fromNonIntAtom(str);
// XXX need better way to find dups
// MOZ_ASSERT(!LookupMemberByID(name),"duplicate method/constant name");
@ -306,12 +306,12 @@ already_AddRefed<XPCNativeInterface> XPCNativeInterface::NewInstance(
if (!bytes) {
return nullptr;
}
RootedString str(cx, JS_AtomizeAndPinString(cx, bytes));
RootedString str(cx, JS_AtomizeString(cx, bytes));
if (!str) {
return nullptr;
}
RootedId interfaceName(cx, PropertyKey::fromPinnedString(str));
RootedId interfaceName(cx, PropertyKey::fromNonIntAtom(str));
// Use placement new to create an object with the right amount of space
// to hold the members array
@ -352,6 +352,23 @@ size_t XPCNativeInterface::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) {
return mallocSizeOf(this);
}
void XPCNativeInterface::Trace(JSTracer* trc) {
JS::TraceRoot(trc, &mName, "XPCNativeInterface::mName");
for (size_t i = 0; i < mMemberCount; i++) {
JS::PropertyKey key = mMembers[i].GetName();
JS::TraceRoot(trc, &key, "XPCNativeInterface::mMembers");
MOZ_ASSERT(mMembers[i].GetName() == key);
}
}
void IID2NativeInterfaceMap::Trace(JSTracer* trc) {
for (Map::Enum e(mMap); !e.empty(); e.popFront()) {
XPCNativeInterface* iface = e.front().value();
iface->Trace(trc);
}
}
void XPCNativeInterface::DebugDump(int16_t depth) {
#ifdef DEBUG
depth--;

View File

@ -1027,7 +1027,7 @@ class XPCNativeMember final {
// creation of XPCNativeInterfaces which have more than 2^12 members.
// If the width of this field changes, update GetMaxIndexInInterface.
uint16_t mIndexInInterface : 12;
} JS_HAZ_NON_GC_POINTER; // Only stores a pinned string
};
/***************************************************************************/
// XPCNativeInterface represents a single idl declared interface. This is
@ -1067,6 +1067,8 @@ class XPCNativeInterface final {
size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf);
void Trace(JSTracer* trc);
protected:
static already_AddRefed<XPCNativeInterface> NewInstance(
JSContext* cx, IID2NativeInterfaceMap* aMap,

View File

@ -96,5 +96,10 @@ bool nsXPTMethodInfo::GetId(JSContext* aCx, jsid& aId) const {
return true;
}
return mozilla::dom::AtomizeAndPinJSString(aCx, aId, Name());
JSString* str = JS_AtomizeString(aCx, Name());
if (!str) {
return false;
}
aId = JS::PropertyKey::fromNonIntAtom(str);
return true;
}