zero-length segments
Michael Zucchi
notzed at gmail.com
Sun Jan 23 01:26:04 UTC 2022
Maurizio,
Thanks for taking this change on.
Cheers for the workaround too, it clicked as a possibility a bit later
on while i was cycling to the beach.
Regards,
Z
On 21/1/22 21:20, Maurizio Cimadamore wrote:
> Hi Michael,
> I think I'm sympathetic with your argument. Not only most of the other
> factories, as you noticed, do allow for zero-length segments, but
> there's also the MemorySegment::mapFile method, which specifically
> returns an instance of a special subclass if the mapped size if zero.
>
> I also did some more tests with the ByteBuffer API, which allows
> allocation (as you mention) with size = 0, but also allows slicing
> with slice size = 0 and limit of 0.
>
> (Java arrays are another case where creating a zero-element array is
> indeed possible).
>
> All this evidence point to the fact that, yes, saying no to zero-byte
> allocation on memory segment (of any kind) is at the very least
> problematic in terms of interop with existing APIs, as it will cause
> surprising behavior.
>
> For this reason, I believe the best course of action is to enhance the
> API in the way you suggest, and accept zero-sized segments.
>
> Thanks for the feedback!
>
> Thinking of possible workarounds in the short term - but maybe you are
> already doing it - you could have something like this:
>
> ```
> private static final MemorySegment EMPTY =
> MemorySegment.ofByteBuffer(ByteBuffer.allocateDirect(0));
>
> MemorySegment wrapAddress(MemoryAddress address, long size,
> ResourceScope scope) {
> return size == 0 ? EMPTY : MemorySegment.ofAddress(address, size,
> scope);
> }
> ```
>
> In terms of performance, there are a couple of points to note:
>
> * adding a singleton anonymous class for zero-sized segment might
> cause profile pollution when using the same callsite with empty and
> non-empty segments
> * having a branch (like in the above code) so that a singleton is
> returned if size == 0 effectively disables escape analysis most of the
> times (when size is not known by C2)
>
> And, other pseudo-random considerations:
>
> * Looking at the impl of ByteBuffer.allocateDirect, it seems like it
> always allocates at least one byte:
>
> ```
> long size = Math.max(1L, (long)cap + (pa ? ps : 0));
> Bits.reserveMemory(size, cap);
> ```
>
> You can see how this is suboptimal (and probably not what a programmer
> would expect).
>
> * In the case of MemorySegment, returning a singleton is not really
> possible, because (as for mapped segments) the user is also providing
> a scope parameter, and it expects that the returned segment will have
> same scope as the provided parameter.
>
> * All things considered, given it's late for 18, I'd prefer to address
> this in 19 - but I do want to address it.
>
> Thanks
> Maurizio
>
More information about the panama-dev
mailing list