Skip to content

Commit 4c3818c

Browse files
SubstrateDiagnostics bugfixes.
Better OutOfMemoryError messages. Use OutOfMemoryUtil.reportOutOfMemoryError(...) more consistently.
1 parent 4db0672 commit 4c3818c

File tree

5 files changed

+30
-17
lines changed

5 files changed

+30
-17
lines changed

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,6 @@ public class AddressRangeCommittedMemoryProvider extends ChunkBasedCommittedMemo
112112
"Consider increasing the address space size (see option -XX:ReservedAddressSpaceSize).");
113113
private static final OutOfMemoryError UNALIGNED_OUT_OF_ADDRESS_SPACE = new OutOfMemoryError("Could not allocate an unaligned heap chunk because the heap address space is exhausted. " +
114114
"Consider increasing the address space size (see option -XX:ReservedAddressSpaceSize).");
115-
private static final OutOfMemoryError ALIGNED_COMMIT_FAILED = new OutOfMemoryError("Could not commit the memory for an aligned heap chunk, OS may be out of memory.");
116-
private static final OutOfMemoryError UNALIGNED_COMMIT_FAILED = new OutOfMemoryError("Could not commit the memory for an unaligned heap chunk, OS may be out of memory.");
117115

118116
/**
119117
* This mutex is used by the GC and the application. The application may hold this mutex only in
@@ -347,7 +345,7 @@ protected OutOfMemoryError reportAlignedChunkAllocationFailed(int error) {
347345
if (error == OUT_OF_ADDRESS_SPACE) {
348346
throw OutOfMemoryUtil.reportOutOfMemoryError(ALIGNED_OUT_OF_ADDRESS_SPACE);
349347
} else if (error == COMMIT_FAILED) {
350-
throw OutOfMemoryUtil.reportOutOfMemoryError(ALIGNED_COMMIT_FAILED);
348+
throw OutOfMemoryUtil.reportOutOfMemoryError(ALIGNED_CHUNK_COMMIT_FAILED);
351349
} else {
352350
throw VMError.shouldNotReachHereAtRuntime();
353351
}
@@ -372,7 +370,7 @@ protected OutOfMemoryError reportUnalignedChunkAllocationFailed(int error) {
372370
if (error == OUT_OF_ADDRESS_SPACE) {
373371
throw OutOfMemoryUtil.reportOutOfMemoryError(UNALIGNED_OUT_OF_ADDRESS_SPACE);
374372
} else if (error == COMMIT_FAILED) {
375-
throw OutOfMemoryUtil.reportOutOfMemoryError(UNALIGNED_COMMIT_FAILED);
373+
throw OutOfMemoryUtil.reportOutOfMemoryError(UNALIGNED_CHUNK_COMMIT_FAILED);
376374
} else {
377375
throw VMError.shouldNotReachHereAtRuntime();
378376
}

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

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.graalvm.nativeimage.c.struct.RawStructure;
4242
import org.graalvm.nativeimage.c.struct.SizeOf;
4343
import org.graalvm.nativeimage.c.type.CCharPointer;
44+
import org.graalvm.nativeimage.impl.ImageSingletonsSupport;
4445
import org.graalvm.word.Pointer;
4546
import org.graalvm.word.PointerBase;
4647
import org.graalvm.word.UnsignedWord;
@@ -175,7 +176,7 @@ public static void printObjectInfo(Log log, Object obj) {
175176
log.string(obj.getClass().getName());
176177

177178
if (obj instanceof String s) {
178-
log.string(": ").string(s, 60);
179+
log.string(": \"").string(s, 60).string("\"");
179180
} else {
180181
int layoutEncoding = DynamicHub.fromClass(obj.getClass()).getLayoutEncoding();
181182

@@ -1306,12 +1307,14 @@ public static synchronized DiagnosticThunkRegistry singleton() {
13061307

13071308
@Platforms(Platform.HOSTED_ONLY.class)
13081309
public synchronized void add(DiagnosticThunk thunk) {
1310+
assert !BuildPhaseProvider.isAnalysisStarted();
13091311
thunks.add(thunk);
13101312
resizeInitialInvocationCount();
13111313
}
13121314

13131315
@Platforms(Platform.HOSTED_ONLY.class)
13141316
public synchronized void add(int insertPos, DiagnosticThunk... extraThunks) {
1317+
assert !BuildPhaseProvider.isAnalysisStarted();
13151318
for (int i = 0; i < extraThunks.length; i++) {
13161319
thunks.add(insertPos + i, extraThunks[i]);
13171320
}
@@ -1320,6 +1323,7 @@ public synchronized void add(int insertPos, DiagnosticThunk... extraThunks) {
13201323

13211324
@Platforms(Platform.HOSTED_ONLY.class)
13221325
public synchronized void addAfter(DiagnosticThunk thunk, Class<? extends DiagnosticThunk> before) {
1326+
assert !BuildPhaseProvider.isAnalysisStarted();
13231327
int insertPos = indexOf(before) + 1;
13241328
assert insertPos > 0;
13251329
thunks.add(insertPos, thunk);
@@ -1370,13 +1374,13 @@ protected void onValueUpdate(EconomicMap<OptionKey<?>, Object> values, Boolean o
13701374

13711375
/*
13721376
* Copy the value to a field in the image heap so that it is safe to access. During
1373-
* image build, it can happen that the singleton does not exist yet. In that case,
1374-
* the value will be copied to the image heap when executing the constructor of the
1375-
* singleton. This is a bit cumbersome but necessary because we can't use a static
1376-
* field. We also need to mark the option as used at run-time (see feature) as the
1377-
* static analysis would otherwise remove the option from the image.
1377+
* the image build, it can happen that the singleton does not exist yet. In that
1378+
* case, the value will be copied to the image heap when executing the constructor
1379+
* of the singleton. This is a bit cumbersome but necessary because we can't use a
1380+
* static field. We also need to mark the option as used at run-time (see feature)
1381+
* as the static analysis would otherwise remove the option from the image.
13781382
*/
1379-
if (ImageSingletons.contains(Options.class)) {
1383+
if (wasConstructorExecuted()) {
13801384
Options.singleton().loopOnFatalError = newValue;
13811385
}
13821386
}
@@ -1389,7 +1393,7 @@ protected void onValueUpdate(EconomicMap<OptionKey<?>, Object> values, Boolean o
13891393
super.onValueUpdate(values, oldValue, newValue);
13901394

13911395
/* See comment above. */
1392-
if (ImageSingletons.contains(Options.class)) {
1396+
if (wasConstructorExecuted()) {
13931397
Options.singleton().implicitExceptionWithoutStacktraceIsFatal = newValue;
13941398
}
13951399
}
@@ -1417,6 +1421,10 @@ public static boolean shouldLoopOnFatalError() {
14171421
public static boolean implicitExceptionWithoutStacktraceIsFatal() {
14181422
return singleton().implicitExceptionWithoutStacktraceIsFatal;
14191423
}
1424+
1425+
private static boolean wasConstructorExecuted() {
1426+
return (!SubstrateUtil.HOSTED || ImageSingletonsSupport.isInstalled()) && ImageSingletons.contains(Options.class);
1427+
}
14201428
}
14211429
}
14221430

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,7 @@ public static void updateMaxJavaStackTraceDepth(EconomicMap<OptionKey<?>, Object
656656
}
657657

