Comments on SegmentAllocator and ResourceScope

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Mon May 17 10:26:06 UTC 2021


On 17/05/2021 07:47, Michael Zucchi wrote:
> Looks a bit odd but note that the original segment is still the 
> current one for subsequent allocations so it will still be used for 
> other small allocations, it probably doesn't have much effect but it 
> might reduce allocation holes.  Also whatever the value is the limit 
> has to be half the block allocation size for alignment to work 
> properly since the base allocations are assumed to be unaligned.
>
> It's also testing against the bytesAlignment aligned size which is not 
> the value bytesAlignment applies to, but by having MAX_ALLOC_SIZE == 
> BLOCK_SIZE/2 this also 'magically' tests the unaligned allocation size 
> limit required to guarantee satisfaction of the alignment as well.  
> Seems overly tricksy.  Also not a fan of "this should not be possible" 
> comment & assertion that only /seems/ to be there to check this 
> tricksiness and enforce the internal expected behaviour of trySlice() 
> - which isn't really serving any purpose as a separate function since 
> the 'try' only affects the first invocation and it isn't used elsewhere.
>
> This also causes the bug above and seems to indicate the 
> straightforward logic flow of "try-to-fit ELSE IF SMALL 
> allocate-and-slice ELSE allocate-separate" all in a single function 
> would be better - even if it does end up with more holes in certain 
> cases (you win some, you lose some).
It's true that MAX_ALLOC_SIZE is set to half the block so that we can 
still adjust for unaligned allocations within the allocated block. I'll 
see if the logic can be simplified - at the very minimum, if we want to 
reuse implementation between bounded and unbounded, some of these limits 
(block size, max allocation size) need to be made instance-dependent.
>
> As an aside the javadoc doesn't seem mention anywhere that 
> bytesAlignment must be a power of 2.  Neither is it checked for 
> validity, that may be on purpose for performance reasons but the 
> comparable posix_memalign() /aligned_alloc() fail with EINVAL if it 
> isn't and well things can get pretty bizarre if it isn't valid.  It 
> isn't an expensive check, 
> https://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2 
> or equivalently (Long.lowestOneBit(i) == i). 

The javadoc could probably be made clearer - but the only way to set 
alignment is "withAlignmentBits", and the javadoc there expects bit 
alignment to be a power of two and >= 8. So I think you can conclude 
that byte alignment must also be a power of two.

One thing which probably fell through the cracks, is that the alignment 
check does not apply when a layout is created - e.g. 
MemoryLayout.valueLayout(10, ByteOrder.nativeOrder()) succeeds, and sets 
alignment of 10, which is incorrect. Same is true for the recursive 
cases, e.g. when a struct/union/sequence layouts are created. I think 
some extra checks are required here. Also, if we want to allow sub-byte 
sizes (e.g. for describing bitmasks) we need to be able to accept bit 
alignment smaller (but still power of two) than 8, I think.

Maurizio



More information about the panama-dev mailing list