Opt-in for trivial native method calls
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Thu Jun 2 11:11:04 UTC 2022
Hi Felix,
this is on our radar. When I see discussion on these topics, I typically
see the discussion bringing up two _different_ features:
1. drop state Java->Native transitions for simple calls (e.g. `getpid`)
2. pass heap objects to native functions directly (e.g. heap buffer,
heap segments, strings, arrays, ...), this is sometimes referred to as
"heap pinning"
The two features are obviously related - disabling state transitions (1)
effectively results in the thread going "native" no longer being able to
safepoint. Since GC is "blocked" heap objects have addresses that can be
"trusted" during the execution of the native call (hence (2)). But
supporting pinning is definitively harder: if you rely on trivial call
support, you can only trust heap addresses from native code - but the
native code Panama calls knows nothing about JVM objects and pinned heap
regions. And this is problematic for Panama, because the code that
lowers memory segments to raw addresses is expressed in Java code (so we
can't use heap addresses safely there). There are other options, such as
that to use GC support for heap pinning [1], those might work (for the
GC which support that feature).
Back to trivial calls, the main limitations around trivial calls are:
* no GC while running the trivial call (as thread won't safepoint)
* if the trivial call tries to upcall to Java, the JVM will crash
Summing up, we have already thought about these topics, and will
probably do something to support some of these features. But we'd like
to arrive with something that people would find useful - only adding
support for trivial calls, while beneficial in a few specialized cases
(like yours), is, alone, not powerful enough to subsume other use cases
where e.g. people reach for critical JNI (because of lack of heap
pinning). In other words, I think it's worth trying to solve both
problems at once.
Maurizio
[1] - https://shipilev.net/jvm/anatomy-quarks/9-jni-critical-gclocker/
On 02/06/2022 11:14, Felix Cravic wrote:
> Hello, coming here after a recommendation from reddit [0] I want to pitch my wish for the Linker API to support "trival" native function.
> My benchmark showed an average latency of around 6ns when calling a native method, which is more than fine most of the time, but fall short for inexpensive calls.
>
> To give a relevant example that could take advantage of such feature, my current toy project [1] involve making the JVM version of Unity's burst compiler [2] which consist in JIT compiling JVM bytecode using LLVM with the hope of getting better performance for highly specialized code (custom intrinsics, stack allocation, value class without valhalla, other fanciness...). And while the calling latency does not make it impossible, it does make it inefficient for taking advantage of specialized instructions (that may not be available in the JDK api) and relatively small methods that could still outperform hotspot equivalent.
>
> I definitely agree that my situation is not the most common (I am responsible for all the native methods, generate class dynamically to create the static method handles) but giving access to low-level tweaks seem like a great solution to me. I am also not sure of what are the tradeoffs of these trivial methods (is it only a matter of safepoint?) so I would be happy to get more technical details.
>
> Thanks!
>
> [0] - https://www.reddit.com/r/java/comments/v33d44/panama_foreign_function_overhead_how_can_it_be/
> [1] - https://github.com/TheMode/Spe
> [2] - https://docs.unity3d.com/Packages/com.unity.burst@0.2-preview.20/manual/index.html
>
More information about the panama-dev
mailing list