const char * Statistics::formatData() { buffer[0] = 0x00; int64_t total = 0, longest = 0; for (SliceData *slice = slices.begin(); slice != slices.end(); slice++) { total += slice->duration(); if (slice->duration() > longest) longest = slice->duration(); } double mmu20 = computeMMU(20 * PRMJ_USEC_PER_MSEC); double mmu50 = computeMMU(50 * PRMJ_USEC_PER_MSEC); fmt("TotalTime: %.1fms, Type: %s", t(total), compartment ? "compartment" : "global"); fmt(", MMU(20ms): %d%%, MMU(50ms): %d%%", int(mmu20 * 100), int(mmu50 * 100)); if (slices.length() > 1) fmt(", MaxPause: %.1f", t(longest)); else fmt(", Reason: %s", ExplainReason(slices[0].reason)); if (wasReset) fmt(", ***RESET***"); fmt(", +chunks: %d, -chunks: %d\n", counts[STAT_NEW_CHUNK], counts[STAT_DESTROY_CHUNK]); if (slices.length() > 1) { for (size_t i = 0; i < slices.length(); i++) { int64_t width = slices[i].duration(); if (i != 0 && i != slices.length() - 1 && width < SLICE_MIN_REPORT_TIME) continue; fmt(" Slice %d @ %.1fms (Pause: %.1f, Reason: %s): ", i, t(slices[i].end - slices[0].start), t(width), ExplainReason(slices[i].reason)); formatPhases(slices[i].phaseTimes); fmt("\n"); } fmt(" Totals: "); } formatPhases(phaseTimes); fmt("\n"); return buffer; }
void Statistics::endGC() { Probes::GCEnd(); crash::SnapshotGCStack(); for (int i = 0; i < PHASE_LIMIT; i++) phaseTotals[i] += phaseTimes[i]; if (JSAccumulateTelemetryDataCallback cb = runtime->telemetryCallback) { int64_t total, longest; gcDuration(&total, &longest); int64_t sccTotal, sccLongest; sccDurations(&sccTotal, &sccLongest); (*cb)(JS_TELEMETRY_GC_IS_COMPARTMENTAL, collectedCount == compartmentCount ? 0 : 1); (*cb)(JS_TELEMETRY_GC_MS, t(total)); (*cb)(JS_TELEMETRY_GC_MAX_PAUSE_MS, t(longest)); (*cb)(JS_TELEMETRY_GC_MARK_MS, t(phaseTimes[PHASE_MARK])); (*cb)(JS_TELEMETRY_GC_SWEEP_MS, t(phaseTimes[PHASE_SWEEP])); (*cb)(JS_TELEMETRY_GC_MARK_ROOTS_MS, t(phaseTimes[PHASE_MARK_ROOTS])); (*cb)(JS_TELEMETRY_GC_MARK_GRAY_MS, t(phaseTimes[PHASE_MARK_GRAY])); (*cb)(JS_TELEMETRY_GC_NON_INCREMENTAL, !!nonincrementalReason); (*cb)(JS_TELEMETRY_GC_INCREMENTAL_DISABLED, !runtime->gcIncrementalEnabled); (*cb)(JS_TELEMETRY_GC_SCC_SWEEP_TOTAL_MS, t(sccTotal)); (*cb)(JS_TELEMETRY_GC_SCC_SWEEP_MAX_PAUSE_MS, t(sccLongest)); double mmu50 = computeMMU(50 * PRMJ_USEC_PER_MSEC); (*cb)(JS_TELEMETRY_GC_MMU_50, mmu50 * 100); } if (fp) printStats(); }
void Statistics::endGC() { Probes::GCEnd(); crash::SnapshotGCStack(); for (int i = 0; i < PHASE_LIMIT; i++) phaseTotals[i] += phaseTimes[i]; if (JSAccumulateTelemetryDataCallback cb = runtime->telemetryCallback) { (*cb)(JS_TELEMETRY_GC_IS_COMPARTMENTAL, compartment ? 1 : 0); (*cb)(JS_TELEMETRY_GC_MS, t(gcDuration())); (*cb)(JS_TELEMETRY_GC_MARK_MS, t(phaseTimes[PHASE_MARK])); (*cb)(JS_TELEMETRY_GC_SWEEP_MS, t(phaseTimes[PHASE_SWEEP])); (*cb)(JS_TELEMETRY_GC_RESET, wasReset); (*cb)(JS_TELEMETRY_GC_INCREMENTAL_DISABLED, !runtime->gcIncrementalEnabled); double mmu50 = computeMMU(50 * PRMJ_USEC_PER_MSEC); (*cb)(JS_TELEMETRY_GC_MMU_50, mmu50 * 100); } if (fp) printStats(); PodArrayZero(counts); }
bool Statistics::formatData(StatisticsSerializer &ss, uint64_t timestamp) { int64_t total, longest; gcDuration(&total, &longest); int64_t sccTotal, sccLongest; sccDurations(&sccTotal, &sccLongest); double mmu20 = computeMMU(20 * PRMJ_USEC_PER_MSEC); double mmu50 = computeMMU(50 * PRMJ_USEC_PER_MSEC); ss.beginObject(NULL); if (ss.isJSON()) ss.appendNumber("Timestamp", "%llu", "", (unsigned long long)timestamp); ss.appendDecimal("Total Time", "ms", t(total)); ss.appendNumber("Compartments Collected", "%d", "", collectedCount); ss.appendNumber("Total Compartments", "%d", "", compartmentCount); ss.appendNumber("MMU (20ms)", "%d", "%", int(mmu20 * 100)); ss.appendNumber("MMU (50ms)", "%d", "%", int(mmu50 * 100)); ss.appendDecimal("SCC Sweep Total", "ms", t(sccTotal)); ss.appendDecimal("SCC Sweep Max Pause", "ms", t(sccLongest)); if (slices.length() > 1 || ss.isJSON()) ss.appendDecimal("Max Pause", "ms", t(longest)); else ss.appendString("Reason", ExplainReason(slices[0].reason)); if (nonincrementalReason || ss.isJSON()) { ss.appendString("Nonincremental Reason", nonincrementalReason ? nonincrementalReason : "none"); } ss.appendNumber("Allocated", "%u", "MB", unsigned(preBytes / 1024 / 1024)); ss.appendNumber("+Chunks", "%d", "", counts[STAT_NEW_CHUNK]); ss.appendNumber("-Chunks", "%d", "", counts[STAT_DESTROY_CHUNK]); ss.endLine(); if (slices.length() > 1 || ss.isJSON()) { ss.beginArray("Slices"); for (size_t i = 0; i < slices.length(); i++) { int64_t width = slices[i].duration(); if (i != 0 && i != slices.length() - 1 && width < SLICE_MIN_REPORT_TIME && !slices[i].resetReason && !ss.isJSON()) { continue; } ss.beginObject(NULL); ss.extra(" "); ss.appendNumber("Slice", "%d", "", i); ss.appendDecimal("Pause", "", t(width)); ss.extra(" ("); ss.appendDecimal("When", "ms", t(slices[i].start - slices[0].start)); ss.appendString("Reason", ExplainReason(slices[i].reason)); if (ss.isJSON()) { ss.appendDecimal("Page Faults", "", double(slices[i].endFaults - slices[i].startFaults)); } if (slices[i].resetReason) ss.appendString("Reset", slices[i].resetReason); ss.extra("): "); FormatPhaseTimes(ss, "Times", slices[i].phaseTimes); ss.endLine(); ss.endObject(); } ss.endArray(); } ss.extra(" Totals: "); FormatPhaseTimes(ss, "Totals", phaseTimes); ss.endObject(); return !ss.isOOM(); }