Bug 1405274 - Make malloc counters count up instead of down r=sfink

This commit is contained in:
Jon Coppeard 2017-10-04 13:20:32 +01:00
parent df11828d61
commit 9bd7df8b2f
4 changed files with 23 additions and 28 deletions

View File

@ -654,19 +654,16 @@ using AllocKinds = mozilla::EnumSet<AllocKind>;
template <typename T>
class MemoryCounter
{
// Bytes counter to measure memory pressure for GC scheduling. It runs
// from maxBytes down to zero.
mozilla::Atomic<ptrdiff_t, mozilla::ReleaseAcquire> bytes_;
// Bytes counter to measure memory pressure for GC scheduling. It counts
// upwards from zero.
mozilla::Atomic<size_t, mozilla::ReleaseAcquire> bytes_;
// GC trigger threshold for memory allocations.
js::ActiveThreadData<size_t> maxBytes_;
size_t maxBytes_;
// Whether a GC has been triggered as a result of bytes falling below
// zero.
//
// This should be a bool, but Atomic only supports 32-bit and pointer-sized
// types.
mozilla::Atomic<uint32_t, mozilla::ReleaseAcquire> triggered_;
// Whether a GC has been triggered as a result of bytes_ exceeding
// maxBytes_.
mozilla::Atomic<bool, mozilla::ReleaseAcquire> triggered_;
public:
MemoryCounter()
@ -676,11 +673,11 @@ class MemoryCounter
{ }
void reset() {
bytes_ = maxBytes_;
bytes_ = 0;
triggered_ = false;
}
void setMax(size_t newMax) {
void setMax(size_t newMax, const AutoLockGC& lock) {
// For compatibility treat any value that exceeds PTRDIFF_T_MAX to
// mean that value.
maxBytes_ = (ptrdiff_t(newMax) >= 0) ? newMax : size_t(-1) >> 1;
@ -688,7 +685,7 @@ class MemoryCounter
}
bool update(T* owner, size_t bytes) {
bytes_ -= ptrdiff_t(bytes);
bytes_ += ptrdiff_t(bytes);
if (MOZ_UNLIKELY(isTooMuchMalloc())) {
if (!triggered_)
triggered_ = owner->triggerGCForTooMuchMalloc();
@ -698,7 +695,7 @@ class MemoryCounter
ptrdiff_t bytes() const { return bytes_; }
size_t maxBytes() const { return maxBytes_; }
bool isTooMuchMalloc() const { return bytes_ <= 0; }
bool isTooMuchMalloc() const { return bytes_ >= maxBytes_; }
};
class GCRuntime
@ -845,7 +842,7 @@ class GCRuntime
size_t maxMallocBytesAllocated() const { return mallocCounter.maxBytes(); }
bool isTooMuchMalloc() const { return mallocCounter.isTooMuchMalloc(); }
void resetMallocBytes() { mallocCounter.reset(); }
void setMaxMallocBytes(size_t value);
void setMaxMallocBytes(size_t value, const AutoLockGC& lock);
bool updateMallocCounter(size_t nbytes) { return mallocCounter.update(this, nbytes); }
void setGCCallback(JSGCCallback callback, void* data);

View File

@ -68,8 +68,8 @@ JS::Zone::Zone(JSRuntime* rt, ZoneGroup* group)
AutoLockGC lock(rt);
threshold.updateAfterGC(8192, GC_NORMAL, rt->gc.tunables, rt->gc.schedulingState, lock);
setGCMaxMallocBytes(rt->gc.maxMallocBytesAllocated() * 0.9);
jitCodeCounter.setMax(jit::MaxCodeBytesPerProcess * 0.8);
setGCMaxMallocBytes(rt->gc.maxMallocBytesAllocated() * 0.9, lock);
jitCodeCounter.setMax(jit::MaxCodeBytesPerProcess * 0.8, lock);
}
Zone::~Zone()

View File

@ -443,7 +443,9 @@ struct Zone : public JS::shadow::Zone,
}
void resetGCMallocBytes() { gcMallocCounter.reset(); }
void setGCMaxMallocBytes(size_t value) { gcMallocCounter.setMax(value); }
void setGCMaxMallocBytes(size_t value, const js::AutoLockGC& lock) {
gcMallocCounter.setMax(value, lock);
}
void updateMallocCounter(size_t nbytes) {
if (!runtime_->gc.updateMallocCounter(nbytes))
gcMallocCounter.update(this, nbytes);

View File

@ -1165,7 +1165,7 @@ GCRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes)
*/
MOZ_ALWAYS_TRUE(tunables.setParameter(JSGC_MAX_BYTES, maxbytes, lock));
MOZ_ALWAYS_TRUE(tunables.setParameter(JSGC_MAX_NURSERY_BYTES, maxNurseryBytes, lock));
setMaxMallocBytes(maxbytes);
setMaxMallocBytes(maxbytes, lock);
const char* size = getenv("JSGC_MARK_STACK_LIMIT");
if (size)
@ -1247,9 +1247,7 @@ GCRuntime::setParameter(JSGCParamKey key, uint32_t value, AutoLockGC& lock)
{
switch (key) {
case JSGC_MAX_MALLOC_BYTES:
setMaxMallocBytes(value);
for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next())
zone->setGCMaxMallocBytes(maxMallocBytesAllocated() * 0.9);
setMaxMallocBytes(value, lock);
break;
case JSGC_SLICE_TIME_BUDGET:
defaultTimeBudget_ = value ? value : SliceBudget::UnlimitedTimeBudget;
@ -1438,9 +1436,7 @@ GCRuntime::resetParameter(JSGCParamKey key, AutoLockGC& lock)
{
switch (key) {
case JSGC_MAX_MALLOC_BYTES:
setMaxMallocBytes(0xffffffff);
for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next())
zone->setGCMaxMallocBytes(maxMallocBytesAllocated() * 0.9);
setMaxMallocBytes(0xffffffff, lock);
break;
case JSGC_SLICE_TIME_BUDGET:
defaultTimeBudget_ = TuningDefaults::DefaultTimeBudget;
@ -1816,11 +1812,11 @@ js::RemoveRawValueRoot(JSContext* cx, Value* vp)
}
void
GCRuntime::setMaxMallocBytes(size_t value)
GCRuntime::setMaxMallocBytes(size_t value, const AutoLockGC& lock)
{
mallocCounter.setMax(value);
mallocCounter.setMax(value, lock);
for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next())
zone->setGCMaxMallocBytes(value);
zone->setGCMaxMallocBytes(value * 0.9, lock);
}
double