зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
47d4b17e68
Коммит
d320a4eb15
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче