Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement method handle support for GraalVM Native Image #2761

Closed
christianwimmer opened this issue Aug 18, 2020 · 29 comments
Closed

Implement method handle support for GraalVM Native Image #2761

christianwimmer opened this issue Aug 18, 2020 · 29 comments
Assignees
Labels

Comments

@christianwimmer
Copy link

No description provided.

@kaspernielsen
Copy link

kaspernielsen commented Sep 26, 2020

Is the plan that every method handle created either via a field/constructor/executable or via java.lang.invoke.MethodHandles as part of an image's build time will work at runtime without any additional configuration?

@loicottet
Copy link
Member

Method handles will require some configuration. Whether it will be the existing reflection configuration or a separate one is still open.

@kaspernielsen
Copy link

I'm not sure I understand why you need any configuration. MethodHandles that are strongly reachable after the image creation phase will in 99.99% of all cases be meant for invocation at runtime.

@christianwimmer
Copy link
Author

MethodHandles that are strongly reachable after the image creation phase will in 99.99% of all cases be meant for invocation at runtime.

Yes, and such method handles will work without configuration. Same as reflection: if you have a java.lang.reflect.Method instance strongly reachable in the image heap, it works without further configuration.

But if you create new method method handle at run time, then you need configuration at image build time.

@kaspernielsen
Copy link

Sounds great. I must admit the more I work with MHs the less my need for runtime support for them. Transformations via the various static methods on MethodHandles can mostly be done at image creation time. The only thing I actually miss is being able to bind object instances that cannot be created until runtime. For example, via MethodHandle#bindTo or MethodHandles#insertArguments

@felixbarny
Copy link

Are invokedynamic instructions supported whose bootstrap method returns a dynamically computed ConstantCallSite?

@christianwimmer
Copy link
Author

When everything is finished, all aspects of method handles including bootstrap methods will be supported.

@johnynek
Copy link

johnynek commented Jan 2, 2021

For Scala, this sbt plugin will handle replacing a use of method handles in the standard library:

https://github.com/scalameta/sbt-native-image

That may solve scala issues for the short term.

It would still be nice to not need a work around.

@loicottet
Copy link
Member

Full method handles support will be included in the 21.0 release. This will remove the need for --report-unsupported-elements-at-runtime and the various substitution hacks that were needed until now, including in the Scala library. Methods accessed through method handles will have to be registered in the same configuration file as the reflection methods, and this config will be able to be automatically generated through the Native Image agent.

@kaspernielsen
Copy link

kaspernielsen commented Jan 6, 2021

Is there any to get a warning/error if you create non-direct methodhandles at runtime?
I want to make sure that all my MethodHandles are created at build-time and not accidentally at runtime for maximum effiency.

@loicottet
Copy link
Member

@kaspernielsen sorry for the late reply. There is currently no way of checking that, but you can create an issue to request that feature.

@gustavocoding
Copy link

Something seems to be missing from the MethodHandle support, getting:

Caused by: java.lang.ClassCastException: java.lang.invoke.BoundMethodHandle$Species_LL cannot be cast to java.lang.invoke.SimpleMethodHandle
	at com.oracle.svm.methodhandles.MethodHandleIntrinsic.execute(MethodHandleIntrinsic.java:254)
	at java.lang.invoke.MethodHandle.invokeBasic(MethodHandle.java:80)
	at java.lang.invoke.LambdaForm$NamedFunction.invokeWithArguments(LambdaForm.java:74)
	at java.lang.invoke.LambdaForm.interpretName(LambdaForm.java:981)
	at java.lang.invoke.LambdaForm.interpretWithArguments(LambdaForm.java:958)
	at java.lang.invoke.MethodHandle.invokeBasic(MethodHandle.java:171)
	at java.lang.invoke.MethodHandle.invokeBasic(MethodHandle.java:0)
	at java.lang.invoke.LambdaForm$MH/1417001346.invokeExact_MT(LambdaForm$MH)
	at org.apache.lucene.store.MMapDirectory.lambda$null$0(MMapDirectory.java:404)
	at java.security.AccessController.doPrivileged(AccessController.java:84)
	at org.apache.lucene.store.MMapDirectory.lambda$newBufferCleaner$1(MMapDirectory.java:402)
	... 47 more

