From 7c480a8b301e35f7c0ff328db375b8b0329cf05d Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Thu, 15 Feb 2024 15:07:23 +0200 Subject: [PATCH] Switch to runtime initialization instead of rerun They both have the same result starting with 23.1. Runtime initialization is public API while rerun is not, and will soon be deprecated and at some point removed in future releases. See https://github.com/oracle/graal/issues/5013#issuecomment-1944747803 and https://github.com/oracle/graal/pull/8323/ --- .../steps/NativeImageFeatureStep.java | 36 +++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageFeatureStep.java b/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageFeatureStep.java index f91930e898ed8..6112a1ef3dd97 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageFeatureStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageFeatureStep.java @@ -25,6 +25,7 @@ import io.quarkus.gizmo.CatchBlockCreator; import io.quarkus.gizmo.ClassCreator; import io.quarkus.gizmo.ClassOutput; +import io.quarkus.gizmo.ForEachLoop; import io.quarkus.gizmo.MethodCreator; import io.quarkus.gizmo.MethodDescriptor; import io.quarkus.gizmo.ResultHandle; @@ -176,29 +177,44 @@ public void write(String s, byte[] bytes) { // hack in reinitialization of process info classes if (!runtimeReinitializedClassBuildItems.isEmpty()) { MethodCreator runtimeReinitializedClasses = file - .getMethodCreator("runtimeReinitializedClasses", void.class) + .getMethodCreator("runtimeReinitializedClasses", Class[].class) .setModifiers(Modifier.PRIVATE | Modifier.STATIC); ResultHandle thisClass = runtimeReinitializedClasses.loadClassFromTCCL(GRAAL_FEATURE); ResultHandle cl = runtimeReinitializedClasses.invokeVirtualMethod( ofMethod(Class.class, "getClassLoader", ClassLoader.class), thisClass); - ResultHandle quarkus = runtimeReinitializedClasses.load("Quarkus"); - ResultHandle imageSingleton = runtimeReinitializedClasses.invokeStaticMethod(IMAGE_SINGLETONS_LOOKUP, - runtimeReinitializedClasses.loadClassFromTCCL(RUNTIME_CLASS_INITIALIZATION_SUPPORT)); - for (RuntimeReinitializedClassBuildItem runtimeReinitializedClass : runtimeReinitializedClassBuildItems) { + ResultHandle classesArray = runtimeReinitializedClasses.newArray(Class.class, + runtimeReinitializedClasses.load(runtimeInitializedClassBuildItems.size())); + for (int i = 0; i < runtimeReinitializedClassBuildItems.size(); i++) { TryBlock tc = runtimeReinitializedClasses.tryBlock(); ResultHandle clazz = tc.invokeStaticMethod( ofMethod(Class.class, "forName", Class.class, String.class, boolean.class, ClassLoader.class), - tc.load(runtimeReinitializedClass.getClassName()), tc.load(false), cl); - tc.invokeInterfaceMethod(RERUN_INITIALIZATION, imageSingleton, clazz, quarkus); - + tc.load(runtimeReinitializedClassBuildItems.get(i).getClassName()), tc.load(false), cl); + tc.writeArrayValue(classesArray, i, clazz); CatchBlockCreator cc = tc.addCatch(Throwable.class); cc.invokeVirtualMethod(ofMethod(Throwable.class, "printStackTrace", void.class), cc.getCaughtException()); } - runtimeReinitializedClasses.returnVoid(); + runtimeReinitializedClasses.returnValue(classesArray); - overallCatch.invokeStaticMethod(runtimeReinitializedClasses.getMethodDescriptor()); + ResultHandle classes = overallCatch.invokeStaticMethod(runtimeReinitializedClasses.getMethodDescriptor()); + + ResultHandle graalVMVersion = overallCatch.invokeStaticMethod(GRAALVM_VERSION_GET_CURRENT); + BranchResult graalVm23_1Test = overallCatch + .ifGreaterEqualZero(overallCatch.invokeVirtualMethod(GRAALVM_VERSION_COMPARE_TO, graalVMVersion, + overallCatch.marshalAsArray(int.class, overallCatch.load(23), overallCatch.load(1)))); + /* GraalVM >= 23.1 */ + try (BytecodeCreator greaterEqual23_1 = graalVm23_1Test.trueBranch()) { + greaterEqual23_1.invokeStaticMethod(INITIALIZE_CLASSES_AT_RUN_TIME, classes); + } + /* GraalVM < 23.1 */ + try (BytecodeCreator less23_1 = graalVm23_1Test.trueBranch()) { + ResultHandle quarkus = less23_1.load("Quarkus"); + ResultHandle imageSingleton = less23_1.invokeStaticMethod(IMAGE_SINGLETONS_LOOKUP, + less23_1.loadClassFromTCCL(RUNTIME_CLASS_INITIALIZATION_SUPPORT)); + ForEachLoop loop = less23_1.forEach(classes); + loop.block().invokeInterfaceMethod(RERUN_INITIALIZATION, imageSingleton, loop.element(), quarkus); + } } // Ensure registration of fields being accessed through unsafe is done last to ensure that the class