Auto-port 5.0: fix FFM address semantics in directBufferAddress#16641
Merged
Conversation
Motivation:
- Unnecessary JNI fallback
When `Unsafe` is disabled or unavailable, but the JDK provides a usable
FFM (Foreign Function & Memory) API, the existing code still falls back
to JNI to obtain the address of a direct `ByteBuffer`.
- Incorrect FFM semantics in `PlatformDependent0#directBufferAddress`
The `Unsafe` branch returns the **base address** of the direct buffer
(index 0), consistent with JNI `GetDirectBufferAddress`.
However, the FFM branch uses `MemorySegment.ofBuffer(buffer).address()`,
which effectively returns `baseAddress + position`.
This leads to inconsistent semantics between the FFM and Unsafe/JNI
implementations.
``` java
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1024);
//ffm api
System.out.println(PlatformDependent.directBufferAddress(byteBuffer));
// jni
System.out.println(Buffer.memoryAddress(byteBuffer));
byteBuffer = byteBuffer.position(16);
System.out.println(PlatformDependent.directBufferAddress(byteBuffer));
System.out.println(Buffer.memoryAddress(byteBuffer));
```
On Java 25 and Netty 4.2.12.Final, this code prints:
```
129502193232224
129502193232224
129502193232240
129502193232224
```
The third line reflects baseAddress + 16, demonstrating that the FFM
path is position-dependent, while the JNI path remains
position-independent.
Modification:
- Prefer the FFM/JVM path when `Unsafe` is unavailable but FFM is
available, avoiding the JNI fallback.
- Fix the FFM branch to return the same **base-address semantics** as
the Unsafe/JNI paths (i.e., position-independent).
Result:
fix FFM address semantics in directBufferAddress
Co-authored-by: Norman Maurer <norman_maurer@apple.com>
(cherry picked from commit b4c2ddb)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Auto-port of #16603 to 5.0
Cherry-picked commit: b4c2ddb
Motivation:
Unnecessary JNI fallback
When
Unsafeis disabled or unavailable, but the JDK provides a usable FFM (Foreign Function & Memory) API, the existing code still falls back to JNI to obtain the address of a directByteBuffer.Incorrect FFM semantics in
PlatformDependent0#directBufferAddressThe
Unsafebranch returns the base address of the direct buffer (index 0), consistent with JNIGetDirectBufferAddress.However, the FFM branch uses
MemorySegment.ofBuffer(buffer).address(), which effectively returnsbaseAddress + position.This leads to inconsistent semantics between the FFM and Unsafe/JNI implementations.
On Java 25 and Netty 4.2.12.Final, this code prints:
The third line reflects baseAddress + 16, demonstrating that the FFM path is position-dependent, while the JNI path remains position-independent.
Modification:
Unsafeis unavailable but FFM is available, avoiding the JNI fallback.Result:
fix FFM address semantics in directBufferAddress