Bug 1405274 - Add a dynamic malloc bytes threshold: Reland to fix timeout in wpt /wasm/many-memories.window.html. r=sfink

--HG--
extra : amend_source : f264f9be43a07b5dfe52cde125957506f23e48e7
This commit is contained in:
Jon Coppeard 2017-10-10 20:01:26 +02:00
Родитель 47d4b17e68
Коммит d320a4eb15
3 изменённых файлов: 56 добавлений и 16 удалений

Просмотреть файл

@ -661,6 +661,9 @@ class MemoryCounter
// GC trigger threshold for memory allocations.
size_t maxBytes_;
// Initial GC trigger threshold.
GCLockData<size_t> initialMaxBytes_;
// Whether a GC has been triggered as a result of bytes_ exceeding
// maxBytes_.
mozilla::Atomic<bool, mozilla::ReleaseAcquire> triggered_;
@ -669,18 +672,23 @@ class MemoryCounter
MemoryCounter()
: bytes_(0),
maxBytes_(0),
initialMaxBytes_(0),
triggered_(false)
{ }
void reset() {
bytes_ = 0;
triggered_ = false;
void updateOnGC(const AutoLockGC& lock) {
if (isTooMuchMalloc())
maxBytes_ *= 2;
else
maxBytes_ = std::max(initialMaxBytes_.ref(), size_t(maxBytes_ * 0.9));
reset();
}
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;
initialMaxBytes_ = (ptrdiff_t(newMax) >= 0) ? newMax : size_t(-1) >> 1;
maxBytes_ = initialMaxBytes_;
reset();
}
@ -693,6 +701,11 @@ class MemoryCounter
return triggered_;
}
void decrement(size_t bytes) {
MOZ_ASSERT(bytes <= bytes_);
bytes_ -= bytes;
}
void adopt(MemoryCounter<T>& other) {
bytes_ += other.bytes();
other.reset();
@ -700,7 +713,14 @@ class MemoryCounter
ptrdiff_t bytes() const { return bytes_; }
size_t maxBytes() const { return maxBytes_; }
size_t initialMaxBytes(const AutoLockGC& lock) const { return initialMaxBytes_; }
bool isTooMuchMalloc() const { return bytes_ >= maxBytes_; }
private:
void reset() {
bytes_ = 0;
triggered_ = false;
}
};
class GCRuntime
@ -846,9 +866,9 @@ class GCRuntime
int32_t getMallocBytes() const { return mallocCounter.bytes(); }
size_t maxMallocBytesAllocated() const { return mallocCounter.maxBytes(); }
bool isTooMuchMalloc() const { return mallocCounter.isTooMuchMalloc(); }
void resetMallocBytes() { mallocCounter.reset(); }
void setMaxMallocBytes(size_t value, const AutoLockGC& lock);
bool updateMallocCounter(size_t nbytes) { return mallocCounter.update(this, nbytes); }
void updateMallocCountersOnGC();
void setGCCallback(JSGCCallback callback, void* data);
void callGCCallback(JSGCStatus status) const;

Просмотреть файл

@ -442,7 +442,9 @@ struct Zone : public JS::shadow::Zone,
return false;
}
void resetGCMallocBytes() { gcMallocCounter.reset(); }
void updateGCMallocBytesOnGC(const js::AutoLockGC& lock) {
gcMallocCounter.updateOnGC(lock);
}
void setGCMaxMallocBytes(size_t value, const js::AutoLockGC& lock) {
gcMallocCounter.setMax(value, lock);
}
@ -458,10 +460,10 @@ struct Zone : public JS::shadow::Zone,
void updateJitCodeMallocBytes(size_t size) { jitCodeCounter.update(this, size); }
// Resets all the memory counters.
void resetAllMallocBytes() {
resetGCMallocBytes();
jitCodeCounter.reset();
// Updates all the memory counters after GC.
void updateAllMallocBytesOnGC(const js::AutoLockGC& lock) {
updateGCMallocBytesOnGC(lock);
jitCodeCounter.updateOnGC(lock);
}
bool isTooMuchMalloc() const {
return gcMallocCounter.isTooMuchMalloc() ||

Просмотреть файл

@ -4253,6 +4253,8 @@ GCRuntime::beginMarkPhase(JS::gcreason::Reason reason, AutoLockForExclusiveAcces
if (isIncremental)
markCompartments();
updateMallocCountersOnGC();
/*
* Process any queued source compressions during the start of a major
* GC.
@ -4333,6 +4335,28 @@ GCRuntime::markCompartments()
}
}
void
GCRuntime::updateMallocCountersOnGC()
{
AutoLockGC lock(rt);
size_t totalBytesInCollectedZones = 0;
for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
if (zone->isCollecting()) {
totalBytesInCollectedZones += zone->GCMallocBytes();
zone->updateGCMallocBytesOnGC(lock);
}
}
// Update the runtime malloc counter. If we are doing a full GC then clear
// it, otherwise decrement it by the previous malloc bytes count for the
// zones we did collect.
if (isFull)
mallocCounter.updateOnGC(lock);
else
mallocCounter.decrement(totalBytesInCollectedZones);
}
template <class ZoneIterT>
void
GCRuntime::markWeakReferences(gcstats::PhaseKind phase)
@ -7141,12 +7165,6 @@ GCRuntime::gcCycle(bool nonincrementalByAPI, SliceBudget& budget, JS::gcreason::
clearSelectedForMarking();
#endif
/* Clear gcMallocBytes for all zones. */
for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next())
zone->resetAllMallocBytes();
resetMallocBytes();
TraceMajorGCEnd();
return IncrementalResult::Ok;