Ability to extend a MemorySegment

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Tue Jan 21 17:31:22 UTC 2020


I cooked up this test:

public class TestUnionAccess {
     static final GroupLayout union = MemoryLayout.ofUnion(
             MemoryLayouts.JAVA_BYTE.withName("one"),
             MemoryLayouts.JAVA_LONG.withName("two"),
             MemoryLayouts.JAVA_INT.withName("three"));

     static final VarHandle unionHandle = 
MemoryLayouts.JAVA_LONG.varHandle(long.class);
     static final VarHandle fieldHandle = union.varHandle(long.class, 
MemoryLayout.PathElement.groupElement("two"));

     @Test
     public void testUnionHandles() {
         try (MemorySegment segment = MemorySegment.allocateNative(union)) {
             fieldHandle.set(segment.baseAddress(), Long.MAX_VALUE);
assertEquals((long)unionHandle.get(segment.baseAddress()), Long.MAX_VALUE);
assertEquals((long)fieldHandle.get(segment.baseAddress()), Long.MAX_VALUE);
             unionHandle.set(segment.baseAddress(), Long.MIN_VALUE);
assertEquals((long)unionHandle.get(segment.baseAddress()), Long.MIN_VALUE);
assertEquals((long)fieldHandle.get(segment.baseAddress()), Long.MIN_VALUE);
             fieldHandle.set(segment.baseAddress(), Long.MAX_VALUE);
assertEquals((long)unionHandle.get(segment.baseAddress()), Long.MAX_VALUE);
assertEquals((long)fieldHandle.get(segment.baseAddress()), Long.MAX_VALUE);
         }
     }

     @Test
     public void testUnionSlices() {
         try (MemorySegment segment = MemorySegment.allocateNative(union)) {
             MemoryAddress unionAddress = segment.baseAddress();
             MemoryAddress fieldAddress = segment.asSlice(0, 
union.memberLayouts().get(1).byteSize()).baseAddress();
             fieldHandle.set(fieldAddress, Long.MAX_VALUE);
             assertEquals((long)fieldHandle.get(unionAddress), 
Long.MAX_VALUE);
             assertEquals((long)fieldHandle.get(fieldAddress), 
Long.MAX_VALUE);
             fieldHandle.set(unionAddress, Long.MIN_VALUE);
             assertEquals((long)fieldHandle.get(unionAddress), 
Long.MIN_VALUE);
             assertEquals((long)fieldHandle.get(fieldAddress), 
Long.MIN_VALUE);
             fieldHandle.set(fieldAddress, Long.MAX_VALUE);
             assertEquals((long)fieldHandle.get(unionAddress), 
Long.MAX_VALUE);
             assertEquals((long)fieldHandle.get(fieldAddress), 
Long.MAX_VALUE);
         }
     }
}

This passes without issues.

I took a look at your code - and I noticed an endianness mismatch 
between NumberField and Union:

https://github.com/BlueGoliath/Crosspoint/blob/master/src/main/java/org/goliath/crosspoint/fields/NumberField.java#L29

vs.

https://github.com/BlueGoliath/Crosspoint/blob/master/src/main/java/org/goliath/crosspoint/unions/BasicUnion.java#L39

Could this be the issue?

Maurizio



On 21/01/2020 17:03, Ty Young wrote:
> Yes.
>
>
> Union<Long> union = Union.ofLayouts(MemoryLayouts.JAVA_BYTE, 
> MemoryLayouts.JAVA_LONG, MemoryLayouts.JAVA_INT);
>
> Field<Long> field = union.getField(1);
>
> field.setValue(Long.MAX_VALUE);
>
> System.out.println(field.getValue()); // GOOD
>
> union.setValue(Long.MIN_VALUE);
>
> System.out.println(field.getValue()); // BAD
>
> field.setValue(Long.MAX_VALUE);
>
> System.out.println(union.getValue()); // BAD
>
> System.out.println(field.getValue()); // GOOD
>
>
> Union class can be found here: 
> https://github.com/BlueGoliath/Crosspoint/blob/master/src/main/java/org/goliath/crosspoint/unions/BasicUnion.java
>
>
>
> On 1/21/20 10:39 AM, Maurizio Cimadamore wrote:
>> Not aware of anything deliberate here - do you have an example?
>>
>> Maurizio
>>
>> On 21/01/2020 16:31, Ty Young wrote:
>>> I've noticed some weirdness with Unions in Memory Access as well - 
>>> creating a slice that is the exact size of the Union's 
>>> MemoryAddress(long for example) and applying a value results in the 
>>> Union's base MemoryAddress being made invalid(despite being the same 
>>> size). Maybe that's intentional. 


More information about the panama-dev mailing list