Skip to content

Commit 48c7bb2

Browse files
committed
[GR-62629] Report user errors for huge relocatable objects in heap.
PullRequest: graal/20436
2 parents 4179b4f + 023f9ec commit 48c7bb2

File tree

2 files changed

+28
-17
lines changed

2 files changed

+28
-17
lines changed

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

Lines changed: 27 additions & 6 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;
@@ -75,6 +78,8 @@ public class ChunkedImageHeapLayouter implements ImageHeapLayouter {
7578
private static final int READ_ONLY_HUGE = WRITABLE_HUGE + 1;
7679
private static final int PARTITION_COUNT = READ_ONLY_HUGE + 1;
7780

81+
private static final String ALIGNED_HEAP_CHUNK_OPTION = SubstrateOptionsParser.commandArgument(SerialAndEpsilonGCOptions.AlignedHeapChunkSize, "<2^n>");
82+
7883
private final ChunkedImageHeapPartition[] partitions;
7984
private final ImageHeapInfo heapInfo;
8085
private final long startOffset;
@@ -120,15 +125,21 @@ private ChunkedImageHeapPartition choosePartition(ImageHeapObject info, boolean
120125
if (patched) {
121126
return getWritablePatched();
122127
} else if (immutable) {
123-
if (hasRelocatables) {
124-
VMError.guarantee(info.getSize() < hugeObjectThreshold, "Objects with relocatable pointers cannot be huge objects");
125-
return getReadOnlyRelocatable();
126-
}
127128
if (info.getSize() >= hugeObjectThreshold) {
128-
VMError.guarantee(info.getObjectClass() != DynamicHub.class, "Class metadata (dynamic hubs) cannot be huge objects");
129+
if (hasRelocatables) {
130+
if (info.getObjectClass() == DynamicHub.class) {
131+
throw reportHugeObjectError(info, "Class metadata (dynamic hubs) cannot be huge objects: the dynamic hub %s", info.getObject().toString());
132+
}
133+
throw reportHugeObjectError(info, "Objects in image heap with relocatable pointers cannot be huge objects. Detected an object of type %s",
134+
info.getObject().getClass().getTypeName());
135+
}
129136
return getReadOnlyHuge();
130137
}
131-
return getReadOnlyRegular();
138+
if (hasRelocatables) {
139+
return getReadOnlyRelocatable();
140+
} else {
141+
return getReadOnlyRegular();
142+
}
132143
} else {
133144
assert info.getObjectClass() != DynamicHub.class : "Class metadata (dynamic hubs) cannot be writable";
134145
if (info.getSize() >= hugeObjectThreshold) {
@@ -138,6 +149,16 @@ private ChunkedImageHeapPartition choosePartition(ImageHeapObject info, boolean
138149
}
139150
}
140151

152+
private Error reportHugeObjectError(ImageHeapObject info, String objectTypeMsg, String objectText) {
153+
String msg = String.format(objectTypeMsg + " with size %d B and the limit is %d B. Use '%s' to increase GC chunk size to be larger than the object.",
154+
objectText, info.getSize(), hugeObjectThreshold, ALIGNED_HEAP_CHUNK_OPTION);
155+
if (ImageInfo.inImageBuildtimeCode()) {
156+
throw UserError.abort(msg);
157+
} else {
158+
throw VMError.shouldNotReachHere(msg);
159+
}
160+
}
161+
141162
@Override
142163
public ImageHeapLayoutInfo layout(ImageHeap imageHeap, int pageSize) {
143164
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)