1 /* 2 * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 /* 26 * @test 27 * @enablePreview 28 * @run testng TestVarHandleCombinators 29 */ 30 31 import java.lang.foreign.Arena; 32 import java.lang.foreign.ValueLayout; 33 34 import org.testng.annotations.Test; 35 36 import java.lang.foreign.MemorySegment; 37 import java.lang.invoke.MethodHandles; 38 import java.lang.invoke.VarHandle; 39 import java.nio.ByteOrder; 40 41 import static org.testng.Assert.assertEquals; 42 43 public class TestVarHandleCombinators { 44 45 @Test 46 public void testElementAccess() { 47 VarHandle vh = MethodHandles.memorySegmentViewVarHandle(ValueLayout.JAVA_BYTE); 48 49 byte[] arr = { 0, 0, -1, 0 }; 50 MemorySegment segment = MemorySegment.ofArray(arr); 51 assertEquals((byte) vh.get(segment, 2), (byte) -1); 52 } 53 54 @Test(expectedExceptions = IllegalArgumentException.class) 55 public void testUnalignedElement() { 56 VarHandle vh = MethodHandles.memorySegmentViewVarHandle(ValueLayout.JAVA_BYTE.withByteAlignment(4)); 57 MemorySegment segment = MemorySegment.ofArray(new byte[4]); 58 vh.get(segment, 2L); //should throw 59 //FIXME: the VH only checks the alignment of the segment, which is fine if the VH is derived from layouts, 60 //FIXME: but not if the VH is just created from scratch - we need a VH variable to govern this property, 61 //FIXME: at least until the VM is fixed 62 } 63 64 @Test 65 public void testAlign() { 66 VarHandle vh = MethodHandles.memorySegmentViewVarHandle(ValueLayout.JAVA_BYTE.withByteAlignment(2)); 67 68 Arena scope = Arena.ofAuto(); 69 MemorySegment segment = scope.allocate(1L, 2); 70 vh.set(segment, 0L, (byte) 10); // fine, memory region is aligned 71 assertEquals((byte) vh.get(segment, 0L), (byte) 10); 72 } 73 74 @Test 75 public void testByteOrderLE() { 76 VarHandle vh = MethodHandles.memorySegmentViewVarHandle(ValueLayout.JAVA_SHORT_UNALIGNED 77 .withOrder(ByteOrder.LITTLE_ENDIAN)); 78 byte[] arr = new byte[2]; 79 MemorySegment segment = MemorySegment.ofArray(arr); 80 vh.set(segment, 0L, (short) 0xFF); 81 assertEquals(arr[0], (byte) 0xFF); 82 assertEquals(arr[1], (byte) 0); 83 } 84 85 @Test 86 public void testByteOrderBE() { 87 VarHandle vh = MethodHandles.memorySegmentViewVarHandle(ValueLayout.JAVA_SHORT_UNALIGNED 88 .withOrder(ByteOrder.BIG_ENDIAN)); 89 byte[] arr = new byte[2]; 90 MemorySegment segment = MemorySegment.ofArray(arr); 91 vh.set(segment, 0L, (short) 0xFF); 92 assertEquals(arr[0], (byte) 0); 93 assertEquals(arr[1], (byte) 0xFF); 94 } 95 96 @Test 97 public void testNestedSequenceAccess() { 98 int outer_size = 10; 99 int inner_size = 5; 100 101 //[10 : [5 : [x32 i32]]] 102 103 VarHandle vh = MethodHandles.memorySegmentViewVarHandle(ValueLayout.JAVA_INT); 104 int count = 0; 105 try (Arena arena = Arena.ofConfined()) { 106 MemorySegment segment = arena.allocate(inner_size * outer_size * 8, 4); 107 for (long i = 0; i < outer_size; i++) { 108 for (long j = 0; j < inner_size; j++) { 109 vh.set(segment, i * 40 + j * 8, count); 110 assertEquals( 111 (int)vh.get(segment.asSlice(i * inner_size * 8), j * 8), 112 count); 113 count++; 114 } 115 } 116 } 117 } 118 }