Skip to content

Commit 9905a78

Browse files
committed
Report user errors for huge relocatable objects in heap
1 parent 6086ff0 commit 9905a78

File tree

2 files changed

+34
-16
lines changed

2 files changed

+34
-16
lines changed

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

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.nio.ByteBuffer;
2828
import java.util.List;
2929

30+
import org.graalvm.nativeimage.ImageInfo;
3031
import org.graalvm.word.UnsignedWord;
3132

3233
import com.oracle.svm.core.SubstrateOptions;
@@ -41,6 +42,8 @@
4142
import com.oracle.svm.core.image.ImageHeapLayoutInfo;
4243
import com.oracle.svm.core.image.ImageHeapLayouter;
4344
import com.oracle.svm.core.image.ImageHeapObject;
45+
import com.oracle.svm.core.option.SubstrateOptionsParser;
46+
import com.oracle.svm.core.util.UserError;
4447
import com.oracle.svm.core.util.VMError;
4548

4649
import jdk.graal.compiler.core.common.NumUtil;
@@ -120,14 +123,19 @@ private ChunkedImageHeapPartition choosePartition(ImageHeapObject info, boolean
120123
if (patched) {
121124
return getWritablePatched();
122125
} else if (immutable) {
123-
if (hasRelocatables) {
124-
VMError.guarantee(info.getSize() < hugeObjectThreshold, "Objects with relocatable pointers cannot be huge objects");
125-
return getReadOnlyRelocatable();
126-
}
127126
if (info.getSize() >= hugeObjectThreshold) {
128-
VMError.guarantee(info.getObjectClass() != DynamicHub.class, "Class metadata (dynamic hubs) cannot be huge objects");
127+
if (info.getObjectClass() == DynamicHub.class) {
128+
throw reportHugeObjectError(info, "Class metadata (dynamic hubs) cannot be huge objects. The dynamic hub %s", info.getObject().toString());
129+
}
130+
if (hasRelocatables) {
131+
throw reportHugeObjectError(info, "Objects in image heap with relocatable pointers cannot be huge objects. Detected an object of type %s",
132+
info.getObject().getClass().getTypeName());
133+
}
129134
return getReadOnlyHuge();
130135
}
136+
if (hasRelocatables) {
137+
return getReadOnlyRelocatable();
138+
}
131139
return getReadOnlyRegular();
132140
} else {
133141
assert info.getObjectClass() != DynamicHub.class : "Class metadata (dynamic hubs) cannot be writable";
@@ -138,6 +146,26 @@ private ChunkedImageHeapPartition choosePartition(ImageHeapObject info, boolean
138146
}
139147
}
140148

149+
private Error reportHugeObjectError(ImageHeapObject info, String objectTypeMsg, String objectText) {
150+
String msg = String.format(
151+
objectTypeMsg + " with size %d B and the limit is %d B. Use '%s' to increase GC chunk size to be larger than the object.",
152+
objectText, info.getSize(), hugeObjectThreshold,
153+
SubstrateOptionsParser.commandArgument(SerialAndEpsilonGCOptions.AlignedHeapChunkSize, "<2^n>"));
154+
if (ImageInfo.inImageBuildtimeCode()) {
155+
throw UserError.abort(msg);
156+
} else {
157+
throw VMError.shouldNotReachHere(msg);
158+
}
159+
}
160+
161+
private static void reportError(String msg) {
162+
if (ImageInfo.inImageBuildtimeCode()) {
163+
UserError.abort(msg);
164+
} else {
165+
VMError.shouldNotReachHere(msg);
166+
}
167+
}
168+
141169
@Override
142170
public ImageHeapLayoutInfo layout(ImageHeap imageHeap, int pageSize) {
143171
int objectAlignment = ConfigurationValues.getObjectLayout().getAlignment();

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

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,12 @@
2424
*/
2525
package com.oracle.svm.core.genscavenge;
2626

27-
import org.graalvm.collections.EconomicMap;
28-
2927
import com.oracle.svm.core.SubstrateOptions;
3028
import com.oracle.svm.core.option.HostedOptionKey;
3129
import com.oracle.svm.core.option.NotifyGCRuntimeOptionKey;
3230
import com.oracle.svm.core.option.RuntimeOptionKey;
3331
import com.oracle.svm.core.util.UserError;
34-
3532
import jdk.graal.compiler.options.Option;
36-
import jdk.graal.compiler.options.OptionKey;
3733
import jdk.graal.compiler.options.OptionType;
3834

3935
/** Common options that can be specified for both the serial and the epsilon GC. */
@@ -45,13 +41,7 @@ public final class SerialAndEpsilonGCOptions {
4541
public static final RuntimeOptionKey<Integer> MaximumYoungGenerationSizePercent = new NotifyGCRuntimeOptionKey<>(10, SerialAndEpsilonGCOptions::validateSerialOrEpsilonRuntimeOption);
4642

4743
@Option(help = "The size of an aligned chunk. Serial and epsilon GC only.", type = OptionType.Expert) //
48-
public static final HostedOptionKey<Long> AlignedHeapChunkSize = new HostedOptionKey<>(512 * 1024L, SerialAndEpsilonGCOptions::validateSerialOrEpsilonHostedOption) {
49-
@Override
50-
protected void onValueUpdate(EconomicMap<OptionKey<?>, Object> values, Long oldValue, Long newValue) {
51-
int multiple = 4096;
52-
UserError.guarantee(newValue > 0 && newValue % multiple == 0, "%s value must be a multiple of %d.", getName(), multiple);
53-
}
54-
};
44+
public static final HostedOptionKey<Long> AlignedHeapChunkSize = new HostedOptionKey<>(512 * 1024L, SerialAndEpsilonGCOptions::validateSerialOrEpsilonHostedOption);
5545

5646
/*
5747
* This should be a fraction of the size of an aligned chunk, else large small arrays will not

0 commit comments

Comments
 (0)