nsresult nsTraceRefcnt::DumpStatistics() { if (!gBloatLog || !gBloatView) { return NS_ERROR_FAILURE; } AutoTraceLogLock lock; MOZ_ASSERT(!gDumpedStatistics, "Calling DumpStatistics more than once may result in " "bogus positive or negative leaks being reported"); gDumpedStatistics = true; // Don't try to log while we hold the lock, we'd deadlock. AutoRestore<LoggingType> saveLogging(gLogging); gLogging = NoLogging; BloatEntry total("TOTAL", 0); PL_HashTableEnumerateEntries(gBloatView, BloatEntry::TotalEntries, &total); const char* msg; if (gLogLeaksOnly) { msg = "ALL (cumulative) LEAK STATISTICS"; } else { msg = "ALL (cumulative) LEAK AND BLOAT STATISTICS"; } const bool leaked = total.PrintDumpHeader(gBloatLog, msg); nsTArray<BloatEntry*> entries; PL_HashTableEnumerateEntries(gBloatView, BloatEntry::DumpEntry, &entries); const uint32_t count = entries.Length(); if (!gLogLeaksOnly || leaked) { // Sort the entries alphabetically by classname. entries.Sort(); for (uint32_t i = 0; i < count; ++i) { BloatEntry* entry = entries[i]; entry->Dump(i, gBloatLog); } fprintf(gBloatLog, "\n"); } fprintf(gBloatLog, "nsTraceRefcnt::DumpStatistics: %d entries\n", count); if (gSerialNumbers) { fprintf(gBloatLog, "\nSerial Numbers of Leaked Objects:\n"); PL_HashTableEnumerateEntries(gSerialNumbers, DumpSerialNumbers, gBloatLog); } return NS_OK; }
nsresult nsTraceRefcntImpl::DumpStatistics(StatisticsType type, FILE* out) { #ifdef NS_IMPL_REFCNT_LOGGING if (gBloatLog == nullptr || gBloatView == nullptr) { return NS_ERROR_FAILURE; } if (out == nullptr) { out = gBloatLog; } LOCK_TRACELOG(); bool wasLogging = gLogging; gLogging = false; // turn off logging for this method BloatEntry total("TOTAL", 0); PL_HashTableEnumerateEntries(gBloatView, BloatEntry::TotalEntries, &total); const char* msg; if (type == NEW_STATS) { if (gLogLeaksOnly) msg = "NEW (incremental) LEAK STATISTICS"; else msg = "NEW (incremental) LEAK AND BLOAT STATISTICS"; } else { if (gLogLeaksOnly) msg = "ALL (cumulative) LEAK STATISTICS"; else msg = "ALL (cumulative) LEAK AND BLOAT STATISTICS"; } const bool leaked = total.PrintDumpHeader(out, msg, type); nsTArray<BloatEntry*> entries; PL_HashTableEnumerateEntries(gBloatView, BloatEntry::DumpEntry, &entries); const uint32_t count = entries.Length(); if (!gLogLeaksOnly || leaked) { // Sort the entries alphabetically by classname. entries.Sort(); for (uint32_t i = 0; i < count; ++i) { BloatEntry* entry = entries[i]; entry->Dump(i, out, type); } fprintf(out, "\n"); } fprintf(out, "nsTraceRefcntImpl::DumpStatistics: %d entries\n", count); if (gSerialNumbers) { fprintf(out, "\nSerial Numbers of Leaked Objects:\n"); PL_HashTableEnumerateEntries(gSerialNumbers, DumpSerialNumbers, out); } gLogging = wasLogging; UNLOCK_TRACELOG(); #endif return NS_OK; }
nsresult nsTraceRefcnt::DumpStatistics(StatisticsType aType, FILE* aOut) { #ifdef NS_IMPL_REFCNT_LOGGING if (!gBloatLog || !gBloatView) { return NS_ERROR_FAILURE; } if (!aOut) { aOut = gBloatLog; } AutoTraceLogLock lock; // Don't try to log while we hold the lock, we'd deadlock. AutoRestore<LoggingType> saveLogging(gLogging); gLogging = NoLogging; BloatEntry total("TOTAL", 0); PL_HashTableEnumerateEntries(gBloatView, BloatEntry::TotalEntries, &total); const char* msg; if (aType == NEW_STATS) { if (gLogLeaksOnly) { msg = "NEW (incremental) LEAK STATISTICS"; } else { msg = "NEW (incremental) LEAK AND BLOAT STATISTICS"; } } else { if (gLogLeaksOnly) { msg = "ALL (cumulative) LEAK STATISTICS"; } else { msg = "ALL (cumulative) LEAK AND BLOAT STATISTICS"; } } const bool leaked = total.PrintDumpHeader(aOut, msg, aType); nsTArray<BloatEntry*> entries; PL_HashTableEnumerateEntries(gBloatView, BloatEntry::DumpEntry, &entries); const uint32_t count = entries.Length(); if (!gLogLeaksOnly || leaked) { // Sort the entries alphabetically by classname. entries.Sort(); for (uint32_t i = 0; i < count; ++i) { BloatEntry* entry = entries[i]; entry->Dump(i, aOut, aType); } fprintf(aOut, "\n"); } fprintf(aOut, "nsTraceRefcnt::DumpStatistics: %d entries\n", count); if (gSerialNumbers) { fprintf(aOut, "\nSerial Numbers of Leaked Objects:\n"); PL_HashTableEnumerateEntries(gSerialNumbers, DumpSerialNumbers, aOut); } #endif return NS_OK; }