oracle / graal

GraalVM compiles Java applications into native executables that start instantly, scale fast, and use fewer compute resources 🚀
https://www.graalvm.org
Other
20.4k stars 1.64k forks source link

Truffle implemented language gets "Blocklisted method" on a native method #4556

Closed HugoGGuerrier closed 2 years ago

HugoGGuerrier commented 2 years ago

Description of the issue : When I try to compile my Truffle language implementation with "native-image" I get an error of the "Blocklisted method" type on a custom (myself-defined) native function.

GraalVM environment :

Here is the code of the JNI library :

package org.gordon.runtime;

public class JNILib {

    private static JNILib instance = null;

    protected JNILib() {
        System.loadLibrary("grd");
    }

    public static JNILib getInstance() {
        if(instance == null) {
            instance = new JNILib();
        }
        return instance;
    }

    public native int addInt(int x, int y);

}

Here is the code of the Truffle node :

package org.gordon.nodes;

import com.oracle.truffle.api.frame.VirtualFrame;
import org.gordon.runtime.JNILib;

public class NativeCallNode extends GordonNode {

    private final JNILib jniLib;

    public NativeCallNode() {
        this.jniLib = JNILib.getInstance();
    }

    @Override
    public Object executeGeneric(VirtualFrame frame) {
        return jniLib.addInt(40, 2);
    }

}

Here is the error message that I get :

========================================================================================================================
GraalVM Native Image: Generating 'bin/gordon' (executable)...
========================================================================================================================
--initialize-at-build-time without arguments has been deprecated when not using --diagnostics-mode. With GraalVM 22.0.0 --initialize-at-build-time will only work with --diagnostics-mode for debugging purposes.
The reason for deprecation is that --initalize-at-build-time does not compose, i.e., a single library can make assumptions that the whole classpath can be safely initialized at build time; that assumption is often incorrect.
[1/7] Initializing...                                                                                    (1.9s @ 0.24GB)
 Version info: 'GraalVM 22.1.0 Java 17 CE'
 C compiler: gcc (pc, x86_64, 11.2.1)
 Garbage collector: Serial GC
[2/7] Performing analysis...  [*********]                                                               (11.5s @ 2.35GB)
   8,796 (90.18%) of  9,754 classes reachable
  12,871 (61.43%) of 20,951 fields reachable
  43,185 (59.27%) of 72,857 methods reachable
   1,879 ( 2.58%) of 72,857 methods included for runtime compilation
     192 classes,   101 fields, and   942 methods registered for reflection
      58 classes,    58 fields, and    52 methods registered for JNI access
[3/7] Building universe...                                                                               (1.2s @ 2.74GB)

=== Found 1 compilation blocklist violations ===

Blocklisted method
  org.gordon.runtime.JNILib.addInt(int, int)
called from
  org.gordon.nodes.NativeCallNode.executeGeneric(NativeCallNode.java:17)
  org.gordon.nodes.GordonRootNode.execute(GordonRootNode.java:37) -> org.gordon.nodes.FuncCallNode.execute(FuncCallNode.java:45)
  org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.executeRootNode(OptimizedCallTarget.java:659)
  org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.profiledPERoot(OptimizedCallTarget.java:631)

Fatal error: com.oracle.svm.core.util.VMError$HostedError: Blocklisted methods are reachable for runtime compilation
    at com.oracle.svm.core.util.VMError.shouldNotReachHere(VMError.java:68)
    at com.oracle.svm.truffle.TruffleFeature.beforeCompilation(TruffleFeature.java:682)
    at com.oracle.svm.hosted.NativeImageGenerator.lambda$doRun$4(NativeImageGenerator.java:624)
    at com.oracle.svm.hosted.FeatureHandler.forEachFeature(FeatureHandler.java:74)
    at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:624)
    at com.oracle.svm.hosted.NativeImageGenerator.run(NativeImageGenerator.java:515)
    at com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:407)
    at com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:585)
    at com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:128)
------------------------------------------------------------------------------------------------------------------------
    at com.oracle.svm.hosted.NativeImageGeneratorRunner$JDK9Plus.main(NativeImageGeneratorRunner.java:615)
                        0.6s (3.9% of total time) in 16 GCs | Peak RSS: 3.20GB | CPU load: 7.48
========================================================================================================================

Here you can found the Truffle project : https://anonfiles.com/1dc8D0ecy5/GordonTruffle.tar_xz To reproduce this error :

Thanks.

fniephaus commented 2 years ago

What happens if you annotate addInt(int x, int y) with @TruffleBoundary? I don't think you can make JNI calls on the fast path.

wirthi commented 2 years ago

Closing this ticket. Adding the Boundary seems the right solution. If you have any additional information, feel free to reopen.