diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8dfee940fa03..5077b704d52b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -122,7 +122,7 @@ jobs: PRIMARY: "substratevm" - env: JDK_VERSION: "latest" - GATE_TAGS: "build,helloworld,native_unittests" + GATE_TAGS: "build,helloworld,native_unittests,standalone_pointsto_unittests" PRIMARY: "substratevm" PIP_PACKAGES: "jsonschema==4.6.1" - os: ubuntu-24.04 diff --git a/substratevm/ci/ci.jsonnet b/substratevm/ci/ci.jsonnet index f66891cb9873..e07038a71c79 100644 --- a/substratevm/ci/ci.jsonnet +++ b/substratevm/ci/ci.jsonnet @@ -126,7 +126,7 @@ "style-fullbuild": mxgate("fullbuild,style,nativeimagehelp,check_libcontainer_annotations,check_libcontainer_namespace") + eclipse + jdt + spotbugs + maven + mx_build_exploded + gdb("14.2") + platform_spec(no_jobs) + platform_spec({ "linux:amd64:jdk-latest": tier1 + t("30:00"), }), - "basics": mxgate("build,helloworld,native_unittests,truffle_unittests,debuginfotest,hellomodule,java_agent,condconfig") + maven + jsonschema + platform_spec(no_jobs) + platform_spec({ + "basics": mxgate("build,helloworld,native_unittests,standalone_pointsto_unittests,truffle_unittests,debuginfotest,hellomodule,java_agent,condconfig") + maven + jsonschema + platform_spec(no_jobs) + platform_spec({ "linux:amd64:jdk-latest": tier2 + partial(2) + gdb("14.2") + t("40:00"), "windows:amd64:jdk-latest": tier3 + t("1:30:00"), }) + variants({ diff --git a/substratevm/mx.substratevm/mx_substratevm.py b/substratevm/mx.substratevm/mx_substratevm.py index 4d940e41be50..37449f4c9a36 100644 --- a/substratevm/mx.substratevm/mx_substratevm.py +++ b/substratevm/mx.substratevm/mx_substratevm.py @@ -208,6 +208,7 @@ def __getattr__(self, name): GraalTags = Tags([ 'helloworld', 'debuginfotest', + 'standalone_pointsto_unittests', 'native_unittests', 'build', 'benchmarktest', @@ -440,6 +441,16 @@ def svm_gate_body(args, tasks): with native_image_context(IMAGE_ASSERTION_FLAGS) as native_image: gdbdebughelperstest(['--output-path', svmbuild_dir()] + args.extra_image_builder_arguments) + with Task('standalone pointsto unittests', tasks, tags=[GraalTags.standalone_pointsto_unittests]) as t: + if t: + if '--static' in args.extra_image_builder_arguments: + mx.warn('Skipping standalone pointsto unittests if --static.') + elif mx.is_windows(): + mx.warn('Skipping standalone pointsto unittests on Windows.') + else: + jvm_unittest(['--record-results', '--print-failed', 'failed.txt', + '--use-graalvm'] + args.extra_image_builder_arguments + ['com.oracle.graal.pointsto.standalone.test']) + with Task('native unittests', tasks, tags=[GraalTags.native_unittests]) as t: if t: with native_image_context(IMAGE_ASSERTION_FLAGS) as native_image: @@ -2726,3 +2737,25 @@ def capnp_compile(args): shaded = line.replace("org.capnproto", "com.oracle.svm.shaded.org.capnproto") f.write(shaded) f.write('}\n') + +class StandalonePointstoUnittestsConfig(mx_unittest.MxUnittestConfig): + + def __init__(self): + super(StandalonePointstoUnittestsConfig, self).__init__('standalone-pointsto-unittest') + + def apply(self, config): + vmArgs, mainClass, mainClassArgs = config + + vmArgs.extend(['--add-exports=jdk.graal.compiler/jdk.graal.compiler.options=ALL-UNNAMED']) + + # JVMCI is dynamically exported to Graal when JVMCI is initialized. This is too late + # for the junit harness which uses reflection to find @Test methods. In addition, the + # tests widely use JVMCI classes so JVMCI needs to also export all its packages to + # ALL-UNNAMED. + mainClassArgs.extend(['-JUnitOpenPackages', 'jdk.internal.vm.ci/*=jdk.graal.compiler,ALL-UNNAMED']) + mainClassArgs.extend(['-JUnitOpenPackages', 'org.graalvm.nativeimage/*=ALL-UNNAMED']) + + return (vmArgs, mainClass, mainClassArgs) + + +mx_unittest.register_unittest_config(StandalonePointstoUnittestsConfig()) diff --git a/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py index 9507701d2b8c..0c4cb682e6fa 100644 --- a/substratevm/mx.substratevm/suite.py +++ b/substratevm/mx.substratevm/suite.py @@ -2446,6 +2446,7 @@ "dependencies" : [ "com.oracle.graal.pointsto.standalone.test", ], + "unittestConfig" : "standalone-pointsto-unittest", "distDependencies": [ "mx:JUNIT_TOOL", "sdk:NATIVEIMAGE", diff --git a/substratevm/src/com.oracle.graal.pointsto.standalone.test/src/com/oracle/graal/pointsto/standalone/test/StandaloneConstantScanDynamicCase.java b/substratevm/src/com.oracle.graal.pointsto.standalone.test/src/com/oracle/graal/pointsto/standalone/test/StandaloneConstantScanDynamicCase.java index 8f5d90706d94..f7779e431845 100644 --- a/substratevm/src/com.oracle.graal.pointsto.standalone.test/src/com/oracle/graal/pointsto/standalone/test/StandaloneConstantScanDynamicCase.java +++ b/substratevm/src/com.oracle.graal.pointsto.standalone.test/src/com/oracle/graal/pointsto/standalone/test/StandaloneConstantScanDynamicCase.java @@ -50,9 +50,5 @@ public static void main(String[] args) { public void run() { STATUS.compareAndSet(this, status, 1); - doSomething(); - } - - private void doSomething() { } } diff --git a/substratevm/src/com.oracle.graal.pointsto.standalone.test/src/com/oracle/graal/pointsto/standalone/test/StandaloneConstantScanDynamicTest.java b/substratevm/src/com.oracle.graal.pointsto.standalone.test/src/com/oracle/graal/pointsto/standalone/test/StandaloneConstantScanDynamicTest.java index 09ac8070d752..24cd95f72a0e 100644 --- a/substratevm/src/com.oracle.graal.pointsto.standalone.test/src/com/oracle/graal/pointsto/standalone/test/StandaloneConstantScanDynamicTest.java +++ b/substratevm/src/com.oracle.graal.pointsto.standalone.test/src/com/oracle/graal/pointsto/standalone/test/StandaloneConstantScanDynamicTest.java @@ -28,86 +28,6 @@ import org.junit.Test; -/** - * This test shall fail because it makes the analysis code itself reachable if the classes are not - * separated by classloaders. - * - * The exception stack is: - * - *
- * Exception:com.oracle.graal.pointsto.util.ParallelExecutionException - * at com.oracle.graal.pointsto.util.CompletionExecutor.complete(CompletionExecutor.java:261) - * at com.oracle.graal.pointsto.PointsToAnalysis.doTypeflow(PointsToAnalysis.java:528) - * at com.oracle.graal.pointsto.PointsToAnalysis.finish(PointsToAnalysis.java:516) - * at com.oracle.graal.pointsto.AbstractAnalysisEngine.runAnalysis(AbstractAnalysisEngine.java:161) - * at com.oracle.graal.pointsto.standalone.PointsToAnalyzer.run(PointsToAnalyzer.java:278) - * at com.oracle.graal.pointsto.standalone.test.PointstoAnalyzerTester.runAnalysisAndAssert(PointstoAnalyzerTester.java:159) - * at com.oracle.graal.pointsto.standalone.test.PointstoAnalyzerTester.runAnalysisAndAssert(PointstoAnalyzerTester.java:145) - * at com.oracle.graal.pointsto.standalone.test.StandaloneConstantScanDynamicTest.test(StandaloneConstantScanDynamicTest.java:43) - * at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - * at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) - * at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - * at java.base/java.lang.reflect.Method.invoke(Method.java:568) - * at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) - * at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) - * at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) - * at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) - * at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) - * at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) - * at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) - * at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) - * at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) - * at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) - * at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) - * at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) - * at org.junit.runners.ParentRunner.run(ParentRunner.java:363) - * at org.junit.runners.Suite.runChild(Suite.java:128) - * at org.junit.runners.Suite.runChild(Suite.java:27) - * at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) - * at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) - * at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) - * at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) - * at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) - * at org.junit.runners.ParentRunner.run(ParentRunner.java:363) - * at org.junit.runner.JUnitCore.run(JUnitCore.java:137) - * at org.junit.runner.JUnitCore.run(JUnitCore.java:115) - * at com.oracle.mxtool.junit.MxJUnitWrapper.runRequest(MxJUnitWrapper.java:375) - * at com.oracle.mxtool.junit.MxJUnitWrapper.main(MxJUnitWrapper.java:230) - * cause 0jdk.graal.compiler.debug.GraalError: jdk.graal.compiler.debug.GraalError: jdk.graal.compiler.debug.GraalError: - * should not reach here: Double wrapping of constant. Most likely, the reachability analysis code itself is seen as reachable. java.lang.Object[] - * at com.oracle.graal.pointsto.util.AnalysisFuture.setException(AnalysisFuture.java:49) - * at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:269) - * at com.oracle.graal.pointsto.util.AnalysisFuture.ensureDone(AnalysisFuture.java:63) - * at com.oracle.graal.pointsto.heap.ImageHeapObjectArray.readElementValue(ImageHeapObjectArray.java:84) - * at com.oracle.graal.pointsto.heap.ImageHeapScanner.onObjectReachable(ImageHeapScanner.java:463) - * at com.oracle.graal.pointsto.heap.ImageHeapScanner.lambda$markReachable$5(ImageHeapScanner.java:451) - * at com.oracle.graal.pointsto.heap.ImageHeapScanner.lambda$postTask$14(ImageHeapScanner.java:690) - * at com.oracle.graal.pointsto.util.CompletionExecutor.executeCommand(CompletionExecutor.java:187) - * at com.oracle.graal.pointsto.util.CompletionExecutor.lambda$executeService$0(CompletionExecutor.java:171) - * at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1395) - * at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373) - * at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182) - * at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655) - * at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622) - * at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165) - * Caused by: jdk.graal.compiler.debug.GraalError: jdk.graal.compiler.debug.GraalError: should not reach here: Double wrapping of constant. Most likely, the reachability analysis code itself is seen as reachable. java.lang.Object[] - * at com.oracle.graal.pointsto.util.AnalysisFuture.setException(AnalysisFuture.java:49) - * at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:269) - * at com.oracle.graal.pointsto.util.AnalysisFuture.ensureDone(AnalysisFuture.java:63) - * at com.oracle.graal.pointsto.heap.ImageHeapScanner.getOrCreateImageHeapConstant(ImageHeapScanner.java:212) - * at com.oracle.graal.pointsto.heap.ImageHeapScanner.createImageHeapConstant(ImageHeapScanner.java:186) - * at com.oracle.graal.pointsto.heap.ImageHeapScanner.lambda$createImageHeapObjectArray$3(ImageHeapScanner.java:270) - * at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) - * ... 13 more - * Caused by: jdk.graal.compiler.debug.GraalError: should not reach here: Double wrapping of constant. Most likely, the reachability analysis code itself is seen as reachable. java.lang.Object[] - * at jdk.graal.compiler/jdk.graal.compiler.debug.GraalError.shouldNotReachHere(GraalError.java:57) - * at com.oracle.graal.pointsto.heap.ImageHeapScanner.maybeReplace(ImageHeapScanner.java:307) - * at com.oracle.graal.pointsto.heap.ImageHeapScanner.createImageHeapObject(ImageHeapScanner.java:225) - * at com.oracle.graal.pointsto.heap.ImageHeapScanner.lambda$getOrCreateImageHeapConstant$2(ImageHeapScanner.java:205) - * at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) - * ... 18 more - *- */ public class StandaloneConstantScanDynamicTest { @Test @@ -115,8 +35,7 @@ public void test() throws NoSuchMethodException { PointstoAnalyzerTester tester = new PointstoAnalyzerTester(StandaloneConstantScanDynamicCase.class); tester.setAnalysisArguments(tester.getTestClassName(), "-H:AnalysisTargetAppCP=" + tester.getTestClassJar()); - tester.setExpectedReachableMethods(tester.getTestClass().getDeclaredMethod("run"), - tester.getTestClass().getDeclaredMethod("doSomething")); + tester.setExpectedReachableMethods(tester.getTestClass().getDeclaredMethod("run")); tester.runAnalysisAndAssert(); } } 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 c3e5a665aaef..0b72b4f71948 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,8 +26,6 @@ package com.oracle.graal.pointsto.standalone; -import static jdk.graal.compiler.replacements.StandardGraphBuilderPlugins.registerInvocationPlugins; - import java.io.File; import java.lang.reflect.Method; import java.net.MalformedURLException; @@ -56,6 +54,7 @@ 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.plugins.PointstoGraphBuilderPlugins; import com.oracle.graal.pointsto.reports.AnalysisReporter; import com.oracle.graal.pointsto.standalone.features.StandaloneAnalysisFeatureImpl; import com.oracle.graal.pointsto.standalone.features.StandaloneAnalysisFeatureManager; @@ -97,7 +96,6 @@ public final class PointsToAnalyzer { ModuleSupport.accessPackagesToClass(ModuleSupport.Access.OPEN, null, false, "java.base", "sun.text.spi"); ModuleSupport.accessPackagesToClass(ModuleSupport.Access.OPEN, null, false, "java.base", "sun.reflect.annotation"); ModuleSupport.accessPackagesToClass(ModuleSupport.Access.OPEN, null, false, "java.base", "sun.security.jca"); - ModuleSupport.accessPackagesToClass(ModuleSupport.Access.OPEN, null, false, "jdk.jdeps", "com.sun.tools.classfile"); } private final OptionValues options; @@ -212,7 +210,9 @@ private PointsToAnalyzer(String mainEntryClass, OptionValues options) { NoClassInitializationPlugin classInitializationPlugin = new NoClassInitializationPlugin(); plugins.setClassInitializationPlugin(classInitializationPlugin); aProviders.setGraphBuilderPlugins(plugins); - registerInvocationPlugins(originalProviders.getSnippetReflection(), plugins.getInvocationPlugins(), false, true, false); + PointstoGraphBuilderPlugins.registerArrayPlugins(plugins.getInvocationPlugins()); + PointstoGraphBuilderPlugins.registerSystemPlugins(plugins.getInvocationPlugins()); + PointstoGraphBuilderPlugins.registerObjectPlugins(plugins.getInvocationPlugins()); } } @@ -286,6 +286,7 @@ public int run() { try (Timer t = new Timer("analysis", analysisName)) { StandaloneAnalysisFeatureImpl.DuringAnalysisAccessImpl config = new StandaloneAnalysisFeatureImpl.DuringAnalysisAccessImpl(standaloneAnalysisFeatureManager, analysisClassLoader, bigbang, debugContext); + bigbang.getUniverse().setConcurrentAnalysisAccess(config); bigbang.runAnalysis(debugContext, (analysisUniverse) -> { bigbang.getHostVM().notifyClassReachabilityListener(analysisUniverse, config); standaloneAnalysisFeatureManager.forEachFeature(feature -> feature.duringAnalysis(config)); diff --git a/substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/StandaloneObjectScanner.java b/substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/StandaloneObjectScanner.java index 95944778cc59..3ca9201ac605 100644 --- a/substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/StandaloneObjectScanner.java +++ b/substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/StandaloneObjectScanner.java @@ -58,7 +58,13 @@ protected void scanEmbeddedRoot(JavaConstant root, Object position) { @Override protected final void scanField(AnalysisField field, JavaConstant receiver, ScanReason prevReason) { if (shouldScanField.test(field)) { - super.scanField(field, receiver, prevReason); + if (field.isStatic()) { + if (field.getDeclaringClass().isInitialized()) { + super.scanField(field, receiver, prevReason); + } + } else { + super.scanField(field, receiver, prevReason); + } } } diff --git a/substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/heap/StandaloneImageHeapScanner.java b/substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/heap/StandaloneImageHeapScanner.java index aa8fc1affaf2..d39702e45e20 100644 --- a/substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/heap/StandaloneImageHeapScanner.java +++ b/substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/heap/StandaloneImageHeapScanner.java @@ -69,19 +69,26 @@ protected Class> getClass(String className) { @Override public ValueSupplier