Example #1
0
UniqueChars
Statistics::formatCompactSlicePhaseTimes(const PhaseTimeTable phaseTimes) const
{
    static const int64_t MaxUnaccountedTimeUS = 100;

    FragmentVector fragments;
    char buffer[128];
    for (AllPhaseIterator iter(phaseTimes); !iter.done(); iter.advance()) {
        Phase phase;
        size_t dagSlot;
        size_t level;
        iter.get(&phase, &dagSlot, &level);
        MOZ_ASSERT(level < 4);

        int64_t ownTime = phaseTimes[dagSlot][phase];
        int64_t childTime = SumChildTimes(dagSlot, phase, phaseTimes);
        if (ownTime > MaxUnaccountedTimeUS) {
            SprintfLiteral(buffer, "%s: %.3fms", phases[phase].name, t(ownTime));
            if (!fragments.append(DuplicateString(buffer)))
                return UniqueChars(nullptr);

            if (childTime && (ownTime - childTime) > MaxUnaccountedTimeUS) {
                MOZ_ASSERT(level < 3);
                SprintfLiteral(buffer, "%s: %.3fms", "Other", t(ownTime - childTime));
                if (!fragments.append(DuplicateString(buffer)))
                    return UniqueChars(nullptr);
            }
        }
    }
    return Join(fragments, ", ");
}
UniqueChars
Statistics::formatPhaseTimes(int64_t (*phaseTimes)[PHASE_LIMIT])
{
    static const char* LevelToIndent[] = { "", "  ", "    ", "      " };
    static const int64_t MaxUnaccountedChildTimeUS = 50;

    FragmentVector fragments;
    char buffer[128];
    for (AllPhaseIterator iter(phaseTimes); !iter.done(); iter.advance()) {
        Phase phase;
        size_t dagSlot;
        size_t level;
        iter.get(&phase, &dagSlot, &level);
        MOZ_ASSERT(level < 4);

        int64_t ownTime = phaseTimes[dagSlot][phase];
        int64_t childTime = SumChildTimes(dagSlot, phase, phaseTimes);
        if (ownTime > 0) {
            JS_snprintf(buffer, sizeof(buffer), "      %s%s: %.3fms\n",
                        LevelToIndent[level], phases[phase].name, t(ownTime));
            if (!fragments.append(make_string_copy(buffer)))
                return UniqueChars(nullptr);

            if (childTime && (ownTime - childTime) > MaxUnaccountedChildTimeUS) {
                MOZ_ASSERT(level < 3);
                JS_snprintf(buffer, sizeof(buffer), "      %s%s: %.3fms\n",
                            LevelToIndent[level + 1], "Other", t(ownTime - childTime));
                if (!fragments.append(make_string_copy(buffer)))
                    return UniqueChars(nullptr);
            }
        }
    }
    return Join(fragments);
}
Example #3
0
UniqueChars
Statistics::formatCompactSliceMessage() const
{
    // Skip if we OOM'ed.
    if (slices.length() == 0)
        return UniqueChars(nullptr);

    const size_t index = slices.length() - 1;
    const SliceData& slice = slices[index];

    char budgetDescription[200];
    slice.budget.describe(budgetDescription, sizeof(budgetDescription) - 1);

    const char* format =
        "GC Slice %u - Pause: %.3fms of %s budget (@ %.3fms); Reason: %s; Reset: %s%s; Times: ";
    char buffer[1024];
    SprintfLiteral(buffer, format, index,
                   t(slice.duration()), budgetDescription, t(slice.start - slices[0].start),
                   ExplainReason(slice.reason),
                   slice.wasReset() ? "yes - " : "no",
                   slice.wasReset() ? ExplainAbortReason(slice.resetReason) : "");

    FragmentVector fragments;
    if (!fragments.append(DuplicateString(buffer)) ||
        !fragments.append(formatCompactSlicePhaseTimes(slices[index].phaseTimes)))
    {
        return UniqueChars(nullptr);
    }
    return Join(fragments);
}
Example #4
0
static UniqueChars
Join(const FragmentVector& fragments, const char* separator = "") {
    const size_t separatorLength = strlen(separator);
    size_t length = 0;
    for (size_t i = 0; i < fragments.length(); ++i) {
        length += fragments[i] ? strlen(fragments[i].get()) : 0;
        if (i < (fragments.length() - 1))
            length += separatorLength;
    }

    char* joined = js_pod_malloc<char>(length + 1);
    joined[length] = '\0';

    char* cursor = joined;
    for (size_t i = 0; i < fragments.length(); ++i) {
        if (fragments[i])
            strcpy(cursor, fragments[i].get());
        cursor += fragments[i] ? strlen(fragments[i].get()) : 0;
        if (i < (fragments.length() - 1)) {
            if (separatorLength)
                strcpy(cursor, separator);
            cursor += separatorLength;
        }
    }

    return UniqueChars(joined);
}
Example #5
0
UniqueChars
Statistics::formatCompactSummaryMessage() const
{
    const double bytesPerMiB = 1024 * 1024;

    FragmentVector fragments;
    if (!fragments.append(DuplicateString("Summary - ")))
        return UniqueChars(nullptr);

    int64_t total, longest;
    gcDuration(&total, &longest);

    const double mmu20 = computeMMU(20 * PRMJ_USEC_PER_MSEC);
    const double mmu50 = computeMMU(50 * PRMJ_USEC_PER_MSEC);

    char buffer[1024];
    if (!nonincremental()) {
        SprintfLiteral(buffer,
                       "Max Pause: %.3fms; MMU 20ms: %.1f%%; MMU 50ms: %.1f%%; Total: %.3fms; ",
                       t(longest), mmu20 * 100., mmu50 * 100., t(total));
    } else {
        SprintfLiteral(buffer, "Non-Incremental: %.3fms (%s); ",
                       t(total), ExplainAbortReason(nonincrementalReason_));
    }
    if (!fragments.append(DuplicateString(buffer)))
        return UniqueChars(nullptr);

    SprintfLiteral(buffer,
                   "Zones: %d of %d (-%d); Compartments: %d of %d (-%d); HeapSize: %.3f MiB; " \
                   "HeapChange (abs): %+d (%d); ",
                   zoneStats.collectedZoneCount, zoneStats.zoneCount, zoneStats.sweptZoneCount,
                   zoneStats.collectedCompartmentCount, zoneStats.compartmentCount,
                   zoneStats.sweptCompartmentCount,
                   double(preBytes) / bytesPerMiB,
                   counts[STAT_NEW_CHUNK] - counts[STAT_DESTROY_CHUNK],
                   counts[STAT_NEW_CHUNK] + counts[STAT_DESTROY_CHUNK]);
    if (!fragments.append(DuplicateString(buffer)))
        return UniqueChars(nullptr);

    MOZ_ASSERT_IF(counts[STAT_ARENA_RELOCATED], gckind == GC_SHRINK);
    if (gckind == GC_SHRINK) {
        SprintfLiteral(buffer,
                       "Kind: %s; Relocated: %.3f MiB; ",
                       ExplainInvocationKind(gckind),
                       double(ArenaSize * counts[STAT_ARENA_RELOCATED]) / bytesPerMiB);
        if (!fragments.append(DuplicateString(buffer)))
            return UniqueChars(nullptr);
    }

    return Join(fragments);
}
Example #6
0
static UniqueChars
Join(const FragmentVector &fragments) {
    size_t length = 0;
    for (size_t i = 0; i < fragments.length(); ++i)
        length += fragments[i] ? strlen(fragments[i].get()) : 0;

    char *joined = js_pod_malloc<char>(length + 1);
    joined[length] = '\0';

    char *cursor = joined;
    for (size_t i = 0; i < fragments.length(); ++i) {
        if (fragments[i])
            strcpy(cursor, fragments[i].get());
        cursor += fragments[i] ? strlen(fragments[i].get()) : 0;
    }

    return UniqueChars(joined);
}
Example #7
0
UniqueChars
Statistics::formatJsonPhaseTimes(const PhaseTimeTable phaseTimes)
{
    FragmentVector fragments;
    char buffer[128];
    for (AllPhaseIterator iter(phaseTimes); !iter.done(); iter.advance()) {
        Phase phase;
        size_t dagSlot;
        iter.get(&phase, &dagSlot);

        UniqueChars name = FilterJsonKey(phases[phase].name);
        int64_t ownTime = phaseTimes[dagSlot][phase];
        JS_snprintf(buffer, sizeof(buffer), "\"%s\":%llu.%03llu",
                    name.get(), ownTime / 1000, ownTime % 1000);

        if (!fragments.append(DuplicateString(buffer)))
            return UniqueChars(nullptr);
    }
    return Join(fragments, ",");
}
Example #8
0
UniqueChars
Statistics::formatPhaseTimes(int64_t *phaseTimes)
{
    static const char *LevelToIndent[] = { "", "  ", "    ", "      " };
    static const int64_t MaxUnaccountedChildTimeUS = 50;

    FragmentVector fragments;
    char buffer[128];
    for (unsigned i = 0; phases[i].name; i++) {
        unsigned level = 0;
        unsigned current = i;
        while (phases[current].parent != PHASE_NO_PARENT) {
            current = phases[current].parent;
            level++;
        }
        MOZ_ASSERT(level < 4);

        int64_t ownTime = phaseTimes[phases[i].index];
        int64_t childTime = SumChildTimes(Phase(i), phaseTimes);
        if (ownTime > 0) {
            JS_snprintf(buffer, sizeof(buffer), "      %s%s: %.3fms\n",
                        LevelToIndent[level], phases[i].name, t(ownTime));
            if (!fragments.append(make_string_copy(buffer)))
                return UniqueChars(nullptr);

            if (childTime && (ownTime - childTime) > MaxUnaccountedChildTimeUS) {
                MOZ_ASSERT(level < 3);
                JS_snprintf(buffer, sizeof(buffer), "      %s%s: %.3fms\n",
                            LevelToIndent[level + 1], "Other", t(ownTime - childTime));
                if (!fragments.append(make_string_copy(buffer)))
                    return UniqueChars(nullptr);
            }
        }
    }
    return Join(fragments);
}
Example #9
0
UniqueChars
Statistics::formatDetailedMessage()
{
    FragmentVector fragments;

    if (!fragments.append(formatDescription()))
        return UniqueChars(nullptr);

    if (slices.length() > 1) {
        for (unsigned i = 0; i < slices.length(); i++) {
            if (!fragments.append(formatSliceDescription(i, slices[i])))
                return UniqueChars(nullptr);
            if (!fragments.append(formatPhaseTimes(slices[i].phaseTimes)))
                return UniqueChars(nullptr);
        }
    }
    if (!fragments.append(formatTotals()))
        return UniqueChars(nullptr);
    if (!fragments.append(formatPhaseTimes(phaseTimes)))
        return UniqueChars(nullptr);

    return Join(fragments);
}
Example #10
0
UniqueChars
Statistics::formatJsonMessage(uint64_t timestamp)
{
    MOZ_ASSERT(!aborted);

    FragmentVector fragments;

    if (!fragments.append(DuplicateString("{")) ||
        !fragments.append(formatJsonDescription(timestamp)) ||
        !fragments.append(DuplicateString("\"slices\":[")))
    {
        return UniqueChars(nullptr);
    }

    for (unsigned i = 0; i < slices.length(); i++) {
        if (!fragments.append(DuplicateString("{")) ||
            !fragments.append(formatJsonSliceDescription(i, slices[i])) ||
            !fragments.append(DuplicateString("\"times\":{")) ||
            !fragments.append(formatJsonPhaseTimes(slices[i].phaseTimes)) ||
            !fragments.append(DuplicateString("}}")) ||
            (i < (slices.length() - 1) && !fragments.append(DuplicateString(","))))
        {
            return UniqueChars(nullptr);
        }
    }

    if (!fragments.append(DuplicateString("],\"totals\":{")) ||
        !fragments.append(formatJsonPhaseTimes(phaseTimes)) ||
        !fragments.append(DuplicateString("}}")))
    {
        return UniqueChars(nullptr);
    }

    return Join(fragments);
}