2727import java .nio .ByteBuffer ;
2828import java .util .List ;
2929
30+ import org .graalvm .nativeimage .ImageInfo ;
3031import org .graalvm .word .UnsignedWord ;
3132
3233import com .oracle .svm .core .SubstrateOptions ;
4142import com .oracle .svm .core .image .ImageHeapLayoutInfo ;
4243import com .oracle .svm .core .image .ImageHeapLayouter ;
4344import com .oracle .svm .core .image .ImageHeapObject ;
45+ import com .oracle .svm .core .option .SubstrateOptionsParser ;
46+ import com .oracle .svm .core .util .UserError ;
4447import com .oracle .svm .core .util .VMError ;
4548
4649import 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 ();
0 commit comments