Bug 1833854 - Part 2: Common up GCSchedulingTunables invariant checks r=sfink

Some of these are duplicated, for example when two parameters need to be
checked against each other. It's easier to define them all in once place and
then we ensure we run all of them when anything changes.

Depends on D178524

Differential Revision: https://phabricator.services.mozilla.com/D178525
This commit is contained in:
Jon Coppeard 2023-05-22 14:31:40 +00:00
Родитель 8086cc2149
Коммит e95ca1fcba
2 изменённых файлов: 32 добавлений и 11 удалений

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

@ -7,6 +7,7 @@
#include "gc/Scheduling.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/TimeStamp.h"
#include <algorithm>
@ -43,6 +44,10 @@ static constexpr double MinHeapGrowthFactor =
1.0f / std::min(HighFrequencyEagerAllocTriggerFactor,
LowFrequencyEagerAllocTriggerFactor);
// Limit various parameters to reasonable levels to catch errors.
static constexpr double MaxHeapGrowthFactor = 100;
static constexpr size_t MaxNurseryBytesParam = 128 * 1024 * 1024;
GCSchedulingTunables::GCSchedulingTunables()
: gcMaxBytes_(TuningDefaults::GCMaxBytes),
gcMinNurseryBytes_(Nursery::roundSize(TuningDefaults::GCMinNurseryBytes)),
@ -77,12 +82,12 @@ GCSchedulingTunables::GCSchedulingTunables()
mallocThresholdBase_(TuningDefaults::MallocThresholdBase),
urgentThresholdBytes_(TuningDefaults::UrgentThresholdBytes),
parallelMarkingThresholdBytes_(
TuningDefaults::ParallelMarkingThresholdBytes) {}
TuningDefaults::ParallelMarkingThresholdBytes) {
checkInvariants();
}
bool GCSchedulingTunables::setParameter(JSGCParamKey key, uint32_t value) {
// Limit various parameters to reasonable levels to catch errors.
const double MaxHeapGrowthFactor = 100;
const size_t MaxNurseryBytesParam = 128 * 1024 * 1024;
auto guard = mozilla::MakeScopeExit([this] { checkInvariants(); });
switch (key) {
case JSGC_MAX_BYTES:
@ -293,7 +298,6 @@ void GCSchedulingTunables::setSmallHeapSizeMaxBytes(size_t value) {
if (smallHeapSizeMaxBytes_ >= largeHeapSizeMinBytes_) {
largeHeapSizeMinBytes_ = smallHeapSizeMaxBytes_ + 1;
}
MOZ_ASSERT(largeHeapSizeMinBytes_ > smallHeapSizeMaxBytes_);
}
void GCSchedulingTunables::setLargeHeapSizeMinBytes(size_t value) {
@ -301,7 +305,6 @@ void GCSchedulingTunables::setLargeHeapSizeMinBytes(size_t value) {
if (largeHeapSizeMinBytes_ <= smallHeapSizeMaxBytes_) {
smallHeapSizeMaxBytes_ = largeHeapSizeMinBytes_ - 1;
}
MOZ_ASSERT(largeHeapSizeMinBytes_ > smallHeapSizeMaxBytes_);
}
void GCSchedulingTunables::setHighFrequencyLargeHeapGrowth(double value) {
@ -309,8 +312,6 @@ void GCSchedulingTunables::setHighFrequencyLargeHeapGrowth(double value) {
if (highFrequencyLargeHeapGrowth_ > highFrequencySmallHeapGrowth_) {
highFrequencySmallHeapGrowth_ = highFrequencyLargeHeapGrowth_;
}
MOZ_ASSERT(highFrequencyLargeHeapGrowth_ >= MinHeapGrowthFactor);
MOZ_ASSERT(highFrequencyLargeHeapGrowth_ <= highFrequencySmallHeapGrowth_);
}
void GCSchedulingTunables::setHighFrequencySmallHeapGrowth(double value) {
@ -318,13 +319,10 @@ void GCSchedulingTunables::setHighFrequencySmallHeapGrowth(double value) {
if (highFrequencySmallHeapGrowth_ < highFrequencyLargeHeapGrowth_) {
highFrequencyLargeHeapGrowth_ = highFrequencySmallHeapGrowth_;
}
MOZ_ASSERT(highFrequencyLargeHeapGrowth_ >= MinHeapGrowthFactor);
MOZ_ASSERT(highFrequencyLargeHeapGrowth_ <= highFrequencySmallHeapGrowth_);
}
void GCSchedulingTunables::setLowFrequencyHeapGrowth(double value) {
lowFrequencyHeapGrowth_ = value;
MOZ_ASSERT(lowFrequencyHeapGrowth_ >= MinHeapGrowthFactor);
}
void GCSchedulingTunables::setHeapGrowthFactor(double value) {
@ -332,6 +330,8 @@ void GCSchedulingTunables::setHeapGrowthFactor(double value) {
}
void GCSchedulingTunables::resetParameter(JSGCParamKey key) {
auto guard = mozilla::MakeScopeExit([this] { checkInvariants(); });
switch (key) {
case JSGC_MAX_BYTES:
gcMaxBytes_ = TuningDefaults::GCMaxBytes;
@ -415,6 +415,25 @@ void GCSchedulingTunables::resetParameter(JSGCParamKey key) {
}
}
void GCSchedulingTunables::checkInvariants() {
MOZ_ASSERT(gcMinNurseryBytes_ == Nursery::roundSize(gcMinNurseryBytes_));
MOZ_ASSERT(gcMaxNurseryBytes_ == Nursery::roundSize(gcMaxNurseryBytes_));
MOZ_ASSERT(gcMinNurseryBytes_ <= gcMaxNurseryBytes_);
MOZ_ASSERT(gcMinNurseryBytes_ >= SystemPageSize());
MOZ_ASSERT(gcMaxNurseryBytes_ <= MaxNurseryBytesParam);
MOZ_ASSERT(largeHeapSizeMinBytes_ > smallHeapSizeMaxBytes_);
MOZ_ASSERT(lowFrequencyHeapGrowth_ >= MinHeapGrowthFactor);
MOZ_ASSERT(lowFrequencyHeapGrowth_ <= MaxHeapGrowthFactor);
MOZ_ASSERT(highFrequencySmallHeapGrowth_ >= MinHeapGrowthFactor);
MOZ_ASSERT(highFrequencySmallHeapGrowth_ <= MaxHeapGrowthFactor);
MOZ_ASSERT(highFrequencyLargeHeapGrowth_ <= highFrequencySmallHeapGrowth_);
MOZ_ASSERT(highFrequencyLargeHeapGrowth_ >= MinHeapGrowthFactor);
MOZ_ASSERT(highFrequencySmallHeapGrowth_ <= MaxHeapGrowthFactor);
}
void GCSchedulingState::updateHighFrequencyMode(
const mozilla::TimeStamp& lastGCTime, const mozilla::TimeStamp& currentTime,
const GCSchedulingTunables& tunables) {

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

@ -684,6 +684,8 @@ class GCSchedulingTunables {
void setMinEmptyChunkCount(uint32_t value);
void setMaxEmptyChunkCount(uint32_t value);
void checkInvariants();
static bool megabytesToBytes(uint32_t value, size_t* bytesOut);
static bool kilobytesToBytes(uint32_t value, size_t* bytesOut);
};