The exception above is when trying to invoke the method invokeCleaner from sun.misc.Unsafe:

final Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
final MethodHandle unmapper = lookup.findVirtual(unsafeClass, "invokeCleaner", methodType(void.class, ByteBuffer.class));
final Field f = unsafeClass.getDeclaredField("theUnsafe");
f.setAccessible(true);
final Object theUnsafe = f.get(null);
unmapper.bindTo(theUnsafe);

//...
unmapper.invokeExact(buffer);

@loicottet
Copy link
Member

@gustavonalle can you open a separate issue for this bug? I'll look into it.

@gustavocoding
Copy link

@loicottet sure, I have a reproducer inside Quarkus only, when trying to create a reproducer for GraalVM directly, got caught in #3241, could you take a look?

@revintec
Copy link

revintec commented Jun 28, 2023

I'm using native-image 20.0.1 2023-04-18
GraalVM Runtime Environment Oracle GraalVM 20.0.1+9.1 (build 20.0.1+9-jvmci-23.0-b12)
Substrate VM Oracle GraalVM 20.0.1+9.1 (build 20.0.1+9, serial gc, compressed references)
latest versions as of writing, it seems Panama is not supported

this is causing a great trouble, as I have to manually patch every callsites, and the changed version are not equivalent to the panama one(think errno

  1. is there a way to support Panama now?
  2. why is Panama specifically disabled in native-image?
Fatal error: com.oracle.graal.pointsto.util.AnalysisError$ParsingError: Error encountered while parsing jdk.internal.foreign.SystemLookup.find(SystemLookup.java:136)
Parsing context:
   at Native.<clinit>(Native.kt:65)
   at static root method.(Unknown Source)

	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.AnalysisError.parsingError(AnalysisError.java:149)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.createFlowsGraph(MethodTypeFlow.java:178)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.ensureFlowsGraphCreated(MethodTypeFlow.java:152)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.getOrCreateMethodFlowsGraphInfo(MethodTypeFlow.java:110)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.typestate.DefaultVirtualInvokeTypeFlow.onObservedUpdate(DefaultVirtualInvokeTypeFlow.java:113)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.TypeFlow.update(TypeFlow.java:583)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.PointsToAnalysis$1.run(PointsToAnalysis.java:474)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.CompletionExecutor.executeCommand(CompletionExecutor.java:187)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.CompletionExecutor.lambda$executeService$0(CompletionExecutor.java:171)
	at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1423)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1843)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1808)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)
