Bug 1154441 - imported patch budget, r=terrence

This commit is contained in:
Steve Fink 2015-04-10 13:58:06 -07:00
parent 73a4f659b2
commit 0e2e744142
4 changed files with 46 additions and 12 deletions

View File

@ -33,6 +33,12 @@ struct JS_PUBLIC_API(WorkBudget)
*/
struct JS_PUBLIC_API(SliceBudget)
{
// Memory of the originally requested budget. If isUnlimited, neither of
// these are in use. If deadline==0, then workBudget is valid. Otherwise
// timeBudget is valid.
TimeBudget timeBudget;
WorkBudget workBudget;
int64_t deadline; /* in microseconds */
intptr_t counter;
@ -64,10 +70,12 @@ struct JS_PUBLIC_API(SliceBudget)
return checkOverBudget();
}
bool isUnlimited() {
bool isUnlimited() const {
return deadline == unlimitedDeadline;
}
int describe(char* buffer, size_t maxlen) const;
private:
bool checkOverBudget();

View File

@ -529,6 +529,9 @@ Statistics::formatData(StatisticsSerializer& ss, uint64_t timestamp)
continue;
}
char budgetDescription[200];
slices[i].budget.describe(budgetDescription, sizeof(budgetDescription) - 1);
ss.beginObject(nullptr);
ss.extra(" ");
ss.appendNumber("Slice", "%d", "", i);
@ -536,6 +539,7 @@ Statistics::formatData(StatisticsSerializer& ss, uint64_t timestamp)
ss.extra(" (");
ss.appendDecimal("When", "ms", t(slices[i].start - slices[0].start));
ss.appendString("Reason", ExplainReason(slices[i].reason));
ss.appendString("Budget", budgetDescription);
if (ss.isJSON()) {
ss.appendDecimal("Page Faults", "",
double(slices[i].endFaults - slices[i].startFaults));
@ -629,13 +633,16 @@ Statistics::formatDescription()
UniqueChars
Statistics::formatSliceDescription(unsigned i, const SliceData& slice)
{
char budgetDescription[200];
slice.budget.describe(budgetDescription, sizeof(budgetDescription) - 1);
const char* format =
"\
---- Slice %u ----\n\
Reason: %s\n\
Reset: %s%s\n\
Page Faults: %ld\n\
Pause: %.3fms (@ %.3fms)\n\
Pause: %.3fms of %s budget (@ %.3fms)\n\
";
char buffer[1024];
memset(buffer, 0, sizeof(buffer));
@ -643,7 +650,7 @@ Statistics::formatSliceDescription(unsigned i, const SliceData& slice)
ExplainReason(slice.reason),
slice.resetReason ? "yes - " : "no", slice.resetReason ? slice.resetReason : "",
uint64_t(slice.endFaults - slice.startFaults),
t(slice.duration()), t(slice.start - slices[0].start));
t(slice.duration()), budgetDescription, t(slice.start - slices[0].start));
return make_string_copy(buffer);
}
@ -985,7 +992,7 @@ Statistics::endGC()
void
Statistics::beginSlice(const ZoneGCStats& zoneStats, JSGCInvocationKind gckind,
JS::gcreason::Reason reason)
SliceBudget budget, JS::gcreason::Reason reason)
{
this->zoneStats = zoneStats;
@ -993,7 +1000,7 @@ Statistics::beginSlice(const ZoneGCStats& zoneStats, JSGCInvocationKind gckind,
if (first)
beginGC(gckind);
SliceData data(reason, PRMJ_Now(), GetPageFaultCount());
SliceData data(budget, reason, PRMJ_Now(), GetPageFaultCount());
if (!slices.append(data)) {
// OOM testing fails if we CrashAtUnhandlableOOM here.
aborted = true;

View File

@ -162,7 +162,7 @@ struct Statistics
void endParallelPhase(Phase phase, const GCParallelTask* task);
void beginSlice(const ZoneGCStats& zoneStats, JSGCInvocationKind gckind,
JS::gcreason::Reason reason);
SliceBudget budget, JS::gcreason::Reason reason);
void endSlice();
void startTimingMutator();
@ -206,13 +206,16 @@ struct Statistics
static const size_t MAX_NESTING = 20;
struct SliceData {
SliceData(JS::gcreason::Reason reason, int64_t start, size_t startFaults)
: reason(reason), resetReason(nullptr), start(start), startFaults(startFaults)
SliceData(SliceBudget budget, JS::gcreason::Reason reason, int64_t start, size_t startFaults)
: budget(budget), reason(reason),
resetReason(nullptr),
start(start), startFaults(startFaults)
{
for (size_t i = 0; i < MAX_MULTIPARENT_PHASES + 1; i++)
mozilla::PodArrayZero(phaseTimes[i]);
}
SliceBudget budget;
JS::gcreason::Reason reason;
const char* resetReason;
int64_t start, end;
@ -318,12 +321,12 @@ struct Statistics
struct AutoGCSlice
{
AutoGCSlice(Statistics& stats, const ZoneGCStats& zoneStats, JSGCInvocationKind gckind,
JS::gcreason::Reason reason
SliceBudget budget, JS::gcreason::Reason reason
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: stats(stats)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
stats.beginSlice(zoneStats, gckind, reason);
stats.beginSlice(zoneStats, gckind, budget, reason);
}
~AutoGCSlice() { stats.endSlice(); }

View File

@ -2924,11 +2924,13 @@ GCRuntime::refillFreeListInGC(Zone* zone, AllocKind thingKind)
}
SliceBudget::SliceBudget()
: timeBudget(Unlimited), workBudget(Unlimited)
{
makeUnlimited();
}
SliceBudget::SliceBudget(TimeBudget time)
: timeBudget(time), workBudget(Unlimited)
{
if (time.budget < 0) {
makeUnlimited();
@ -2940,6 +2942,7 @@ SliceBudget::SliceBudget(TimeBudget time)
}
SliceBudget::SliceBudget(WorkBudget work)
: timeBudget(Unlimited), workBudget(work)
{
if (work.budget < 0) {
makeUnlimited();
@ -2949,6 +2952,17 @@ SliceBudget::SliceBudget(WorkBudget work)
}
}
int
SliceBudget::describe(char* buffer, size_t maxlen) const
{
if (isUnlimited())
return JS_snprintf(buffer, maxlen, "unlimited");
else if (deadline == 0)
return JS_snprintf(buffer, maxlen, "work(%lld)", workBudget.budget);
else
return JS_snprintf(buffer, maxlen, "%lldms", timeBudget.budget);
}
bool
SliceBudget::checkOverBudget()
{
@ -6094,7 +6108,7 @@ GCRuntime::collect(bool incremental, SliceBudget budget, JS::gcreason::Reason re
AutoStopVerifyingBarriers av(rt, reason == JS::gcreason::SHUTDOWN_CC ||
reason == JS::gcreason::DESTROY_RUNTIME);
gcstats::AutoGCSlice agc(stats, scanZonesBeforeGC(), invocationKind, reason);
gcstats::AutoGCSlice agc(stats, scanZonesBeforeGC(), invocationKind, budget, reason);
bool repeat = false;
do {
@ -6206,7 +6220,9 @@ GCRuntime::abortGC()
AutoStopVerifyingBarriers av(rt, false);
gcstats::AutoGCSlice agc(stats, scanZonesBeforeGC(), invocationKind, JS::gcreason::ABORT_GC);
SliceBudget unlimited;
gcstats::AutoGCSlice agc(stats, scanZonesBeforeGC(), invocationKind,
unlimited, JS::gcreason::ABORT_GC);
evictNursery(JS::gcreason::ABORT_GC);
AutoDisableStoreBuffer adsb(this);