Bug 1385459 - Don't use QI to canonicalize nsISupports pointers in the purple buffer. r=smaug

The nsISupports objects added to the purple buffer are already
canonical, so we can avoid some overhead by not QIing them to
nsCycleCollectionISupports. This QIing overhead shows up in profiles.

MozReview-Commit-ID: CQN6wwc7MZm

--HG--
extra : rebase_source : 27e6b70f83b42b5db7af3d1e7d62e36d6f4013a0
This commit is contained in:
Andrew McCreight 2017-07-28 15:24:17 -07:00
Родитель e159a1cd0a
Коммит 23896c49cb
1 изменённых файлов: 25 добавлений и 29 удалений

Просмотреть файл

@ -956,27 +956,6 @@ CanonicalizeXPCOMParticipant(nsISupports* aIn)
return out;
}
static inline void
ToParticipant(nsISupports* aPtr, nsXPCOMCycleCollectionParticipant** aCp);
static void
CanonicalizeParticipant(void** aParti, nsCycleCollectionParticipant** aCp)
{
// If the participant is null, this is an nsISupports participant,
// so we must QI to get the real participant.
if (!*aCp) {
nsISupports* nsparti = static_cast<nsISupports*>(*aParti);
nsparti = CanonicalizeXPCOMParticipant(nsparti);
NS_ASSERTION(nsparti,
"Don't add objects that don't participate in collection!");
nsXPCOMCycleCollectionParticipant* xcp;
ToParticipant(nsparti, &xcp);
*aParti = nsparti;
*aCp = xcp;
}
}
struct nsPurpleBufferEntry
{
nsPurpleBufferEntry(void* aObject, nsCycleCollectingAutoRefCnt* aRefCnt,
@ -1426,6 +1405,21 @@ ToParticipant(nsISupports* aPtr, nsXPCOMCycleCollectionParticipant** aCp)
CallQueryInterface(aPtr, aCp);
}
static void
ToParticipant(void* aParti, nsCycleCollectionParticipant** aCp)
{
// If the participant is null, this is an nsISupports participant,
// so we must QI to get the real participant.
if (!*aCp) {
nsISupports* nsparti = static_cast<nsISupports*>(aParti);
MOZ_ASSERT(CanonicalizeXPCOMParticipant(nsparti) == nsparti);
nsXPCOMCycleCollectionParticipant* xcp;
ToParticipant(nsparti, &xcp);
*aCp = xcp;
}
}
template<class Visitor>
MOZ_NEVER_INLINE void
GraphWalker<Visitor>::Walk(PtrInfo* aPi)
@ -2234,7 +2228,7 @@ CCGraphBuilder::AddNode(void* aPtr, nsCycleCollectionParticipant* aParticipant)
bool
CCGraphBuilder::AddPurpleRoot(void* aRoot, nsCycleCollectionParticipant* aParti)
{
CanonicalizeParticipant(&aRoot, &aParti);
ToParticipant(aRoot, &aParti);
if (WantAllTraces() || !aParti->CanSkipInCC(aRoot)) {
PtrInfo* pinfo = AddNode(aRoot, aParti);
@ -2670,7 +2664,7 @@ public:
if (!aEntry->mRefCnt->get()) {
void* o = aEntry->mObject;
nsCycleCollectionParticipant* cp = aEntry->mParticipant;
CanonicalizeParticipant(&o, &cp);
ToParticipant(o, &cp);
SnowWhiteObject swo = { o, cp, aEntry->mRefCnt };
mObjects.InfallibleAppend(swo);
aBuffer.Remove(aEntry);
@ -2796,7 +2790,7 @@ public:
}
void* o = aEntry->mObject;
nsCycleCollectionParticipant* cp = aEntry->mParticipant;
CanonicalizeParticipant(&o, &cp);
ToParticipant(o, &cp);
if (aEntry->mRefCnt->IsPurple() && !cp->CanSkip(o, false) &&
(!mRemoveChildlessNodes || MayHaveChild(o, cp))) {
return true;
@ -3003,10 +2997,9 @@ public:
"Snow-white objects shouldn't be in the purple buffer.");
void* obj = aEntry->mObject;
if (!aEntry->mParticipant) {
obj = CanonicalizeXPCOMParticipant(static_cast<nsISupports*>(obj));
MOZ_ASSERT(obj, "Don't add objects that don't participate in collection!");
}
MOZ_ASSERT(aEntry->mParticipant || CanonicalizeXPCOMParticipant(static_cast<nsISupports*>(obj)) == obj,
"Suspect nsISupports pointer must be canonical");
PtrInfo* pi = mGraph.FindNode(obj);
if (!pi) {
@ -3489,6 +3482,9 @@ nsCycleCollector::Suspect(void* aPtr, nsCycleCollectionParticipant* aParti,
MOZ_ASSERT(HasParticipant(aPtr, aParti),
"Suspected nsISupports pointer must QI to nsXPCOMCycleCollectionParticipant");
MOZ_ASSERT(aParti || CanonicalizeXPCOMParticipant(static_cast<nsISupports*>(aPtr)) == aPtr,
"Suspect nsISupports pointer must be canonical");
mPurpleBuf.Put(aPtr, aParti, aRefCnt);
}
@ -4009,7 +4005,7 @@ SuspectAfterShutdown(void* aPtr, nsCycleCollectionParticipant* aCp,
if (aRefCnt->get() == 0) {
if (!aShouldDelete) {
// The CC is shut down, so we can't be in the middle of an ICC.
CanonicalizeParticipant(&aPtr, &aCp);
ToParticipant(aPtr, &aCp);
aRefCnt->stabilizeForDeletion();
aCp->DeleteCycleCollectable(aPtr);
} else {