Skip to content

Commit d5b8d40

Browse files
Fixes and cleanups for TLAB-related options.
1 parent 4a74b8f commit d5b8d40

File tree

10 files changed

+96
-111
lines changed

10 files changed

+96
-111
lines changed

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ public static UnsignedWord getChunkBytes() {
425425
}
426426

427427
private static void resizeAllTlabs() {
428-
if (SubstrateGCOptions.TlabOptions.ResizeTLAB.getValue()) {
428+
if (SubstrateGCOptions.ResizeTLAB.getValue()) {
429429
for (IsolateThread thread = VMThreads.firstThread(); thread.isNonNull(); thread = VMThreads.nextThread(thread)) {
430430
TlabSupport.resize(thread);
431431
}

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GenScavengeGCFeature.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,11 @@ public void duringSetup(DuringSetupAccess access) {
106106
ImageSingletons.add(Heap.class, new HeapImpl());
107107
ImageSingletons.add(ImageHeapInfo.class, new ImageHeapInfo());
108108
ImageSingletons.add(GCAllocationSupport.class, new GenScavengeAllocationSupport());
109-
ImageSingletons.add(TlabOptionCache.class, new TlabOptionCache());
109+
110+
TlabOptionCache tlabOptionCache = new TlabOptionCache();
111+
ImageSingletons.add(TlabOptionCache.class, tlabOptionCache);
112+
tlabOptionCache.validateHostedOptionValues();
113+
110114
if (ImageLayerBuildingSupport.firstImageBuild()) {
111115
ImageSingletons.add(PinnedObjectSupport.class, new PinnedObjectSupportImpl());
112116
}

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/SerialAndEpsilonGCOptions.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424
*/
2525
package com.oracle.svm.core.genscavenge;
2626

27-
import static com.oracle.svm.core.option.RuntimeOptionKey.RuntimeOptionKeyFlag.RegisterForIsolateArgumentParser;
28-
2927
import com.oracle.svm.core.SubstrateOptions;
3028
import com.oracle.svm.core.metaspace.Metaspace;
3129
import com.oracle.svm.core.option.HostedOptionKey;
@@ -71,9 +69,6 @@ public final class SerialAndEpsilonGCOptions {
7169
@Option(help = "Number of bytes at the beginning of each heap chunk that are not used for payload data, i.e., can be freely used as metadata by the heap chunk provider. Serial and epsilon GC only.", type = OptionType.Debug) //
7270
public static final HostedOptionKey<Integer> HeapChunkHeaderPadding = new HostedOptionKey<>(0, SerialAndEpsilonGCOptions::validateSerialOrEpsilonHostedOption);
7371

74-
@Option(help = "Starting TLAB size (in bytes); zero means set ergonomically.", type = OptionType.Expert)//
75-
public static final RuntimeOptionKey<Long> InitialTLABSize = new RuntimeOptionKey<>(8 * 1024L, SerialAndEpsilonGCOptions::validateSerialOrEpsilonRuntimeOption, RegisterForIsolateArgumentParser);
76-
7772
@Option(help = "Print information about TLABs. Printed when The TLABs are retired before a GC, and during the resizing of the TLABs. Serial and epsilon GC only.", type = OptionType.Expert)//
7873
public static final HostedOptionKey<Boolean> PrintTLAB = new HostedOptionKey<>(false, SerialAndEpsilonGCOptions::validateSerialOrEpsilonHostedOption);
7974

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/TlabOptionCache.java

Lines changed: 74 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
package com.oracle.svm.core.genscavenge;
2626

2727
import static com.oracle.svm.core.Uninterruptible.CALLED_FROM_UNINTERRUPTIBLE_CODE;
28-
import static com.oracle.svm.core.genscavenge.TlabSupport.maxSize;
2928

3029
import org.graalvm.nativeimage.ImageSingletons;
3130
import org.graalvm.nativeimage.Platform;
@@ -34,10 +33,15 @@
3433
import com.oracle.svm.core.IsolateArgumentParser;
3534
import com.oracle.svm.core.SubstrateGCOptions;
3635
import com.oracle.svm.core.SubstrateOptions;
36+
import com.oracle.svm.core.SubstrateUtil;
3737
import com.oracle.svm.core.Uninterruptible;
3838
import com.oracle.svm.core.config.ConfigurationValues;
39+
import com.oracle.svm.core.config.ObjectLayout;
3940
import com.oracle.svm.core.jdk.UninterruptibleUtils;
41+
import com.oracle.svm.core.option.RuntimeOptionKey;
4042
import com.oracle.svm.core.option.RuntimeOptionValidationSupport;
43+
import com.oracle.svm.core.option.RuntimeOptionValidationSupport.RuntimeOptionValidation;
44+
import com.oracle.svm.core.util.UserError;
4145

4246
import jdk.graal.compiler.api.replacements.Fold;
4347
import jdk.graal.compiler.core.common.NumUtil;
@@ -49,26 +53,42 @@
4953
* options and reports errors (see {@link #registerOptionValidations}).
5054
*/
5155
public class TlabOptionCache {
56+
private static final long DEFAULT_INITIAL_TLAB_SIZE = 8 * 1024;
5257

5358
private long minTlabSize;
5459
private long tlabSize;
55-
private long initialTLABSize;
5660

5761
@Platforms(Platform.HOSTED_ONLY.class)
5862
public TlabOptionCache() {
59-
minTlabSize = getAbsoluteMinTlabSize();
60-
tlabSize = SubstrateGCOptions.TlabOptions.TLABSize.getHostedValue();
61-
initialTLABSize = SerialAndEpsilonGCOptions.InitialTLABSize.getHostedValue();
63+
ObjectLayout objectLayout = ConfigurationValues.getObjectLayout();
64+
long maxSize = TlabSupport.maxSize().rawValue();
65+
assert objectLayout.isAligned(maxSize) : "rounded value must not exceed max size";
66+
67+
/* Based on the hosted option values, set sane initial values good enough for startup. */
68+
long minInitialTlabSize = Math.clamp(SubstrateGCOptions.ConcealedOptions.MinTLABSize.getHostedValue(), getAbsoluteMinTlabSize(), maxSize);
69+
minTlabSize = objectLayout.alignUp(minInitialTlabSize);
70+
71+
long initialTlabSize = SubstrateGCOptions.ConcealedOptions.TLABSize.getHostedValue();
72+
if (initialTlabSize == 0) {
73+
initialTlabSize = Math.min(Math.max(minTlabSize, DEFAULT_INITIAL_TLAB_SIZE), maxSize);
74+
} else {
75+
initialTlabSize = Math.min(Math.max(minTlabSize, initialTlabSize), maxSize);
76+
}
77+
tlabSize = objectLayout.alignUp(initialTlabSize);
6278
}
6379

6480
@Fold
6581
public static TlabOptionCache singleton() {
6682
return ImageSingletons.lookup(TlabOptionCache.class);
6783
}
6884

69-
/*
70-
* The minimum size a TLAB must always have. A smaller TLAB may lead to a VM crash.
71-
*/
85+
@Platforms(Platform.HOSTED_ONLY.class)
86+
public void validateHostedOptionValues() {
87+
validateMinTlabSize(SubstrateGCOptions.ConcealedOptions.MinTLABSize);
88+
validateTlabSize(SubstrateGCOptions.ConcealedOptions.TLABSize);
89+
}
90+
91+
/* The minimum size that a TLAB must have. Anything smaller than that could crash the VM. */
7292
@Fold
7393
static long getAbsoluteMinTlabSize() {
7494
int additionalHeaderBytes = SubstrateOptions.AdditionalHeaderBytes.getValue();
@@ -78,97 +98,78 @@ static long getAbsoluteMinTlabSize() {
7898

7999
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
80100
public long getMinTlabSize() {
101+
assert minTlabSize > 0 && ConfigurationValues.getObjectLayout().isAligned(minTlabSize) && minTlabSize <= TlabSupport.maxSize().rawValue();
81102
return minTlabSize;
82103
}
83104

84105
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
85106
public long getTlabSize() {
107+
assert tlabSize >= minTlabSize && ConfigurationValues.getObjectLayout().isAligned(tlabSize) && tlabSize <= TlabSupport.maxSize().rawValue();
86108
return tlabSize;
87109
}
88110

89111
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
90-
public long getInitialTLABSize() {
91-
return initialTLABSize;
112+
public void cacheOptionValues() {
113+
cacheMinTlabSize();
114+
cacheTlabSize();
92115
}
93116

94117
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
95-
public void cacheOptionValues() {
96-
int minTlabSizeIdx = IsolateArgumentParser.getOptionIndex(SubstrateGCOptions.TlabOptions.MinTLABSize);
97-
long minTlabSizeValue = IsolateArgumentParser.singleton().getLongOptionValue(minTlabSizeIdx);
98-
cacheMinTlabSize(minTlabSizeValue);
99-
100-
int tlabSizeIdx = IsolateArgumentParser.getOptionIndex(SubstrateGCOptions.TlabOptions.TLABSize);
101-
long tlabSizeValue = IsolateArgumentParser.singleton().getLongOptionValue(tlabSizeIdx);
102-
cacheTlabSize(tlabSizeValue);
118+
private void cacheMinTlabSize() {
119+
int optionIndex = IsolateArgumentParser.getOptionIndex(SubstrateGCOptions.ConcealedOptions.MinTLABSize);
120+
long optionValue = IsolateArgumentParser.singleton().getLongOptionValue(optionIndex);
121+
if (optionValue != 0) {
122+
optionValue = UninterruptibleUtils.Math.clamp(optionValue, getAbsoluteMinTlabSize(), TlabSupport.maxSize().rawValue());
123+
minTlabSize = ConfigurationValues.getObjectLayout().alignUp(optionValue);
124+
}
125+
}
103126

104-
int initialTlabSizeIdx = IsolateArgumentParser.getOptionIndex(SerialAndEpsilonGCOptions.InitialTLABSize);
105-
long initialTlabSizeValue = IsolateArgumentParser.singleton().getLongOptionValue(initialTlabSizeIdx);
106-
cacheInitialTlabSize(initialTlabSizeValue, initialTLABSize != initialTlabSizeValue);
127+
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
128+
private void cacheTlabSize() {
129+
int optionIndex = IsolateArgumentParser.getOptionIndex(SubstrateGCOptions.ConcealedOptions.TLABSize);
130+
long optionValue = IsolateArgumentParser.singleton().getLongOptionValue(optionIndex);
131+
if (optionValue != 0) {
132+
optionValue = UninterruptibleUtils.Math.clamp(optionValue, minTlabSize, TlabSupport.maxSize().rawValue());
133+
} else {
134+
optionValue = UninterruptibleUtils.Math.clamp(tlabSize, minTlabSize, TlabSupport.maxSize().rawValue());
135+
}
136+
tlabSize = ConfigurationValues.getObjectLayout().alignUp(optionValue);
107137
}
108138

109139
public static void registerOptionValidations() {
110-
111-
long maxSize = maxSize().rawValue();
112-
113140
RuntimeOptionValidationSupport validationSupport = RuntimeOptionValidationSupport.singleton();
141+
validationSupport.register(new RuntimeOptionValidation<>(TlabOptionCache::validateMinTlabSize, SubstrateGCOptions.ConcealedOptions.MinTLABSize));
142+
validationSupport.register(new RuntimeOptionValidation<>(TlabOptionCache::validateTlabSize, SubstrateGCOptions.ConcealedOptions.TLABSize));
143+
}
114144

115-
validationSupport.register(new RuntimeOptionValidationSupport.RuntimeOptionValidation<>(optionKey -> {
116-
long minTlabSizeValue = optionKey.getValue();
117-
118-
if (optionKey.hasBeenSet() && minTlabSizeValue < getAbsoluteMinTlabSize()) {
119-
throw new IllegalArgumentException(String.format("MinTLABSize (%d) must be greater than or equal to reserved area in TLAB (%d).", minTlabSizeValue, getAbsoluteMinTlabSize()));
120-
}
121-
if (minTlabSizeValue > maxSize) {
122-
throw new IllegalArgumentException(String.format("MinTLABSize (%d) must be less than or equal to ergonomic TLAB maximum (%d).", minTlabSizeValue, maxSize));
123-
}
124-
}, SubstrateGCOptions.TlabOptions.MinTLABSize));
125-
126-
validationSupport.register(new RuntimeOptionValidationSupport.RuntimeOptionValidation<>(optionKey -> {
127-
// Check that TLABSize is still the default value or size >= abs min && size <= abs max.
128-
long tlabSizeValue = optionKey.getValue();
129-
if (optionKey.hasBeenSet() && tlabSizeValue < SubstrateGCOptions.TlabOptions.MinTLABSize.getValue()) {
130-
throw new IllegalArgumentException(
131-
String.format("TLABSize (%d) must be greater than or equal to MinTLABSize (%d).", tlabSizeValue, SubstrateGCOptions.TlabOptions.MinTLABSize.getValue()));
132-
}
133-
if (tlabSizeValue > maxSize) {
134-
throw new IllegalArgumentException(String.format("TLABSize (%d) must be less than or equal to ergonomic TLAB maximum size (%d).", tlabSizeValue, maxSize));
135-
}
136-
}, SubstrateGCOptions.TlabOptions.TLABSize));
137-
138-
validationSupport.register(new RuntimeOptionValidationSupport.RuntimeOptionValidation<>(optionKey -> {
139-
long initialTlabSizeValue = optionKey.getValue();
140-
if (initialTlabSizeValue < SubstrateGCOptions.TlabOptions.MinTLABSize.getValue()) {
141-
throw new IllegalArgumentException(
142-
String.format("InitialTLABSize (%d) must be greater than or equal to MinTLABSize (%d).", initialTlabSizeValue, SubstrateGCOptions.TlabOptions.MinTLABSize.getValue()));
143-
}
144-
if (initialTlabSizeValue > maxSize) {
145-
throw new IllegalArgumentException(String.format("TLABSize (%d) must be less than or equal to ergonomic TLAB maximum size (%d).", initialTlabSizeValue, maxSize));
146-
}
147-
}, SerialAndEpsilonGCOptions.InitialTLABSize));
145+
private static void validateMinTlabSize(RuntimeOptionKey<Long> optionKey) {
146+
long optionValue = optionKey.getValue();
147+
if (optionKey.hasBeenSet() && optionValue < getAbsoluteMinTlabSize()) {
148+
throw invalidOptionValue("Option 'MinTLABSize' (" + optionValue + ") must not be smaller than " + getAbsoluteMinTlabSize());
149+
}
148150

151+
long maxSize = TlabSupport.maxSize().rawValue();
152+
if (optionValue > maxSize) {
153+
throw invalidOptionValue("Option 'MinTLABSize' (" + optionValue + ") must not be larger than " + maxSize);
154+
}
149155
}
150156

151-
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
152-
private void cacheMinTlabSize(long optionValue) {
153-
if (getAbsoluteMinTlabSize() <= optionValue && optionValue <= maxSize().rawValue()) {
154-
minTlabSize = optionValue;
157+
private static void validateTlabSize(RuntimeOptionKey<Long> optionKey) {
158+
long optionValue = optionKey.getValue();
159+
if (optionKey.hasBeenSet() && optionValue < TlabOptionCache.singleton().getMinTlabSize()) {
160+
throw invalidOptionValue("Option 'TLABSize' (" + optionValue + ") must not be smaller than 'MinTLABSize' (" + TlabOptionCache.singleton().getMinTlabSize() + ").");
155161
}
156-
}
157162

158-
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
159-
private void cacheTlabSize(long optionValue) {
160-
if (getAbsoluteMinTlabSize() <= optionValue && optionValue <= maxSize().rawValue()) {
161-
tlabSize = optionValue;
163+
long maxSize = TlabSupport.maxSize().rawValue();
164+
if (optionValue > maxSize) {
165+
throw invalidOptionValue("Option 'TLABSize' (" + optionValue + ") must not be larger than " + maxSize);
162166
}
163167
}
164168

165-
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
166-
private void cacheInitialTlabSize(long optionValue, boolean hasBeenSet) {
167-
if (!hasBeenSet && minTlabSize > initialTLABSize) {
168-
initialTLABSize = minTlabSize;
169-
} else if (getAbsoluteMinTlabSize() <= optionValue && optionValue <= maxSize().rawValue()) {
170-
initialTLABSize = UninterruptibleUtils.Math.max(minTlabSize, optionValue);
169+
private static RuntimeException invalidOptionValue(String msg) {
170+
if (SubstrateUtil.HOSTED) {
171+
throw UserError.abort(msg);
171172
}
173+
throw new IllegalArgumentException(msg);
172174
}
173-
174175
}

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/TlabSupport.java

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -379,25 +379,15 @@ private static void resetStatistics(IsolateThread thread) {
379379
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-23-ga/src/hotspot/share/gc/shared/threadLocalAllocBuffer.cpp#L270-L289")
380380
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
381381
private static UnsignedWord initialDesiredSize() {
382-
UnsignedWord initSize;
383-
384-
if (TlabOptionCache.singleton().getTlabSize() > 0) {
385-
long tlabSize = TlabOptionCache.singleton().getTlabSize();
386-
initSize = Word.unsigned(ConfigurationValues.getObjectLayout().alignUp(tlabSize));
387-
} else {
388-
long initialTLABSize = TlabOptionCache.singleton().getInitialTLABSize();
389-
initSize = Word.unsigned(ConfigurationValues.getObjectLayout().alignUp(initialTLABSize));
390-
}
391-
long minTlabSize = TlabOptionCache.singleton().getMinTlabSize();
392-
return UnsignedUtils.clamp(initSize, Word.unsigned(minTlabSize), maxSize());
382+
return Word.unsigned(TlabOptionCache.singleton().getTlabSize());
393383
}
394384

395385
/**
396386
* Compute the next tlab size using expected allocation amount.
397387
*/
398388
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+11/src/hotspot/share/gc/shared/threadLocalAllocBuffer.cpp#L154-L172")
399389
public static void resize(IsolateThread thread) {
400-
assert SubstrateGCOptions.TlabOptions.ResizeTLAB.getValue();
390+
assert SubstrateGCOptions.ResizeTLAB.getValue();
401391
assert VMOperation.isGCInProgress();
402392

403393
UnsignedWord allocatedAvg = Word.unsigned((long) AdaptiveWeightedAverageStruct.getAverage(allocatedBytesAvg.getAddress(thread)));

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/GenScavengeAllocationSupport.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public ForeignCallDescriptor getNewPodInstanceStub() {
9191

9292
@Override
9393
public boolean useTLAB() {
94-
return SubstrateGCOptions.TlabOptions.UseTLAB.getValue();
94+
return SubstrateGCOptions.UseTLAB.getValue();
9595
}
9696

9797
@Override

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateGCOptions.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@
4747
*/
4848
@DuplicatedInNativeCode
4949
public class SubstrateGCOptions {
50-
private static final int K = 1024;
51-
5250
@Option(help = "The minimum heap size at run-time, in bytes.", type = OptionType.User)//
5351
public static final RuntimeOptionKey<Long> MinHeapSize = new NotifyGCRuntimeOptionKey<>(0L, RegisterForIsolateArgumentParser) {
5452
@Override
@@ -106,20 +104,20 @@ protected void onValueUpdate(EconomicMap<OptionKey<?>, Object> values, Long oldV
106104
@Option(help = "Determines if references from runtime-compiled code to Java heap objects should be treated as strong or weak.", type = OptionType.Debug)//
107105
public static final HostedOptionKey<Boolean> TreatRuntimeCodeInfoReferencesAsWeak = new HostedOptionKey<>(true);
108106

109-
@DuplicatedInNativeCode
110-
public static class TlabOptions {
111-
@Option(help = "Use thread-local object allocation.", type = OptionType.Expert)//
112-
public static final HostedOptionKey<Boolean> UseTLAB = new HostedOptionKey<>(true);
107+
@Option(help = "Use thread-local object allocation.", type = OptionType.Expert)//
108+
public static final HostedOptionKey<Boolean> UseTLAB = new HostedOptionKey<>(true);
113109

114-
@Option(help = "Dynamically resize TLAB size for threads.", type = OptionType.Expert)//
115-
public static final RuntimeOptionKey<Boolean> ResizeTLAB = new RuntimeOptionKey<>(true, IsolateCreationOnly);
110+
@Option(help = "Dynamically resize TLAB size for threads.", type = OptionType.Expert)//
111+
public static final RuntimeOptionKey<Boolean> ResizeTLAB = new RuntimeOptionKey<>(true, IsolateCreationOnly);
116112

113+
@DuplicatedInNativeCode
114+
public static class ConcealedOptions {
115+
/** Use GC-specific accessors instead. */
117116
@Option(help = "Minimum allowed TLAB size (in bytes).", type = OptionType.Expert)//
118-
public static final RuntimeOptionKey<Long> MinTLABSize = new RuntimeOptionKey<>(2L * K, RegisterForIsolateArgumentParser);
117+
public static final RuntimeOptionKey<Long> MinTLABSize = new RuntimeOptionKey<>(0L, RegisterForIsolateArgumentParser);
119118

119+
/** Use GC-specific accessors instead. */
120120
@Option(help = "Starting TLAB size (in bytes); zero means set ergonomically.", type = OptionType.Expert)//
121121
public static final RuntimeOptionKey<Long> TLABSize = new RuntimeOptionKey<>(0L, RegisterForIsolateArgumentParser);
122-
123122
}
124-
125123
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/gc/shared/graal/NativeGCAllocationSupport.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public ForeignCallDescriptor getNewPodInstanceStub() {
108108

109109
@Override
110110
public boolean useTLAB() {
111-
return SubstrateGCOptions.TlabOptions.UseTLAB.getValue();
111+
return SubstrateGCOptions.UseTLAB.getValue();
112112
}
113113

114114
@Override

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/option/RuntimeOptionValidationSupport.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ public void validate() {
6666
}
6767

6868
public static class RuntimeOptionValidation<T> {
69-
7069
private final Consumer<RuntimeOptionKey<T>> validation;
7170
private final RuntimeOptionKey<T> optionKey;
7271

@@ -78,7 +77,5 @@ public RuntimeOptionValidation(Consumer<RuntimeOptionKey<T>> validation, Runtime
7877
void validate() {
7978
validation.accept(optionKey);
8079
}
81-
8280
}
83-
8481
}

0 commit comments

Comments
 (0)