Memory segment and unaligned access
Alexander Biryukov
sanya.rnd at gmail.com
Mon Jun 13 13:06:24 UTC 2022
Hi, I'm testing MemorySegment and stumbled across some inconsistent
behavior in the API.
I have the following task:
* read binary file to RAM, file structure is fixed, but no
padding/alignment is present (lots of strings of variable length)
* read file content depending on the user input, e.g. sometimes I need to
read offset 13, sometimes offset 24 and so on
* Stored values are typically privitives (byte, long, double etc) or arrays
(byte[], short[], int[] and so on)
* Primitives are decoded on the fly to variables, same is true for arrays
(random access) or sometimes arrays are copied as a blob to another
MemorySegment
I'm trying to create a VarHandle for MemorySegment:
> @Test
> fun sample() {
> val mem = MemorySegment.allocateNative(100,
> MemorySession.openImplicit())
> val buf = ByteBuffer.allocateDirect(100).order(ByteOrder.LITTLE_ENDIAN)
> buf.put(-20) // 0
> buf.putDouble(5.0) // 1
> buf.put(2) // 9
> buf.putInt(5) // 10
> buf.putInt(10) // 14
> buf.flip()
> mem.copyFrom(MemorySegment.ofBuffer(buf))
>
>
val mh = MethodHandles.memorySegmentViewVarHandle(ValueLayout.JAVA_INT)
> val bh = MethodHandles.byteBufferViewVarHandle(IntArray::class.java,
> ByteOrder.LITTLE_ENDIAN)
> println(mh.get(mem, 14L) as Int) // <-- throws
> "Misaligned access at address"
> println(bh.get(mem.asByteBuffer(), 14) as Int) // works, prints "10"
> }
The variant with memorySegmentViewVarHandle throws, while variant with
byteBufferViewVarHandle works.
I checked the source code and found that for some reason MemorySegment-variant
uses offsetNoVMAlignCheck, while ByteBuffer-variant doesn't.
Here's the code from the source:
ByteBuffer-variant
> return UNSAFE.getLongUnaligned(
> ba,
> ((long) index(ba, index)) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
> handle.be);
>
MemorySegment-variant
> return SCOPED_MEMORY_ACCESS.getIntUnaligned(bb.sessionImpl(),
> bb.unsafeGetBase(),
> offsetNoVMAlignCheck(bb, base, handle.alignmentMask),
> handle.be);
>
I'm not sure, but it seems like offsetNoVMAlignCheck shouldn't be present
or there must be an alternative API for querying unaligned data?
If nothing is wrong, is there a way to query data in MemorySegment without
alignment?
ByteBuffer is technically fine for the time being, but I'm expecting a high
load on the service, and since I'm not using ByteBuffers I'd rather not pay
for them (GC).
Best regards,
Alexander Biryukov
More information about the panama-dev
mailing list