Allocating an Array segment of a primitive type with 1 initialized element.

Jorn Vernee jorn.vernee at oracle.com
Wed Jul 5 22:05:13 UTC 2023


Hello,

 > I get that allocating an array of length 1 is not common but it still 
seems a bit off

I agree, it seems a bit off. I've filed an issue: 
https://bugs.openjdk.org/browse/JDK-8311533 (assuming you're talking 
about SegmentAllocator::allocateArray, as MemorySegment doesn't have 
such a method).

I agree that one of these overloads should be renamed. They both 
semantically do something different. One merely allocates an empty 
memory segment, the other also initializes its contents.

'allocateArrayFromValues' seems like a decent suggestion. Maybe a 
simpler 'allocateArrayOf' also works, since we have 
MemorySegment::ofArray as well. Or maybe we can just rename the 
(MemoryLayout, long) overload to 'allocate', and keep 'allocateArray' 
for the other overload. Will think about it.

Thanks for the report,
Jorn

On 05/07/2023 21:24, Philip Race wrote:
> MemorySegment.allocateArray() has these variants
>
> default MemorySegment allocateArray(MemoryLayout elementLayout, long 
> count)
> and
> default MemorySegment allocateArray(ValueLayout.OfLong elementLayout, 
> long... elements)
> default MemorySegment allocateArray(ValueLayout.OfInt elementLayout, 
> long... elements)
> (etc)
> and in all cases the first arg is a MemoryLayout
>
> eg it could be this
> ValueLayout.OfLong JAVA_LONG;
> where
> ValueLayout.OfLong extends ValueLayout
> ValueLayout extends MemoryLayout
>
> So what happens if you want to allocate an array of length 1  with 
> value 10 ?
>
> You'll try something like
> MemorySegment.allocateArray(JAVA_LONG, 10);
> but that doesn't get you what you expected
>
> import java.lang.foreign.*;
> import static java.lang.foreign.ValueLayout.*;
>
> public class AllocArray {
>
>   public static void main(String[] args) {
>     try (Arena arena = Arena.ofConfined()) {
>        MemorySegment lseg1 = arena.allocateArray(JAVA_LONG, 10L);
>        MemorySegment lseg2 = arena.allocateArray(JAVA_LONG, 10L, 20L);
>        MemorySegment iseg1 = arena.allocateArray(JAVA_INT, 10);
>        MemorySegment iseg2 = arena.allocateArray(JAVA_INT, 10, 20);
>        System.out.println("long seg1 size = " + lseg1.byteSize());
>        System.out.println("long seg2 size = " + lseg2.byteSize());
>        System.out.println("int seg1 size = " + iseg1.byteSize());
>        System.out.println("int seg2 size = " + iseg2.byteSize());
>     } catch (Throwable t) {
>       t.printStackTrace();
>     }
>  }
> }
>
> % javac --enable-preview -source 22 AllocArray.java
> % java --enable-preview  AllocArray
> long seg1 size = 80
> long seg2 size = 16
> int seg1 size = 40
> int seg2 size = 8
>
>
> I get that allocating an array of length 1 is not common but it still 
> seems a bit off, and
> I'm surprised the compiler didn't prefer the more specific case.
> Unless I am missing something it seems to me that for the sake of 
> clarity that
> the first version should be renamed allocateArrayOfLength(), or
> the second renamed to something like allocateArrayFromValues()
>
>


More information about the panama-dev mailing list