Skip to content

Commit d6c8b01

Browse files
committed
[GR-45287] Add root reasons
PullRequest: graal/14603
2 parents 49dfb0a + b55ac8c commit d6c8b01

File tree

29 files changed

+117
-110
lines changed

29 files changed

+117
-110
lines changed

substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/PointsToAnalyzer.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
package com.oracle.graal.pointsto.standalone;
2828

29+
import static org.graalvm.compiler.replacements.StandardGraphBuilderPlugins.registerInvocationPlugins;
30+
2931
import java.io.File;
3032
import java.lang.reflect.Method;
3133
import java.net.MalformedURLException;
@@ -37,7 +39,6 @@
3739
import java.util.List;
3840
import java.util.concurrent.ForkJoinPool;
3941

40-
import com.oracle.graal.pointsto.standalone.heap.StandaloneHeapSnapshotVerifier;
4142
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
4243
import org.graalvm.compiler.debug.DebugContext;
4344
import org.graalvm.compiler.debug.Indent;
@@ -64,9 +65,10 @@
6465
import com.oracle.graal.pointsto.meta.HostedProviders;
6566
import com.oracle.graal.pointsto.meta.PointsToAnalysisFactory;
6667
import com.oracle.graal.pointsto.phases.NoClassInitializationPlugin;
68+
import com.oracle.graal.pointsto.reports.AnalysisReporter;
6769
import com.oracle.graal.pointsto.standalone.features.StandaloneAnalysisFeatureImpl;
6870
import com.oracle.graal.pointsto.standalone.features.StandaloneAnalysisFeatureManager;
69-
import com.oracle.graal.pointsto.reports.AnalysisReporter;
71+
import com.oracle.graal.pointsto.standalone.heap.StandaloneHeapSnapshotVerifier;
7072
import com.oracle.graal.pointsto.standalone.heap.StandaloneImageHeapScanner;
7173
import com.oracle.graal.pointsto.standalone.meta.StandaloneConstantFieldProvider;
7274
import com.oracle.graal.pointsto.standalone.meta.StandaloneConstantReflectionProvider;
@@ -84,8 +86,6 @@
8486
import jdk.vm.ci.meta.JavaKind;
8587
import jdk.vm.ci.meta.MetaAccessProvider;
8688

