JDK-8254693 : Add Panama feature to pass heap segments to native code
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang.foreign
  • Affected Version: repo-panama
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2020-10-13
  • Updated: 2024-05-16
  • Resolved: 2023-11-14
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 22
22 b24Fixed
Related Reports
CSR :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
The HotSpot JVM currently has feature for native calls that passes elements of a primitive array to a native function if it finds an entry point for that native function that is prefixed with JavaCritical_.[1]

No JDK code currently uses this feature since it is not officially supported, but it may be used in some experimental and external code to improve performance.

We would like to deprecate this feature, but recognize that this may be a useful optimization for performance of native calls. [2]

A suggested Panama replacement could be code that adds a "pin" method to MemorySegment (see comment), or some other marker, that avoids the copy to native memory then calls the function as a trivial function, like:
                func_trivial = abi.downcallHandle(addr, mt, fd.withAttribute(FunctionDescriptor.TRIVIAL_ATTRIBUTE_NAME, true));

[1] https://stackoverflow.com/questions/48730135/how-to-get-javacritical-to-really-work-on-jni

[2] https://bugs.openjdk.java.net/browse/JDK-8233343

Comments
Changeset: 9c982707 Author: Jorn Vernee <jvernee@openjdk.org> Date: 2023-11-14 11:19:30 +0000 URL: https://git.openjdk.org/jdk/commit/9c98270737cd2019f230e9359bb9298f8df2ca35
14-11-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/16201 Date: 2023-10-16 10:19:17 +0000
18-10-2023

From an email thread in Sept. On 9/10/20 5:58 AM, Maurizio Cimadamore wrote: > > On 10/09/2020 10:14, Jorn Vernee wrote: >> The critical arrays are an interesting use-case though. Currently it is possible to wrap a Java array in a MemorySegment, but it's not possible to pass the address of such a segment to native code, as the address is an Object + offset coordinate pair, and we only allow passing addresses that have a null base Object (i.e. an offheap address). I'm not sure how criticals handle pinning the array, but maybe we could have some kind of MemorySegment.pin() method that returns a new MemorySegment that _can_ be passed to native code. Which would make it possible to pass Java arrays to native code again. Something like: >> >> byte[] bytes = { 1, 2, 3 }; >> MemorySegment arrSeg = MemorySegment.ofArray(bytes); >> try (MemorySegment pinned = arrSeg.pin()) { >> myNativeMethod(pinned.address()); >> } // unpin > > Right - this is the use case which, if we could find a way to make it work, would make a lot of people happy: passing _heap_ segments to native functions. I believe this problem has a lot of commonalities with critical JNI. Reasons as to one might want to do that are: > > * allocating small arrays is way faster in the heap than it is off-heap > * if you already have an heap array, you save a lot of churn by passing that _directly_ to native code (think a big matrix of floats to be passed down to some BLAS function) - avoiding to have to first moving data off-heap and then call > > Maurizio >
13-10-2020