Bug 1328198 - Fix locale-dependence in GC statistics JSON output, r=jonco

--HG--
extra : rebase_source : 673fe9c8184afc505dd28e48190171186db76a53
extra : histedit_source : e47f033a61854e0157e8689a25ec32a504c607a8
This commit is contained in:
Steve Fink 2017-01-19 14:22:36 -08:00
parent 2853b63008
commit f6ccbab219
2 changed files with 35 additions and 17 deletions

View File

@ -503,7 +503,7 @@ FOR_EACH_NURSERY_PROFILE_TIME(PRINT_HEADER)
js::Nursery::printProfileDurations(const ProfileDurations& times) js::Nursery::printProfileDurations(const ProfileDurations& times)
{ {
for (auto time : times) for (auto time : times)
fprintf(stderr, " %6.0f", time.ToMicroseconds()); fprintf(stderr, " %6" PRIi64, static_cast<int64_t>(time.ToMicroseconds()));
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }

View File

@ -663,22 +663,36 @@ Statistics::formatJsonMessage(uint64_t timestamp)
return Join(fragments); return Join(fragments);
} }
// JSON requires decimals to be separated by periods, but the LC_NUMERIC
// setting may cause printf to use commas in some locales. Split a duration
// into whole and fractional parts of milliseconds, for use in passing to
// %llu.%03llu.
static lldiv_t
SplitDurationMS(TimeDuration d)
{
return lldiv(static_cast<int64_t>(d.ToMicroseconds()), 1000);
}
UniqueChars UniqueChars
Statistics::formatJsonDescription(uint64_t timestamp) Statistics::formatJsonDescription(uint64_t timestamp)
{ {
TimeDuration total, longest; TimeDuration total, longest;
gcDuration(&total, &longest); gcDuration(&total, &longest);
lldiv_t totalParts = SplitDurationMS(total);
lldiv_t longestParts = SplitDurationMS(longest);
TimeDuration sccTotal, sccLongest; TimeDuration sccTotal, sccLongest;
sccDurations(&sccTotal, &sccLongest); sccDurations(&sccTotal, &sccLongest);
lldiv_t sccTotalParts = SplitDurationMS(sccTotal);
lldiv_t sccLongestParts = SplitDurationMS(sccLongest);
const double mmu20 = computeMMU(TimeDuration::FromMilliseconds(20)); const double mmu20 = computeMMU(TimeDuration::FromMilliseconds(20));
const double mmu50 = computeMMU(TimeDuration::FromMilliseconds(50)); const double mmu50 = computeMMU(TimeDuration::FromMilliseconds(50));
const char *format = const char *format =
"\"timestamp\":%llu," "\"timestamp\":%llu,"
"\"max_pause\":%.3f," "\"max_pause\":%llu.%03llu,"
"\"total_time\":%.3f," "\"total_time\":%llu.%03llu,"
"\"zones_collected\":%d," "\"zones_collected\":%d,"
"\"total_zones\":%d," "\"total_zones\":%d,"
"\"total_compartments\":%d," "\"total_compartments\":%d,"
@ -686,8 +700,8 @@ Statistics::formatJsonDescription(uint64_t timestamp)
"\"store_buffer_overflows\":%d," "\"store_buffer_overflows\":%d,"
"\"mmu_20ms\":%d," "\"mmu_20ms\":%d,"
"\"mmu_50ms\":%d," "\"mmu_50ms\":%d,"
"\"scc_sweep_total\":%.3f," "\"scc_sweep_total\":%llu.%03llu,"
"\"scc_sweep_max_pause\":%.3f," "\"scc_sweep_max_pause\":%llu.%03llu,"
"\"nonincremental_reason\":\"%s\"," "\"nonincremental_reason\":\"%s\","
"\"allocated\":%u," "\"allocated\":%u,"
"\"added_chunks\":%d," "\"added_chunks\":%d,"
@ -695,8 +709,8 @@ Statistics::formatJsonDescription(uint64_t timestamp)
char buffer[1024]; char buffer[1024];
SprintfLiteral(buffer, format, SprintfLiteral(buffer, format,
(unsigned long long)timestamp, (unsigned long long)timestamp,
longest.ToMilliseconds(), longestParts.quot, longestParts.rem,
total.ToMilliseconds(), totalParts.quot, totalParts.rem,
zoneStats.collectedZoneCount, zoneStats.collectedZoneCount,
zoneStats.zoneCount, zoneStats.zoneCount,
zoneStats.compartmentCount, zoneStats.compartmentCount,
@ -704,8 +718,8 @@ Statistics::formatJsonDescription(uint64_t timestamp)
counts[STAT_STOREBUFFER_OVERFLOW], counts[STAT_STOREBUFFER_OVERFLOW],
int(mmu20 * 100), int(mmu20 * 100),
int(mmu50 * 100), int(mmu50 * 100),
sccTotal.ToMilliseconds(), sccTotalParts.quot, sccTotalParts.rem,
sccLongest.ToMilliseconds(), sccLongestParts.quot, sccLongestParts.rem,
ExplainAbortReason(nonincrementalReason_), ExplainAbortReason(nonincrementalReason_),
unsigned(preBytes / 1024 / 1024), unsigned(preBytes / 1024 / 1024),
counts[STAT_NEW_CHUNK], counts[STAT_NEW_CHUNK],
@ -717,7 +731,9 @@ UniqueChars
Statistics::formatJsonSliceDescription(unsigned i, const SliceData& slice) Statistics::formatJsonSliceDescription(unsigned i, const SliceData& slice)
{ {
TimeDuration duration = slice.duration(); TimeDuration duration = slice.duration();
lldiv_t durationParts = SplitDurationMS(duration);
TimeDuration when = slice.start - slices[0].start; TimeDuration when = slice.start - slices[0].start;
lldiv_t whenParts = SplitDurationMS(when);
char budgetDescription[200]; char budgetDescription[200];
slice.budget.describe(budgetDescription, sizeof(budgetDescription) - 1); slice.budget.describe(budgetDescription, sizeof(budgetDescription) - 1);
int64_t pageFaults = slice.endFaults - slice.startFaults; int64_t pageFaults = slice.endFaults - slice.startFaults;
@ -726,20 +742,20 @@ Statistics::formatJsonSliceDescription(unsigned i, const SliceData& slice)
const char* format = const char* format =
"\"slice\":%d," "\"slice\":%d,"
"\"pause\":%.3f," "\"pause\":%llu.%03llu,"
"\"when\":%.3f," "\"when\":%llu.%03llu,"
"\"reason\":\"%s\"," "\"reason\":\"%s\","
"\"initial_state\":\"%s\"," "\"initial_state\":\"%s\","
"\"final_state\":\"%s\"," "\"final_state\":\"%s\","
"\"budget\":\"%s\"," "\"budget\":\"%s\","
"\"page_faults\":%llu," "\"page_faults\":%llu,"
"\"start_timestamp\":%.3f," "\"start_timestamp\":%llu,"
"\"end_timestamp\":%.3f,"; "\"end_timestamp\":%llu,";
char buffer[1024]; char buffer[1024];
SprintfLiteral(buffer, format, SprintfLiteral(buffer, format,
i, i,
duration.ToMilliseconds(), durationParts.quot, durationParts.rem,
when.ToMilliseconds(), whenParts.quot, whenParts.rem,
ExplainReason(slice.reason), ExplainReason(slice.reason),
gc::StateName(slice.initialState), gc::StateName(slice.initialState),
gc::StateName(slice.finalState), gc::StateName(slice.finalState),
@ -778,7 +794,9 @@ Statistics::formatJsonPhaseTimes(const PhaseTimeTable phaseTimes)
UniqueChars name = FilterJsonKey(phases[phase].name); UniqueChars name = FilterJsonKey(phases[phase].name);
TimeDuration ownTime = phaseTimes[dagSlot][phase]; TimeDuration ownTime = phaseTimes[dagSlot][phase];
if (!ownTime.IsZero()) { if (!ownTime.IsZero()) {
SprintfLiteral(buffer, "\"%s\":%.3f", name.get(), ownTime.ToMilliseconds()); lldiv_t ownParts = SplitDurationMS(ownTime);
SprintfLiteral(buffer, "\"%s\":%llu.%03llu",
name.get(), ownParts.quot, ownParts.rem);
if (!fragments.append(DuplicateString(buffer))) if (!fragments.append(DuplicateString(buffer)))
return UniqueChars(nullptr); return UniqueChars(nullptr);
@ -1393,7 +1411,7 @@ FOR_EACH_GC_PROFILE_TIME(PRINT_PROFILE_HEADER)
Statistics::printProfileTimes(const ProfileDurations& times) Statistics::printProfileTimes(const ProfileDurations& times)
{ {
for (auto time : times) for (auto time : times)
fprintf(stderr, " %6.0f", time.ToMilliseconds()); fprintf(stderr, " %6" PRIi64, static_cast<int64_t>(time.ToMilliseconds()));
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }