зеркало из https://github.com/mozilla/gecko-dev.git
Bug 845441: Remove DEBUG_CC. r=mccr8
This commit is contained in:
Родитель
70e8cc44a9
Коммит
8db92146c6
|
@ -151,11 +151,7 @@ using namespace mozilla;
|
||||||
//#define COLLECT_TIME_DEBUG
|
//#define COLLECT_TIME_DEBUG
|
||||||
|
|
||||||
#define DEFAULT_SHUTDOWN_COLLECTIONS 5
|
#define DEFAULT_SHUTDOWN_COLLECTIONS 5
|
||||||
#ifdef DEBUG_CC
|
|
||||||
#define SHUTDOWN_COLLECTIONS(params) params.mShutdownCollections
|
|
||||||
#else
|
|
||||||
#define SHUTDOWN_COLLECTIONS(params) DEFAULT_SHUTDOWN_COLLECTIONS
|
#define SHUTDOWN_COLLECTIONS(params) DEFAULT_SHUTDOWN_COLLECTIONS
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(XP_WIN)
|
#if defined(XP_WIN)
|
||||||
// Defined in nsThreadManager.cpp.
|
// Defined in nsThreadManager.cpp.
|
||||||
|
@ -178,8 +174,8 @@ PRThread* gCycleCollectorThread = nullptr;
|
||||||
// various cycle collector optimizations to give a fuller picture of
|
// various cycle collector optimizations to give a fuller picture of
|
||||||
// the heap.
|
// the heap.
|
||||||
//
|
//
|
||||||
// XPCOM_CC_RUN_DURING_SHUTDOWN: In non-DEBUG or non-DEBUG_CC builds,
|
// XPCOM_CC_RUN_DURING_SHUTDOWN: In non-DEBUG or builds, if this is set,
|
||||||
// if this is set, run cycle collections at shutdown.
|
// run cycle collections at shutdown.
|
||||||
//
|
//
|
||||||
// MOZ_CC_LOG_DIRECTORY: The directory in which logs are placed (such as
|
// MOZ_CC_LOG_DIRECTORY: The directory in which logs are placed (such as
|
||||||
// logs from XPCOM_CC_LOG_ALL and XPCOM_CC_LOG_SHUTDOWN, or other uses
|
// logs from XPCOM_CC_LOG_ALL and XPCOM_CC_LOG_SHUTDOWN, or other uses
|
||||||
|
@ -201,92 +197,16 @@ struct nsCycleCollectorParams
|
||||||
bool mLogShutdown;
|
bool mLogShutdown;
|
||||||
bool mAllTracesAtShutdown;
|
bool mAllTracesAtShutdown;
|
||||||
bool mDoNothing;
|
bool mDoNothing;
|
||||||
#ifdef DEBUG_CC
|
|
||||||
bool mReportStats;
|
|
||||||
bool mLogPointers;
|
|
||||||
uint32_t mShutdownCollections;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nsCycleCollectorParams() :
|
nsCycleCollectorParams() :
|
||||||
mLogAll (PR_GetEnv("XPCOM_CC_LOG_ALL") != NULL),
|
mLogAll (PR_GetEnv("XPCOM_CC_LOG_ALL") != NULL),
|
||||||
mLogShutdown (PR_GetEnv("XPCOM_CC_LOG_SHUTDOWN") != NULL),
|
mLogShutdown (PR_GetEnv("XPCOM_CC_LOG_SHUTDOWN") != NULL),
|
||||||
mAllTracesAtShutdown (PR_GetEnv("XPCOM_CC_ALL_TRACES_AT_SHUTDOWN") != NULL),
|
mAllTracesAtShutdown (PR_GetEnv("XPCOM_CC_ALL_TRACES_AT_SHUTDOWN") != NULL),
|
||||||
#ifdef DEBUG_CC
|
|
||||||
mDoNothing (PR_GetEnv("XPCOM_CC_DO_NOTHING") != NULL),
|
|
||||||
mReportStats (PR_GetEnv("XPCOM_CC_REPORT_STATS") != NULL),
|
|
||||||
mLogPointers (PR_GetEnv("XPCOM_CC_LOG_POINTERS") != NULL),
|
|
||||||
mShutdownCollections(DEFAULT_SHUTDOWN_COLLECTIONS)
|
|
||||||
#else
|
|
||||||
mDoNothing (false)
|
mDoNothing (false)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_CC
|
|
||||||
char *s = PR_GetEnv("XPCOM_CC_SHUTDOWN_COLLECTIONS");
|
|
||||||
if (s)
|
|
||||||
PR_sscanf(s, "%d", &mShutdownCollections);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
// Various operations involving the collector are recorded in a
|
|
||||||
// statistics table. These are for diagnostics.
|
|
||||||
|
|
||||||
struct nsCycleCollectorStats
|
|
||||||
{
|
|
||||||
uint32_t mFailedQI;
|
|
||||||
uint32_t mSuccessfulQI;
|
|
||||||
|
|
||||||
uint32_t mVisitedNode;
|
|
||||||
uint32_t mWalkedGraph;
|
|
||||||
uint32_t mFreedBytes;
|
|
||||||
|
|
||||||
uint32_t mSetColorBlack;
|
|
||||||
uint32_t mSetColorWhite;
|
|
||||||
|
|
||||||
uint32_t mFailedUnlink;
|
|
||||||
uint32_t mCollectedNode;
|
|
||||||
|
|
||||||
uint32_t mSuspectNode;
|
|
||||||
uint32_t mForgetNode;
|
|
||||||
|
|
||||||
uint32_t mCollection;
|
|
||||||
|
|
||||||
nsCycleCollectorStats()
|
|
||||||
{
|
|
||||||
memset(this, 0, sizeof(nsCycleCollectorStats));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Dump()
|
|
||||||
{
|
|
||||||
fprintf(stderr, "\f\n");
|
|
||||||
#define DUMP(entry) fprintf(stderr, "%30.30s: %-20.20d\n", #entry, entry)
|
|
||||||
DUMP(mFailedQI);
|
|
||||||
DUMP(mSuccessfulQI);
|
|
||||||
|
|
||||||
DUMP(mVisitedNode);
|
|
||||||
DUMP(mWalkedGraph);
|
|
||||||
DUMP(mFreedBytes);
|
|
||||||
|
|
||||||
DUMP(mSetColorBlack);
|
|
||||||
DUMP(mSetColorWhite);
|
|
||||||
|
|
||||||
DUMP(mFailedUnlink);
|
|
||||||
DUMP(mCollectedNode);
|
|
||||||
|
|
||||||
DUMP(mSuspectNode);
|
|
||||||
DUMP(mForgetNode);
|
|
||||||
|
|
||||||
DUMP(mCollection);
|
|
||||||
#undef DUMP
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
static bool nsCycleCollector_shouldSuppress(nsISupports *s);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef COLLECT_TIME_DEBUG
|
#ifdef COLLECT_TIME_DEBUG
|
||||||
class TimeLog
|
class TimeLog
|
||||||
{
|
{
|
||||||
|
@ -483,9 +403,6 @@ private:
|
||||||
EdgePool::Iterator mFirstChild;
|
EdgePool::Iterator mFirstChild;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#ifdef DEBUG_CC
|
|
||||||
char *mName;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PtrInfo(void *aPointer, nsCycleCollectionParticipant *aParticipant)
|
PtrInfo(void *aPointer, nsCycleCollectionParticipant *aParticipant)
|
||||||
: mPointer(aPointer),
|
: mPointer(aPointer),
|
||||||
|
@ -494,19 +411,10 @@ public:
|
||||||
mInternalRefs(0),
|
mInternalRefs(0),
|
||||||
mRefCount(0),
|
mRefCount(0),
|
||||||
mFirstChild()
|
mFirstChild()
|
||||||
#ifdef DEBUG_CC
|
|
||||||
, mName(nullptr)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aParticipant);
|
MOZ_ASSERT(aParticipant);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
void Destroy() {
|
|
||||||
PL_strfree(mName);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Allow NodePool::Block's constructor to compile.
|
// Allow NodePool::Block's constructor to compile.
|
||||||
PtrInfo() {
|
PtrInfo() {
|
||||||
NS_NOTREACHED("should never be called");
|
NS_NOTREACHED("should never be called");
|
||||||
|
@ -569,14 +477,6 @@ public:
|
||||||
|
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_CC
|
|
||||||
{
|
|
||||||
Enumerator queue(*this);
|
|
||||||
while (!queue.IsDone()) {
|
|
||||||
queue.GetNext()->Destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
Block *b = mBlocks;
|
Block *b = mBlocks;
|
||||||
while (b) {
|
while (b) {
|
||||||
Block *n = b->mNext;
|
Block *n = b->mNext;
|
||||||
|
@ -759,14 +659,12 @@ private:
|
||||||
nsPurpleBufferEntry mEntries[1365];
|
nsPurpleBufferEntry mEntries[1365];
|
||||||
|
|
||||||
Block() : mNext(nullptr) {
|
Block() : mNext(nullptr) {
|
||||||
#ifndef DEBUG_CC
|
|
||||||
// Ensure Block is the right size (see above).
|
// Ensure Block is the right size (see above).
|
||||||
MOZ_STATIC_ASSERT(
|
MOZ_STATIC_ASSERT(
|
||||||
sizeof(Block) == 16384 || // 32-bit
|
sizeof(Block) == 16384 || // 32-bit
|
||||||
sizeof(Block) == 32768, // 64-bit
|
sizeof(Block) == 32768, // 64-bit
|
||||||
"ill-sized nsPurpleBuffer::Block"
|
"ill-sized nsPurpleBuffer::Block"
|
||||||
);
|
);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
void StaticAsserts();
|
void StaticAsserts();
|
||||||
};
|
};
|
||||||
|
@ -779,27 +677,11 @@ public:
|
||||||
Block mFirstBlock;
|
Block mFirstBlock;
|
||||||
nsPurpleBufferEntry *mFreeList;
|
nsPurpleBufferEntry *mFreeList;
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
PointerSet mNormalObjects; // duplicates our blocks
|
|
||||||
nsCycleCollectorStats &mStats;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
nsPurpleBuffer(nsCycleCollectorParams ¶ms,
|
|
||||||
nsCycleCollectorStats &stats)
|
|
||||||
: mParams(params),
|
|
||||||
mStats(stats)
|
|
||||||
{
|
|
||||||
InitBlocks();
|
|
||||||
mNormalObjects.Init();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
nsPurpleBuffer(nsCycleCollectorParams ¶ms)
|
nsPurpleBuffer(nsCycleCollectorParams ¶ms)
|
||||||
: mParams(params)
|
: mParams(params)
|
||||||
{
|
{
|
||||||
InitBlocks();
|
InitBlocks();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
~nsPurpleBuffer()
|
~nsPurpleBuffer()
|
||||||
{
|
{
|
||||||
|
@ -875,13 +757,6 @@ public:
|
||||||
// removed. CanSkip() may be run on these children.
|
// removed. CanSkip() may be run on these children.
|
||||||
void RemoveSkippable(bool removeChildlessNodes);
|
void RemoveSkippable(bool removeChildlessNodes);
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
bool Exists(void *p) const
|
|
||||||
{
|
|
||||||
return mNormalObjects.GetEntry(p);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nsPurpleBufferEntry* NewEntry()
|
nsPurpleBufferEntry* NewEntry()
|
||||||
{
|
{
|
||||||
if (!mFreeList) {
|
if (!mFreeList) {
|
||||||
|
@ -923,10 +798,6 @@ public:
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mCount != 0, "must have entries");
|
MOZ_ASSERT(mCount != 0, "must have entries");
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
mNormalObjects.RemoveEntry(e->mObject);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
e->mNextInFreeList =
|
e->mNextInFreeList =
|
||||||
(nsPurpleBufferEntry*)(uintptr_t(mFreeList) | uintptr_t(1));
|
(nsPurpleBufferEntry*)(uintptr_t(mFreeList) | uintptr_t(1));
|
||||||
mFreeList = e;
|
mFreeList = e;
|
||||||
|
@ -954,7 +825,6 @@ public:
|
||||||
// - mParams: because it only contains scalars.
|
// - mParams: because it only contains scalars.
|
||||||
// - mFreeList: because it points into the purple buffer, which is
|
// - mFreeList: because it points into the purple buffer, which is
|
||||||
// within mFirstBlock and thus within |this|.
|
// within mFirstBlock and thus within |this|.
|
||||||
// - mNormalObjects, mStats: because they're DEBUG_CC-only.
|
|
||||||
//
|
//
|
||||||
// We also don't measure the things pointed to by mEntries[] because
|
// We also don't measure the things pointed to by mEntries[] because
|
||||||
// those pointers are non-owning.
|
// those pointers are non-owning.
|
||||||
|
@ -969,25 +839,6 @@ AddPurpleRoot(GCGraphBuilder &builder, void *root, nsCycleCollectionParticipant
|
||||||
void
|
void
|
||||||
nsPurpleBuffer::SelectPointers(GCGraphBuilder &aBuilder)
|
nsPurpleBuffer::SelectPointers(GCGraphBuilder &aBuilder)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_CC
|
|
||||||
// Can't use mCount here, since it may include null entries.
|
|
||||||
uint32_t realCount = 0;
|
|
||||||
for (Block *b = &mFirstBlock; b; b = b->mNext) {
|
|
||||||
for (nsPurpleBufferEntry *e = b->mEntries,
|
|
||||||
*eEnd = ArrayEnd(b->mEntries);
|
|
||||||
e != eEnd; ++e) {
|
|
||||||
if (!(uintptr_t(e->mObject) & uintptr_t(1))) {
|
|
||||||
if (e->mObject && !e->mNotPurple) {
|
|
||||||
++realCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ABORT_IF_FALSE(mNormalObjects.Count() == realCount,
|
|
||||||
"count out of sync");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Walk through all the blocks.
|
// Walk through all the blocks.
|
||||||
for (Block *b = &mFirstBlock; b; b = b->mNext) {
|
for (Block *b = &mFirstBlock; b; b = b->mNext) {
|
||||||
for (nsPurpleBufferEntry *e = b->mEntries,
|
for (nsPurpleBufferEntry *e = b->mEntries,
|
||||||
|
@ -1100,14 +951,6 @@ struct nsCycleCollector
|
||||||
size_t *aGraphEdgesSize,
|
size_t *aGraphEdgesSize,
|
||||||
size_t *aWhiteNodeSize,
|
size_t *aWhiteNodeSize,
|
||||||
size_t *aPurpleBufferSize) const;
|
size_t *aPurpleBufferSize) const;
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
nsCycleCollectorStats mStats;
|
|
||||||
FILE *mPtrLog;
|
|
||||||
|
|
||||||
bool LogPurpleAddition(void* aObject, nsCycleCollectionParticipant *cp);
|
|
||||||
void LogPurpleRemoval(void* aObject);
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1158,37 +1001,11 @@ Fault(const char *msg, const void *ptr=nullptr)
|
||||||
NS_RUNTIMEABORT("cycle collector fault");
|
NS_RUNTIMEABORT("cycle collector fault");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
static void
|
|
||||||
Fault(const char *msg, PtrInfo *pi)
|
|
||||||
{
|
|
||||||
printf("Fault in cycle collector: %s\n"
|
|
||||||
" while operating on pointer %p %s\n",
|
|
||||||
msg, pi->mPointer, pi->mName);
|
|
||||||
if (pi->mInternalRefs) {
|
|
||||||
printf(" which has internal references from:\n");
|
|
||||||
NodePool::Enumerator queue(sCollector->mGraph.mNodes);
|
|
||||||
while (!queue.IsDone()) {
|
|
||||||
PtrInfo *ppi = queue.GetNext();
|
|
||||||
for (EdgePool::Iterator e = ppi->FirstChild(),
|
|
||||||
e_end = ppi->LastChild();
|
|
||||||
e != e_end; ++e) {
|
|
||||||
if (*e == pi) {
|
|
||||||
printf(" %p %s\n", ppi->mPointer, ppi->mName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Fault(msg, pi->mPointer);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static void
|
static void
|
||||||
Fault(const char *msg, PtrInfo *pi)
|
Fault(const char *msg, PtrInfo *pi)
|
||||||
{
|
{
|
||||||
Fault(msg, pi->mPointer);
|
Fault(msg, pi->mPointer);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
AbortIfOffMainThreadIfCheckFast()
|
AbortIfOffMainThreadIfCheckFast()
|
||||||
|
@ -1208,12 +1025,6 @@ ToParticipant(nsISupports *s, nsXPCOMCycleCollectionParticipant **cp)
|
||||||
// object that implements traversal and unlinking logic for the nsISupports
|
// object that implements traversal and unlinking logic for the nsISupports
|
||||||
// in question.
|
// in question.
|
||||||
CallQueryInterface(s, cp);
|
CallQueryInterface(s, cp);
|
||||||
#ifdef DEBUG_CC
|
|
||||||
if (cp)
|
|
||||||
++sCollector->mStats.mSuccessfulQI;
|
|
||||||
else
|
|
||||||
++sCollector->mStats.mFailedQI;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Visitor>
|
template <class Visitor>
|
||||||
|
@ -1260,10 +1071,6 @@ GraphWalker<Visitor>::DoWalk(nsDeque &aQueue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
sCollector->mStats.mWalkedGraph++;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CCGraphDescriber
|
struct CCGraphDescriber
|
||||||
|
@ -1722,10 +1529,6 @@ private:
|
||||||
void DescribeNode(uint32_t refCount, const char *objName)
|
void DescribeNode(uint32_t refCount, const char *objName)
|
||||||
{
|
{
|
||||||
mCurrPi->mRefCount = refCount;
|
mCurrPi->mRefCount = refCount;
|
||||||
#ifdef DEBUG_CC
|
|
||||||
mCurrPi->mName = PL_strdup(objName);
|
|
||||||
sCollector->mStats.mVisitedNode++;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -1804,10 +1607,6 @@ GCGraphBuilder::GCGraphBuilder(GCGraph &aGraph,
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
#ifdef DEBUG_CC
|
|
||||||
flags = nsCycleCollectionTraversalCallback::WANT_DEBUG_INFO |
|
|
||||||
nsCycleCollectionTraversalCallback::WANT_ALL_TRACES;
|
|
||||||
#endif
|
|
||||||
if (!flags && mListener) {
|
if (!flags && mListener) {
|
||||||
flags = nsCycleCollectionTraversalCallback::WANT_DEBUG_INFO;
|
flags = nsCycleCollectionTraversalCallback::WANT_DEBUG_INFO;
|
||||||
bool all = false;
|
bool all = false;
|
||||||
|
@ -1863,13 +1662,6 @@ GCGraphBuilder::Traverse(PtrInfo* aPtrInfo)
|
||||||
{
|
{
|
||||||
mCurrPi = aPtrInfo;
|
mCurrPi = aPtrInfo;
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
if (!mCurrPi->mParticipant) {
|
|
||||||
Fault("unknown pointer during walk", aPtrInfo);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mCurrPi->SetFirstChild(mEdgeBuilder.Mark());
|
mCurrPi->SetFirstChild(mEdgeBuilder.Mark());
|
||||||
|
|
||||||
nsresult rv = aPtrInfo->mParticipant->Traverse(aPtrInfo->mPointer, *this);
|
nsresult rv = aPtrInfo->mParticipant->Traverse(aPtrInfo->mPointer, *this);
|
||||||
|
@ -1891,11 +1683,6 @@ GCGraphBuilder::NoteXPCOMRoot(nsISupports *root)
|
||||||
NS_ASSERTION(root,
|
NS_ASSERTION(root,
|
||||||
"Don't add objects that don't participate in collection!");
|
"Don't add objects that don't participate in collection!");
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
if (nsCycleCollector_shouldSuppress(root))
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nsXPCOMCycleCollectionParticipant *cp;
|
nsXPCOMCycleCollectionParticipant *cp;
|
||||||
ToParticipant(root, &cp);
|
ToParticipant(root, &cp);
|
||||||
|
|
||||||
|
@ -1960,11 +1747,6 @@ GCGraphBuilder::NoteXPCOMChild(nsISupports *child)
|
||||||
if (!child || !(child = CanonicalizeXPCOMParticipant(child)))
|
if (!child || !(child = CanonicalizeXPCOMParticipant(child)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
if (nsCycleCollector_shouldSuppress(child))
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nsXPCOMCycleCollectionParticipant *cp;
|
nsXPCOMCycleCollectionParticipant *cp;
|
||||||
ToParticipant(child, &cp);
|
ToParticipant(child, &cp);
|
||||||
if (cp && (!cp->CanSkipThis(child) || WantAllTraces())) {
|
if (cp && (!cp->CanSkipThis(child) || WantAllTraces())) {
|
||||||
|
@ -2215,9 +1997,6 @@ struct ScanBlackVisitor
|
||||||
if (pi->mColor == white)
|
if (pi->mColor == white)
|
||||||
--mWhiteNodeCount;
|
--mWhiteNodeCount;
|
||||||
pi->mColor = black;
|
pi->mColor = black;
|
||||||
#ifdef DEBUG_CC
|
|
||||||
sCollector->mStats.mSetColorBlack++;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t &mWhiteNodeCount;
|
uint32_t &mWhiteNodeCount;
|
||||||
|
@ -2243,9 +2022,6 @@ struct scanVisitor
|
||||||
if (pi->mInternalRefs == pi->mRefCount || pi->mRefCount == 0) {
|
if (pi->mInternalRefs == pi->mRefCount || pi->mRefCount == 0) {
|
||||||
pi->mColor = white;
|
pi->mColor = white;
|
||||||
++mWhiteNodeCount;
|
++mWhiteNodeCount;
|
||||||
#ifdef DEBUG_CC
|
|
||||||
sCollector->mStats.mSetColorWhite++;
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
GraphWalker<ScanBlackVisitor>(ScanBlackVisitor(mWhiteNodeCount)).Walk(pi);
|
GraphWalker<ScanBlackVisitor>(ScanBlackVisitor(mWhiteNodeCount)).Walk(pi);
|
||||||
MOZ_ASSERT(pi->mColor == black,
|
MOZ_ASSERT(pi->mColor == black,
|
||||||
|
@ -2306,19 +2082,6 @@ nsCycleCollector::ScanRoots()
|
||||||
GraphWalker<scanVisitor>(scanVisitor(mWhiteNodeCount)).WalkFromRoots(mGraph);
|
GraphWalker<scanVisitor>(scanVisitor(mWhiteNodeCount)).WalkFromRoots(mGraph);
|
||||||
|
|
||||||
ScanWeakMaps();
|
ScanWeakMaps();
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
// Sanity check: scan should have colored all grey nodes black or
|
|
||||||
// white. So we ensure we have no grey nodes at this point.
|
|
||||||
NodePool::Enumerator etor(mGraph.mNodes);
|
|
||||||
while (!etor.IsDone())
|
|
||||||
{
|
|
||||||
PtrInfo *pinfo = etor.GetNext();
|
|
||||||
if (pinfo->mColor == grey) {
|
|
||||||
Fault("valid grey node after scanning", pinfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2382,10 +2145,6 @@ nsCycleCollector::CollectWhite(nsICycleCollectorListener *aListener)
|
||||||
mBeforeUnlinkCB();
|
mBeforeUnlinkCB();
|
||||||
timeLog.Checkpoint("CollectWhite::BeforeUnlinkCB");
|
timeLog.Checkpoint("CollectWhite::BeforeUnlinkCB");
|
||||||
}
|
}
|
||||||
#if defined(DEBUG_CC) && !defined(__MINGW32__) && defined(WIN32)
|
|
||||||
struct _CrtMemState ms1, ms2;
|
|
||||||
_CrtMemCheckpoint(&ms1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (aListener) {
|
if (aListener) {
|
||||||
for (uint32_t i = 0; i < count; ++i) {
|
for (uint32_t i = 0; i < count; ++i) {
|
||||||
|
@ -2411,14 +2170,6 @@ nsCycleCollector::CollectWhite(nsICycleCollectorListener *aListener)
|
||||||
#endif
|
#endif
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
Fault("Failed unlink call while unlinking", pinfo);
|
Fault("Failed unlink call while unlinking", pinfo);
|
||||||
#ifdef DEBUG_CC
|
|
||||||
mStats.mFailedUnlink++;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
++mStats.mCollectedNode;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
timeLog.Checkpoint("CollectWhite::Unlink");
|
timeLog.Checkpoint("CollectWhite::Unlink");
|
||||||
|
@ -2431,12 +2182,6 @@ nsCycleCollector::CollectWhite(nsICycleCollectorListener *aListener)
|
||||||
}
|
}
|
||||||
timeLog.Checkpoint("CollectWhite::Unroot");
|
timeLog.Checkpoint("CollectWhite::Unroot");
|
||||||
|
|
||||||
#if defined(DEBUG_CC) && !defined(__MINGW32__) && defined(WIN32)
|
|
||||||
_CrtMemCheckpoint(&ms2);
|
|
||||||
if (ms2.lTotalCount < ms1.lTotalCount)
|
|
||||||
mStats.mFreedBytes += (ms1.lTotalCount - ms2.lTotalCount);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return count > 0;
|
return count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2538,12 +2283,7 @@ nsCycleCollector::nsCycleCollector() :
|
||||||
mBeforeUnlinkCB(nullptr),
|
mBeforeUnlinkCB(nullptr),
|
||||||
mForgetSkippableCB(nullptr),
|
mForgetSkippableCB(nullptr),
|
||||||
mReporter(nullptr),
|
mReporter(nullptr),
|
||||||
#ifdef DEBUG_CC
|
|
||||||
mPurpleBuf(mParams, mStats),
|
|
||||||
mPtrLog(nullptr)
|
|
||||||
#else
|
|
||||||
mPurpleBuf(mParams)
|
mPurpleBuf(mParams)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2587,75 +2327,6 @@ nsCycleCollector::ForgetJSRuntime()
|
||||||
mJSRuntime = nullptr;
|
mJSRuntime = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
|
|
||||||
class Suppressor :
|
|
||||||
public nsCycleCollectionTraversalCallback
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
static char *sSuppressionList;
|
|
||||||
static bool sInitialized;
|
|
||||||
bool mSuppressThisNode;
|
|
||||||
public:
|
|
||||||
Suppressor()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool shouldSuppress(nsISupports *s)
|
|
||||||
{
|
|
||||||
if (!sInitialized) {
|
|
||||||
sSuppressionList = PR_GetEnv("XPCOM_CC_SUPPRESS");
|
|
||||||
sInitialized = true;
|
|
||||||
}
|
|
||||||
if (sSuppressionList == nullptr) {
|
|
||||||
mSuppressThisNode = false;
|
|
||||||
} else {
|
|
||||||
nsresult rv;
|
|
||||||
nsXPCOMCycleCollectionParticipant *cp;
|
|
||||||
rv = CallQueryInterface(s, &cp);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
Fault("checking suppression on wrong type of pointer", s);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
cp->Traverse(s, *this);
|
|
||||||
}
|
|
||||||
return mSuppressThisNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHOD_(void) DescribeRefCountedNode(nsrefcnt refCount,
|
|
||||||
const char *objName)
|
|
||||||
{
|
|
||||||
mSuppressThisNode = (PL_strstr(sSuppressionList, objName) != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHOD_(void) DescribeGCedNode(bool isMarked, const char *objName)
|
|
||||||
{
|
|
||||||
mSuppressThisNode = (PL_strstr(sSuppressionList, objName) != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHOD_(void) NoteXPCOMRoot(nsISupports *root) {}
|
|
||||||
NS_IMETHOD_(void) NoteJSRoot(void *root) {}
|
|
||||||
NS_IMETHOD_(void) NoteNativeRoot(void *root,
|
|
||||||
nsCycleCollectionParticipant *participant) {}
|
|
||||||
NS_IMETHOD_(void) NoteXPCOMChild(nsISupports *child) {}
|
|
||||||
NS_IMETHOD_(void) NoteJSChild(void *child) {}
|
|
||||||
NS_IMETHOD_(void) NoteNativeChild(void *child,
|
|
||||||
nsCycleCollectionParticipant *participant) {}
|
|
||||||
NS_IMETHOD_(void) NoteNextEdgeName(const char* name) {}
|
|
||||||
NS_IMETHOD_(void) NoteWeakMapping(void *map, void *key, void *kdelegate, void *val) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
char *Suppressor::sSuppressionList = nullptr;
|
|
||||||
bool Suppressor::sInitialized = false;
|
|
||||||
|
|
||||||
static bool
|
|
||||||
nsCycleCollector_shouldSuppress(nsISupports *s)
|
|
||||||
{
|
|
||||||
Suppressor supp;
|
|
||||||
return supp.shouldSuppress(s);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static bool
|
static bool
|
||||||
nsCycleCollector_isScanSafe(void *s, nsCycleCollectionParticipant *cp)
|
nsCycleCollector_isScanSafe(void *s, nsCycleCollectionParticipant *cp)
|
||||||
|
@ -2691,11 +2362,6 @@ nsCycleCollector::Suspect2(void *n, nsCycleCollectionParticipant *cp)
|
||||||
if (mParams.mDoNothing)
|
if (mParams.mDoNothing)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
if (!LogPurpleAddition(n, cp))
|
|
||||||
return nullptr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Caller is responsible for filling in result's mRefCnt.
|
// Caller is responsible for filling in result's mRefCnt.
|
||||||
return mPurpleBuf.Put(n, cp);
|
return mPurpleBuf.Put(n, cp);
|
||||||
}
|
}
|
||||||
|
@ -2713,75 +2379,10 @@ nsCycleCollector::Forget2(nsPurpleBufferEntry *e)
|
||||||
if (mScanInProgress)
|
if (mScanInProgress)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
LogPurpleRemoval(e->mObject);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mPurpleBuf.Remove(e);
|
mPurpleBuf.Remove(e);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
void
|
|
||||||
nsCycleCollector_logPurpleAddition(void* aObject,
|
|
||||||
nsCycleCollectionParticipant *cp)
|
|
||||||
{
|
|
||||||
if (sCollector) {
|
|
||||||
sCollector->LogPurpleAddition(aObject, cp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
nsCycleCollector::LogPurpleAddition(void* aObject,
|
|
||||||
nsCycleCollectionParticipant *cp)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (mScanInProgress)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (mParams.mDoNothing)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
mStats.mSuspectNode++;
|
|
||||||
|
|
||||||
if (!cp &&
|
|
||||||
nsCycleCollector_shouldSuppress(static_cast<nsISupports *>(aObject)))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (mParams.mLogPointers) {
|
|
||||||
if (!mPtrLog)
|
|
||||||
mPtrLog = fopen("pointer_log", "w");
|
|
||||||
fprintf(mPtrLog, "S %p\n", static_cast<void*>(aObject));
|
|
||||||
}
|
|
||||||
|
|
||||||
mPurpleBuf.mNormalObjects.PutEntry(aObject);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsCycleCollector_logPurpleRemoval(void* aObject)
|
|
||||||
{
|
|
||||||
if (sCollector) {
|
|
||||||
sCollector->LogPurpleRemoval(aObject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsCycleCollector::LogPurpleRemoval(void* aObject)
|
|
||||||
{
|
|
||||||
AbortIfOffMainThreadIfCheckFast();
|
|
||||||
|
|
||||||
mStats.mForgetNode++;
|
|
||||||
|
|
||||||
if (mParams.mLogPointers) {
|
|
||||||
if (!mPtrLog)
|
|
||||||
mPtrLog = fopen("pointer_log", "w");
|
|
||||||
fprintf(mPtrLog, "F %p\n", aObject);
|
|
||||||
}
|
|
||||||
mPurpleBuf.mNormalObjects.RemoveEntry(aObject);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// The cycle collector uses the mark bitmap to discover what JS objects
|
// The cycle collector uses the mark bitmap to discover what JS objects
|
||||||
// were reachable only from XPConnect roots that might participate in
|
// were reachable only from XPConnect roots that might participate in
|
||||||
// cycles. We ask the JS runtime whether we need to force a GC before
|
// cycles. We ask the JS runtime whether we need to force a GC before
|
||||||
|
@ -2935,30 +2536,8 @@ nsCycleCollector::BeginCollection(bool aMergeCompartments,
|
||||||
timeLog.Checkpoint("mJSRuntime->BeginCycleCollection()");
|
timeLog.Checkpoint("mJSRuntime->BeginCycleCollection()");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
uint32_t purpleStart = builder.Count();
|
|
||||||
#endif
|
|
||||||
mScanInProgress = true;
|
mScanInProgress = true;
|
||||||
SelectPurple(builder);
|
SelectPurple(builder);
|
||||||
#ifdef DEBUG_CC
|
|
||||||
uint32_t purpleEnd = builder.Count();
|
|
||||||
|
|
||||||
if (purpleStart != purpleEnd) {
|
|
||||||
if (mParams.mLogPointers && !mPtrLog)
|
|
||||||
mPtrLog = fopen("pointer_log", "w");
|
|
||||||
|
|
||||||
uint32_t i = 0;
|
|
||||||
NodePool::Enumerator queue(mGraph.mNodes);
|
|
||||||
while (i++ < purpleStart) {
|
|
||||||
queue.GetNext();
|
|
||||||
}
|
|
||||||
while (i++ < purpleEnd) {
|
|
||||||
mStats.mForgetNode++;
|
|
||||||
if (mParams.mLogPointers)
|
|
||||||
fprintf(mPtrLog, "F %p\n", queue.GetNext()->mPointer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
timeLog.Checkpoint("SelectPurple()");
|
timeLog.Checkpoint("SelectPurple()");
|
||||||
|
|
||||||
|
@ -2988,25 +2567,6 @@ nsCycleCollector::BeginCollection(bool aMergeCompartments,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
if (mFollowupCollection && purpleStart != purpleEnd) {
|
|
||||||
uint32_t i = 0;
|
|
||||||
NodePool::Enumerator queue(mGraph.mNodes);
|
|
||||||
while (i++ < purpleStart) {
|
|
||||||
queue.GetNext();
|
|
||||||
}
|
|
||||||
while (i++ < purpleEnd) {
|
|
||||||
PtrInfo *pi = queue.GetNext();
|
|
||||||
if (pi->mColor == white) {
|
|
||||||
printf("nsCycleCollector: a later shutdown collection collected the additional\n"
|
|
||||||
" suspect %p %s\n"
|
|
||||||
" (which could be fixed by improving traversal)\n",
|
|
||||||
pi->mPointer, pi->mName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (mJSRuntime) {
|
if (mJSRuntime) {
|
||||||
mJSRuntime->FinishTraverse();
|
mJSRuntime->FinishTraverse();
|
||||||
timeLog.Checkpoint("mJSRuntime->FinishTraverse()");
|
timeLog.Checkpoint("mJSRuntime->FinishTraverse()");
|
||||||
|
@ -3025,28 +2585,8 @@ nsCycleCollector::FinishCollection(nsICycleCollectorListener *aListener)
|
||||||
bool collected = CollectWhite(aListener);
|
bool collected = CollectWhite(aListener);
|
||||||
timeLog.Checkpoint("CollectWhite()");
|
timeLog.Checkpoint("CollectWhite()");
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
mStats.mCollection++;
|
|
||||||
if (mParams.mReportStats)
|
|
||||||
mStats.Dump();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mFollowupCollection = true;
|
mFollowupCollection = true;
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
uint32_t i, count = mWhiteNodes->Length();
|
|
||||||
for (i = 0; i < count; ++i) {
|
|
||||||
PtrInfo *pinfo = mWhiteNodes->ElementAt(i);
|
|
||||||
if (mPurpleBuf.Exists(pinfo->mPointer)) {
|
|
||||||
printf("nsCycleCollector: %s object @%p is still alive after\n"
|
|
||||||
" calling RootAndUnlinkJSObjects, Unlink, and Unroot on"
|
|
||||||
" it! This probably\n"
|
|
||||||
" means the Unlink implementation was insufficient.\n",
|
|
||||||
pinfo->mName, pinfo->mPointer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mWhiteNodes->Clear();
|
mWhiteNodes->Clear();
|
||||||
ClearGraph();
|
ClearGraph();
|
||||||
timeLog.Checkpoint("ClearGraph()");
|
timeLog.Checkpoint("ClearGraph()");
|
||||||
|
@ -3066,9 +2606,7 @@ void
|
||||||
nsCycleCollector::Shutdown()
|
nsCycleCollector::Shutdown()
|
||||||
{
|
{
|
||||||
#ifndef DEBUG
|
#ifndef DEBUG
|
||||||
#ifndef DEBUG_CC
|
|
||||||
if (PR_GetEnv("XPCOM_CC_RUN_DURING_SHUTDOWN"))
|
if (PR_GetEnv("XPCOM_CC_RUN_DURING_SHUTDOWN"))
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsCycleCollectorLogger> listener;
|
nsCOMPtr<nsCycleCollectorLogger> listener;
|
||||||
|
@ -3081,17 +2619,6 @@ nsCycleCollector::Shutdown()
|
||||||
Collect(false, nullptr, SHUTDOWN_COLLECTIONS(mParams), listener);
|
Collect(false, nullptr, SHUTDOWN_COLLECTIONS(mParams), listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
GCGraphBuilder builder(mGraph, mJSRuntime, nullptr, false);
|
|
||||||
mScanInProgress = true;
|
|
||||||
SelectPurple(builder);
|
|
||||||
mScanInProgress = false;
|
|
||||||
if (builder.Count() != 0) {
|
|
||||||
printf("Might have been able to release more cycles if the cycle collector would "
|
|
||||||
"run once more at shutdown.\n");
|
|
||||||
}
|
|
||||||
ClearGraph();
|
|
||||||
#endif
|
|
||||||
mParams.mDoNothing = true;
|
mParams.mDoNothing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3119,7 +2646,6 @@ nsCycleCollector::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||||
// - mResults: because it's tiny and only contains scalars.
|
// - mResults: because it's tiny and only contains scalars.
|
||||||
// - mJSRuntime: because it's non-owning and measured by JS reporters.
|
// - mJSRuntime: because it's non-owning and measured by JS reporters.
|
||||||
// - mParams: because it only contains scalars.
|
// - mParams: because it only contains scalars.
|
||||||
// - mStats, mPtrLog: because they're DEBUG_CC-only.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
#ifndef nsCycleCollector_h__
|
#ifndef nsCycleCollector_h__
|
||||||
#define nsCycleCollector_h__
|
#define nsCycleCollector_h__
|
||||||
|
|
||||||
//#define DEBUG_CC
|
|
||||||
|
|
||||||
class nsISupports;
|
class nsISupports;
|
||||||
class nsICycleCollectorListener;
|
class nsICycleCollectorListener;
|
||||||
class nsCycleCollectionParticipant;
|
class nsCycleCollectionParticipant;
|
||||||
|
@ -37,12 +35,6 @@ void nsCycleCollector_setForgetSkippableCallback(CC_ForgetSkippableCallback aCB)
|
||||||
|
|
||||||
void nsCycleCollector_forgetSkippable(bool aRemoveChildlessNodes = false);
|
void nsCycleCollector_forgetSkippable(bool aRemoveChildlessNodes = false);
|
||||||
|
|
||||||
#ifdef DEBUG_CC
|
|
||||||
void nsCycleCollector_logPurpleAddition(void* aObject,
|
|
||||||
nsCycleCollectionParticipant* cp);
|
|
||||||
void nsCycleCollector_logPurpleRemoval(void* aObject);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void nsCycleCollector_collect(bool aMergeCompartments,
|
void nsCycleCollector_collect(bool aMergeCompartments,
|
||||||
nsCycleCollectorResults *aResults,
|
nsCycleCollectorResults *aResults,
|
||||||
nsICycleCollectorListener *aListener);
|
nsICycleCollectorListener *aListener);
|
||||||
|
|
|
@ -145,12 +145,6 @@ public:
|
||||||
MOZ_ASSERT(e->mObject == owner, "wrong entry");
|
MOZ_ASSERT(e->mObject == owner, "wrong entry");
|
||||||
MOZ_ASSERT(int32_t(e->mRefCnt) > 0, "purple ISupports with bad refcnt");
|
MOZ_ASSERT(int32_t(e->mRefCnt) > 0, "purple ISupports with bad refcnt");
|
||||||
refcount = ++(e->mRefCnt);
|
refcount = ++(e->mRefCnt);
|
||||||
#ifdef DEBUG_CC
|
|
||||||
if (!e->mNotPurple) {
|
|
||||||
nsCycleCollector_logPurpleRemoval(
|
|
||||||
NS_CCAR_TAGGED_TO_PURPLE_ENTRY(mTagged)->mObject);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
e->mNotPurple = true;
|
e->mNotPurple = true;
|
||||||
} else {
|
} else {
|
||||||
refcount = NS_CCAR_TAGGED_TO_REFCNT(mTagged);
|
refcount = NS_CCAR_TAGGED_TO_REFCNT(mTagged);
|
||||||
|
@ -184,19 +178,9 @@ public:
|
||||||
MOZ_ASSERT(int32_t(e->mRefCnt) > 0, "purple ISupports with bad refcnt");
|
MOZ_ASSERT(int32_t(e->mRefCnt) > 0, "purple ISupports with bad refcnt");
|
||||||
refcount = --(e->mRefCnt);
|
refcount = --(e->mRefCnt);
|
||||||
if (MOZ_UNLIKELY(refcount == 0)) {
|
if (MOZ_UNLIKELY(refcount == 0)) {
|
||||||
#ifdef DEBUG_CC
|
|
||||||
nsCycleCollector_logPurpleRemoval(
|
|
||||||
NS_CCAR_TAGGED_TO_PURPLE_ENTRY(mTagged)->mObject);
|
|
||||||
#endif
|
|
||||||
e->mObject = nullptr;
|
e->mObject = nullptr;
|
||||||
mTagged = NS_CCAR_REFCNT_TO_TAGGED(0);
|
mTagged = NS_CCAR_REFCNT_TO_TAGGED(0);
|
||||||
} else {
|
} else {
|
||||||
#ifdef DEBUG_CC
|
|
||||||
if (e->mNotPurple) {
|
|
||||||
nsCycleCollector_logPurpleAddition(
|
|
||||||
NS_CCAR_TAGGED_TO_PURPLE_ENTRY(mTagged)->mObject, p);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
e->mNotPurple = false;
|
e->mNotPurple = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -227,10 +211,6 @@ public:
|
||||||
MOZ_ALWAYS_INLINE void RemovePurple()
|
MOZ_ALWAYS_INLINE void RemovePurple()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(IsPurple(), "must be purple");
|
MOZ_ASSERT(IsPurple(), "must be purple");
|
||||||
#ifdef DEBUG_CC
|
|
||||||
nsCycleCollector_logPurpleRemoval(
|
|
||||||
NS_CCAR_TAGGED_TO_PURPLE_ENTRY(mTagged)->mObject);
|
|
||||||
#endif
|
|
||||||
// The entry will be added to the free list later.
|
// The entry will be added to the free list later.
|
||||||
NS_CCAR_TAGGED_TO_PURPLE_ENTRY(mTagged)->mObject = nullptr;
|
NS_CCAR_TAGGED_TO_PURPLE_ENTRY(mTagged)->mObject = nullptr;
|
||||||
ReleasePurpleBufferEntry();
|
ReleasePurpleBufferEntry();
|
||||||
|
|
Загрузка…
Ссылка в новой задаче