Caused by: org.graalvm.compiler.java.BytecodeParser$BytecodeParserError: java.lang.InternalError: com.oracle.graal.pointsto.constraints.UnresolvedElementException: Error loading a referenced type: com.oracle.svm.hosted.substitute.DeletedElementException: Unsupported method jdk.internal.loader.NativeLibrary.findEntry0(long, String) is reachable
To diagnose the issue, you can add the option --report-unsupported-elements-at-runtime. The unsupported element is then reported at run time when it is accessed the first time.
	at parsing jdk.internal.loader.RawNativeLibraries$RawNativeLibraryImpl.find(RawNativeLibraries.java:170)
	at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.throwParserError(BytecodeParser.java:2536)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.phases.SharedGraphBuilderPhase$SharedBytecodeParser.throwParserError(SharedGraphBuilderPhase.java:169)
	at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.iterateBytecodesForBlock(BytecodeParser.java:3414)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.phases.SharedGraphBuilderPhase$SharedBytecodeParser.iterateBytecodesForBlock(SharedGraphBuilderPhase.java:712)
	at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.handleBytecodeBlock(BytecodeParser.java:3366)
	at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.processBlock(BytecodeParser.java:3208)
	at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.build(BytecodeParser.java:1134)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.phases.SharedGraphBuilderPhase$SharedBytecodeParser.build(SharedGraphBuilderPhase.java:152)
	at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.buildRootMethod(BytecodeParser.java:1026)
	at jdk.internal.vm.compiler/org.graalvm.compiler.java.GraphBuilderPhase$Instance.run(GraphBuilderPhase.java:97)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.phases.SharedGraphBuilderPhase.run(SharedGraphBuilderPhase.java:114)
	at jdk.internal.vm.compiler/org.graalvm.compiler.phases.Phase.run(Phase.java:49)
	at jdk.internal.vm.compiler/org.graalvm.compiler.phases.BasePhase.apply(BasePhase.java:434)
	at jdk.internal.vm.compiler/org.graalvm.compiler.phases.Phase.apply(Phase.java:42)
	at jdk.internal.vm.compiler/org.graalvm.compiler.phases.Phase.apply(Phase.java:38)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.AnalysisParsedGraph.parseBytecode(AnalysisParsedGraph.java:146)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.meta.AnalysisMethod.parseGraph(AnalysisMethod.java:819)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.meta.AnalysisMethod.ensureGraphParsedHelper(AnalysisMethod.java:784)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.meta.AnalysisMethod.ensureGraphParsed(AnalysisMethod.java:767)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.phases.InlineBeforeAnalysisGraphDecoder.lookupEncodedGraph(InlineBeforeAnalysisGraphDecoder.java:120)
	at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.doInline(PEGraphDecoder.java:1190)
	at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.tryInline(PEGraphDecoder.java:1173)
	at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.trySimplifyInvoke(PEGraphDecoder.java:1028)
	at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.handleInvoke(PEGraphDecoder.java:982)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.GraphDecoder.processNextNode(GraphDecoder.java:871)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.phases.InlineBeforeAnalysisGraphDecoder.processNextNode(InlineBeforeAnalysisGraphDecoder.java:186)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.GraphDecoder.decode(GraphDecoder.java:600)
	at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.decode(PEGraphDecoder.java:854)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.phases.InlineBeforeAnalysis.decodeGraph(InlineBeforeAnalysis.java:77)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.parse(MethodTypeFlowBuilder.java:193)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.apply(MethodTypeFlowBuilder.java:583)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.createFlowsGraph(MethodTypeFlow.java:165)
	... 13 more
Caused by: java.lang.InternalError: com.oracle.graal.pointsto.constraints.UnresolvedElementException: Error loading a referenced type: com.oracle.svm.hosted.substitute.DeletedElementException: Unsupported method jdk.internal.loader.NativeLibrary.findEntry0(long, String) is reachable
To diagnose the issue, you can add the option --report-unsupported-elements-at-runtime. The unsupported element is then reported at run time when it is accessed the first time.
	at jdk.internal.vm.compiler/org.graalvm.compiler.serviceprovider.GraalServices.lookupMethodWithCaller(GraalServices.java:562)
	at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.lookupMethodInPool(BytecodeParser.java:4244)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.phases.SharedGraphBuilderPhase$SharedBytecodeParser.lookupMethodInPool(SharedGraphBuilderPhase.java:197)
	at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.lookupMethod(BytecodeParser.java:4236)
	at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.genInvokeStatic(BytecodeParser.java:1652)
	at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.processBytecode(BytecodeParser.java:5331)
	at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.iterateBytecodesForBlock(BytecodeParser.java:3406)
	... 42 more
Caused by: com.oracle.graal.pointsto.constraints.UnresolvedElementException: Error loading a referenced type: com.oracle.svm.hosted.substitute.DeletedElementException: Unsupported method jdk.internal.loader.NativeLibrary.findEntry0(long, String) is reachable
To diagnose the issue, you can add the option --report-unsupported-elements-at-runtime. The unsupported element is then reported at run time when it is accessed the first time.
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.infrastructure.WrappedConstantPool.lookupMethod(WrappedConstantPool.java:149)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:578)
	at jdk.internal.vm.compiler/org.graalvm.compiler.serviceprovider.GraalServices.lookupMethodWithCaller(GraalServices.java:555)
	... 48 more
