RFR: 8286715: Generalize MemorySegment::ofBuffer
Maurizio Cimadamore
mcimadamore at openjdk.java.net
Fri May 13 12:43:28 UTC 2022
On Fri, 13 May 2022 12:33:10 GMT, Maurizio Cimadamore <mcimadamore at openjdk.org> wrote:
> This patch makes MemorySegment::ofBuffer more general, by allowing clients to pass *any* `Buffer` instance, not just `ByteBuffer`.
> This allows us to match expressiveness of JNI API, where JNI clients can obtain the address of any direct buffer instance, using the `GetDirectBufferAddress` function.
>
> We thought about also providing a more general way to view a segment as a buffer (e.g. asIntBuffer) but doing that doesn't seem worth it: direct buffers can only created form `ByteBuffer`.
> So, to create a direct `IntBuffer`, clients have to first create a direct `ByteBuffer` then to view that buffer as an `IntBuffer`.
>
> In other words, `IntBuffer` and friends are not first-class citizens in the `Buffer` API. As such it would not be possible to map many memory segments into an `IntBuffer`; in fact, the only segment we could safely map into an `IntBuffer` would be an _heap_ segment backed by an `int[]`. As such it doesn't seem worth adding a lot of API surface (in terms of additional overloads) for such a corner case.
src/java.base/share/classes/java/lang/foreign/MemorySegment.java line 88:
> 86: * if it is associated with a confined session, it can only be accessed by the thread which owns the memory session.
> 87: * <p>
> 88: * Heap segments are always associated with the {@linkplain MemorySession#global() global} memory session.
I've tweaked this text, as I realized the old version was erroneously suggesting that all buffer segments were backed by a global session.
src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java line 577:
> 575: }
> 576:
> 577: private static int getScaleFactor(Buffer buffer) {
Note: for each buffer kind, there are three possible cases. Consider `IntBuffer`: an `IntBuffer` can be backed by:
* `byte[]`, if it's a byte buffer view
* `int[]`, if it's allocated with `IntBuffer.allocate`, or `IntBuffer.wrap`
* null, if it comes from a direct byte buffer viewed as an `IntBuffer`
As such, the buffer kind (IntBuffer vs. LongBuffer) determines the buffer element size, and therefore how much the buffer position and size should be scaled.
But to check whether we need to create a heap vs. off-heap vs. mapped segment, or to check _which_ kind of heap segment we need, we need to look into the buffer base object, since there can be multiple options for any single buffer type.
-------------
PR: https://git.openjdk.java.net/jdk/pull/8701
More information about the security-dev
mailing list