Path: blob/master/test/jdk/java/foreign/TestArrays.java
41144 views
/*1* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324/*25* @test26* @run testng/othervm --enable-native-access=ALL-UNNAMED TestArrays27*/2829import jdk.incubator.foreign.MemoryAddress;30import jdk.incubator.foreign.MemoryLayout;31import jdk.incubator.foreign.MemoryLayout.PathElement;32import jdk.incubator.foreign.MemoryLayouts;33import jdk.incubator.foreign.MemorySegment;34import jdk.incubator.foreign.ResourceScope;35import jdk.incubator.foreign.SequenceLayout;3637import java.lang.invoke.VarHandle;38import java.util.function.BiConsumer;39import java.util.function.BiFunction;40import java.util.function.Consumer;41import java.util.function.Function;4243import org.testng.annotations.*;4445import static org.testng.Assert.*;4647public class TestArrays {4849static SequenceLayout bytes = MemoryLayout.sequenceLayout(100,50MemoryLayouts.JAVA_BYTE51);5253static SequenceLayout chars = MemoryLayout.sequenceLayout(100,54MemoryLayouts.JAVA_CHAR55);5657static SequenceLayout shorts = MemoryLayout.sequenceLayout(100,58MemoryLayouts.JAVA_SHORT59);6061static SequenceLayout ints = MemoryLayout.sequenceLayout(100,62MemoryLayouts.JAVA_INT63);6465static SequenceLayout floats = MemoryLayout.sequenceLayout(100,66MemoryLayouts.JAVA_FLOAT67);6869static SequenceLayout longs = MemoryLayout.sequenceLayout(100,70MemoryLayouts.JAVA_LONG71);7273static SequenceLayout doubles = MemoryLayout.sequenceLayout(100,74MemoryLayouts.JAVA_DOUBLE75);7677static VarHandle byteHandle = bytes.varHandle(byte.class, PathElement.sequenceElement());78static VarHandle charHandle = chars.varHandle(char.class, PathElement.sequenceElement());79static VarHandle shortHandle = shorts.varHandle(short.class, PathElement.sequenceElement());80static VarHandle intHandle = ints.varHandle(int.class, PathElement.sequenceElement());81static VarHandle floatHandle = floats.varHandle(float.class, PathElement.sequenceElement());82static VarHandle longHandle = longs.varHandle(long.class, PathElement.sequenceElement());83static VarHandle doubleHandle = doubles.varHandle(double.class, PathElement.sequenceElement());8485static void initBytes(MemorySegment base, SequenceLayout seq, BiConsumer<MemorySegment, Long> handleSetter) {86for (long i = 0; i < seq.elementCount().getAsLong() ; i++) {87handleSetter.accept(base, i);88}89}9091static void checkBytes(MemorySegment base, SequenceLayout layout, Function<MemorySegment, Object> arrayFactory, BiFunction<MemorySegment, Long, Object> handleGetter) {92int nelems = (int)layout.elementCount().getAsLong();93Object arr = arrayFactory.apply(base);94for (int i = 0; i < nelems; i++) {95Object found = handleGetter.apply(base, (long) i);96Object expected = java.lang.reflect.Array.get(arr, i);97assertEquals(expected, found);98}99}100101@Test(dataProvider = "arrays")102public void testArrays(Consumer<MemorySegment> init, Consumer<MemorySegment> checker, MemoryLayout layout) {103MemorySegment segment = MemorySegment.allocateNative(layout, ResourceScope.newImplicitScope());104init.accept(segment);105assertFalse(segment.isReadOnly());106checker.accept(segment);107}108109@Test(dataProvider = "elemLayouts",110expectedExceptions = IllegalStateException.class)111public void testTooBigForArray(MemoryLayout layout, Function<MemorySegment, Object> arrayFactory) {112MemoryLayout seq = MemoryLayout.sequenceLayout((Integer.MAX_VALUE * layout.byteSize()) + 1, layout);113//do not really allocate here, as it's way too much memory114MemorySegment segment = MemoryAddress.NULL.asSegment(seq.byteSize(), ResourceScope.globalScope());115arrayFactory.apply(segment);116}117118@Test(dataProvider = "elemLayouts",119expectedExceptions = IllegalStateException.class)120public void testBadSize(MemoryLayout layout, Function<MemorySegment, Object> arrayFactory) {121if (layout.byteSize() == 1) throw new IllegalStateException(); //make it fail122try (ResourceScope scope = ResourceScope.newConfinedScope()) {123MemorySegment segment = MemorySegment.allocateNative(layout.byteSize() + 1, layout.byteSize(), scope);124arrayFactory.apply(segment);125}126}127128@Test(dataProvider = "elemLayouts",129expectedExceptions = IllegalStateException.class)130public void testArrayFromClosedSegment(MemoryLayout layout, Function<MemorySegment, Object> arrayFactory) {131MemorySegment segment = MemorySegment.allocateNative(layout, ResourceScope.newConfinedScope());132segment.scope().close();133arrayFactory.apply(segment);134}135136@DataProvider(name = "arrays")137public Object[][] nativeAccessOps() {138Consumer<MemorySegment> byteInitializer =139(base) -> initBytes(base, bytes, (addr, pos) -> byteHandle.set(addr, pos, (byte)(long)pos));140Consumer<MemorySegment> charInitializer =141(base) -> initBytes(base, chars, (addr, pos) -> charHandle.set(addr, pos, (char)(long)pos));142Consumer<MemorySegment> shortInitializer =143(base) -> initBytes(base, shorts, (addr, pos) -> shortHandle.set(addr, pos, (short)(long)pos));144Consumer<MemorySegment> intInitializer =145(base) -> initBytes(base, ints, (addr, pos) -> intHandle.set(addr, pos, (int)(long)pos));146Consumer<MemorySegment> floatInitializer =147(base) -> initBytes(base, floats, (addr, pos) -> floatHandle.set(addr, pos, (float)(long)pos));148Consumer<MemorySegment> longInitializer =149(base) -> initBytes(base, longs, (addr, pos) -> longHandle.set(addr, pos, (long)pos));150Consumer<MemorySegment> doubleInitializer =151(base) -> initBytes(base, doubles, (addr, pos) -> doubleHandle.set(addr, pos, (double)(long)pos));152153Consumer<MemorySegment> byteChecker =154(base) -> checkBytes(base, bytes, MemorySegment::toByteArray, (addr, pos) -> (byte)byteHandle.get(addr, pos));155Consumer<MemorySegment> shortChecker =156(base) -> checkBytes(base, shorts, MemorySegment::toShortArray, (addr, pos) -> (short)shortHandle.get(addr, pos));157Consumer<MemorySegment> charChecker =158(base) -> checkBytes(base, chars, MemorySegment::toCharArray, (addr, pos) -> (char)charHandle.get(addr, pos));159Consumer<MemorySegment> intChecker =160(base) -> checkBytes(base, ints, MemorySegment::toIntArray, (addr, pos) -> (int)intHandle.get(addr, pos));161Consumer<MemorySegment> floatChecker =162(base) -> checkBytes(base, floats, MemorySegment::toFloatArray, (addr, pos) -> (float)floatHandle.get(addr, pos));163Consumer<MemorySegment> longChecker =164(base) -> checkBytes(base, longs, MemorySegment::toLongArray, (addr, pos) -> (long)longHandle.get(addr, pos));165Consumer<MemorySegment> doubleChecker =166(base) -> checkBytes(base, doubles, MemorySegment::toDoubleArray, (addr, pos) -> (double)doubleHandle.get(addr, pos));167168return new Object[][]{169{byteInitializer, byteChecker, bytes},170{charInitializer, charChecker, chars},171{shortInitializer, shortChecker, shorts},172{intInitializer, intChecker, ints},173{floatInitializer, floatChecker, floats},174{longInitializer, longChecker, longs},175{doubleInitializer, doubleChecker, doubles}176};177}178179@DataProvider(name = "elemLayouts")180public Object[][] elemLayouts() {181return new Object[][] {182{ MemoryLayouts.JAVA_BYTE, (Function<MemorySegment, Object>) MemorySegment::toByteArray },183{ MemoryLayouts.JAVA_SHORT, (Function<MemorySegment, Object>) MemorySegment::toShortArray },184{ MemoryLayouts.JAVA_CHAR, (Function<MemorySegment, Object>) MemorySegment::toCharArray },185{ MemoryLayouts.JAVA_INT, (Function<MemorySegment, Object>) MemorySegment::toIntArray },186{ MemoryLayouts.JAVA_FLOAT, (Function<MemorySegment, Object>) MemorySegment::toFloatArray },187{ MemoryLayouts.JAVA_LONG, (Function<MemorySegment, Object>) MemorySegment::toLongArray },188{ MemoryLayouts.JAVA_DOUBLE, (Function<MemorySegment, Object>) MemorySegment::toDoubleArray }189};190}191}192193194