Caused by: com.oracle.svm.hosted.substitute.DeletedElementException: Unsupported method jdk.internal.loader.NativeLibrary.findEntry0(long, String) is reachable
To diagnose the issue, you can add the option --report-unsupported-elements-at-runtime. The unsupported element is then reported at run time when it is accessed the first time.
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.substitute.AnnotationSubstitutionProcessor.lookup(AnnotationSubstitutionProcessor.java:272)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.infrastructure.SubstitutionProcessor$ChainedSubstitutionProcessor.lookup(SubstitutionProcessor.java:140)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.infrastructure.SubstitutionProcessor$ChainedSubstitutionProcessor.lookup(SubstitutionProcessor.java:140)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.meta.AnalysisUniverse.lookupAllowUnresolved(AnalysisUniverse.java:438)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.infrastructure.WrappedConstantPool.lookupMethod(WrappedConstantPool.java:141)
	... 51 more
------------------------------------------------------------------------------------------------------------------------
                        0.9s (8.2% of total time) in 28 GCs | Peak RSS: 1.50GB | CPU load: 5.34
========================================================================================================================

@christianwimmer
Copy link
Author

@revintec "Panama" is an umbrella term for many different features. But most of them are currently not support on Native Image, because they are still incubator / preview and changing quickly. So nothing is "specifically disabled", but when you enable preview features and use them then you can get all sorts of strange errors like the one you observed.

We are actively working on the foreign call interface of Panama. For other parts like the vector API we have not started any implementation at all.

@Glavo
Copy link

Glavo commented Jul 27, 2023

https://mail.openjdk.org/pipermail/panama-dev/2023-July/019510.html

Foreign Function & Memory API will (very likely) be stable in Java 22, I'm looking forward to seeing it on GraalVM.

@dreamlike-ocean
Copy link

@revintec "Panama" is an umbrella term for many different features. But most of them are currently not support on Native Image, because they are still incubator / preview and changing quickly. So nothing is "specifically disabled", but when you enable preview features and use them then you can get all sorts of strange errors like the one you observed.

We are actively working on the foreign call interface of Panama. For other parts like the vector API we have not started any implementation at all.

Does it support vector api in native-image now?

@christianwimmer
Copy link
Author

Does it support vector api in native-image now?

No, there is no work on vector API support for native image. It does not seem likely that the vector API moves out of the incubator status anytime soon.

@revintec
Copy link

https://mail.openjdk.org/pipermail/panama-dev/2023-July/019510.html

Foreign Function & Memory API will (very likely) be stable in Java 22, I'm looking forward to seeing it on GraalVM.

@christianwimmer it seems FFM is finally stable in JDK22 https://openjdk.org/jeps/454
can we have a interoperable FFM in GraalVM for JDK 22(due March 19, 2024 according to release calendar)?

currently I have to cook every native call in my java program to suit native-image... the code was littered with if(inImageCode())... and since the calling method(methodHandle vs annotated native method for native-image) is not compatible, signature incompatibilities, and the native-image version doesn't support errno(it seems there is no way to support that currently). very painful and ugly

@christianwimmer
Copy link
Author

There is some support for the Foreign Function & Memory API in the upcoming GraalVM for JDK 22, but not everything is working yet and it is not optimize yet, i.e., the parts that are working are likely to be slow compared to the HotSpot VM.

@revintec
Copy link

@christianwimmer from what I've read here
https://www.graalvm.org/release-notes/JDK_21/
it seems GraalVM 21.0.2 should already support FFM
image
however there is no documentation, and using standard FFM won't work

========================================================================================================================
GraalVM Native Image: Generating 'mainkt' (executable)...
========================================================================================================================
[1/8] Initializing...                                                                                    (3.2s @ 0.10GB)
 Java version: 21.0.2+13-LTS, vendor version: Oracle GraalVM 21.0.2+13.1
 Graal compiler: optimization level: 2, target machine: armv8-a, PGO: off
 C compiler: cc (apple, arm64, 14.0.0)
 Garbage collector: Serial GC (max heap size: 80% of RAM)
 1 user-specific feature(s):
 - com.oracle.svm.thirdparty.gson.GsonFeature
