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