Skip to content

Commit d4f0b58

Browse files
[GR-62543] Initialize the locking datastructures for the reference handler thread during early startup.
PullRequest: graal/20153
2 parents 1bf3f76 + 11f5ba3 commit d4f0b58

File tree

5 files changed

+27
-2
lines changed

5 files changed

+27
-2
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/snippets/CEntryPointSnippets.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
import com.oracle.svm.core.heap.PhysicalMemory;
8080
import com.oracle.svm.core.heap.ReferenceHandler;
8181
import com.oracle.svm.core.heap.ReferenceHandlerThread;
82+
import com.oracle.svm.core.heap.ReferenceInternals;
8283
import com.oracle.svm.core.heap.RestrictHeapAccess;
8384
import com.oracle.svm.core.imagelayer.ImageLayerBuildingSupport;
8485
import com.oracle.svm.core.imagelayer.ImageLayerSection;
@@ -434,6 +435,7 @@ private static int initializeIsolateInterruptibly1(CEntryPointCreateIsolateParam
434435
* result in deadlocks if ReferenceInternals.waitForReferenceProcessing() is called.
435436
*/
436437
if (ReferenceHandler.useDedicatedThread()) {
438+
ReferenceInternals.initializeLocking();
437439
ReferenceHandlerThread.start();
438440
}
439441

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public void run() {
9191
if (t instanceof OutOfMemoryError && VMThreads.isTearingDown()) {
9292
// Likely failed to allocate the InterruptedException, ignore either way.
9393
} else {
94-
VMError.shouldNotReachHere("Reference processing and cleaners must handle all potential exceptions", t);
94+
throw VMError.shouldNotReachHere("Reference processing and cleaners must handle all potential exceptions", t);
9595
}
9696
}
9797
}

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import com.oracle.svm.core.NeverInline;
3636
import com.oracle.svm.core.SubstrateUtil;
3737
import com.oracle.svm.core.Uninterruptible;
38+
import com.oracle.svm.core.monitor.MonitorSupport;
3839
import com.oracle.svm.core.thread.VMOperation;
3940
import com.oracle.svm.core.util.BasedOnJDKClass;
4041
import com.oracle.svm.core.util.TimeUtils;
@@ -170,6 +171,14 @@ public static boolean hasQueue(Reference<?> instance) {
170171
private static final Object processPendingLock = new Object();
171172
private static boolean processPendingActive = false;
172173

174+
public static void initializeLocking() {
175+
/*
176+
* Initialize the locking datastructures as early as possible. This makes it less likely
177+
* that the reference handler thread fails with an OutOfMemoryError because of locking.
178+
*/
179+
MonitorSupport.singleton().ensureInitialized(processPendingLock);
180+
}
181+
173182
@NeverInline("Ensure that every exception can be caught, including implicit exceptions.")
174183
public static void waitForPendingReferences() throws InterruptedException {
175184
Heap.getHeap().waitForReferencePendingList();

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/monitor/MonitorSupport.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,13 @@
2424
*/
2525
package com.oracle.svm.core.monitor;
2626

27-
import jdk.graal.compiler.api.replacements.Fold;
2827
import org.graalvm.nativeimage.ImageSingletons;
2928

3029
import com.oracle.svm.core.Uninterruptible;
3130
import com.oracle.svm.core.thread.ThreadStatus;
3231

32+
import jdk.graal.compiler.api.replacements.Fold;
33+
3334
/**
3435
* This interface provides functions related to monitor operations (the Java "synchronized" keyword
3536
* and related functions in the JDK) that are invoked by other parts of the VM.
@@ -112,4 +113,11 @@ public final void wait(Object obj, long timeoutMillis) throws InterruptedExcepti
112113
* state until the monitor has been successfully acquired.
113114
*/
114115
public abstract int getParkedThreadStatus(Thread thread, boolean timed);
116+
117+
/**
118+
* Ensures that all locking-related Java heap objects are allocated so that the given object can
119+
* be used in {@code synchronized} statements and in calls to {@link Object#notify} and
120+
* {@link Object#notifyAll} without triggering any locking-related Java heap allocations.
121+
*/
122+
public abstract void ensureInitialized(Object obj);
115123
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/monitor/MultiThreadedMonitorSupport.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,12 @@ public int getParkedThreadStatus(Thread thread, boolean timed) {
202202
return timed ? ThreadStatus.PARKED_TIMED : ThreadStatus.PARKED;
203203
}
204204

205+
@Override
206+
public void ensureInitialized(Object obj) {
207+
JavaMonitor monitor = getOrCreateMonitor(obj, MonitorInflationCause.VM_INTERNAL);
208+
monitor.getOrCreateCondition(true);
209+
}
210+
205211
@SubstrateForeignCallTarget(stubCallingConvention = false)
206212
@Uninterruptible(reason = "Avoid stack overflow error before yellow zone has been activated", calleeMustBe = false)
207213
private static void slowPathMonitorEnter(Object obj) {

0 commit comments

Comments
 (0)