87-
import static org.graalvm.compiler.replacements.StandardGraphBuilderPlugins.registerInvocationPlugins;
88-
8989
public final class PointsToAnalyzer {
9090

9191
static {
@@ -188,14 +188,15 @@ private PointsToAnalyzer(String mainEntryClass, OptionValues options) {
188188
bigbang.addRootClass(byte[][].class, false, false).registerAsInHeap("root class");
189189
bigbang.addRootClass(Object[].class, false, false).registerAsInHeap("root class");
190190

191-
bigbang.addRootMethod(ReflectionUtil.lookupMethod(Object.class, "getClass"), true);
191+
var rootReason = "Registered in " + PointsToAnalyzer.class;
192+
bigbang.addRootMethod(ReflectionUtil.lookupMethod(Object.class, "getClass"), true, rootReason);
192193

193194
for (JavaKind kind : JavaKind.values()) {
194195
if (kind.isPrimitive() && kind != JavaKind.Void) {
195196
bigbang.addRootClass(kind.toJavaClass(), false, true);
196197
bigbang.addRootField(kind.toBoxedJavaClass(), "value");
197-
bigbang.addRootMethod(ReflectionUtil.lookupMethod(kind.toBoxedJavaClass(), "valueOf", kind.toJavaClass()), true);
198-
bigbang.addRootMethod(ReflectionUtil.lookupMethod(kind.toBoxedJavaClass(), kind.getJavaName() + "Value"), true);
198+
bigbang.addRootMethod(ReflectionUtil.lookupMethod(kind.toBoxedJavaClass(), "valueOf", kind.toJavaClass()), true, rootReason);
199+
bigbang.addRootMethod(ReflectionUtil.lookupMethod(kind.toBoxedJavaClass(), kind.getJavaName() + "Value"), true, rootReason);
199200
/*
200201
* Register the cache location as reachable.
201202
* BoxingSnippets$Templates#getCacheLocation accesses the cache field.
@@ -333,7 +334,7 @@ public void registerEntryMethods() {
333334
Class<?> analysisMainClass = Class.forName(entryClass, false, analysisClassLoader);
334335
Method main = analysisMainClass.getDeclaredMethod("main", String[].class);
335336
// main method is static, whatever the invokeSpecial is it is ignored.
336-
bigbang.addRootMethod(main, true);
337+
bigbang.addRootMethod(main, true, "Single entry point, registered in " + PointsToAnalyzer.class);
337338
} catch (ClassNotFoundException e) {
338339
throw new RuntimeException("Can't find the specified analysis main class " + entryClass, e);
339340
} catch (NoSuchMethodException e) {
@@ -351,7 +352,7 @@ public void registerEntryMethods() {
351352
if (!t.isAbstract()) {
352353
t.registerAsInHeap("Root class.");
353354
}
354-
bigbang.addRootMethod(m, isInvokeSpecial);
355+
bigbang.addRootMethod(m, isInvokeSpecial, "Entry point from file, registered in " + PointsToAnalyzer.class);
355356
});
356357
}
357358
}

substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/StandalonePointsToAnalysis.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
import jdk.vm.ci.meta.ConstantReflectionProvider;
4747

4848
public class StandalonePointsToAnalysis extends PointsToAnalysis {
49-
private Set<AnalysisMethod> addedClinits = ConcurrentHashMap.newKeySet();
49+
private final Set<AnalysisMethod> addedClinits = ConcurrentHashMap.newKeySet();
5050

5151
public StandalonePointsToAnalysis(OptionValues options, AnalysisUniverse universe, HostVM hostVM,
5252
AnalysisMetaAccess metaAccess, SnippetReflectionProvider snippetReflectionProvider,
@@ -78,7 +78,7 @@ public void initializeMetaData(AnalysisType type) {
7878
public void onTypeReachable(AnalysisType type) {
7979
AnalysisMethod clinitMethod = type.getClassInitializer();
8080
if (clinitMethod != null && !addedClinits.contains(clinitMethod)) {
81-
addRootMethod(clinitMethod, true);
81+
addRootMethod(clinitMethod, true, "Class initializer added onTypeReachable, in " + StandalonePointsToAnalysis.class);
8282
addedClinits.add(clinitMethod);
8383
}
8484
}

substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/features/StandaloneAnalysisFeatureImpl.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -240,12 +240,12 @@ public void registerAsUnsafeAccessed(AnalysisField aField, UnsafePartitionKind p
240240
}
241241
}
242242

243-
public void registerAsInvoked(Executable method, boolean invokeSpecial) {
244-
registerAsInvoked(getMetaAccess().lookupJavaMethod(method), invokeSpecial);
243+
public void registerAsInvoked(Executable method, boolean invokeSpecial, Object reason) {
244+
registerAsInvoked(getMetaAccess().lookupJavaMethod(method), invokeSpecial, reason);
245245
}
246246

247-
public void registerAsInvoked(AnalysisMethod aMethod, boolean invokeSpecial) {
248-
bb.addRootMethod(aMethod, invokeSpecial);
247+
public void registerAsInvoked(AnalysisMethod aMethod, boolean invokeSpecial, Object reason) {
248+
bb.addRootMethod(aMethod, invokeSpecial, reason);
249249
}
250250

251251
public void registerUnsafeFieldsRecomputed(Class<?> clazz) {

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/PointsToAnalysis.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -290,13 +290,13 @@ public Iterable<AnalysisType> getAllSynchronizedTypes() {
290290
}
291291

292292
@Override
293-
public AnalysisMethod addRootMethod(Executable method, boolean invokeSpecial, MultiMethod.MultiMethodKey... otherRoots) {
294-
return addRootMethod(metaAccess.lookupJavaMethod(method), invokeSpecial, otherRoots);
293+
public AnalysisMethod addRootMethod(Executable method, boolean invokeSpecial, Object reason, MultiMethod.MultiMethodKey... otherRoots) {
294+
return addRootMethod(metaAccess.lookupJavaMethod(method), invokeSpecial, reason, otherRoots);
295295
}
296296

297297
@Override
298298
@SuppressWarnings("try")
299-
public AnalysisMethod addRootMethod(AnalysisMethod aMethod, boolean invokeSpecial, MultiMethod.MultiMethodKey... otherRoots) {
299+
public AnalysisMethod addRootMethod(AnalysisMethod aMethod, boolean invokeSpecial, Object reason, MultiMethod.MultiMethodKey... otherRoots) {
300300
assert !universe.sealed() : "Cannot register root methods after analysis universe is sealed.";
301301
AnalysisError.guarantee(aMethod.isOriginalMethod());
302302
AnalysisType declaringClass = aMethod.getDeclaringClass();
@@ -313,8 +313,8 @@ public AnalysisMethod addRootMethod(AnalysisMethod aMethod, boolean invokeSpecia
313313
*/
314314
Consumer<PointsToAnalysisMethod> triggerStaticMethodFlow = (pointsToMethod) -> {
315315
postTask(() -> {
316-
pointsToMethod.registerAsDirectRootMethod();
317-
pointsToMethod.registerAsImplementationInvoked("static root method");
316+
pointsToMethod.registerAsDirectRootMethod(reason);
317+
pointsToMethod.registerAsImplementationInvoked(reason.toString());
318318
MethodFlowsGraphInfo flowInfo = analysisPolicy.staticRootMethodGraph(this, pointsToMethod);
319319
for (int idx = 0; idx < paramCount; idx++) {
320320
AnalysisType declaredParamType = (AnalysisType) signature.getParameterType(idx, declaringClass);
@@ -359,9 +359,9 @@ public AnalysisMethod addRootMethod(AnalysisMethod aMethod, boolean invokeSpecia
359359
*/
360360
postTask(() -> {
361361
if (invokeSpecial) {
362-
originalPTAMethod.registerAsDirectRootMethod();
362+
originalPTAMethod.registerAsDirectRootMethod(reason);
363363
} else {
364-
originalPTAMethod.registerAsVirtualRootMethod();
364+
originalPTAMethod.registerAsVirtualRootMethod(reason);
365365
}
366366
InvokeTypeFlow invoke = originalPTAMethod.initAndGetContextInsensitiveInvoke(PointsToAnalysis.this, null, invokeSpecial, MultiMethod.ORIGINAL_METHOD);
367367
/*
@@ -492,7 +492,7 @@ public void run(DebugContext ignored) {
492492

493493
@Override
494494
public String toString() {
495-
return "Operation: " + operation.toString();
495+
return "Operation: " + operation;
496496
}
497497

498498
@Override

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/ReachabilityAnalysis.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,13 @@ public interface ReachabilityAnalysis {
7979
* it is itself an override. If the method is static this flag is ignored.
8080
* @param otherRoots other versions of this method to also register as roots.
8181
*/
82-
AnalysisMethod addRootMethod(AnalysisMethod aMethod, boolean invokeSpecial, MultiMethod.MultiMethodKey... otherRoots);
82+
AnalysisMethod addRootMethod(AnalysisMethod aMethod, boolean invokeSpecial, Object reason, MultiMethod.MultiMethodKey... otherRoots);
8383

8484
/**
85-
* @see ReachabilityAnalysis#addRootMethod(AnalysisMethod, boolean,
85+
* @see ReachabilityAnalysis#addRootMethod(AnalysisMethod, boolean, Object,
8686
* MultiMethod.MultiMethodKey...)
8787
*/
88-
AnalysisMethod addRootMethod(Executable method, boolean invokeSpecial, MultiMethod.MultiMethodKey... otherRoots);
88+
AnalysisMethod addRootMethod(Executable method, boolean invokeSpecial, Object reason, MultiMethod.MultiMethodKey... otherRoots);
8989

9090
default void registerAsFrozenUnsafeAccessed(AnalysisField field) {
9191
field.setUnsafeFrozenTypeState(true);

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@
147147
import jdk.vm.ci.meta.JavaConstant;
148148
import jdk.vm.ci.meta.JavaKind;
149149
import jdk.vm.ci.meta.JavaType;
150+
import jdk.vm.ci.meta.ResolvedJavaMethod;
150151
import jdk.vm.ci.meta.VMConstant;
151152

152153
public class MethodTypeFlowBuilder {
@@ -334,13 +335,13 @@ protected static void registerUsedElements(PointsToAnalysis bb, StructuredGraph
334335

335336
} else if (n instanceof ForeignCall) {
336337
ForeignCall node = (ForeignCall) n;
337-
registerForeignCall(bb, providers.getForeignCalls(), node.getDescriptor());
338+
registerForeignCall(bb, providers.getForeignCalls(), node.getDescriptor(), graph.method());
338339
} else if (n instanceof UnaryMathIntrinsicNode) {
339340
UnaryMathIntrinsicNode node = (UnaryMathIntrinsicNode) n;
340-
registerForeignCall(bb, providers.getForeignCalls(), providers.getForeignCalls().getDescriptor(node.getOperation().foreignCallSignature));
341+
registerForeignCall(bb, providers.getForeignCalls(), providers.getForeignCalls().getDescriptor(node.getOperation().foreignCallSignature), graph.method());
341342
} else if (n instanceof BinaryMathIntrinsicNode) {
342343
BinaryMathIntrinsicNode node = (BinaryMathIntrinsicNode) n;
343-
registerForeignCall(bb, providers.getForeignCalls(), providers.getForeignCalls().getDescriptor(node.getOperation().foreignCallSignature));
344+
registerForeignCall(bb, providers.getForeignCalls(), providers.getForeignCalls().getDescriptor(node.getOperation().foreignCallSignature), graph.method());
344345
}
345346
}
346347
}
@@ -410,9 +411,9 @@ private static void registerEmbeddedRoot(PointsToAnalysis bb, ConstantNode cn) {
410411
}
411412
}
412413

413-
private static void registerForeignCall(PointsToAnalysis bb, ForeignCallsProvider foreignCallsProvider, ForeignCallDescriptor foreignCallDescriptor) {
414+
private static void registerForeignCall(PointsToAnalysis bb, ForeignCallsProvider foreignCallsProvider, ForeignCallDescriptor foreignCallDescriptor, ResolvedJavaMethod from) {
414415
Optional<AnalysisMethod> targetMethod = bb.getHostVM().handleForeignCall(foreignCallDescriptor, foreignCallsProvider);
415-
targetMethod.ifPresent(analysisMethod -> bb.addRootMethod(analysisMethod, true));
416+
targetMethod.ifPresent(analysisMethod -> bb.addRootMethod(analysisMethod, true, from));
416417
}
417418

418419
private boolean handleNodeIntrinsic() {

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisMethod.java

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
import java.util.Map;
3939
import java.util.Set;
4040
import java.util.concurrent.ConcurrentHashMap;
41-
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
4241
import java.util.concurrent.atomic.AtomicReference;
4342
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
4443
import java.util.concurrent.locks.ReentrantLock;
@@ -85,9 +84,11 @@
8584
import jdk.vm.ci.meta.SpeculationLog;
8685

8786
public abstract class AnalysisMethod extends AnalysisElement implements WrappedJavaMethod, GraphProvider, OriginalMethodProvider, MultiMethod {
88-
private static final AtomicIntegerFieldUpdater<AnalysisMethod> isVirtualRootMethodUpdater = AtomicIntegerFieldUpdater.newUpdater(AnalysisMethod.class, "isVirtualRootMethod");
87+
private static final AtomicReferenceFieldUpdater<AnalysisMethod, Object> isVirtualRootMethodUpdater = AtomicReferenceFieldUpdater
88+
.newUpdater(AnalysisMethod.class, Object.class, "isVirtualRootMethod");
8989

90-
private static final AtomicIntegerFieldUpdater<AnalysisMethod> isDirectRootMethodUpdater = AtomicIntegerFieldUpdater.newUpdater(AnalysisMethod.class, "isDirectRootMethod");
90+
private static final AtomicReferenceFieldUpdater<AnalysisMethod, Object> isDirectRootMethodUpdater = AtomicReferenceFieldUpdater
91+
.newUpdater(AnalysisMethod.class, Object.class, "isDirectRootMethod");
9192

9293
private static final AtomicReferenceFieldUpdater<AnalysisMethod, Object> isInvokedUpdater = AtomicReferenceFieldUpdater
9394
.newUpdater(AnalysisMethod.class, Object.class, "isInvoked");
@@ -136,9 +137,9 @@ public record Signature(String name, AnalysisType[] parameterTypes) {
136137
"multiMethodMap");
137138

138139
/** Virtually invoked method registered as root. */
139-
@SuppressWarnings("unused") private volatile int isVirtualRootMethod;
140+
@SuppressWarnings("unused") private volatile Object isVirtualRootMethod;
140141
/** Direct (special or static) invoked method registered as root. */
141-
@SuppressWarnings("unused") private volatile int isDirectRootMethod;
142+
@SuppressWarnings("unused") private volatile Object isDirectRootMethod;
142143
private Object entryPointData;
143144
@SuppressWarnings("unused") private volatile Object isInvoked;
144145
@SuppressWarnings("unused") private volatile Object isImplementationInvoked;
@@ -449,17 +450,17 @@ public Object getIntrinsicMethodReason() {
449450
* Class is always marked as reachable regardless of the success of the atomic mark, same reason
450451
* as in {@link AnalysisMethod#registerAsImplementationInvoked(Object)}.
451452
*/
452-
public boolean registerAsVirtualRootMethod() {
453+
public boolean registerAsVirtualRootMethod(Object reason) {
453454
getDeclaringClass().registerAsReachable("declared method " + qualifiedName + " is registered as virtual root");
454-
return AtomicUtils.atomicMark(this, isVirtualRootMethodUpdater);
455+
return AtomicUtils.atomicSet(this, reason, isVirtualRootMethodUpdater);
455456
}
456457

457458
/**
458459
* Registers this method as a direct (special or static) root for the analysis.
459460
*/
460-
public boolean registerAsDirectRootMethod() {
461+
public boolean registerAsDirectRootMethod(Object reason) {
461462
getDeclaringClass().registerAsReachable("declared method " + qualifiedName + " is registered as direct root");
462-
return AtomicUtils.atomicMark(this, isDirectRootMethodUpdater);
463+
return AtomicUtils.atomicSet(this, reason, isDirectRootMethodUpdater);
463464
}
464465

465466
/**
@@ -779,7 +780,7 @@ public LineNumberTable getLineNumberTable() {
779780
public String toString() {
780781
return "AnalysisMethod<" + format("%h.%n") + " -> " + wrapped.toString() + ", invoked: " + (isInvoked != null) +
781782
", implInvoked: " + (isImplementationInvoked != null) + ", intrinsic: " + (isIntrinsicMethod != null) + ", inlined: " + (isInlined != null) +
782-
(isVirtualRootMethod != 0 ? ", virtual root" : "") + (isDirectRootMethod != 0 ? ", direct root" : "") + (isEntryPoint() ? ", entry point" : "") + ">";
783+
(isVirtualRootMethod() ? ", virtual root" : "") + (isDirectRootMethod() ? ", direct root" : "") + (isEntryPoint() ? ", entry point" : "") + ">";
783784
}
784785

785786
@Override

substratevm/src/com.oracle.graal.reachability/src/com/oracle/graal/reachability/DirectMethodProcessingHandler.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -177,24 +177,24 @@ private static void analyzeStructuredGraph(ReachabilityAnalysisEngine bb, Reacha
177177
} else if (n instanceof ForeignCall) {
178178
MultiMethod.MultiMethodKey key = method == null ? MultiMethod.ORIGINAL_METHOD : method.getMultiMethodKey();
179179
ForeignCallsProvider foreignCallsProvider = bb.getProviders(key).getForeignCalls();
180-
handleForeignCall(bb, ((ForeignCall) n).getDescriptor(), foreignCallsProvider);
180+
handleForeignCall(bb, ((ForeignCall) n).getDescriptor(), foreignCallsProvider, graph.method());
181181
} else if (n instanceof UnaryMathIntrinsicNode) {
182182
ForeignCallSignature signature = ((UnaryMathIntrinsicNode) n).getOperation().foreignCallSignature;
183183
MultiMethod.MultiMethodKey key = method == null ? MultiMethod.ORIGINAL_METHOD : method.getMultiMethodKey();
184184
ForeignCallsProvider foreignCallsProvider = bb.getProviders(key).getForeignCalls();
185-
handleForeignCall(bb, foreignCallsProvider.getDescriptor(signature), foreignCallsProvider);
185+
handleForeignCall(bb, foreignCallsProvider.getDescriptor(signature), foreignCallsProvider, graph.method());
186186
} else if (n instanceof BinaryMathIntrinsicNode) {
187187
ForeignCallSignature signature = ((BinaryMathIntrinsicNode) n).getOperation().foreignCallSignature;
188188
MultiMethod.MultiMethodKey key = method == null ? MultiMethod.ORIGINAL_METHOD : method.getMultiMethodKey();
189189
ForeignCallsProvider foreignCallsProvider = bb.getProviders(key).getForeignCalls();
190-
handleForeignCall(bb, foreignCallsProvider.getDescriptor(signature), foreignCallsProvider);
190+
handleForeignCall(bb, foreignCallsProvider.getDescriptor(signature), foreignCallsProvider, graph.method());
191191

192192
}
193193
}
194194
}
195195

196-
private static void handleForeignCall(ReachabilityAnalysisEngine bb, ForeignCallDescriptor descriptor, ForeignCallsProvider foreignCallsProvider) {
196+
private static void handleForeignCall(ReachabilityAnalysisEngine bb, ForeignCallDescriptor descriptor, ForeignCallsProvider foreignCallsProvider, ResolvedJavaMethod from) {
197197
Optional<AnalysisMethod> targetMethod = bb.getHostVM().handleForeignCall(descriptor, foreignCallsProvider);
198-
targetMethod.ifPresent(method -> bb.addRootMethod(method, false));
198+
targetMethod.ifPresent(method -> bb.addRootMethod(method, false, from));
199199
}
200200
}

substratevm/src/com.oracle.graal.reachability/src/com/oracle/graal/reachability/MethodSummaryBasedHandler.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
/**
3838
* This handler analyzes methods using method summaries, which are obtained via an instance of
3939
* MethodSummaryProvider.
40-
*
40+
*
4141
* @see MethodSummaryProvider
4242
*/
4343
public class MethodSummaryBasedHandler implements ReachabilityMethodProcessingHandler {
@@ -102,7 +102,7 @@ private static void processSummary(ReachabilityAnalysisEngine bb, ReachabilityAn
102102
bb.handleEmbeddedConstant(method, constant, method);
103103
}
104104
for (AnalysisMethod rootMethod : summary.foreignCallTargets) {
105-
bb.addRootMethod(rootMethod, false);
105+
bb.addRootMethod(rootMethod, false, method);
106106
}
107107
}
108108
}

0 commit comments

Comments
 (0)