------------------------------------------------------------------------------------------------------------------------
Build resources:
 - 12.09GB of memory (75.6% of 16.00GB system memory, determined at start)
 - 10 thread(s) (100.0% of 10 available processor(s), determined at start)
[2/8] Performing analysis...  [*****]                                                                    (8.9s @ 0.32GB)
    4,298 reachable types   (75.8% of    5,673 total)
    4,734 reachable fields  (50.2% of    9,433 total)
   21,441 reachable methods (50.5% of   42,462 total)
    1,385 types,   249 fields, and 1,006 methods registered for reflection
       57 types,    57 fields, and    52 methods registered for JNI access
        4 native libraries: -framework Foundation, dl, pthread, z

Error: Error loading a referenced type: com.oracle.svm.hosted.substitute.DeletedElementException: Unsupported method jdk.internal.loader.NativeLibrary.findEntry0(long, String) is reachable
To diagnose the issue, you can add the option --report-unsupported-elements-at-runtime. The unsupported element is then reported at run time when it is accessed the first time.
Error encountered while parsing jdk.internal.loader.RawNativeLibraries$RawNativeLibraryImpl.find(RawNativeLibraries.java:170)
Parsing context:
   at jdk.internal.loader.NativeLibrary.lookup(NativeLibrary.java:49)
   at jdk.internal.foreign.SystemLookup.lambda$libLookup$8(SystemLookup.java:112)
   at jdk.internal.foreign.SystemLookup.find(SystemLookup.java:139)
   at MainKt.downcallHandle(Main.kt:24)
   at MainKt.main(Main.kt:31)
   at static root method.(Unknown Source)

Detailed message:

------------------------------------------------------------------------------------------------------------------------
                        1.2s (9.2% of total time) in 85 GCs | Peak RSS: 0.82GB | CPU load: 5.31
========================================================================================================================
Finished generating 'mainkt' in 12.3s.

reference code:

import java.lang.foreign.*
import java.lang.foreign.Linker.Option
import java.lang.foreign.Linker.Option.captureStateLayout
import java.lang.foreign.MemoryLayout.PathElement

val linker=Linker.nativeLinker()
val opts=arrayOf(Option.captureCallState("errno"))
val _errno=captureStateLayout()
val errno=_errno.varHandle(PathElement.groupElement("errno"))

fun downcallHandle(name:String,fn:FunctionDescriptor,vararg opts:Option)=linker.defaultLookup().find(name).orElse(null)?.let{
    linker.downcallHandle(it,fn,*opts)
}


fun main(args:Array<String>) {

    val mh=downcallHandle("geteuid",FunctionDescriptor.of(ValueLayout.JAVA_INT,*arrayOfNulls<MemoryLayout>(0)),*opts)

    val arena = Arena.ofConfined()
    val state = arena.allocate(_errno)

    println(mh!!.invokeExact(state)as Int)
    val aa=errno.get(state)as Int
    println(aa)
}

@dreamlike-ocean
Copy link

@christianwimmer from what I've read here
https://www.graalvm.org/release-notes/JDK_21/
it seems GraalVM 21.0.2 should already support FFM
image
however there is no documentation, and using standard FFM won't work

========================================================================================================================
GraalVM Native Image: Generating 'mainkt' (executable)...
========================================================================================================================
[1/8] Initializing...                                                                                    (3.2s @ 0.10GB)
 Java version: 21.0.2+13-LTS, vendor version: Oracle GraalVM 21.0.2+13.1
 Graal compiler: optimization level: 2, target machine: armv8-a, PGO: off
 C compiler: cc (apple, arm64, 14.0.0)
 Garbage collector: Serial GC (max heap size: 80% of RAM)
 1 user-specific feature(s):
 - com.oracle.svm.thirdparty.gson.GsonFeature
