Native method binding

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Wed Dec 18 10:39:10 UTC 2024


Hi David (and Yasumasa).

What you are proposing makes some sense -- although I think I see 
different things being discussed which can be a little confusing. David 
seems to want to call FFM using a plain native method. Yasumasa showed 
an example of registering a "code segment" as an implementation of a 
native method, using the existing RegisterNatives functionality. The 
latter can be done (and has been done!) outside the JDK -- after all, 
RegisterNatives just wants a function pointer that points to a function 
whose calling convention respects the JNI one.

But the former -- calling a native function using FFM through a native 
method -- is not as straightforward as it seems. Quoting my colleague 
Brian, "they look cute when they're small!" [1] and I do believe that to 
be the case here. It is pretty easy to convince ourselves that we have 
all we need to support calling FFM via native methods. But, upon closer 
inspection we'll realize at least few things:

* FFM is more expressive than JNI, as it allows to pass things such as 
by-value structs and unions. Passing these things however, requires a 
_layout_ -- and crucially, native methods do not support layouts. We 
could imagine all kinds of annotations with stringy layout 
representations, but you see where this is headed :-)

* FFM is also _less_ expressive than JNI in that it does not allow to 
pass objects directly to native code (with the exception of critical FFM 
calls allowing heap segments). Maybe objects should be passed "as 
pointers" and the Linker should know how to create a JNI ref 
automatically and pass that. But again, not as straightforward as it seems.

* This will likely result in a "coloring" of native methods of some 
sort. Whether a native method declaration corresponds to JNI code, or 
target directly a native function (via FFM) will be not very visible in 
the code. And, since the semantics of native/JNI methods is different 
from that of native/FFM methods, that becomes more of a problem.

Popping back a level, I think you raise two important points:

* it would be nice if downcall method handles could be called "more 
safely" w/o using method handles directly.
* it would be nice if warmup costs associated with downcall method 
handles could be improved/eliminated

I think both are ideas worth exploring (and both are indeed on our 
radar). In the former case, I think a road that is not given enough 
attention is that it is quite easy, in fact, to create an instance of a 
functional interface using a downcall method handle, via the 
MethodHandleProxy::asInterfaceInstance method [2]. And the latter 
problem is bigger than downcall method handles -- a similar warmup 
problem also exists for FFM's memory access var handles, so I think a 
deeper exploration in coordination with Leyden would yield better 
outcomes for FFM as a whole (and, likely, also for _all_ Java code using 
method/var handles).

Maurizio

[1] - https://youtu.be/mIbA2ymCWDs?si=ZVicqr9Gq9tdjc5X&t=147
[2] - 
https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/lang/invoke/MethodHandleProxies.html

On 17/12/2024 17:12, David Lloyd wrote:
> With the (hopeful) ascendance of FFM over JNI, what about the idea of 
> allowing `native` methods to be bound to `MethodHandle`s on the Java 
> side at run time? This would allow for a much nicer experience than 
> creating wrapper methods and would bring another level of parity with 
> JNI, which has this capability (`RegisterNatives`). The capability 
> could be restricted as a form of native access, and only allowed for 
> methods in classes within the same module.
>
> What do you think?
>
> -- 
> - DML • he/him
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/panama-dev/attachments/20241218/8f07781d/attachment.htm>


More information about the panama-dev mailing list