Skip to content

Commit

Permalink
[GR-45287] Add root reasons
Browse files Browse the repository at this point in the history
PullRequest: graal/14603
  • Loading branch information
liufengyun committed Aug 7, 2023
2 parents 49dfb0a + b55ac8c commit d6c8b01
Show file tree
Hide file tree
Showing 29 changed files with 117 additions and 110 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

package com.oracle.graal.pointsto.standalone;

import static org.graalvm.compiler.replacements.StandardGraphBuilderPlugins.registerInvocationPlugins;

import java.io.File;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
Expand All @@ -37,7 +39,6 @@
import java.util.List;
import java.util.concurrent.ForkJoinPool;

import com.oracle.graal.pointsto.standalone.heap.StandaloneHeapSnapshotVerifier;
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.Indent;
Expand All @@ -64,9 +65,10 @@
import com.oracle.graal.pointsto.meta.HostedProviders;
import com.oracle.graal.pointsto.meta.PointsToAnalysisFactory;
import com.oracle.graal.pointsto.phases.NoClassInitializationPlugin;
import com.oracle.graal.pointsto.reports.AnalysisReporter;
import com.oracle.graal.pointsto.standalone.features.StandaloneAnalysisFeatureImpl;
import com.oracle.graal.pointsto.standalone.features.StandaloneAnalysisFeatureManager;
import com.oracle.graal.pointsto.reports.AnalysisReporter;
import com.oracle.graal.pointsto.standalone.heap.StandaloneHeapSnapshotVerifier;
import com.oracle.graal.pointsto.standalone.heap.StandaloneImageHeapScanner;
import com.oracle.graal.pointsto.standalone.meta.StandaloneConstantFieldProvider;
import com.oracle.graal.pointsto.standalone.meta.StandaloneConstantReflectionProvider;
Expand All @@ -84,8 +86,6 @@
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.MetaAccessProvider;

import static org.graalvm.compiler.replacements.StandardGraphBuilderPlugins.registerInvocationPlugins;

public final class PointsToAnalyzer {

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

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

for (JavaKind kind : JavaKind.values()) {
if (kind.isPrimitive() && kind != JavaKind.Void) {
bigbang.addRootClass(kind.toJavaClass(), false, true);
bigbang.addRootField(kind.toBoxedJavaClass(), "value");
bigbang.addRootMethod(ReflectionUtil.lookupMethod(kind.toBoxedJavaClass(), "valueOf", kind.toJavaClass()), true);
bigbang.addRootMethod(ReflectionUtil.lookupMethod(kind.toBoxedJavaClass(), kind.getJavaName() + "Value"), true);
bigbang.addRootMethod(ReflectionUtil.lookupMethod(kind.toBoxedJavaClass(), "valueOf", kind.toJavaClass()), true, rootReason);
bigbang.addRootMethod(ReflectionUtil.lookupMethod(kind.toBoxedJavaClass(), kind.getJavaName() + "Value"), true, rootReason);
/*
* Register the cache location as reachable.
* BoxingSnippets$Templates#getCacheLocation accesses the cache field.
Expand Down Expand Up @@ -333,7 +334,7 @@ public void registerEntryMethods() {
Class<?> analysisMainClass = Class.forName(entryClass, false, analysisClassLoader);
Method main = analysisMainClass.getDeclaredMethod("main", String[].class);
// main method is static, whatever the invokeSpecial is it is ignored.
bigbang.addRootMethod(main, true);
bigbang.addRootMethod(main, true, "Single entry point, registered in " + PointsToAnalyzer.class);
} catch (ClassNotFoundException e) {
throw new RuntimeException("Can't find the specified analysis main class " + entryClass, e);
} catch (NoSuchMethodException e) {
Expand All @@ -351,7 +352,7 @@ public void registerEntryMethods() {
if (!t.isAbstract()) {
t.registerAsInHeap("Root class.");
}
bigbang.addRootMethod(m, isInvokeSpecial);
bigbang.addRootMethod(m, isInvokeSpecial, "Entry point from file, registered in " + PointsToAnalyzer.class);
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
import jdk.vm.ci.meta.ConstantReflectionProvider;

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

public StandalonePointsToAnalysis(OptionValues options, AnalysisUniverse universe, HostVM hostVM,
AnalysisMetaAccess metaAccess, SnippetReflectionProvider snippetReflectionProvider,
Expand Down Expand Up @@ -78,7 +78,7 @@ public void initializeMetaData(AnalysisType type) {
public void onTypeReachable(AnalysisType type) {
AnalysisMethod clinitMethod = type.getClassInitializer();
if (clinitMethod != null && !addedClinits.contains(clinitMethod)) {
addRootMethod(clinitMethod, true);
addRootMethod(clinitMethod, true, "Class initializer added onTypeReachable, in " + StandalonePointsToAnalysis.class);
addedClinits.add(clinitMethod);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,12 +240,12 @@ public void registerAsUnsafeAccessed(AnalysisField aField, UnsafePartitionKind p
}
}

public void registerAsInvoked(Executable method, boolean invokeSpecial) {
registerAsInvoked(getMetaAccess().lookupJavaMethod(method), invokeSpecial);
public void registerAsInvoked(Executable method, boolean invokeSpecial, Object reason) {
registerAsInvoked(getMetaAccess().lookupJavaMethod(method), invokeSpecial, reason);
}

public void registerAsInvoked(AnalysisMethod aMethod, boolean invokeSpecial) {
bb.addRootMethod(aMethod, invokeSpecial);
public void registerAsInvoked(AnalysisMethod aMethod, boolean invokeSpecial, Object reason) {
bb.addRootMethod(aMethod, invokeSpecial, reason);
}

public void registerUnsafeFieldsRecomputed(Class<?> clazz) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,13 +290,13 @@ public Iterable<AnalysisType> getAllSynchronizedTypes() {
}

@Override
public AnalysisMethod addRootMethod(Executable method, boolean invokeSpecial, MultiMethod.MultiMethodKey... otherRoots) {
return addRootMethod(metaAccess.lookupJavaMethod(method), invokeSpecial, otherRoots);
public AnalysisMethod addRootMethod(Executable method, boolean invokeSpecial, Object reason, MultiMethod.MultiMethodKey... otherRoots) {
return addRootMethod(metaAccess.lookupJavaMethod(method), invokeSpecial, reason, otherRoots);
}

@Override
@SuppressWarnings("try")
public AnalysisMethod addRootMethod(AnalysisMethod aMethod, boolean invokeSpecial, MultiMethod.MultiMethodKey... otherRoots) {
public AnalysisMethod addRootMethod(AnalysisMethod aMethod, boolean invokeSpecial, Object reason, MultiMethod.MultiMethodKey... otherRoots) {
assert !universe.sealed() : "Cannot register root methods after analysis universe is sealed.";
AnalysisError.guarantee(aMethod.isOriginalMethod());
AnalysisType declaringClass = aMethod.getDeclaringClass();
Expand All @@ -313,8 +313,8 @@ public AnalysisMethod addRootMethod(AnalysisMethod aMethod, boolean invokeSpecia
*/
Consumer<PointsToAnalysisMethod> triggerStaticMethodFlow = (pointsToMethod) -> {
postTask(() -> {
pointsToMethod.registerAsDirectRootMethod();
pointsToMethod.registerAsImplementationInvoked("static root method");
pointsToMethod.registerAsDirectRootMethod(reason);
pointsToMethod.registerAsImplementationInvoked(reason.toString());
MethodFlowsGraphInfo flowInfo = analysisPolicy.staticRootMethodGraph(this, pointsToMethod);
for (int idx = 0; idx < paramCount; idx++) {
AnalysisType declaredParamType = (AnalysisType) signature.getParameterType(idx, declaringClass);
Expand Down Expand Up @@ -359,9 +359,9 @@ public AnalysisMethod addRootMethod(AnalysisMethod aMethod, boolean invokeSpecia
*/
postTask(() -> {
if (invokeSpecial) {
originalPTAMethod.registerAsDirectRootMethod();
originalPTAMethod.registerAsDirectRootMethod(reason);
} else {
originalPTAMethod.registerAsVirtualRootMethod();
originalPTAMethod.registerAsVirtualRootMethod(reason);
}
InvokeTypeFlow invoke = originalPTAMethod.initAndGetContextInsensitiveInvoke(PointsToAnalysis.this, null, invokeSpecial, MultiMethod.ORIGINAL_METHOD);
/*
Expand Down Expand Up @@ -492,7 +492,7 @@ public void run(DebugContext ignored) {

@Override
public String toString() {
return "Operation: " + operation.toString();
return "Operation: " + operation;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,13 @@ public interface ReachabilityAnalysis {
* it is itself an override. If the method is static this flag is ignored.
* @param otherRoots other versions of this method to also register as roots.
*/
AnalysisMethod addRootMethod(AnalysisMethod aMethod, boolean invokeSpecial, MultiMethod.MultiMethodKey... otherRoots);
AnalysisMethod addRootMethod(AnalysisMethod aMethod, boolean invokeSpecial, Object reason, MultiMethod.MultiMethodKey... otherRoots);

/**
* @see ReachabilityAnalysis#addRootMethod(AnalysisMethod, boolean,
* @see ReachabilityAnalysis#addRootMethod(AnalysisMethod, boolean, Object,
* MultiMethod.MultiMethodKey...)
*/
AnalysisMethod addRootMethod(Executable method, boolean invokeSpecial, MultiMethod.MultiMethodKey... otherRoots);
AnalysisMethod addRootMethod(Executable method, boolean invokeSpecial, Object reason, MultiMethod.MultiMethodKey... otherRoots);

default void registerAsFrozenUnsafeAccessed(AnalysisField field) {
field.setUnsafeFrozenTypeState(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.VMConstant;

public class MethodTypeFlowBuilder {
Expand Down Expand Up @@ -334,13 +335,13 @@ protected static void registerUsedElements(PointsToAnalysis bb, StructuredGraph

} else if (n instanceof ForeignCall) {
ForeignCall node = (ForeignCall) n;
registerForeignCall(bb, providers.getForeignCalls(), node.getDescriptor());
registerForeignCall(bb, providers.getForeignCalls(), node.getDescriptor(), graph.method());
} else if (n instanceof UnaryMathIntrinsicNode) {
UnaryMathIntrinsicNode node = (UnaryMathIntrinsicNode) n;
registerForeignCall(bb, providers.getForeignCalls(), providers.getForeignCalls().getDescriptor(node.getOperation().foreignCallSignature));
registerForeignCall(bb, providers.getForeignCalls(), providers.getForeignCalls().getDescriptor(node.getOperation().foreignCallSignature), graph.method());
} else if (n instanceof BinaryMathIntrinsicNode) {
BinaryMathIntrinsicNode node = (BinaryMathIntrinsicNode) n;
registerForeignCall(bb, providers.getForeignCalls(), providers.getForeignCalls().getDescriptor(node.getOperation().foreignCallSignature));
registerForeignCall(bb, providers.getForeignCalls(), providers.getForeignCalls().getDescriptor(node.getOperation().foreignCallSignature), graph.method());
}
}
}
Expand Down Expand Up @@ -410,9 +411,9 @@ private static void registerEmbeddedRoot(PointsToAnalysis bb, ConstantNode cn) {
}
}

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

private boolean handleNodeIntrinsic() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import java.util.concurrent.locks.ReentrantLock;
Expand Down Expand Up @@ -85,9 +84,11 @@
import jdk.vm.ci.meta.SpeculationLog;

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

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

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

/** Virtually invoked method registered as root. */
@SuppressWarnings("unused") private volatile int isVirtualRootMethod;
@SuppressWarnings("unused") private volatile Object isVirtualRootMethod;
/** Direct (special or static) invoked method registered as root. */
@SuppressWarnings("unused") private volatile int isDirectRootMethod;
@SuppressWarnings("unused") private volatile Object isDirectRootMethod;
private Object entryPointData;
@SuppressWarnings("unused") private volatile Object isInvoked;
@SuppressWarnings("unused") private volatile Object isImplementationInvoked;
Expand Down Expand Up @@ -449,17 +450,17 @@ public Object getIntrinsicMethodReason() {
* Class is always marked as reachable regardless of the success of the atomic mark, same reason
* as in {@link AnalysisMethod#registerAsImplementationInvoked(Object)}.
*/
public boolean registerAsVirtualRootMethod() {
public boolean registerAsVirtualRootMethod(Object reason) {
getDeclaringClass().registerAsReachable("declared method " + qualifiedName + " is registered as virtual root");
return AtomicUtils.atomicMark(this, isVirtualRootMethodUpdater);
return AtomicUtils.atomicSet(this, reason, isVirtualRootMethodUpdater);
}

/**
* Registers this method as a direct (special or static) root for the analysis.
*/
public boolean registerAsDirectRootMethod() {
public boolean registerAsDirectRootMethod(Object reason) {
getDeclaringClass().registerAsReachable("declared method " + qualifiedName + " is registered as direct root");
return AtomicUtils.atomicMark(this, isDirectRootMethodUpdater);
return AtomicUtils.atomicSet(this, reason, isDirectRootMethodUpdater);
}

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

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,24 +177,24 @@ private static void analyzeStructuredGraph(ReachabilityAnalysisEngine bb, Reacha
} else if (n instanceof ForeignCall) {
MultiMethod.MultiMethodKey key = method == null ? MultiMethod.ORIGINAL_METHOD : method.getMultiMethodKey();
ForeignCallsProvider foreignCallsProvider = bb.getProviders(key).getForeignCalls();
handleForeignCall(bb, ((ForeignCall) n).getDescriptor(), foreignCallsProvider);
handleForeignCall(bb, ((ForeignCall) n).getDescriptor(), foreignCallsProvider, graph.method());
} else if (n instanceof UnaryMathIntrinsicNode) {
ForeignCallSignature signature = ((UnaryMathIntrinsicNode) n).getOperation().foreignCallSignature;
MultiMethod.MultiMethodKey key = method == null ? MultiMethod.ORIGINAL_METHOD : method.getMultiMethodKey();
ForeignCallsProvider foreignCallsProvider = bb.getProviders(key).getForeignCalls();
handleForeignCall(bb, foreignCallsProvider.getDescriptor(signature), foreignCallsProvider);
handleForeignCall(bb, foreignCallsProvider.getDescriptor(signature), foreignCallsProvider, graph.method());
} else if (n instanceof BinaryMathIntrinsicNode) {
ForeignCallSignature signature = ((BinaryMathIntrinsicNode) n).getOperation().foreignCallSignature;
MultiMethod.MultiMethodKey key = method == null ? MultiMethod.ORIGINAL_METHOD : method.getMultiMethodKey();
ForeignCallsProvider foreignCallsProvider = bb.getProviders(key).getForeignCalls();
handleForeignCall(bb, foreignCallsProvider.getDescriptor(signature), foreignCallsProvider);
handleForeignCall(bb, foreignCallsProvider.getDescriptor(signature), foreignCallsProvider, graph.method());

}
}
}

private static void handleForeignCall(ReachabilityAnalysisEngine bb, ForeignCallDescriptor descriptor, ForeignCallsProvider foreignCallsProvider) {
private static void handleForeignCall(ReachabilityAnalysisEngine bb, ForeignCallDescriptor descriptor, ForeignCallsProvider foreignCallsProvider, ResolvedJavaMethod from) {
Optional<AnalysisMethod> targetMethod = bb.getHostVM().handleForeignCall(descriptor, foreignCallsProvider);
targetMethod.ifPresent(method -> bb.addRootMethod(method, false));
targetMethod.ifPresent(method -> bb.addRootMethod(method, false, from));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
/**
* This handler analyzes methods using method summaries, which are obtained via an instance of
* MethodSummaryProvider.
*
*
* @see MethodSummaryProvider
*/
public class MethodSummaryBasedHandler implements ReachabilityMethodProcessingHandler {
Expand Down Expand Up @@ -102,7 +102,7 @@ private static void processSummary(ReachabilityAnalysisEngine bb, ReachabilityAn
bb.handleEmbeddedConstant(method, constant, method);
}
for (AnalysisMethod rootMethod : summary.foreignCallTargets) {
bb.addRootMethod(rootMethod, false);
bb.addRootMethod(rootMethod, false, method);
}
}
}
Loading

0 comments on commit d6c8b01

Please sign in to comment.