Skip to content

Commit 3e8ffa7

Browse files
committed
[GR-59742] Re-enable @Uninterruptible and @RestrictHeapAccess for open world and layered images.
PullRequest: graal/21439
2 parents 3ff585b + a1f61dc commit 3e8ffa7

File tree

6 files changed

+90
-36
lines changed

6 files changed

+90
-36
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
import com.oracle.svm.core.threadlocal.VMThreadLocalInfos;
9797
import com.oracle.svm.core.util.CounterSupport;
9898
import com.oracle.svm.core.util.ImageHeapList;
99+
import com.oracle.svm.core.util.RuntimeImageHeapList;
99100
import com.oracle.svm.core.util.TimeUtils;
100101
import com.oracle.svm.core.util.VMError;
101102

@@ -1352,7 +1353,12 @@ int size() {
13521353
}
13531354

13541355
DiagnosticThunk getThunk(int index) {
1355-
return thunks.get(index);
1356+
/*
1357+
* Use an explicit cast to aid open-world analysis. Otherwise, this may trigger false
1358+
* positive violations of @RestrictHeapAccess since some implementations of List.get()
1359+
* can allocate.
1360+
*/
1361+
return ((RuntimeImageHeapList<DiagnosticThunk>) thunks).get(index);
13561362
}
13571363

