<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p><br>
</p>
<div class="moz-cite-prefix">On 14/06/2022 00:51, Alexander Biryukov
wrote:<br>
</div>
<blockquote type="cite" cite="mid:CACRQ6qscThCzmNFUT7X1YwZG1_T+vxXO=axcdN=-KVc+g4jxpw@mail.gmail.com">
<div dir="ltr">
<div>Thanks Maurizio, this is definitely helpful. I'll be
waiting for the updated constants, meanwhile using my own :)<br>
</div>
<div>I also think some of these points could be reflected in
documentation, especially the part about MemorySegment
dereferencing.<br>
</div>
</div>
</blockquote>
Hi,<br>
the documentation can be improved perhaps. I note that there is
already a section on alignment:
<p><a class="moz-txt-link-freetext" href="https://download.java.net/java/early_access/jdk19/docs/api/java.base/java/lang/foreign/MemorySegment.html#segment-alignment">https://download.java.net/java/early_access/jdk19/docs/api/java.base/java/lang/foreign/MemorySegment.html#segment-alignment</a></p>
<p>Which also explains in details how alignment w.r.t. heap segments
is enforced. But perhaps what's missing is a section which says:
ok, if you don't care about alignment, just do this.</p>
<p>Maurizio<br>
</p>
<blockquote type="cite" cite="mid:CACRQ6qscThCzmNFUT7X1YwZG1_T+vxXO=axcdN=-KVc+g4jxpw@mail.gmail.com">
<div dir="ltr">
<div><br>
</div>
<div>Best regards,</div>
<div>Alexander Biryukov<br>
</div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">пн, 13 июн. 2022 г. в 17:35,
Maurizio Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com" moz-do-not-send="true" class="moz-txt-link-freetext">maurizio.cimadamore@oracle.com</a>>:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi
Alexander,<br>
MemorySegment and ByteBuffer are a bit different when it comes
to <br>
dereferencing. ByteBuffers always allow you to dereference a
value, <br>
regardless of its starting offset. So you can read an `int`
value at <br>
offset 3 in a buffer - which might or might not be aligned
(but of <br>
course I do realized that, when working with packed
representation, <br>
alignment is not a concern).<br>
<br>
On the other hand, when a memory segment is dereferenced, the
<br>
ValueLayout used for the dereference operation is consulted.
This layout <br>
might have alignment information attached (all layout
constants provided <br>
by default such as JAVA_INT and JAVA_LONG do).<br>
<br>
So if you try something like<br>
<br>
segment.get(JAVA_INT, 3);<br>
<br>
This will likely fail with an alignment error.<br>
<br>
If this is not the behavior you want, because you work on
packed <br>
layouts, or you simply wants the same behavior you get with
the <br>
ByteBuffer API, the solution is to declare unaligned layout
constants - <br>
like this:<br>
<br>
final static ValueLayout.OfInt JAVA_INT_UNALIGNED = <br>
JAVA_INT.withBitAlignment(8);<br>
<br>
And then:<br>
<br>
segment.get(JAVA_INT_UNALIGNED, 3);<br>
<br>
This will work w/o issues.<br>
<br>
I note that this tends to come up quite a bit - which probably
suggests <br>
that working with unaligned layouts is not uncommon - we might
consider <br>
adding unaligned layout constants in the ValueLayout API, so
that both <br>
aligned and unaligned use cases are supported
"out-of-the-box". But the <br>
capability to support unaligned access is there.<br>
<br>
I hope this helps<br>
Maurizio<br>
<br>
On 13/06/2022 14:06, Alexander Biryukov wrote:<br>
> Hi, I'm testing MemorySegment and stumbled across some
inconsistent<br>
> behavior in the API.<br>
><br>
> I have the following task:<br>
> * read binary file to RAM, file structure is fixed, but
no<br>
> padding/alignment is present (lots of strings of variable
length)<br>
> * read file content depending on the user input, e.g.
sometimes I need to<br>
> read offset 13, sometimes offset 24 and so on<br>
> * Stored values are typically privitives (byte, long,
double etc) or arrays<br>
> (byte[], short[], int[] and so on)<br>
> * Primitives are decoded on the fly to variables, same is
true for arrays<br>
> (random access) or sometimes arrays are copied as a blob
to another<br>
> MemorySegment<br>
><br>
> I'm trying to create a VarHandle for MemorySegment:<br>
><br>
>> @Test<br>
>> fun sample() {<br>
>> val mem = MemorySegment.allocateNative(100,<br>
>> MemorySession.openImplicit())<br>
>> val buf =
ByteBuffer.allocateDirect(100).order(ByteOrder.LITTLE_ENDIAN)<br>
>> buf.put(-20) // 0<br>
>> buf.putDouble(5.0) // 1<br>
>> buf.put(2) // 9<br>
>> buf.putInt(5) // 10<br>
>> buf.putInt(10) // 14<br>
>> buf.flip()<br>
>> mem.copyFrom(MemorySegment.ofBuffer(buf))<br>
>><br>
> val mh =
MethodHandles.memorySegmentViewVarHandle(ValueLayout.JAVA_INT)<br>
>> val bh =
MethodHandles.byteBufferViewVarHandle(IntArray::class.java,<br>
>> ByteOrder.LITTLE_ENDIAN)<br>
><br>
>> println(mh.get(mem, 14L) as Int)
// <-- throws<br>
>> "Misaligned access at address"<br>
>> println(bh.get(mem.asByteBuffer(), 14) as Int)
// works, prints "10"<br>
>> }<br>
><br>
> The variant with memorySegmentViewVarHandle throws, while
variant with<br>
> byteBufferViewVarHandle works.<br>
> I checked the source code and found that for some reason
MemorySegment-variant<br>
> uses offsetNoVMAlignCheck, while ByteBuffer-variant
doesn't.<br>
> Here's the code from the source:<br>
><br>
> ByteBuffer-variant<br>
><br>
>> return UNSAFE.getLongUnaligned(<br>
>> ba,<br>
>> ((long) index(ba, index)) +
Unsafe.ARRAY_BYTE_BASE_OFFSET,<br>
>> <a href="https://urldefense.com/v3/__http://handle.be__;!!ACWV5N9M2RV99hQ!LiFa43Fuc1M0ZIi2xsVdjDyRPIsqkSPux6u3cqQXwzuopEHcKeuZHYrniUbTV6Bu73hNjNbEA5fVv14EOp9dOgdnxA$" rel="noreferrer" target="_blank" moz-do-not-send="true">handle.be</a>);<br>
>><br>
> MemorySegment-variant<br>
><br>
>> return
SCOPED_MEMORY_ACCESS.getIntUnaligned(bb.sessionImpl(),<br>
>> bb.unsafeGetBase(),<br>
>> offsetNoVMAlignCheck(bb, base,
handle.alignmentMask),<br>
>> <a href="https://urldefense.com/v3/__http://handle.be__;!!ACWV5N9M2RV99hQ!LiFa43Fuc1M0ZIi2xsVdjDyRPIsqkSPux6u3cqQXwzuopEHcKeuZHYrniUbTV6Bu73hNjNbEA5fVv14EOp9dOgdnxA$" rel="noreferrer" target="_blank" moz-do-not-send="true">handle.be</a>);<br>
>><br>
><br>
> I'm not sure, but it seems like offsetNoVMAlignCheck
shouldn't be present<br>
> or there must be an alternative API for querying
unaligned data?<br>
> If nothing is wrong, is there a way to query data in
MemorySegment without<br>
> alignment?<br>
> ByteBuffer is technically fine for the time being, but
I'm expecting a high<br>
> load on the service, and since I'm not using ByteBuffers
I'd rather not pay<br>
> for them (GC).<br>
><br>
><br>
> Best regards,<br>
> Alexander Biryukov<br>
</blockquote>
</div>
</blockquote>
</body>
</html>