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 27ebadc644b5..34f3e03cfcd9 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 @@ -563,13 +563,12 @@ public void registerAsAssignable(BigBang bb) { public boolean registerAsReachable(Object reason) { assert isValidReason(reason) : "Registering a type as reachable needs to provide a valid reason."; - CausalityExport.Event thisReachable = new CausalityExport.TypeReachable(this); - CausalityExport.get().registerEvent(thisReachable); + CausalityExport.get().registerEvent(new CausalityExport.TypeReachable(this)); if (!AtomicUtils.isSet(this, isReachableUpdater)) { /* Mark this type and all its super types as reachable. */ forAllSuperTypes(type -> { if(type != this) { - CausalityExport.get().registerEdge(thisReachable, new CausalityExport.TypeReachable(type)); + CausalityExport.get().registerEdge(new CausalityExport.TypeReachable(this), new CausalityExport.TypeReachable(type)); } AtomicUtils.atomicSetAndRun(type, reason, isReachableUpdater, type::onReachable); }); diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/reports/CausalityExport.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/reports/CausalityExport.java index 49d898657a02..58ff7c9cdd53 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/reports/CausalityExport.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/reports/CausalityExport.java @@ -3,7 +3,6 @@ import com.oracle.graal.pointsto.BigBang; import com.oracle.graal.pointsto.ObjectScanner; import com.oracle.graal.pointsto.PointsToAnalysis; -import com.oracle.graal.pointsto.constraints.UnsupportedFeatureException; import com.oracle.graal.pointsto.flow.AbstractVirtualInvokeTypeFlow; import com.oracle.graal.pointsto.flow.TypeFlow; import com.oracle.graal.pointsto.meta.AnalysisElement; @@ -15,11 +14,11 @@ import com.oracle.graal.pointsto.reports.causality.Graph; import com.oracle.graal.pointsto.reports.causality.TypeflowImpl; import com.oracle.graal.pointsto.typestate.TypeState; +import com.oracle.graal.pointsto.util.AnalysisError; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaField; import jdk.vm.ci.meta.JavaMethod; import jdk.vm.ci.meta.JavaType; -import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.MetaUtil; import jdk.vm.ci.meta.Signature; @@ -31,7 +30,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Optional; import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -41,30 +39,46 @@ public class CausalityExport { protected CausalityExport() { } - private static final CausalityExport dummyInstance = new CausalityExport(); - private static ThreadLocal instances; - private static List instancesOfAllThreads; - private static boolean collectTypeflowInformation; - - // Starts collection of Causality Data - public static synchronized void activate(boolean collectTypeflowInformation) { - CausalityExport.collectTypeflowInformation = collectTypeflowInformation; - instances = ThreadLocal.withInitial(CausalityExport::createInstance); - instancesOfAllThreads = new ArrayList<>(); + public enum Level { + DISABLED, + ENABLED_WITHOUT_TYPEFLOW, + ENABLED; } + private static Level requestedLevel = Level.DISABLED; + + public static final class InitializationOnDemandHolder { + private static final Level frozenLevel = CausalityExport.requestedLevel; + } + + /** + * Must be called before any usage of {@link #get()} + */ + public static void activate(Level level) { + requestedLevel = level; + if (level != InitializationOnDemandHolder.frozenLevel) { + throw AnalysisError.shouldNotReachHere("Causality Export must have been activated before the first usage of CausalityExport.get()"); + } + } + + private static final CausalityExport dummyInstance = new CausalityExport(); + private static ThreadLocal instances = ThreadLocal.withInitial(CausalityExport::createInstance); + private static List instancesOfAllThreads = new ArrayList<>(); + private static synchronized Impl createInstance() { - Impl instance = collectTypeflowInformation ? new TypeflowImpl() : new Impl(); + Impl instance = InitializationOnDemandHolder.frozenLevel == Level.ENABLED ? new TypeflowImpl() : new Impl(); instancesOfAllThreads.add(instance); return instance; } public static CausalityExport get() { - return instances != null ? instances.get() : dummyInstance; + if (InitializationOnDemandHolder.frozenLevel == Level.DISABLED || instances == null) + return dummyInstance; + return instances.get(); } public static synchronized void dump(PointsToAnalysis bb, ZipOutputStream zip, boolean exportTypeflowNames) throws java.io.IOException { - Impl data = collectTypeflowInformation ? new TypeflowImpl((Iterable)(Iterable) instancesOfAllThreads, bb) : new Impl(instancesOfAllThreads, bb); + Impl data = InitializationOnDemandHolder.frozenLevel == Level.ENABLED ? new TypeflowImpl((Iterable)(Iterable) instancesOfAllThreads, bb) : new Impl(instancesOfAllThreads, bb); // Let GC collect intermediate data structures instances = null; instancesOfAllThreads = null; diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java index 904720f66f1a..13108adf1d37 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java @@ -403,7 +403,7 @@ public static void updateMaxJavaStackTraceDepth(EconomicMap, Object public static final String REACHABILITY_FILE_NAME = "reachability.json"; @Option(help = "Create a " + REACHABILITY_FILE_NAME + " file in the build directory. The output conforms to the JSON schema located at: " + "docs/reference-manual/native-image/assets/reachability-schema-v0.9.0.json", type = OptionType.User)// - public static final HostedOptionKey GenerateReachabilityFile = new HostedOptionKey<>(true); + public static final HostedOptionKey GenerateReachabilityFile = new HostedOptionKey<>(false); /* * Build output options. 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 8b429a59eb3d..4a487b0571c9 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 @@ -874,7 +874,10 @@ protected void setupNativeImage(OptionValues options, Map, InitKind> classInitKinds, @Override public boolean isInConfiguration(IsInConfigurationAccess access) { - return SubstrateOptions.GenerateReachabilityFile.getValue(); + return SubstrateOptions.GenerateReachabilityFile.getValue() || AnalysisReportsOptions.PrintCausalityGraph.getValue(HostedOptionValues.singleton()); } @Override