13581364
int getInitialInvocationCount(int index) {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/sampler/AbstractJfrExecutionSampler.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ protected static boolean isExecutionSamplingAllowedInCurrentThread() {
170170

171171
protected abstract void updateInterval();
172172

173+
@Uninterruptible(reason = "Prevent VM operations that modify the recurring callbacks.")
173174
protected abstract void uninstall(IsolateThread thread);
174175

175176
@Uninterruptible(reason = "The method executes during signal handling.", callerMustBe = true)

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/util/ImageHeapList.java

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
import org.graalvm.nativeimage.Platforms;
3636

3737
import com.oracle.svm.core.BuildPhaseProvider;
38-
import com.oracle.svm.core.Uninterruptible;
3938

4039
/**
4140
* A list that is filled at image build time while the static analysis is running, and then read at
@@ -80,7 +79,7 @@ private ImageHeapList() {
8079
public static final class HostedImageHeapList<E> extends AbstractList<E> {
8180
private final Comparator<E> comparator;
8281
private final List<E> hostedList;
83-
public final RuntimeImageHeapList<E> runtimeList;
82+
private final RuntimeImageHeapList<E> runtimeList;
8483
/**
8584
* Used to signal if this list has been modified. If true, the change should be propagated
8685
* from the hosted list to the runtime list by calling {@link #update()}. This variable
@@ -96,6 +95,10 @@ private HostedImageHeapList(Class<E> elementClass, Comparator<E> comparator) {
9695
this.runtimeList = new RuntimeImageHeapList<>((E[]) Array.newInstance(elementClass, 0));
9796
}
9897

98+
public RuntimeImageHeapList<E> getRuntimeList() {
99+
return runtimeList;
100+
}
101+
99102
public synchronized boolean needsUpdate() {
100103
return modified;
101104
}
@@ -158,25 +161,3 @@ private static UnsupportedOperationException notSupported() {
158161
}
159162
}
160163
}
161-
162-
final class RuntimeImageHeapList<E> extends AbstractList<E> {
163-
164-
E[] elementData;
165-
166-
@Platforms(Platform.HOSTED_ONLY.class)
167-
RuntimeImageHeapList(E[] elementData) {
168-
this.elementData = elementData;
169-
}
170-
171-
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
172-
@Override
173-
public E get(int index) {
174-
return elementData[index];
175-
}
176-
177-
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
178-
@Override
179-
public int size() {
180-
return elementData.length;
181-
}
182-
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.core.util;
26+
27+
import java.util.AbstractList;
28+
29+
import org.graalvm.nativeimage.Platform;
30+
import org.graalvm.nativeimage.Platforms;
31+
32+
import com.oracle.svm.core.Uninterruptible;
33+
34+
/**
35+
* The immutable runtime list view for an {@link ImageHeapList}.
36+
*/
37+
public final class RuntimeImageHeapList<E> extends AbstractList<E> {
38+
39+
E[] elementData;
40+
41+
@Platforms(Platform.HOSTED_ONLY.class)
42+
RuntimeImageHeapList(E[] elementData) {
43+
this.elementData = elementData;
44+
}
45+
46+
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
47+
@Override
48+
public E get(int index) {
49+
return elementData[index];
50+
}
51+
52+
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
53+
@Override
54+
public int size() {
55+
return elementData.length;
56+
}
57+
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CompileQueue.java

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,11 @@
4242

4343
import com.oracle.graal.pointsto.api.PointstoOptions;
4444
import com.oracle.graal.pointsto.flow.AnalysisParsedGraph;
45+
import com.oracle.graal.pointsto.infrastructure.OriginalClassProvider;
4546
import com.oracle.graal.pointsto.meta.HostedProviders;
4647
import com.oracle.graal.pointsto.util.CompletionExecutor;
4748
import com.oracle.graal.pointsto.util.CompletionExecutor.DebugContextRunnable;
49+
import com.oracle.graal.pointsto.util.GraalAccess;
4850
import com.oracle.svm.common.meta.MultiMethod;
4951
import com.oracle.svm.core.SubstrateOptions;
5052
import com.oracle.svm.core.Uninterruptible;
@@ -137,6 +139,7 @@
137139
import jdk.vm.ci.code.site.Infopoint;
138140
import jdk.vm.ci.meta.MetaAccessProvider;
139141
import jdk.vm.ci.meta.ResolvedJavaMethod;
142+
import jdk.vm.ci.meta.ResolvedJavaType;
140143
import jdk.vm.ci.meta.VMConstant;
141144

142145
public class CompileQueue {
@@ -182,6 +185,9 @@ protected PhaseSuite<HighTierContext> getAfterParseSuite() {
182185

183186
private final boolean printMethodHistogram = NativeImageOptions.PrintMethodHistogram.getValue();
184187
private final boolean optionAOTTrivialInline = SubstrateOptions.AOTTrivialInline.getValue();
188+
private final boolean allowFoldMethods = NativeImageOptions.AllowFoldMethods.getValue();
189+
190+
private final ResolvedJavaType generatedFoldInvocationPluginType;
185191

186192
public record UnpublishedTrivialMethods(CompilationGraph unpublishedGraph, boolean newlyTrivial) {
187193
}
@@ -387,6 +393,7 @@ public CompileQueue(DebugContext debug, FeatureHandler featureHandler, HostedUni
387393
this.defaultParseHooks = new ParseHooks(this);
388394

389395
callForReplacements(debug, runtimeConfig);
396+
generatedFoldInvocationPluginType = GraalAccess.getOriginalProviders().getMetaAccess().lookupJavaType(GeneratedFoldInvocationPlugin.class);
390397
}
391398

392399
protected AnalysisToHostedGraphTransplanter createGraphTransplanter() {
@@ -409,9 +416,7 @@ public void finish(DebugContext debug) {
409416
parseAll();
410417
}
411418

412-
// GR-59742 re-enable for open type world and layered images
413-
if (SubstrateOptions.useClosedTypeWorld() && !ImageLayerBuildingSupport.buildingImageLayer() &&
414-
!PointstoOptions.UseExperimentalReachabilityAnalysis.getValue(universe.hostVM().options())) {
419+
if (!PointstoOptions.UseExperimentalReachabilityAnalysis.getValue(universe.hostVM().options())) {
415420
/*
416421
* Reachability Analysis creates call graphs with more edges compared to the
417422
* Points-to Analysis, therefore the annotations would have to be added to a lot
@@ -1005,17 +1010,21 @@ protected void ensureParsed(HostedMethod method, HostedMethod callerMethod, Comp
10051010
return;
10061011
}
10071012

1008-
if (!(NativeImageOptions.AllowFoldMethods.getValue() || method.getAnnotation(Fold.class) == null ||
1009-
(callerMethod != null && metaAccess.lookupJavaType(GeneratedFoldInvocationPlugin.class).isAssignableFrom(callerMethod.getDeclaringClass())))) {
1010-
throw VMError.shouldNotReachHere("Parsing method annotated with @" + Fold.class.getSimpleName() + ": " +
1011-
method.format("%H.%n(%p)") +
1012-
". Make sure you have used Graal annotation processors on the parent-project of the method's declaring class.");
1013+
if (!allowFoldMethods && method.getAnnotation(Fold.class) != null && !isFoldInvocationPluginMethod(callerMethod)) {
1014+
throw VMError.shouldNotReachHere("Parsing method annotated with @%s: %s. " +
1015+
"This could happen if either: the Graal annotation processor was not executed on the parent-project of the method's declaring class, " +
1016+
"the arguments passed to the method were not compile-time constants, or the plugin was disabled by the corresponding %s.",
1017+
Fold.class.getSimpleName(), method.format("%H.%n(%p)"), GraphBuilderContext.class.getSimpleName());
10131018
}
10141019
if (!method.compilationInfo.inParseQueue.getAndSet(true)) {
10151020
executor.execute(new ParseTask(method, reason));
10161021
}
10171022
}
10181023

1024+
private boolean isFoldInvocationPluginMethod(HostedMethod method) {
1025+
return method != null && generatedFoldInvocationPluginType.isAssignableFrom(OriginalClassProvider.getOriginalType(method.getDeclaringClass()));
1026+
}
1027+
10191028
protected final void doParse(DebugContext debug, ParseTask task) {
10201029
HostedMethod method = task.method;
10211030
if (HostedImageLayerBuildingSupport.buildingExtensionLayer()) {

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/heap/ImageHeapCollectionFeature.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ private Object replaceHostedWithRuntime(Object obj) {
6868
} else {
6969
allLists.add(hostedImageHeapList);
7070
}
71-
return hostedImageHeapList.runtimeList;
71+
return hostedImageHeapList.getRuntimeList();
7272
}
7373
return obj;
7474
}
@@ -101,7 +101,7 @@ public void duringAnalysis(DuringAnalysisAccess a) {
101101
allLists.parallelStream().forEach(hostedImageHeapList -> {
102102
if (hostedImageHeapList.needsUpdate()) {
103103
hostedImageHeapList.update();
104-
objectsToRescan.add(hostedImageHeapList.runtimeList);
104+
objectsToRescan.add(hostedImageHeapList.getRuntimeList());
105105
}
106106
});
107107
if (!objectsToRescan.isEmpty()) {
@@ -135,7 +135,7 @@ public void afterImageWrite(AfterImageWriteAccess access) {
135135
for (var hostedImageHeapList : allLists) {
136136
if (hostedImageHeapList.needsUpdate()) {
137137
throw VMError.shouldNotReachHere("ImageHeapList modified after static analysis:%n%s%n%s",
138-
hostedImageHeapList, hostedImageHeapList.runtimeList);
138+
hostedImageHeapList, hostedImageHeapList.getRuntimeList());
139139

140140
}
141141
}

0 commit comments

Comments
 (0)