1 /* 2 * Copyright (c) 2019, 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 * @run testng TestVarHandleCombinators 28 */ 29 30 import jdk.incubator.foreign.MemoryHandles; 31 import org.testng.annotations.DataProvider; 32 import org.testng.annotations.Test; 33 34 import jdk.incubator.foreign.MemoryAddress; 35 import jdk.incubator.foreign.MemorySegment; 36 37 import java.lang.invoke.VarHandle; 38 import java.nio.ByteOrder; 39 40 import static org.testng.Assert.assertEquals; 41 42 public class TestVarHandleCombinators { 43 44 @Test 45 public void testElementAccess() { 46 VarHandle vh = MemoryHandles.varHandle(byte.class, ByteOrder.nativeOrder()); 47 vh = MemoryHandles.withStride(vh, 1); 48 49 byte[] arr = { 0, 0, -1, 0 }; 50 MemorySegment segment = MemorySegment.ofArray(arr); 51 MemoryAddress addr = segment.baseAddress(); 52 53 assertEquals((byte) vh.get(addr, 2), (byte) -1); 54 } 55 56 @Test(expectedExceptions = IllegalArgumentException.class) 57 public void testUnalignedElement() { 58 VarHandle vh = MemoryHandles.varHandle(byte.class, 4, ByteOrder.nativeOrder()); 59 MemoryHandles.withStride(vh, 2); 60 } 61 62 @Test(expectedExceptions = IllegalArgumentException.class) 63 public void testBadStrideElement() { 64 VarHandle vh = MemoryHandles.varHandle(int.class, ByteOrder.nativeOrder()); 65 MemoryHandles.withStride(vh, 0); //scale factor cant be zero 66 } 67 68 @Test(expectedExceptions = IllegalArgumentException.class) 69 public void testAlignNotPowerOf2() { 70 VarHandle vh = MemoryHandles.varHandle(byte.class, 3, ByteOrder.nativeOrder()); 71 } 72 73 @Test(expectedExceptions = IllegalArgumentException.class) 74 public void testAlignNegative() { 75 VarHandle vh = MemoryHandles.varHandle(byte.class, -1, ByteOrder.nativeOrder()); 76 } 77 78 @Test 79 public void testAlign() { 80 VarHandle vh = MemoryHandles.varHandle(byte.class, 2, ByteOrder.nativeOrder()); 81 82 MemorySegment segment = MemorySegment.allocateNative(1, 2); 83 MemoryAddress address = segment.baseAddress(); 84 85 vh.set(address, (byte) 10); // fine, memory region is aligned 86 assertEquals((byte) vh.get(address), (byte) 10); 87 } 88 89 @Test(expectedExceptions = IllegalArgumentException.class) 90 public void testAlignBadAccess() { 91 VarHandle vh = MemoryHandles.varHandle(byte.class, 2, ByteOrder.nativeOrder()); 92 vh = MemoryHandles.withOffset(vh, 1); // offset by 1 byte 93 94 MemorySegment segment = MemorySegment.allocateNative(2, 2); 95 MemoryAddress address = segment.baseAddress(); 96 97 vh.set(address, (byte) 10); // should be bad align 98 } 99 100 @Test(expectedExceptions = IllegalArgumentException.class) 101 public void testOffsetNegative() { 102 VarHandle vh = MemoryHandles.varHandle(byte.class, ByteOrder.nativeOrder()); 103 MemoryHandles.withOffset(vh, -1); 104 } 105 106 @Test(expectedExceptions = IllegalArgumentException.class) 107 public void testUnalignedOffset() { 108 VarHandle vh = MemoryHandles.varHandle(byte.class, 4, ByteOrder.nativeOrder()); 109 MemoryHandles.withOffset(vh, 2); 110 } 111 112 @Test 113 public void testOffset() { 114 VarHandle vh = MemoryHandles.varHandle(byte.class, ByteOrder.nativeOrder()); 115 vh = MemoryHandles.withOffset(vh, 1); 116 117 MemorySegment segment = MemorySegment.ofArray(new byte[2]); 118 MemoryAddress address = segment.baseAddress(); 119 120 vh.set(address, (byte) 10); 121 assertEquals((byte) vh.get(address), (byte) 10); 122 } 123 124 @Test 125 public void testByteOrderLE() { 126 VarHandle vh = MemoryHandles.varHandle(short.class, 2, ByteOrder.LITTLE_ENDIAN); 127 byte[] arr = new byte[2]; 128 MemorySegment segment = MemorySegment.ofArray(arr); 129 MemoryAddress address = segment.baseAddress(); 130 131 vh.set(address, (short) 0xFF); 132 assertEquals(arr[0], (byte) 0xFF); 133 assertEquals(arr[1], (byte) 0); 134 } 135 136 @Test 137 public void testByteOrderBE() { 138 VarHandle vh = MemoryHandles.varHandle(short.class, 2, ByteOrder.BIG_ENDIAN); 139 byte[] arr = new byte[2]; 140 MemorySegment segment = MemorySegment.ofArray(arr); 141 MemoryAddress address = segment.baseAddress(); 142 143 vh.set(address, (short) 0xFF); 144 assertEquals(arr[0], (byte) 0); 145 assertEquals(arr[1], (byte) 0xFF); 146 } 147 148 @Test 149 public void testNestedSequenceAccess() { 150 int outer_size = 10; 151 int inner_size = 5; 152 153 //[10 : [5 : [x32 i32]]] 154 155 VarHandle vh = MemoryHandles.varHandle(int.class, ByteOrder.nativeOrder()); 156 vh = MemoryHandles.withOffset(vh, 4); 157 VarHandle inner_vh = MemoryHandles.withStride(vh, 8); 158 VarHandle outer_vh = MemoryHandles.withStride(inner_vh, 5 * 8); 159 int count = 0; 160 try (MemorySegment segment = MemorySegment.allocateNative(inner_size * outer_size * 8)) { 161 for (long i = 0; i < outer_size; i++) { 162 for (long j = 0; j < inner_size; j++) { 163 outer_vh.set(segment.baseAddress(), i, j, count); 164 assertEquals( 165 (int)inner_vh.get(segment.baseAddress().offset(i * inner_size * 8), j), 166 count); 167 count++; 168 } 169 } 170 } 171 } 172 173 @Test(dataProvider = "badCarriers", expectedExceptions = IllegalArgumentException.class) 174 public void testBadCarrier(Class<?> carrier) { 175 MemoryHandles.varHandle(carrier, ByteOrder.nativeOrder()); 176 } 177 178 @DataProvider(name = "badCarriers") 179 public Object[][] createBadCarriers() { 180 return new Object[][] { 181 { void.class }, 182 { boolean.class }, 183 { Object.class }, 184 { int[].class }, 185 { MemoryAddress.class } 186 }; 187 } 188 189 }