1 /* 2 * Copyright (c) 2019, 2020, 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 TestArrays 28 */ 29 30 import jdk.incubator.foreign.MemoryAddress; 31 import jdk.incubator.foreign.MemoryLayout; 32 import jdk.incubator.foreign.MemoryLayout.PathElement; 33 import jdk.incubator.foreign.MemoryLayouts; 34 import jdk.incubator.foreign.MemorySegment; 35 import jdk.incubator.foreign.SequenceLayout; 36 37 import java.lang.invoke.VarHandle; 38 import java.util.function.BiConsumer; 39 import java.util.function.Consumer; 40 41 import org.testng.SkipException; 42 import org.testng.annotations.*; 43 import static org.testng.Assert.*; 44 45 public class TestArrays { 46 47 static SequenceLayout bytes = MemoryLayout.ofSequence(100, 48 MemoryLayouts.JAVA_BYTE 49 ); 50 51 static SequenceLayout chars = MemoryLayout.ofSequence(100, 52 MemoryLayouts.JAVA_CHAR 53 ); 54 55 static SequenceLayout shorts = MemoryLayout.ofSequence(100, 56 MemoryLayouts.JAVA_SHORT 57 ); 58 59 static SequenceLayout ints = MemoryLayout.ofSequence(100, 60 MemoryLayouts.JAVA_INT 61 ); 62 63 static SequenceLayout floats = MemoryLayout.ofSequence(100, 64 MemoryLayouts.JAVA_FLOAT 65 ); 66 67 static SequenceLayout longs = MemoryLayout.ofSequence(100, 68 MemoryLayouts.JAVA_LONG 69 ); 70 71 static SequenceLayout doubles = MemoryLayout.ofSequence(100, 72 MemoryLayouts.JAVA_DOUBLE 73 ); 74 75 static VarHandle byteHandle = bytes.varHandle(byte.class, PathElement.sequenceElement()); 76 static VarHandle charHandle = chars.varHandle(char.class, PathElement.sequenceElement()); 77 static VarHandle shortHandle = shorts.varHandle(short.class, PathElement.sequenceElement()); 78 static VarHandle intHandle = ints.varHandle(int.class, PathElement.sequenceElement()); 79 static VarHandle floatHandle = floats.varHandle(float.class, PathElement.sequenceElement()); 80 static VarHandle longHandle = longs.varHandle(long.class, PathElement.sequenceElement()); 81 static VarHandle doubleHandle = doubles.varHandle(double.class, PathElement.sequenceElement()); 82 83 static void initBytes(MemoryAddress base, SequenceLayout seq, BiConsumer<MemoryAddress, Long> handleSetter) { 84 for (long i = 0; i < seq.elementCount().getAsLong() ; i++) { 85 handleSetter.accept(base, i); 86 } 87 } 88 89 static void checkBytes(MemoryAddress base, SequenceLayout layout) { 90 long nBytes = layout.elementCount().getAsLong() * layout.elementLayout().byteSize(); 91 byte[] arr = base.segment().toByteArray(); 92 for (long i = 0 ; i < nBytes ; i++) { 93 byte expected = (byte)byteHandle.get(base, i); 94 byte found = arr[(int)i]; 95 assertEquals(expected, found); 96 } 97 } 98 99 @Test(dataProvider = "arrays") 100 public void testArrays(Consumer<MemoryAddress> init, SequenceLayout layout) { 101 try (MemorySegment segment = MemorySegment.allocateNative(layout)) { 102 init.accept(segment.baseAddress()); 103 checkBytes(segment.baseAddress(), layout); 104 } 105 } 106 107 @Test(expectedExceptions = { UnsupportedOperationException.class, 108 OutOfMemoryError.class }) 109 public void testTooBigForArray() { 110 if (System.getProperty("sun.arch.data.model").equals("32")) { 111 throw new SkipException("32-bit Unsafe does not support this allocation size"); 112 } 113 114 MemorySegment.allocateNative((long) Integer.MAX_VALUE * 2).toByteArray(); 115 } 116 117 @Test(expectedExceptions = IllegalStateException.class) 118 public void testArrayFromClosedSegment() { 119 MemorySegment segment = MemorySegment.allocateNative(8); 120 segment.close(); 121 segment.toByteArray(); 122 } 123 124 @DataProvider(name = "arrays") 125 public Object[][] nativeAccessOps() { 126 Consumer<MemoryAddress> byteInitializer = 127 (base) -> initBytes(base, bytes, (addr, pos) -> byteHandle.set(addr, pos, (byte)(long)pos)); 128 Consumer<MemoryAddress> charInitializer = 129 (base) -> initBytes(base, chars, (addr, pos) -> charHandle.set(addr, pos, (char)(long)pos)); 130 Consumer<MemoryAddress> shortInitializer = 131 (base) -> initBytes(base, shorts, (addr, pos) -> shortHandle.set(addr, pos, (short)(long)pos)); 132 Consumer<MemoryAddress> intInitializer = 133 (base) -> initBytes(base, ints, (addr, pos) -> intHandle.set(addr, pos, (int)(long)pos)); 134 Consumer<MemoryAddress> floatInitializer = 135 (base) -> initBytes(base, floats, (addr, pos) -> floatHandle.set(addr, pos, (float)(long)pos)); 136 Consumer<MemoryAddress> longInitializer = 137 (base) -> initBytes(base, longs, (addr, pos) -> longHandle.set(addr, pos, (long)pos)); 138 Consumer<MemoryAddress> doubleInitializer = 139 (base) -> initBytes(base, doubles, (addr, pos) -> doubleHandle.set(addr, pos, (double)(long)pos)); 140 141 return new Object[][]{ 142 {byteInitializer, bytes}, 143 {charInitializer, chars}, 144 {shortInitializer, shorts}, 145 {intInitializer, ints}, 146 {floatInitializer, floats}, 147 {longInitializer, longs}, 148 {doubleInitializer, doubles} 149 }; 150 } 151 }