Bug 1833854 - Part 4: Move all code that deals with maintaining invariants into a separate method r=sfink

This makes the setParameter code simpler and amenable to generation by a macro.

Depends on D178527

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

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

@ -97,15 +97,13 @@ bool GCSchedulingTunables::setParameter(JSGCParamKey key, uint32_t value) {
if (value < SystemPageSize() || value >= MaxNurseryBytesParam) { if (value < SystemPageSize() || value >= MaxNurseryBytesParam) {
return false; return false;
} }
value = Nursery::roundSize(value); gcMinNurseryBytes_ = Nursery::roundSize(value);
setMinNurseryBytes(value);
break; break;
case JSGC_MAX_NURSERY_BYTES: case JSGC_MAX_NURSERY_BYTES:
if (value < SystemPageSize() || value >= MaxNurseryBytesParam) { if (value < SystemPageSize() || value >= MaxNurseryBytesParam) {
return false; return false;
} }
value = Nursery::roundSize(value); gcMaxNurseryBytes_ = Nursery::roundSize(value);
setMaxNurseryBytes(value);
break; break;
case JSGC_HIGH_FREQUENCY_TIME_LIMIT: case JSGC_HIGH_FREQUENCY_TIME_LIMIT:
highFrequencyThreshold_ = TimeDuration::FromMilliseconds(value); highFrequencyThreshold_ = TimeDuration::FromMilliseconds(value);
@ -115,7 +113,7 @@ bool GCSchedulingTunables::setParameter(JSGCParamKey key, uint32_t value) {
if (!megabytesToBytes(value, &newLimit)) { if (!megabytesToBytes(value, &newLimit)) {
return false; return false;
} }
setSmallHeapSizeMaxBytes(newLimit); smallHeapSizeMaxBytes_ = newLimit;
break; break;
} }
case JSGC_LARGE_HEAP_SIZE_MIN: { case JSGC_LARGE_HEAP_SIZE_MIN: {
@ -123,7 +121,7 @@ bool GCSchedulingTunables::setParameter(JSGCParamKey key, uint32_t value) {
if (!megabytesToBytes(value, &newLimit) || newLimit == 0) { if (!megabytesToBytes(value, &newLimit) || newLimit == 0) {
return false; return false;
} }
setLargeHeapSizeMinBytes(newLimit); largeHeapSizeMinBytes_ = newLimit;
break; break;
} }
case JSGC_HIGH_FREQUENCY_SMALL_HEAP_GROWTH: { case JSGC_HIGH_FREQUENCY_SMALL_HEAP_GROWTH: {
@ -131,7 +129,7 @@ bool GCSchedulingTunables::setParameter(JSGCParamKey key, uint32_t value) {
if (newGrowth < MinHeapGrowthFactor || newGrowth > MaxHeapGrowthFactor) { if (newGrowth < MinHeapGrowthFactor || newGrowth > MaxHeapGrowthFactor) {
return false; return false;
} }
setHighFrequencySmallHeapGrowth(newGrowth); highFrequencySmallHeapGrowth_ = newGrowth;
break; break;
} }
case JSGC_HIGH_FREQUENCY_LARGE_HEAP_GROWTH: { case JSGC_HIGH_FREQUENCY_LARGE_HEAP_GROWTH: {
@ -139,7 +137,7 @@ bool GCSchedulingTunables::setParameter(JSGCParamKey key, uint32_t value) {
if (newGrowth < MinHeapGrowthFactor || newGrowth > MaxHeapGrowthFactor) { if (newGrowth < MinHeapGrowthFactor || newGrowth > MaxHeapGrowthFactor) {
return false; return false;
} }
setHighFrequencyLargeHeapGrowth(newGrowth); highFrequencyLargeHeapGrowth_ = newGrowth;
break; break;
} }
case JSGC_BALANCED_HEAP_LIMITS_ENABLED: { case JSGC_BALANCED_HEAP_LIMITS_ENABLED: {
@ -151,11 +149,11 @@ bool GCSchedulingTunables::setParameter(JSGCParamKey key, uint32_t value) {
if (newGrowth < MinHeapGrowthFactor || newGrowth > MaxHeapGrowthFactor) { if (newGrowth < MinHeapGrowthFactor || newGrowth > MaxHeapGrowthFactor) {
return false; return false;
} }
setLowFrequencyHeapGrowth(newGrowth); lowFrequencyHeapGrowth_ = newGrowth;
break; break;
} }
case JSGC_HEAP_GROWTH_FACTOR: { case JSGC_HEAP_GROWTH_FACTOR: {
setHeapGrowthFactor(double(value)); heapGrowthFactor_ = double(value);
break; break;
} }
case JSGC_ALLOCATION_THRESHOLD: { case JSGC_ALLOCATION_THRESHOLD: {
@ -257,6 +255,7 @@ bool GCSchedulingTunables::setParameter(JSGCParamKey key, uint32_t value) {
MOZ_CRASH("Unknown GC parameter."); MOZ_CRASH("Unknown GC parameter.");
} }
maintainInvariantsAfterUpdate(key);
return true; return true;
} }
@ -287,56 +286,6 @@ bool GCSchedulingTunables::kilobytesToBytes(uint32_t value, size_t* bytesOut) {
return true; return true;
} }
void GCSchedulingTunables::setMinNurseryBytes(size_t value) {
gcMinNurseryBytes_ = value;
if (gcMaxNurseryBytes_ < gcMinNurseryBytes_) {
gcMaxNurseryBytes_ = gcMinNurseryBytes_;
}
}
void GCSchedulingTunables::setMaxNurseryBytes(size_t value) {
gcMaxNurseryBytes_ = value;
if (gcMinNurseryBytes_ > gcMaxNurseryBytes_) {
gcMinNurseryBytes_ = gcMaxNurseryBytes_;
}
}
void GCSchedulingTunables::setSmallHeapSizeMaxBytes(size_t value) {
smallHeapSizeMaxBytes_ = value;
if (smallHeapSizeMaxBytes_ >= largeHeapSizeMinBytes_) {
largeHeapSizeMinBytes_ = smallHeapSizeMaxBytes_ + 1;
}
}
void GCSchedulingTunables::setLargeHeapSizeMinBytes(size_t value) {
largeHeapSizeMinBytes_ = value;
if (largeHeapSizeMinBytes_ <= smallHeapSizeMaxBytes_) {
smallHeapSizeMaxBytes_ = largeHeapSizeMinBytes_ - 1;
}
}
void GCSchedulingTunables::setHighFrequencyLargeHeapGrowth(double value) {
highFrequencyLargeHeapGrowth_ = value;
if (highFrequencyLargeHeapGrowth_ > highFrequencySmallHeapGrowth_) {
highFrequencySmallHeapGrowth_ = highFrequencyLargeHeapGrowth_;
}
}
void GCSchedulingTunables::setHighFrequencySmallHeapGrowth(double value) {
highFrequencySmallHeapGrowth_ = value;
if (highFrequencySmallHeapGrowth_ < highFrequencyLargeHeapGrowth_) {
highFrequencyLargeHeapGrowth_ = highFrequencySmallHeapGrowth_;
}
}
void GCSchedulingTunables::setLowFrequencyHeapGrowth(double value) {
lowFrequencyHeapGrowth_ = value;
}
void GCSchedulingTunables::setHeapGrowthFactor(double value) {
heapGrowthFactor_ = value;
}
void GCSchedulingTunables::resetParameter(JSGCParamKey key) { void GCSchedulingTunables::resetParameter(JSGCParamKey key) {
auto guard = mozilla::MakeScopeExit([this] { checkInvariants(); }); auto guard = mozilla::MakeScopeExit([this] { checkInvariants(); });
@ -345,37 +294,37 @@ void GCSchedulingTunables::resetParameter(JSGCParamKey key) {
gcMaxBytes_ = TuningDefaults::GCMaxBytes; gcMaxBytes_ = TuningDefaults::GCMaxBytes;
break; break;
case JSGC_MIN_NURSERY_BYTES: case JSGC_MIN_NURSERY_BYTES:
setMinNurseryBytes(TuningDefaults::GCMinNurseryBytes); gcMinNurseryBytes_ = TuningDefaults::GCMinNurseryBytes;
break; break;
case JSGC_MAX_NURSERY_BYTES: case JSGC_MAX_NURSERY_BYTES:
setMaxNurseryBytes(JS::DefaultNurseryMaxBytes); gcMaxNurseryBytes_ = JS::DefaultNurseryMaxBytes;
break; break;
case JSGC_HIGH_FREQUENCY_TIME_LIMIT: case JSGC_HIGH_FREQUENCY_TIME_LIMIT:
highFrequencyThreshold_ = highFrequencyThreshold_ =
TimeDuration::FromSeconds(TuningDefaults::HighFrequencyThreshold); TimeDuration::FromSeconds(TuningDefaults::HighFrequencyThreshold);
break; break;
case JSGC_SMALL_HEAP_SIZE_MAX: case JSGC_SMALL_HEAP_SIZE_MAX:
setSmallHeapSizeMaxBytes(TuningDefaults::SmallHeapSizeMaxBytes); smallHeapSizeMaxBytes_ = TuningDefaults::SmallHeapSizeMaxBytes;
break; break;
case JSGC_LARGE_HEAP_SIZE_MIN: case JSGC_LARGE_HEAP_SIZE_MIN:
setLargeHeapSizeMinBytes(TuningDefaults::LargeHeapSizeMinBytes); largeHeapSizeMinBytes_ = TuningDefaults::LargeHeapSizeMinBytes;
break; break;
case JSGC_HIGH_FREQUENCY_SMALL_HEAP_GROWTH: case JSGC_HIGH_FREQUENCY_SMALL_HEAP_GROWTH:
setHighFrequencySmallHeapGrowth( highFrequencySmallHeapGrowth_ =
TuningDefaults::HighFrequencySmallHeapGrowth); TuningDefaults::HighFrequencySmallHeapGrowth;
break; break;
case JSGC_HIGH_FREQUENCY_LARGE_HEAP_GROWTH: case JSGC_HIGH_FREQUENCY_LARGE_HEAP_GROWTH:
setHighFrequencyLargeHeapGrowth( highFrequencyLargeHeapGrowth_ =
TuningDefaults::HighFrequencyLargeHeapGrowth); TuningDefaults::HighFrequencyLargeHeapGrowth;
break; break;
case JSGC_LOW_FREQUENCY_HEAP_GROWTH: case JSGC_LOW_FREQUENCY_HEAP_GROWTH:
setLowFrequencyHeapGrowth(TuningDefaults::LowFrequencyHeapGrowth); lowFrequencyHeapGrowth_ = TuningDefaults::LowFrequencyHeapGrowth;
break; break;
case JSGC_BALANCED_HEAP_LIMITS_ENABLED: case JSGC_BALANCED_HEAP_LIMITS_ENABLED:
balancedHeapLimitsEnabled_ = TuningDefaults::BalancedHeapLimitsEnabled; balancedHeapLimitsEnabled_ = TuningDefaults::BalancedHeapLimitsEnabled;
break; break;
case JSGC_HEAP_GROWTH_FACTOR: case JSGC_HEAP_GROWTH_FACTOR:
setHeapGrowthFactor(TuningDefaults::HeapGrowthFactor); heapGrowthFactor_ = TuningDefaults::HeapGrowthFactor;
break; break;
case JSGC_ALLOCATION_THRESHOLD: case JSGC_ALLOCATION_THRESHOLD:
gcZoneAllocThresholdBase_ = TuningDefaults::GCZoneAllocThresholdBase; gcZoneAllocThresholdBase_ = TuningDefaults::GCZoneAllocThresholdBase;
@ -421,6 +370,45 @@ void GCSchedulingTunables::resetParameter(JSGCParamKey key) {
default: default:
MOZ_CRASH("Unknown GC parameter."); MOZ_CRASH("Unknown GC parameter.");
} }
maintainInvariantsAfterUpdate(key);
}
void GCSchedulingTunables::maintainInvariantsAfterUpdate(JSGCParamKey updated) {
switch (updated) {
case JSGC_MIN_NURSERY_BYTES:
if (gcMaxNurseryBytes_ < gcMinNurseryBytes_) {
gcMaxNurseryBytes_ = gcMinNurseryBytes_;
}
break;
case JSGC_MAX_NURSERY_BYTES:
if (gcMinNurseryBytes_ > gcMaxNurseryBytes_) {
gcMinNurseryBytes_ = gcMaxNurseryBytes_;
}
break;
case JSGC_SMALL_HEAP_SIZE_MAX:
if (smallHeapSizeMaxBytes_ >= largeHeapSizeMinBytes_) {
largeHeapSizeMinBytes_ = smallHeapSizeMaxBytes_ + 1;
}
break;
case JSGC_LARGE_HEAP_SIZE_MIN:
if (largeHeapSizeMinBytes_ <= smallHeapSizeMaxBytes_) {
smallHeapSizeMaxBytes_ = largeHeapSizeMinBytes_ - 1;
}
break;
case JSGC_HIGH_FREQUENCY_SMALL_HEAP_GROWTH:
if (highFrequencySmallHeapGrowth_ < highFrequencyLargeHeapGrowth_) {
highFrequencyLargeHeapGrowth_ = highFrequencySmallHeapGrowth_;
}
break;
case JSGC_HIGH_FREQUENCY_LARGE_HEAP_GROWTH:
if (highFrequencyLargeHeapGrowth_ > highFrequencySmallHeapGrowth_) {
highFrequencySmallHeapGrowth_ = highFrequencyLargeHeapGrowth_;
}
break;
default:
break;
}
} }
void GCSchedulingTunables::checkInvariants() { void GCSchedulingTunables::checkInvariants() {

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

@ -675,17 +675,7 @@ class GCSchedulingTunables {
void resetParameter(JSGCParamKey key); void resetParameter(JSGCParamKey key);
private: private:
void setMinNurseryBytes(size_t value); void maintainInvariantsAfterUpdate(JSGCParamKey updated);
void setMaxNurseryBytes(size_t value);
void setSmallHeapSizeMaxBytes(size_t value);
void setLargeHeapSizeMinBytes(size_t value);
void setHighFrequencySmallHeapGrowth(double value);
void setHighFrequencyLargeHeapGrowth(double value);
void setLowFrequencyHeapGrowth(double value);
void setHeapGrowthFactor(double value);
void setMinEmptyChunkCount(uint32_t value);
void setMaxEmptyChunkCount(uint32_t value);
void checkInvariants(); void checkInvariants();
static bool megabytesToBytes(uint32_t value, size_t* bytesOut); static bool megabytesToBytes(uint32_t value, size_t* bytesOut);