Native method binding

David Lloyd david.lloyd at redhat.com
Wed Dec 18 15:31:13 UTC 2024


On Wed, Dec 18, 2024 at 4:39 AM Maurizio Cimadamore <
maurizio.cimadamore at oracle.com> wrote:

> 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.
>
I definitely understand what you're saying here. However, you misunderstand
what I'm proposing. I'm not suggesting being able to call FFM directly
using a plain native method. I'm suggesting being able to *bind* a native
method to any arbitrary `MethodHandle` that matches its exact shape.
Getting a matching `MethodHandle` from FFM would be the user's job, not the
FFM API's job. Technically it wouldn't even be limited to FFM.

Say I'm writing a library, and that library uses the POSIX `read` syscall.
The `read` syscall is pretty simple; it takes a file descriptor, a pointer,
and a size, and returns a result and/or sets `errno`. The file descriptor
is a (C) `int`, the pointer is, well, a pointer, and the size is specified
as `size_t`.

As you correctly surmised, what I want to be able to do is have a native
method that I know is adequate for *all* platforms. For example: `static
native long read(MemorySegment callState, int fd, MemorySegment ptr, long
size)` - and call that from my main code for all POSIX OSes.

Unfortunately, `size_t` - and even `int` - might vary by size per platform.
So, the *actual* layouts for the different platforms are of course all
different. This means that the method handles for all the different
platforms have different types and have to be adapted in many cases. But,
it is much easier for a project to use a single set of static methods, and
to keep a table of layouts and some back-pocket adapter methods, which are
used one time during class init for example, than to manage a large number
of mostly-redundant classes. A very clever user might even maintain a
database of such things.

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).
>
Sure, MethodHandleProxy does a similar job, though you have to define a
whole interface per method shape, which seems unnecessarily heavy
conceptually and computationally. I actually have an experimental project
called `ffm-autolinker` [1] which lets you define a whole interface that
gets implemented by a class which uses indy to dynamically link each
implementation method on demand using FFM plus known runtime platform
information, adapting the arguments and returns as needed. I think this is
more ergonomic than `jextract` and lighter (in many ways) than
MethodHandleProxy, though it is still a little immature.

But it would be nice to take the idea a step farther and get rid of the
interface altogether.

[1] https://github.com/dmlloyd/ffm-autolinker

-- 
- DML • he/him
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/panama-dev/attachments/20241218/a1c7ca7d/attachment.htm>


More information about the panama-dev mailing list