658658
/* Same option name and specification as the Java HotSpot VM. */
659-
@Option(help = "Maximum total size of NIO direct-buffer allocations")//
659+
@Option(help = "Maximum total size of NIO direct-buffer allocations", type = OptionType.Expert)//
660660
public static final RuntimeOptionKey<Long> MaxDirectMemorySize = new RuntimeOptionKey<>(0L);
661661

662662
@Option(help = "Verify naming conventions during image construction.")//

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/OutOfMemoryUtil.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import com.oracle.svm.core.jdk.JDKUtils;
3434
import com.oracle.svm.core.log.Log;
3535
import com.oracle.svm.core.stack.StackOverflowCheck;
36+
import com.oracle.svm.core.thread.VMOperation;
3637
import com.oracle.svm.core.util.VMError;
3738

3839
/**
@@ -62,6 +63,11 @@ public static OutOfMemoryError reportOutOfMemoryError(OutOfMemoryError error) {
6263

6364
@Uninterruptible(reason = "Not uninterruptible but it doesn't matter for the callers.", calleeMustBe = false)
6465
private static void reportOutOfMemoryError0(OutOfMemoryError error) {
66+
if (VMOperation.isGCInProgress()) {
67+
/* If a GC is in progress, then we can't execute the more complex logic below. */
68+
return;
69+
}
70+
6571
if (VMInspectionOptions.hasHeapDumpSupport() && SubstrateOptions.HeapDumpOnOutOfMemoryError.getValue()) {
6672
HeapDumping.singleton().dumpHeapOnOutOfMemoryError();
6773
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/os/ChunkBasedCommittedMemoryProvider.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
import com.oracle.svm.core.Uninterruptible;
3535
import com.oracle.svm.core.config.ConfigurationValues;
36+
import com.oracle.svm.core.heap.OutOfMemoryUtil;
3637
import com.oracle.svm.core.heap.RestrictHeapAccess;
3738
import com.oracle.svm.core.nmt.NmtCategory;
3839
import com.oracle.svm.core.thread.VMOperation;
@@ -41,9 +42,9 @@
4142
import jdk.graal.compiler.word.Word;
4243

4344
public abstract class ChunkBasedCommittedMemoryProvider extends AbstractCommittedMemoryProvider {
44-
private static final OutOfMemoryError ALIGNED_OUT_OF_MEMORY_ERROR = new OutOfMemoryError("Could not allocate an aligned heap chunk. " +
45+
protected static final OutOfMemoryError ALIGNED_CHUNK_COMMIT_FAILED = new OutOfMemoryError("Could not commit an aligned heap chunk. " +
4546
"Either the OS/container is out of memory or another system-level resource limit was reached (such as the number of memory mappings).");
46-
private static final OutOfMemoryError UNALIGNED_OUT_OF_MEMORY_ERROR = new OutOfMemoryError("Could not allocate an unaligned heap chunk. " +
47+
protected static final OutOfMemoryError UNALIGNED_CHUNK_COMMIT_FAILED = new OutOfMemoryError("Could not commit an unaligned heap chunk. " +
4748
"Either the OS/container is out of memory or another system-level resource limit was reached (such as the number of memory mappings).");
4849

4950
@Fold
@@ -56,7 +57,7 @@ public static ChunkBasedCommittedMemoryProvider get() {
5657
public Pointer allocateAlignedChunk(UnsignedWord nbytes, UnsignedWord alignment) {
5758
Pointer result = allocate(nbytes, alignment, false, NmtCategory.JavaHeap);
5859
if (result.isNull()) {
59-
throw ALIGNED_OUT_OF_MEMORY_ERROR;
60+
throw OutOfMemoryUtil.reportOutOfMemoryError(ALIGNED_CHUNK_COMMIT_FAILED);
6061
}
6162
return result;
6263
}
@@ -66,7 +67,7 @@ public Pointer allocateAlignedChunk(UnsignedWord nbytes, UnsignedWord alignment)
6667
public Pointer allocateUnalignedChunk(UnsignedWord nbytes) {
6768
Pointer result = allocate(nbytes, getAlignmentForUnalignedChunks(), false, NmtCategory.JavaHeap);
6869
if (result.isNull()) {
69-
throw UNALIGNED_OUT_OF_MEMORY_ERROR;
70+
throw OutOfMemoryUtil.reportOutOfMemoryError(UNALIGNED_CHUNK_COMMIT_FAILED);
7071
}
7172
return result;
7273
}

0 commit comments

Comments
 (0)