------------------------------------------------------------------------------------------------------------------------
Build resources:
 - 12.09GB of memory (75.6% of 16.00GB system memory, determined at start)
 - 10 thread(s) (100.0% of 10 available processor(s), determined at start)
[2/8] Performing analysis...  [*****]                                                                    (8.9s @ 0.32GB)
    4,298 reachable types   (75.8% of    5,673 total)
    4,734 reachable fields  (50.2% of    9,433 total)
   21,441 reachable methods (50.5% of   42,462 total)
    1,385 types,   249 fields, and 1,006 methods registered for reflection
       57 types,    57 fields, and    52 methods registered for JNI access
        4 native libraries: -framework Foundation, dl, pthread, z

Error: Error loading a referenced type: com.oracle.svm.hosted.substitute.DeletedElementException: Unsupported method jdk.internal.loader.NativeLibrary.findEntry0(long, String) is reachable
To diagnose the issue, you can add the option --report-unsupported-elements-at-runtime. The unsupported element is then reported at run time when it is accessed the first time.
Error encountered while parsing jdk.internal.loader.RawNativeLibraries$RawNativeLibraryImpl.find(RawNativeLibraries.java:170)
Parsing context:
   at jdk.internal.loader.NativeLibrary.lookup(NativeLibrary.java:49)
   at jdk.internal.foreign.SystemLookup.lambda$libLookup$8(SystemLookup.java:112)
   at jdk.internal.foreign.SystemLookup.find(SystemLookup.java:139)
   at MainKt.downcallHandle(Main.kt:24)
   at MainKt.main(Main.kt:31)
   at static root method.(Unknown Source)

Detailed message:

------------------------------------------------------------------------------------------------------------------------
                        1.2s (9.2% of total time) in 85 GCs | Peak RSS: 0.82GB | CPU load: 5.31
========================================================================================================================
Finished generating 'mainkt' in 12.3s.

reference code:

import java.lang.foreign.*
import java.lang.foreign.Linker.Option
import java.lang.foreign.Linker.Option.captureStateLayout
import java.lang.foreign.MemoryLayout.PathElement

val linker=Linker.nativeLinker()
val opts=arrayOf(Option.captureCallState("errno"))
val _errno=captureStateLayout()
val errno=_errno.varHandle(PathElement.groupElement("errno"))

fun downcallHandle(name:String,fn:FunctionDescriptor,vararg opts:Option)=linker.defaultLookup().find(name).orElse(null)?.let{
    linker.downcallHandle(it,fn,*opts)
}


fun main(args:Array<String>) {

    val mh=downcallHandle("geteuid",FunctionDescriptor.of(ValueLayout.JAVA_INT,*arrayOfNulls<MemoryLayout>(0)),*opts)

    val arena = Arena.ofConfined()
    val state = arena.allocate(_errno)

    println(mh!!.invokeExact(state)as Int)
    val aa=errno.get(state)as Int
    println(aa)
}

并非全部的符号lookup都会有支持,请参考https://www.graalvm.org/latest/reference-manual/native-image/dynamic-features/foreign-interface/这篇文档
以及可以看看这个https://github.com/dreamlike-ocean/Panama-native-image/blob/master/src/main/java/org/example/PanamaDemo.java 至少这东西在Linux x86 64上跑的很好

@revintec
Copy link

并非全部的符号lookup都会有支持,请参考https://www.graalvm.org/latest/reference-manual/native-image/dynamic-features/foreign-interface/这篇文档 以及可以看看这个https://github.com/dreamlike-ocean/Panama-native-image/blob/master/src/main/java/org/example/PanamaDemo.java 至少这东西在Linux x86 64上跑的很好

thanks for your swift reply! it's of a great help
to summarize, current version can't use defaultLookup, but use loaderLookup, as seen from here
https://github.com/dreamlike-ocean/Panama-native-image/blob/fb4af048a53a5cb189e072acc38f9ed5320531ae/src/main/java/org/example/PanamaDemo.java#L59

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests