From 2a6c26ad7076930c4c5945be57df8ab25de09d88 Mon Sep 17 00:00:00 2001 From: Codrut Stancu Date: Mon, 14 Nov 2022 23:58:08 +0100 Subject: [PATCH] Add reason for analysis type instantiation. --- .../pointsto/standalone/PointsToAnalyzer.java | 58 ++++++++++--------- .../StandaloneAnalysisFeatureImpl.java | 31 +++++----- .../AnalysisObjectScanningObserver.java | 2 +- .../oracle/graal/pointsto/ObjectScanner.java | 2 +- .../graal/pointsto/ReachabilityAnalysis.java | 10 ++-- .../pointsto/flow/MethodTypeFlowBuilder.java | 12 ++-- .../graal/pointsto/heap/ImageHeapScanner.java | 18 +++--- .../graal/pointsto/meta/AnalysisType.java | 35 ++++++----- .../graal/pointsto/util/AtomicUtils.java | 2 + .../DirectMethodProcessingHandler.java | 20 +++---- .../MethodSummaryBasedHandler.java | 12 ++-- .../ReachabilityAnalysisEngine.java | 21 +++---- .../ReachabilityObjectScanner.java | 20 +++---- .../hotspot/libgraal/LibGraalFeature.java | 2 +- .../hosted/RuntimeCompilationFeature.java | 4 +- .../com/oracle/svm/hosted/FeatureImpl.java | 12 ++-- .../svm/hosted/NativeImageGenerator.java | 22 +++---- .../analysis/CustomTypeFieldHandler.java | 2 +- ...NativeImageReachabilityAnalysisEngine.java | 2 +- .../annotation/AnnotationTypeFeature.java | 4 +- .../oracle/svm/hosted/heap/PodSupport.java | 5 +- .../svm/hosted/heap/SVMImageHeapScanner.java | 4 +- .../image/ImageHeapFillerObjectsFeature.java | 6 +- .../svm/hosted/jni/JNIAccessFeature.java | 4 +- .../hosted/reflect/ReflectionDataBuilder.java | 4 +- .../SubstrateGraphBuilderPlugins.java | 3 +- .../polyglot/scala/ScalaAnalysisPlugin.java | 2 +- .../svm/truffle/TruffleBaseFeature.java | 5 +- .../oracle/svm/truffle/TruffleFeature.java | 2 +- 29 files changed, 175 insertions(+), 151 deletions(-) diff --git a/substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/PointsToAnalyzer.java b/substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/PointsToAnalyzer.java index 5c4a9cd988db..d6abda6bdad7 100644 --- a/substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/PointsToAnalyzer.java +++ b/substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/PointsToAnalyzer.java @@ -26,6 +26,27 @@ package com.oracle.graal.pointsto.standalone; +import java.io.File; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ForkJoinPool; + +import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; +import org.graalvm.compiler.debug.DebugContext; +import org.graalvm.compiler.debug.Indent; +import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration; +import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins; +import org.graalvm.compiler.options.OptionValues; +import org.graalvm.compiler.phases.util.Providers; +import org.graalvm.compiler.printer.GraalDebugHandlersFactory; +import org.graalvm.compiler.serviceprovider.JavaVersionUtil; +import org.graalvm.compiler.word.WordTypes; +import org.graalvm.nativeimage.hosted.Feature; + import com.oracle.graal.pointsto.AnalysisObjectScanningObserver; import com.oracle.graal.pointsto.AnalysisPolicy; import com.oracle.graal.pointsto.PointsToAnalysis; @@ -53,30 +74,11 @@ import com.oracle.graal.pointsto.util.TimerCollection; import com.oracle.svm.util.ModuleSupport; import com.oracle.svm.util.ReflectionUtil; + import jdk.vm.ci.amd64.AMD64Kind; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.MetaAccessProvider; -import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; -import org.graalvm.compiler.debug.DebugContext; -import org.graalvm.compiler.debug.Indent; -import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration; -import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins; -import org.graalvm.compiler.options.OptionValues; -import org.graalvm.compiler.phases.util.Providers; -import org.graalvm.compiler.printer.GraalDebugHandlersFactory; -import org.graalvm.compiler.serviceprovider.JavaVersionUtil; -import org.graalvm.compiler.word.WordTypes; -import org.graalvm.nativeimage.hosted.Feature; - -import java.io.File; -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ForkJoinPool; public final class PointsToAnalyzer { @@ -169,14 +171,14 @@ private PointsToAnalyzer(String mainEntryClass, OptionValues options) { * good example. */ try (Indent ignored = debugContext.logAndIndent("add initial classes/fields/methods")) { - bigbang.addRootClass(Object.class, false, false).registerAsInHeap(); - bigbang.addRootClass(String.class, false, false).registerAsInHeap(); - bigbang.addRootClass(String[].class, false, false).registerAsInHeap(); - bigbang.addRootField(String.class, "value").registerAsInHeap(); - bigbang.addRootClass(long[].class, false, false).registerAsInHeap(); - bigbang.addRootClass(byte[].class, false, false).registerAsInHeap(); - bigbang.addRootClass(byte[][].class, false, false).registerAsInHeap(); - bigbang.addRootClass(Object[].class, false, false).registerAsInHeap(); + bigbang.addRootClass(Object.class, false, false).registerAsInHeap("Root class."); + bigbang.addRootClass(String.class, false, false).registerAsInHeap("Root class."); + bigbang.addRootClass(String[].class, false, false).registerAsInHeap("Root class."); + bigbang.addRootField(String.class, "value").registerAsInHeap("Root class."); + bigbang.addRootClass(long[].class, false, false).registerAsInHeap("Root class."); + bigbang.addRootClass(byte[].class, false, false).registerAsInHeap("Root class."); + 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); diff --git a/substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/features/StandaloneAnalysisFeatureImpl.java b/substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/features/StandaloneAnalysisFeatureImpl.java index 18222e26f35d..df8ca9ed8db5 100644 --- a/substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/features/StandaloneAnalysisFeatureImpl.java +++ b/substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/features/StandaloneAnalysisFeatureImpl.java @@ -26,18 +26,6 @@ package com.oracle.graal.pointsto.standalone.features; -import com.oracle.graal.pointsto.BigBang; -import com.oracle.graal.pointsto.meta.AnalysisField; -import com.oracle.graal.pointsto.meta.AnalysisMetaAccess; -import com.oracle.graal.pointsto.meta.AnalysisMethod; -import com.oracle.graal.pointsto.meta.AnalysisType; -import com.oracle.graal.pointsto.meta.AnalysisUniverse; -import com.oracle.graal.pointsto.standalone.StandaloneHost; -import com.oracle.svm.util.UnsafePartitionKind; -import org.graalvm.compiler.debug.DebugContext; -import org.graalvm.nativeimage.hosted.Feature; -import org.graalvm.nativeimage.hosted.FieldValueTransformer; - import java.lang.reflect.Executable; import java.lang.reflect.Field; import java.nio.file.Path; @@ -50,6 +38,19 @@ import java.util.function.Consumer; import java.util.stream.Collectors; +import org.graalvm.compiler.debug.DebugContext; +import org.graalvm.nativeimage.hosted.Feature; +import org.graalvm.nativeimage.hosted.FieldValueTransformer; + +import com.oracle.graal.pointsto.BigBang; +import com.oracle.graal.pointsto.meta.AnalysisField; +import com.oracle.graal.pointsto.meta.AnalysisMetaAccess; +import com.oracle.graal.pointsto.meta.AnalysisMethod; +import com.oracle.graal.pointsto.meta.AnalysisType; +import com.oracle.graal.pointsto.meta.AnalysisUniverse; +import com.oracle.graal.pointsto.standalone.StandaloneHost; +import com.oracle.svm.util.UnsafePartitionKind; + public class StandaloneAnalysisFeatureImpl { public abstract static class FeatureAccessImpl implements Feature.FeatureAccess { @@ -175,11 +176,11 @@ public void registerAsUsed(AnalysisType aType) { @Override public void registerAsInHeap(Class clazz) { - registerAsInHeap(getMetaAccess().lookupJavaType(clazz)); + registerAsInHeap(getMetaAccess().lookupJavaType(clazz), "Registered from Feature API."); } - public void registerAsInHeap(AnalysisType aType) { - aType.registerAsInHeap(); + public void registerAsInHeap(AnalysisType aType, Object reason) { + aType.registerAsInHeap(reason); } @Override diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/AnalysisObjectScanningObserver.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/AnalysisObjectScanningObserver.java index 8f99b7a737df..a8d6366221ad 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/AnalysisObjectScanningObserver.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/AnalysisObjectScanningObserver.java @@ -124,7 +124,7 @@ public void forScannedConstant(JavaConstant value, ScanReason reason) { Object valueObj = analysis.getSnippetReflectionProvider().asObject(Object.class, value); AnalysisType type = bb.getMetaAccess().lookupJavaType(valueObj.getClass()); - type.registerAsInHeap(); + type.registerAsInHeap(reason); } private PointsToAnalysis getAnalysis() { diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/ObjectScanner.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/ObjectScanner.java index 10e3e45083fe..765b1a3ff20e 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/ObjectScanner.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/ObjectScanner.java @@ -247,7 +247,7 @@ public final void scanConstant(JavaConstant value, ScanReason reason) { return; } if (!bb.scanningPolicy().scanConstant(bb, value)) { - bb.markTypeInHeap(bb.getMetaAccess().lookupJavaType(value)); + bb.registerTypeAsInHeap(bb.getMetaAccess().lookupJavaType(value), reason); return; } Object valueObj = (value instanceof ImageHeapConstant) ? value : constantAsObject(bb, value); diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/ReachabilityAnalysis.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/ReachabilityAnalysis.java index 9d7a061b4e73..045020d2d8f1 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/ReachabilityAnalysis.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/ReachabilityAnalysis.java @@ -93,16 +93,16 @@ default boolean registerAsUnsafeAccessed(AnalysisField field, UnsafePartitionKin return false; } - default boolean markTypeReachable(AnalysisType type) { + default boolean markTypeAsReachable(AnalysisType type) { return type.registerAsReachable(); } - default boolean markTypeInstantiated(AnalysisType type) { - return type.registerAsAllocated(null); + default boolean registerTypeAsAllocated(AnalysisType type, Object reason) { + return type.registerAsAllocated(reason); } - default boolean markTypeInHeap(AnalysisType type) { - return type.registerAsInHeap(); + default boolean registerTypeAsInHeap(AnalysisType type, Object reason) { + return type.registerAsInHeap(reason); } default void markFieldAccessed(AnalysisField field) { diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java index 25bdd2c1930a..83818ea22852 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java @@ -237,12 +237,12 @@ public void registerUsedElements(boolean registerEmbeddedRoots) { } else if (n instanceof NewInstanceNode) { NewInstanceNode node = (NewInstanceNode) n; AnalysisType type = (AnalysisType) node.instanceClass(); - type.registerAsAllocated(node); + type.registerAsAllocated(AbstractAnalysisEngine.sourcePosition(node)); } else if (n instanceof VirtualObjectNode) { VirtualObjectNode node = (VirtualObjectNode) n; AnalysisType type = (AnalysisType) node.type(); - type.registerAsAllocated(node); + type.registerAsAllocated(AbstractAnalysisEngine.sourcePosition(node)); } else if (n instanceof CommitAllocationNode) { CommitAllocationNode node = (CommitAllocationNode) n; @@ -265,20 +265,20 @@ public void registerUsedElements(boolean registerEmbeddedRoots) { } else if (n instanceof NewArrayNode) { NewArrayNode node = (NewArrayNode) n; AnalysisType type = ((AnalysisType) node.elementType()).getArrayClass(); - type.registerAsAllocated(node); + type.registerAsAllocated(AbstractAnalysisEngine.sourcePosition(node)); } else if (n instanceof NewMultiArrayNode) { NewMultiArrayNode node = (NewMultiArrayNode) n; AnalysisType type = ((AnalysisType) node.type()); for (int i = 0; i < node.dimensionCount(); i++) { - type.registerAsAllocated(node); + type.registerAsAllocated(AbstractAnalysisEngine.sourcePosition(node)); type = type.getComponentType(); } } else if (n instanceof BoxNode) { BoxNode node = (BoxNode) n; AnalysisType type = (AnalysisType) StampTool.typeOrNull(node); - type.registerAsAllocated(node); + type.registerAsAllocated(AbstractAnalysisEngine.sourcePosition(node)); } else if (n instanceof LoadFieldNode) { LoadFieldNode node = (LoadFieldNode) n; @@ -295,7 +295,7 @@ public void registerUsedElements(boolean registerEmbeddedRoots) { if (cn.hasUsages() && cn.isJavaConstant() && cn.asJavaConstant().getJavaKind() == JavaKind.Object && cn.asJavaConstant().isNonNull()) { assert StampTool.isExactType(cn); AnalysisType type = (AnalysisType) StampTool.typeOrNull(cn); - type.registerAsInHeap(); + type.registerAsInHeap(AbstractAnalysisEngine.sourcePosition(cn)); if (registerEmbeddedRoots && !ignoreConstant(cn)) { registerEmbeddedRoot(cn); } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapScanner.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapScanner.java index cc9e5fd727d6..f4233f649873 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapScanner.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapScanner.java @@ -167,11 +167,11 @@ public TypeData computeTypeData(AnalysisType type) { return data; } - void markTypeInstantiated(AnalysisType type) { + void markTypeInstantiated(AnalysisType type, ScanReason reason) { if (universe.sealed() && !type.isReachable()) { throw AnalysisError.shouldNotReachHere("Universe is sealed. New type reachable: " + type.toJavaName()); } - universe.getBigbang().markTypeInHeap(type); + universe.getBigbang().registerTypeAsInHeap(type, reason); } JavaConstant markConstantReachable(JavaConstant constant, ScanReason reason, Consumer onAnalysisModified) { @@ -249,11 +249,11 @@ protected void scanImageHeapObject(ImageHeapConstant object, ScanReason reason, onArrayElementReachable(array, type, elementValue, idx, arrayReason, onAnalysisModified); } } - markTypeInstantiated(type); + markTypeInstantiated(type, reason); } else { ImageHeapInstance instance = (ImageHeapInstance) object; /* We are about to query the type's fields, the type must be marked as reachable. */ - markTypeInstantiated(type); + markTypeInstantiated(type, reason); for (AnalysisField field : type.getInstanceFields(true)) { if (field.isRead() && isValueAvailable(field)) { final JavaConstant fieldValue = instance.readFieldValue(field); @@ -351,7 +351,7 @@ protected ImageHeapConstant createImageHeapObject(JavaConstant constant, ScanRea array.setElement(idx, arrayElement); } } - markTypeInstantiated(type); + markTypeInstantiated(type, reason); } else { /* * We need to have the new ImageHeapInstance early so that we can reference it in the @@ -359,7 +359,7 @@ protected ImageHeapConstant createImageHeapObject(JavaConstant constant, ScanRea * thread before all instanceFieldValues are filled in. */ /* We are about to query the type's fields, the type must be marked as reachable. */ - markTypeInstantiated(type); + markTypeInstantiated(type, reason); AnalysisField[] instanceFields = type.getInstanceFields(true); newImageHeapConstant = new ImageHeapInstance(type, constant, instanceFields.length); for (AnalysisField field : instanceFields) { @@ -383,7 +383,7 @@ protected ImageHeapConstant createImageHeapObject(JavaConstant constant, ScanRea /* * Following all the array elements and reachable field values can be done asynchronously. */ - postTask(() -> onObjectReachable(newImageHeapConstant)); + postTask(() -> onObjectReachable(newImageHeapConstant, reason)); return newImageHeapConstant; } @@ -510,11 +510,11 @@ private boolean notifyAnalysis(JavaConstant array, AnalysisType arrayType, JavaC return analysisModified; } - protected void onObjectReachable(ImageHeapConstant imageHeapConstant) { + protected void onObjectReachable(ImageHeapConstant imageHeapConstant, ScanReason reason) { AnalysisType objectType = metaAccess.lookupJavaType(imageHeapConstant); imageHeap.add(objectType, imageHeapConstant); - markTypeInstantiated(objectType); + markTypeInstantiated(objectType, reason); if (imageHeapConstant instanceof ImageHeapInstance) { ImageHeapInstance imageHeapInstance = (ImageHeapInstance) imageHeapConstant; diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisType.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisType.java index 0374dbd17924..9a5c51ebac27 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisType.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisType.java @@ -42,7 +42,6 @@ import java.util.function.Function; import org.graalvm.compiler.debug.GraalError; -import org.graalvm.compiler.graph.Node; import org.graalvm.nativeimage.hosted.Feature.DuringAnalysisAccess; import org.graalvm.word.WordBase; @@ -64,6 +63,7 @@ import com.oracle.graal.pointsto.util.ConcurrentLightHashSet; import com.oracle.svm.util.UnsafePartitionKind; +import jdk.vm.ci.code.BytecodePosition; import jdk.vm.ci.meta.Assumptions.AssumptionResult; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaKind; @@ -95,11 +95,11 @@ public abstract class AnalysisType extends AnalysisElement implements WrappedJav private static final AtomicReferenceFieldUpdater instantiatedNotificationsUpdater = AtomicReferenceFieldUpdater .newUpdater(AnalysisType.class, Object.class, "typeInstantiatedNotifications"); - private static final AtomicIntegerFieldUpdater isInHeapUpdater = AtomicIntegerFieldUpdater - .newUpdater(AnalysisType.class, "isInHeap"); + private static final AtomicReferenceFieldUpdater isAllocatedUpdater = AtomicReferenceFieldUpdater + .newUpdater(AnalysisType.class, Object.class, "isAllocated"); - private static final AtomicIntegerFieldUpdater isAllocatedUpdater = AtomicIntegerFieldUpdater - .newUpdater(AnalysisType.class, "isAllocated"); + private static final AtomicReferenceFieldUpdater isInHeapUpdater = AtomicReferenceFieldUpdater + .newUpdater(AnalysisType.class, Object.class, "isInHeap"); private static final AtomicIntegerFieldUpdater isReachableUpdater = AtomicIntegerFieldUpdater .newUpdater(AnalysisType.class, "isReachable"); @@ -110,8 +110,8 @@ public abstract class AnalysisType extends AnalysisElement implements WrappedJav protected final AnalysisUniverse universe; private final ResolvedJavaType wrapped; - @SuppressWarnings("unused") private volatile int isInHeap; - @SuppressWarnings("unused") private volatile int isAllocated; + @SuppressWarnings("unused") private volatile Object isInHeap; + @SuppressWarnings("unused") private volatile Object isAllocated; @SuppressWarnings("unused") private volatile int isReachable; @SuppressWarnings("unused") private volatile int isAnySubtypeInstantiated; private boolean reachabilityListenerNotified; @@ -455,9 +455,15 @@ public static boolean verifyAssignableTypes(BigBang bb) { return true; } - public boolean registerAsInHeap() { + /** + * @param reason the {@link BytecodePosition} where this type is marked as in-heap, or a + * {@link com.oracle.graal.pointsto.ObjectScanner.ScanReason}, or a {@link String} + * describing why this type was manually marked as in-heap + */ + public boolean registerAsInHeap(Object reason) { + assert reason != null && (!(reason instanceof String) || !reason.equals("")) : "Registering a type as in-heap needs to provide a non-empty reason."; registerAsReachable(); - if (AtomicUtils.atomicMark(this, isInHeapUpdater)) { + if (AtomicUtils.atomicSet(this, reason, isInHeapUpdater)) { onInstantiated(UsageKind.InHeap); return true; } @@ -465,11 +471,14 @@ public boolean registerAsInHeap() { } /** - * @param node For future use and debugging + * @param reason the {@link BytecodePosition} where this type is marked as allocated, or a + * {@link com.oracle.graal.pointsto.ObjectScanner.ScanReason}, or a {@link String} + * describing why this type was manually marked as allocated */ - public boolean registerAsAllocated(Node node) { + public boolean registerAsAllocated(Object reason) { + assert reason != null && (!(reason instanceof String) || !reason.equals("")) : "Registering a type as allocated needs to provide a non-empty reason."; registerAsReachable(); - if (AtomicUtils.atomicMark(this, isAllocatedUpdater)) { + if (AtomicUtils.atomicSet(this, reason, isAllocatedUpdater)) { onInstantiated(UsageKind.Allocated); return true; } @@ -551,7 +560,7 @@ protected void onReachable() { * types as instantiated too allows more usages of Arrays.newInstance without the need * of explicit registration of types for reflection. */ - registerAsAllocated(null); + registerAsAllocated("All array types are marked as instantiated eagerly."); } ensureInitialized(); } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/util/AtomicUtils.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/util/AtomicUtils.java index adcfa684d735..0aaf489dd86b 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/util/AtomicUtils.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/util/AtomicUtils.java @@ -24,6 +24,7 @@ */ package com.oracle.graal.pointsto.util; +import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; import java.util.concurrent.atomic.AtomicReference; @@ -34,6 +35,7 @@ public class AtomicUtils { public static boolean atomicSet(T holder, V value, AtomicReferenceFieldUpdater updater) { + Objects.requireNonNull(value, "The value parameter of AtomicUtils.atomicSet() should not be null."); return updater.compareAndSet(holder, null, value); } diff --git a/substratevm/src/com.oracle.graal.reachability/src/com/oracle/graal/reachability/DirectMethodProcessingHandler.java b/substratevm/src/com.oracle.graal.reachability/src/com/oracle/graal/reachability/DirectMethodProcessingHandler.java index 84c1906c9f1b..b24c5ab2c3fc 100644 --- a/substratevm/src/com.oracle.graal.reachability/src/com/oracle/graal/reachability/DirectMethodProcessingHandler.java +++ b/substratevm/src/com.oracle.graal.reachability/src/com/oracle/graal/reachability/DirectMethodProcessingHandler.java @@ -79,32 +79,32 @@ private static void analyzeStructuredGraph(ReachabilityAnalysisEngine bb, Reacha int parameterCount = method.getSignature().getParameterCount(!isStatic); int offset = isStatic ? 0 : 1; for (int i = offset; i < parameterCount; i++) { - bb.markTypeReachable((ReachabilityAnalysisType) method.getSignature().getParameterType(i - offset, method.getDeclaringClass())); + bb.markTypeAsReachable((ReachabilityAnalysisType) method.getSignature().getParameterType(i - offset, method.getDeclaringClass())); } - bb.markTypeReachable((ReachabilityAnalysisType) method.getSignature().getReturnType(method.getDeclaringClass())); + bb.markTypeAsReachable((ReachabilityAnalysisType) method.getSignature().getReturnType(method.getDeclaringClass())); } for (Node n : graph.getNodes()) { if (n instanceof NewInstanceNode) { NewInstanceNode node = (NewInstanceNode) n; - bb.markTypeInstantiated((ReachabilityAnalysisType) node.instanceClass()); + bb.registerTypeAsAllocated((ReachabilityAnalysisType) node.instanceClass(), AbstractAnalysisEngine.sourcePosition(node)); } else if (n instanceof NewArrayNode) { NewArrayNode node = (NewArrayNode) n; - bb.markTypeInstantiated(((ReachabilityAnalysisType) node.elementType()).getArrayClass()); + bb.registerTypeAsAllocated(((ReachabilityAnalysisType) node.elementType()).getArrayClass(), AbstractAnalysisEngine.sourcePosition(node)); } else if (n instanceof NewMultiArrayNode) { NewMultiArrayNode node = (NewMultiArrayNode) n; ResolvedJavaType type = node.type(); for (int i = 0; i < node.dimensionCount(); i++) { - bb.markTypeInstantiated((ReachabilityAnalysisType) type); + bb.registerTypeAsAllocated((ReachabilityAnalysisType) type, AbstractAnalysisEngine.sourcePosition(node)); type = type.getComponentType(); } } else if (n instanceof VirtualInstanceNode) { VirtualInstanceNode node = (VirtualInstanceNode) n; - bb.markTypeInstantiated((ReachabilityAnalysisType) node.type()); + bb.registerTypeAsAllocated((ReachabilityAnalysisType) node.type(), AbstractAnalysisEngine.sourcePosition(node)); } else if (n instanceof VirtualArrayNode) { VirtualArrayNode node = (VirtualArrayNode) n; - bb.markTypeInstantiated(((ReachabilityAnalysisType) node.componentType()).getArrayClass()); + bb.registerTypeAsAllocated(((ReachabilityAnalysisType) node.componentType()).getArrayClass(), AbstractAnalysisEngine.sourcePosition(node)); } else if (n instanceof ConstantNode) { ConstantNode node = (ConstantNode) n; if (!(node.getValue() instanceof JavaConstant)) { @@ -117,10 +117,10 @@ private static void analyzeStructuredGraph(ReachabilityAnalysisEngine bb, Reacha continue; } JavaConstant constant = (JavaConstant) node.getValue(); - bb.handleEmbeddedConstant(method, constant); + bb.handleEmbeddedConstant(method, constant, AbstractAnalysisEngine.sourcePosition(node)); } else if (n instanceof InstanceOfNode) { InstanceOfNode node = (InstanceOfNode) n; - bb.markTypeReachable((ReachabilityAnalysisType) node.type().getType()); + bb.markTypeAsReachable((ReachabilityAnalysisType) node.type().getType()); } else if (n instanceof LoadFieldNode) { LoadFieldNode node = (LoadFieldNode) n; bb.markFieldRead((ReachabilityAnalysisField) node.field(), AbstractAnalysisEngine.sourcePosition(node)); @@ -153,7 +153,7 @@ private static void analyzeStructuredGraph(ReachabilityAnalysisEngine bb, Reacha * scanning during static analysis does not see these classes. */ ReachabilityAnalysisMethod analysisMethod = (ReachabilityAnalysisMethod) frameMethod; - bb.markTypeReachable(analysisMethod.getDeclaringClass()); + bb.markTypeAsReachable(analysisMethod.getDeclaringClass()); } } else if (n instanceof MacroInvokable) { MacroInvokable node = (MacroInvokable) n; diff --git a/substratevm/src/com.oracle.graal.reachability/src/com/oracle/graal/reachability/MethodSummaryBasedHandler.java b/substratevm/src/com.oracle.graal.reachability/src/com/oracle/graal/reachability/MethodSummaryBasedHandler.java index 0057f23bcf91..cf195d98c630 100644 --- a/substratevm/src/com.oracle.graal.reachability/src/com/oracle/graal/reachability/MethodSummaryBasedHandler.java +++ b/substratevm/src/com.oracle.graal.reachability/src/com/oracle/graal/reachability/MethodSummaryBasedHandler.java @@ -24,13 +24,15 @@ */ package com.oracle.graal.reachability; +import org.graalvm.compiler.nodes.StructuredGraph; + import com.oracle.graal.pointsto.meta.AnalysisField; import com.oracle.graal.pointsto.meta.AnalysisMethod; import com.oracle.graal.pointsto.meta.AnalysisType; import com.oracle.graal.pointsto.util.Timer; import com.oracle.graal.pointsto.util.TimerCollection; + import jdk.vm.ci.meta.JavaConstant; -import org.graalvm.compiler.nodes.StructuredGraph; /** * This handler analyzes methods using method summaries, which are obtained via an instance of @@ -81,20 +83,20 @@ private static void processSummary(ReachabilityAnalysisEngine bb, ReachabilityAn bb.markMethodImplementationInvoked((ReachabilityAnalysisMethod) invokedMethod); } for (AnalysisType type : summary.accessedTypes) { - bb.markTypeReachable(type); + bb.markTypeAsReachable(type); } for (AnalysisType type : summary.instantiatedTypes) { - bb.markTypeInstantiated(type); + bb.registerTypeAsAllocated(type, method); } for (AnalysisField field : summary.readFields) { bb.markFieldRead(field, method); - bb.markTypeReachable(field.getType()); + bb.markTypeAsReachable(field.getType()); } for (AnalysisField field : summary.writtenFields) { bb.markFieldWritten(field); } for (JavaConstant constant : summary.embeddedConstants) { - bb.handleEmbeddedConstant(method, constant); + bb.handleEmbeddedConstant(method, constant, method); } for (AnalysisMethod rootMethod : summary.foreignCallTargets) { bb.addRootMethod(rootMethod, false); diff --git a/substratevm/src/com.oracle.graal.reachability/src/com/oracle/graal/reachability/ReachabilityAnalysisEngine.java b/substratevm/src/com.oracle.graal.reachability/src/com/oracle/graal/reachability/ReachabilityAnalysisEngine.java index 7c212b0f099a..f5ed8928c1c3 100644 --- a/substratevm/src/com.oracle.graal.reachability/src/com/oracle/graal/reachability/ReachabilityAnalysisEngine.java +++ b/substratevm/src/com.oracle.graal.reachability/src/com/oracle/graal/reachability/ReachabilityAnalysisEngine.java @@ -32,9 +32,6 @@ import java.util.Set; import java.util.concurrent.ForkJoinPool; -import jdk.vm.ci.code.BytecodePosition; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaKind; import org.graalvm.compiler.debug.Indent; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.options.OptionValues; @@ -53,6 +50,10 @@ import com.oracle.graal.pointsto.util.Timer; import com.oracle.graal.pointsto.util.TimerCollection; +import jdk.vm.ci.code.BytecodePosition; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaKind; + /** * Core class of the Reachability Analysis. Contains the crucial part: resolving virtual methods. * The resolving is done in two directions. Whenever a new method is marked as virtually invoked, @@ -114,7 +115,7 @@ public AnalysisType addRootClass(AnalysisType type, boolean addFields, boolean a } } - markTypeReachable(type); + markTypeAsReachable(type); if (type.getSuperclass() != null) { addRootClass(type.getSuperclass(), addFields, addArrayClass); @@ -185,9 +186,9 @@ private void onMethodImplementationInvoked(ReachabilityAnalysisMethod method) { } @Override - public boolean markTypeInHeap(AnalysisType t) { + public boolean registerTypeAsInHeap(AnalysisType t, Object reason) { ReachabilityAnalysisType type = (ReachabilityAnalysisType) t; - if (!type.registerAsInHeap()) { + if (!type.registerAsInHeap(reason)) { return false; } if (type.registerAsInstantiated()) { @@ -197,9 +198,9 @@ public boolean markTypeInHeap(AnalysisType t) { } @Override - public boolean markTypeInstantiated(AnalysisType t) { + public boolean registerTypeAsAllocated(AnalysisType t, Object reason) { ReachabilityAnalysisType type = (ReachabilityAnalysisType) t; - if (!type.registerAsAllocated(null)) { + if (!type.registerAsAllocated(reason)) { return false; } if (type.registerAsInstantiated()) { @@ -211,7 +212,7 @@ public boolean markTypeInstantiated(AnalysisType t) { /** * Processes an embedded constant found in a method graph/summary. */ - public void handleEmbeddedConstant(ReachabilityAnalysisMethod method, JavaConstant constant) { + public void handleEmbeddedConstant(ReachabilityAnalysisMethod method, JavaConstant constant, Object reason) { if (constant.getJavaKind() == JavaKind.Object && constant.isNonNull()) { if (scanningPolicy().trackConstant(this, constant)) { BytecodePosition position = new BytecodePosition(null, method, 0); @@ -219,7 +220,7 @@ public void handleEmbeddedConstant(ReachabilityAnalysisMethod method, JavaConsta Object obj = getSnippetReflectionProvider().asObject(Object.class, constant); AnalysisType type = getMetaAccess().lookupJavaType(obj.getClass()); - markTypeInHeap(type); + registerTypeAsInHeap(type, reason); } } } diff --git a/substratevm/src/com.oracle.graal.reachability/src/com/oracle/graal/reachability/ReachabilityObjectScanner.java b/substratevm/src/com.oracle.graal.reachability/src/com/oracle/graal/reachability/ReachabilityObjectScanner.java index a2a53c6fc58b..f2aad0f458ae 100644 --- a/substratevm/src/com.oracle.graal.reachability/src/com/oracle/graal/reachability/ReachabilityObjectScanner.java +++ b/substratevm/src/com.oracle.graal.reachability/src/com/oracle/graal/reachability/ReachabilityObjectScanner.java @@ -60,41 +60,41 @@ public boolean forRelocatedPointerFieldValue(JavaConstant receiver, AnalysisFiel public boolean forNullFieldValue(JavaConstant receiver, AnalysisField field, ObjectScanner.ScanReason reason) { boolean modified = false; if (receiver != null) { - modified = bb.markTypeReachable(constantType(receiver)); + modified = bb.markTypeAsReachable(constantType(receiver)); } - return modified || bb.markTypeReachable(field.getType()); + return modified || bb.markTypeAsReachable(field.getType()); } @Override public boolean forNonNullFieldValue(JavaConstant receiver, AnalysisField field, JavaConstant fieldValue, ObjectScanner.ScanReason reason) { boolean modified = false; if (receiver != null) { - bb.markTypeInHeap(constantType(receiver)); - modified = bb.markTypeReachable(constantType(receiver)); + bb.registerTypeAsInHeap(constantType(receiver), reason); + modified = bb.markTypeAsReachable(constantType(receiver)); } - return modified || bb.markTypeReachable(field.getType()); + return modified || bb.markTypeAsReachable(field.getType()); } @Override public boolean forNullArrayElement(JavaConstant array, AnalysisType arrayType, int elementIndex, ObjectScanner.ScanReason reason) { - return bb.markTypeReachable(arrayType); + return bb.markTypeAsReachable(arrayType); } @Override public boolean forNonNullArrayElement(JavaConstant array, AnalysisType arrayType, JavaConstant elementConstant, AnalysisType elementType, int elementIndex, ObjectScanner.ScanReason reason) { - return bb.markTypeReachable(arrayType) || bb.markTypeInHeap(elementType); + return bb.markTypeAsReachable(arrayType) || bb.registerTypeAsInHeap(elementType, reason); } @Override public void forEmbeddedRoot(JavaConstant root, ObjectScanner.ScanReason reason) { - bb.markTypeReachable(constantType(root)); - bb.markTypeInHeap(constantType(root)); + bb.markTypeAsReachable(constantType(root)); + bb.registerTypeAsInHeap(constantType(root), reason); } @Override public void forScannedConstant(JavaConstant scannedValue, ObjectScanner.ScanReason reason) { AnalysisType type = constantType(scannedValue); - bb.markTypeInHeap(type); + bb.registerTypeAsInHeap(type, reason); } private AnalysisType constantType(JavaConstant constant) { diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java index 80fad4bfa357..d1580f5ef056 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java @@ -508,7 +508,7 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { // Mark all the Node classes as allocated so they are available during graph decoding. EncodedSnippets encodedSnippets = HotSpotReplacementsImpl.getEncodedSnippets(); for (NodeClass nodeClass : encodedSnippets.getSnippetNodeClasses()) { - bb.markTypeInHeap(impl.getMetaAccess().lookupJavaType(nodeClass.getClazz())); + bb.registerTypeAsInHeap(impl.getMetaAccess().lookupJavaType(nodeClass.getClazz()), "All " + NodeClass.class.getName() + " classes are marked as instantiated eagerly."); } } diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/RuntimeCompilationFeature.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/RuntimeCompilationFeature.java index 7c5fdf264bb8..34002800cdf2 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/RuntimeCompilationFeature.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/RuntimeCompilationFeature.java @@ -435,7 +435,7 @@ public void beforeAnalysis(BeforeAnalysisAccess c) { NodeClass[] snippetNodeClasses = ((SubstrateReplacements) runtimeProviders.getReplacements()).getSnippetNodeClasses(); for (NodeClass nodeClass : snippetNodeClasses) { - config.getMetaAccess().lookupJavaType(nodeClass.getClazz()).registerAsAllocated(null); + config.getMetaAccess().lookupJavaType(nodeClass.getClazz()).registerAsAllocated("All " + NodeClass.class.getName() + " classes are marked as instantiated eagerly."); } /* Initialize configuration with reasonable default values. */ @@ -534,7 +534,7 @@ public void duringAnalysis(DuringAnalysisAccess c) { AnalysisMetaAccess metaAccess = config.getMetaAccess(); NodeClass[] nodeClasses = graphEncoder.getNodeClasses(); for (NodeClass nodeClass : nodeClasses) { - metaAccess.lookupJavaType(nodeClass.getClazz()).registerAsAllocated(null); + metaAccess.lookupJavaType(nodeClass.getClazz()).registerAsAllocated("All " + NodeClass.class.getName() + " classes are marked as instantiated eagerly."); } if (GraalSupport.setGraphEncoding(config, graphEncoder.getEncoding(), graphEncoder.getObjects(), nodeClasses)) { config.requireAnalysisIteration(); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/FeatureImpl.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/FeatureImpl.java index c942ed499d28..54dd1518eb34 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/FeatureImpl.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/FeatureImpl.java @@ -345,16 +345,20 @@ public void registerAsUsed(Class clazz) { } public void registerAsUsed(AnalysisType aType) { - bb.markTypeReachable(aType); + bb.markTypeAsReachable(aType); } @Override public void registerAsInHeap(Class clazz) { - registerAsInHeap(getMetaAccess().lookupJavaType(clazz)); + registerAsInHeap(getMetaAccess().lookupJavaType(clazz), "Registered from Feature API."); } - public void registerAsInHeap(AnalysisType aType) { - bb.markTypeInHeap(aType); + public void registerAsInHeap(Class clazz, Object reason) { + registerAsInHeap(getMetaAccess().lookupJavaType(clazz), reason); + } + + public void registerAsInHeap(AnalysisType aType, Object reason) { + bb.registerTypeAsInHeap(aType, reason); } @Override diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java index 50ab637aee5c..218d4d9162a0 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java @@ -1041,17 +1041,17 @@ public static void initializeBigBang(Inflation bb, OptionValues options, Feature * good example. */ try (Indent ignored = debug.logAndIndent("add initial classes/fields/methods")) { - bb.markTypeInHeap(bb.addRootClass(Object.class, false, false)); + bb.registerTypeAsInHeap(bb.addRootClass(Object.class, false, false), "Root class."); bb.addRootField(DynamicHub.class, "vtable"); - bb.markTypeInHeap(bb.addRootClass(String.class, false, false)); - bb.markTypeInHeap(bb.addRootClass(String[].class, false, false)); - bb.markTypeInHeap(bb.addRootField(String.class, "value")); - bb.markTypeInHeap(bb.addRootClass(long[].class, false, false)); - bb.markTypeInHeap(bb.addRootClass(byte[].class, false, false)); - bb.markTypeInHeap(bb.addRootClass(byte[][].class, false, false)); - bb.markTypeInHeap(bb.addRootClass(Object[].class, false, false)); - bb.markTypeInHeap(bb.addRootClass(CFunctionPointer[].class, false, false)); - bb.markTypeInHeap(bb.addRootClass(PointerBase[].class, false, false)); + bb.registerTypeAsInHeap(bb.addRootClass(String.class, false, false), "Root class."); + bb.registerTypeAsInHeap(bb.addRootClass(String[].class, false, false), "Root class."); + bb.registerTypeAsInHeap(bb.addRootField(String.class, "value"), "Root class."); + bb.registerTypeAsInHeap(bb.addRootClass(long[].class, false, false), "Root class."); + bb.registerTypeAsInHeap(bb.addRootClass(byte[].class, false, false), "Root class."); + bb.registerTypeAsInHeap(bb.addRootClass(byte[][].class, false, false), "Root class."); + bb.registerTypeAsInHeap(bb.addRootClass(Object[].class, false, false), "Root class."); + bb.registerTypeAsInHeap(bb.addRootClass(CFunctionPointer[].class, false, false), "Root class."); + bb.registerTypeAsInHeap(bb.addRootClass(PointerBase[].class, false, false), "Root class."); bb.addRootMethod(ReflectionUtil.lookupMethod(SubstrateArraycopySnippets.class, "doArraycopy", Object.class, int.class, Object.class, int.class, int.class), true); bb.addRootMethod(ReflectionUtil.lookupMethod(Object.class, "getClass"), true); @@ -1059,7 +1059,7 @@ public static void initializeBigBang(Inflation bb, OptionValues options, Feature for (JavaKind kind : JavaKind.values()) { if (kind.isPrimitive() && kind != JavaKind.Void) { bb.addRootClass(kind.toJavaClass(), false, true); - bb.addRootClass(kind.toBoxedJavaClass(), false, true).registerAsInHeap(); + bb.addRootClass(kind.toBoxedJavaClass(), false, true).registerAsInHeap("Root class."); bb.addRootField(kind.toBoxedJavaClass(), "value"); bb.addRootMethod(ReflectionUtil.lookupMethod(kind.toBoxedJavaClass(), "valueOf", kind.toJavaClass()), true); bb.addRootMethod(ReflectionUtil.lookupMethod(kind.toBoxedJavaClass(), kind.getJavaName() + "Value"), true); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/analysis/CustomTypeFieldHandler.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/analysis/CustomTypeFieldHandler.java index d2f9ef6ee88f..921e56413ad3 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/analysis/CustomTypeFieldHandler.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/analysis/CustomTypeFieldHandler.java @@ -108,7 +108,7 @@ private List extractAnnotationTypes(AnalysisField field, UnknownOb private void injectFieldTypes(AnalysisField field, List customTypes) { for (AnalysisType type : customTypes) { if (!type.isPrimitive()) { - type.registerAsAllocated(null); + type.registerAsAllocated("Is declared as the type of an unknown object field."); } } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/analysis/NativeImageReachabilityAnalysisEngine.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/analysis/NativeImageReachabilityAnalysisEngine.java index 6eee47bb7dac..cb23794c4305 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/analysis/NativeImageReachabilityAnalysisEngine.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/analysis/NativeImageReachabilityAnalysisEngine.java @@ -58,7 +58,7 @@ public NativeImageReachabilityAnalysisEngine(OptionValues options, AnalysisUnive protected void injectFieldTypes(AnalysisField aField, AnalysisType... declaredTypes) { markFieldAccessed(aField); for (AnalysisType declaredType : declaredTypes) { - markTypeReachable(declaredType); + markTypeAsReachable(declaredType); } } }; diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/AnnotationTypeFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/AnnotationTypeFeature.java index fb225b0dca07..72fac676c22e 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/AnnotationTypeFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/AnnotationTypeFeature.java @@ -26,8 +26,8 @@ import com.oracle.graal.pointsto.meta.AnalysisType; import com.oracle.graal.pointsto.meta.AnalysisUniverse; -import com.oracle.svm.core.feature.InternalFeature; import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; +import com.oracle.svm.core.feature.InternalFeature; import com.oracle.svm.hosted.FeatureImpl.DuringAnalysisAccessImpl; @AutomaticallyRegisteredFeature @@ -49,7 +49,7 @@ public void duringAnalysis(DuringAnalysisAccess access) { * array of a requested annotation. We need to mark arrays of all * reachable annotations as in heap. */ - accessImpl.registerAsInHeap(annotationArray); + accessImpl.registerAsInHeap(annotationArray, "Is the array type of a reachable annotation."); access.requireAnalysisIteration(); }); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/heap/PodSupport.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/heap/PodSupport.java index 809248eac9a1..a001f0b7829c 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/heap/PodSupport.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/heap/PodSupport.java @@ -59,6 +59,7 @@ import com.oracle.svm.core.hub.Hybrid; import com.oracle.svm.core.hub.LayoutEncoding; import com.oracle.svm.core.util.UserError; +import com.oracle.svm.hosted.FeatureImpl.BeforeAnalysisAccessImpl; import com.oracle.svm.hosted.FeatureImpl.DuringSetupAccessImpl; import com.oracle.svm.hosted.NativeImageSystemClassLoader; import com.oracle.svm.util.ReflectionUtil; @@ -140,8 +141,8 @@ private void registerAsInstantiated(DuringAnalysisAccess access) { pods.forEach((spec, podInfo) -> registerPodAsInstantiated(access, spec, podInfo)); } - private static void registerPodAsInstantiated(BeforeAnalysisAccess access, PodSpec spec, PodInfo info) { - access.registerAsInHeap(info.podClass); + private static void registerPodAsInstantiated(BeforeAnalysisAccess a, PodSpec spec, PodInfo info) { + ((BeforeAnalysisAccessImpl) a).registerAsInHeap(info.podClass, "Pod class registered by PodFeature."); Pod.RuntimeSupport.singleton().registerPod(spec, info); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/heap/SVMImageHeapScanner.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/heap/SVMImageHeapScanner.java index 10ce05aac2ae..3e5ea754174d 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/heap/SVMImageHeapScanner.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/heap/SVMImageHeapScanner.java @@ -145,8 +145,8 @@ protected void rescanEconomicMap(EconomicMap map) { } @Override - protected void onObjectReachable(ImageHeapConstant imageHeapConstant) { - super.onObjectReachable(imageHeapConstant); + protected void onObjectReachable(ImageHeapConstant imageHeapConstant, ScanReason reason) { + super.onObjectReachable(imageHeapConstant, reason); if (metaAccess.isInstanceOf(imageHeapConstant, Field.class) || metaAccess.isInstanceOf(imageHeapConstant, Executable.class)) { reflectionSupport.registerHeapReflectionObject((AccessibleObject) SubstrateObjectConstant.asObject(imageHeapConstant.getHostedObject())); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/ImageHeapFillerObjectsFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/ImageHeapFillerObjectsFeature.java index ec867f6353c6..be83a9750f1d 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/ImageHeapFillerObjectsFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/ImageHeapFillerObjectsFeature.java @@ -24,9 +24,9 @@ */ package com.oracle.svm.hosted.image; +import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; import com.oracle.svm.core.feature.InternalFeature; import com.oracle.svm.core.heap.FillerObject; -import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; import com.oracle.svm.hosted.FeatureImpl.BeforeAnalysisAccessImpl; import com.oracle.svm.util.ReflectionUtil; @@ -36,7 +36,7 @@ class ImageHeapFillerObjectsFeature implements InternalFeature { public void beforeAnalysis(BeforeAnalysisAccess arg) { BeforeAnalysisAccessImpl access = (BeforeAnalysisAccessImpl) arg; access.registerAsAccessed(ReflectionUtil.lookupField(FillerObject.class, "CLASS_OBJECT")); - access.registerAsInHeap(FillerObject.class); - access.registerAsInHeap(int[].class); + access.registerAsInHeap(FillerObject.class, "Registered by ImageHeapFillerObjectsFeature."); + access.registerAsInHeap(int[].class, "Registered by ImageHeapFillerObjectsFeature."); } } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIAccessFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIAccessFeature.java index 2bbd7449a62f..6e7180322015 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIAccessFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIAccessFeature.java @@ -344,7 +344,7 @@ private static JNIAccessibleClass addClass(Class classObj, DuringAnalysisAcce if (analysisClass.isInterface() || (analysisClass.isInstanceClass() && analysisClass.isAbstract())) { analysisClass.registerAsReachable(); } else { - access.getBigBang().markTypeInstantiated(analysisClass); + access.getBigBang().registerTypeAsAllocated(analysisClass, "Is accessed via JNI."); } return new JNIAccessibleClass(classObj); }); @@ -425,7 +425,7 @@ private static void addField(Field reflField, boolean writable, DuringAnalysisAc if (fieldType.isArray() && !access.isReachable(fieldType)) { // For convenience, make the array type reachable if its elemental type becomes // such, allowing the array creation via JNI without an explicit reflection config. - access.registerReachabilityHandler(a -> access.getBigBang().markTypeInstantiated(fieldType), + access.registerReachabilityHandler(a -> access.getBigBang().registerTypeAsAllocated(fieldType, "Is accessed via JNI."), ((AnalysisType) fieldType.getElementalType()).getJavaClass()); } } else if (field.isStatic() && field.isFinal()) { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java index a96ca48c8e31..b1d01e8da886 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java @@ -674,7 +674,7 @@ private static void registerTypes(DuringAnalysisAccessImpl access, Collection clazz) { */ type.registerAsReachable(); if (unsafeInstantiatedClasses.contains(clazz)) { - type.registerAsAllocated(null); + type.registerAsAllocated("Is registered for reflection."); } if (reflectionClasses.contains(clazz)) { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/SubstrateGraphBuilderPlugins.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/SubstrateGraphBuilderPlugins.java index fcb073578d0c..8bd7f96058d2 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/SubstrateGraphBuilderPlugins.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/SubstrateGraphBuilderPlugins.java @@ -38,6 +38,7 @@ import java.util.function.Function; import java.util.stream.Stream; +import com.oracle.graal.pointsto.AbstractAnalysisEngine; import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; import org.graalvm.compiler.core.common.CompressEncoding; import org.graalvm.compiler.core.common.type.AbstractObjectStamp; @@ -739,7 +740,7 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec AnalysisType type = (AnalysisType) b.getMetaAccess().lookupJavaType(clazz); for (int i = 0; i < dimensionCount; i++) { type = type.getArrayClass(); - type.registerAsAllocated(clazzNode); + type.registerAsAllocated(AbstractAnalysisEngine.sourcePosition(clazzNode)); } } } diff --git a/substratevm/src/com.oracle.svm.polyglot/src/com/oracle/svm/polyglot/scala/ScalaAnalysisPlugin.java b/substratevm/src/com.oracle.svm.polyglot/src/com/oracle/svm/polyglot/scala/ScalaAnalysisPlugin.java index b83fadfd4403..acd77f731fe2 100644 --- a/substratevm/src/com.oracle.svm.polyglot/src/com/oracle/svm/polyglot/scala/ScalaAnalysisPlugin.java +++ b/substratevm/src/com.oracle.svm.polyglot/src/com/oracle/svm/polyglot/scala/ScalaAnalysisPlugin.java @@ -57,7 +57,7 @@ public boolean handleInvoke(GraphBuilderContext b, ResolvedJavaMethod method, Va AnalysisType type = (AnalysisType) b.getConstantReflection().asJavaType(clazzConstant); for (int i = 0; i < SUPPORTED_LEVEL_OF_NESTED_ARRAYS; i++) { type = type.getArrayClass(); - type.registerAsInHeap(); + type.registerAsInHeap(b.getGraph().currentNodeSourcePosition()); } } } diff --git a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleBaseFeature.java b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleBaseFeature.java index f93746a27add..dde3835b752a 100644 --- a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleBaseFeature.java +++ b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleBaseFeature.java @@ -370,11 +370,12 @@ public static void preInitializeEngine() { * * @see #initializeTruffleLibrariesAtBuildTime */ - private static void registerTruffleLibrariesAsInHeap(DuringAnalysisAccess access, Class clazz) { + private static void registerTruffleLibrariesAsInHeap(DuringAnalysisAccess a, Class clazz) { + DuringAnalysisAccessImpl access = (DuringAnalysisAccessImpl) a; assert access.isReachable(clazz) : clazz; assert LibraryFactory.class.isAssignableFrom(clazz) || LibraryExport.class.isAssignableFrom(clazz) : clazz; if (!Modifier.isAbstract(clazz.getModifiers())) { - access.registerAsInHeap(clazz); + access.registerAsInHeap(clazz, "Truffle library class registered by TruffleBaseFeature."); } } diff --git a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleFeature.java b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleFeature.java index 59d86f4cac34..d45a8182a81a 100644 --- a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleFeature.java +++ b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleFeature.java @@ -412,7 +412,7 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { * adds it as a root and non-static root methods are only compiled if types implementing * them or any of their subtypes are allocated. */ - access.registerAsInHeap(TruffleSupport.singleton().getOptimizedCallTargetClass()); + config.registerAsInHeap(TruffleSupport.singleton().getOptimizedCallTargetClass(), "Concrete subclass of OptimizedCallTarget registered by TruffleFeature."); /* * This effectively initializes the Truffle fallback engine which does all the system