Path: blob/master/test/jdk/java/foreign/TestAdaptVarHandles.java
41145 views
/*1* Copyright (c) 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 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false -Xverify:all TestAdaptVarHandles27* @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true -Xverify:all TestAdaptVarHandles28* @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false -Xverify:all TestAdaptVarHandles29* @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true -Xverify:all TestAdaptVarHandles30*/3132import jdk.incubator.foreign.MemoryHandles;33import jdk.incubator.foreign.MemoryLayout;34import jdk.incubator.foreign.MemoryLayouts;35import jdk.incubator.foreign.MemorySegment;36import jdk.incubator.foreign.ResourceScope;37import jdk.incubator.foreign.ValueLayout;38import org.testng.annotations.*;39import static org.testng.Assert.*;4041import java.lang.invoke.MethodHandle;42import java.lang.invoke.MethodHandles;43import java.lang.invoke.MethodType;44import java.lang.invoke.VarHandle;45import java.util.List;4647public class TestAdaptVarHandles {4849static MethodHandle S2I;50static MethodHandle I2S;51static MethodHandle CTX_I2S;52static MethodHandle O2I;53static MethodHandle I2O;54static MethodHandle S2L;55static MethodHandle S2L_EX;56static MethodHandle S2I_EX;57static MethodHandle I2S_EX;58static MethodHandle BASE_ADDR;59static MethodHandle SUM_OFFSETS;60static MethodHandle VOID_FILTER;6162static {63try {64S2I = MethodHandles.lookup().findStatic(TestAdaptVarHandles.class, "stringToInt", MethodType.methodType(int.class, String.class));65I2S = MethodHandles.lookup().findStatic(TestAdaptVarHandles.class, "intToString", MethodType.methodType(String.class, int.class));66CTX_I2S = MethodHandles.lookup().findStatic(TestAdaptVarHandles.class, "ctxIntToString",67MethodType.methodType(String.class, String.class, String.class, int.class));68O2I = MethodHandles.explicitCastArguments(S2I, MethodType.methodType(int.class, Object.class));69I2O = MethodHandles.explicitCastArguments(I2S, MethodType.methodType(Object.class, int.class));70S2L = MethodHandles.lookup().findStatic(TestAdaptVarHandles.class, "stringToLong", MethodType.methodType(long.class, String.class));71S2L_EX = MethodHandles.lookup().findStatic(TestAdaptVarHandles.class, "stringToLongException", MethodType.methodType(long.class, String.class));72BASE_ADDR = MethodHandles.lookup().findStatic(TestAdaptVarHandles.class, "baseAddress", MethodType.methodType(MemorySegment.class, MemorySegment.class));73SUM_OFFSETS = MethodHandles.lookup().findStatic(TestAdaptVarHandles.class, "sumOffsets", MethodType.methodType(long.class, long.class, long.class));74VOID_FILTER = MethodHandles.lookup().findStatic(TestAdaptVarHandles.class, "void_filter", MethodType.methodType(void.class, String.class));7576MethodHandle s2i_ex = MethodHandles.throwException(int.class, Throwable.class);77s2i_ex = MethodHandles.insertArguments(s2i_ex, 0, new Throwable());78S2I_EX = MethodHandles.dropArguments(s2i_ex, 0, String.class);7980MethodHandle i2s_ex = MethodHandles.throwException(String.class, Throwable.class);81i2s_ex = MethodHandles.insertArguments(i2s_ex, 0, new Throwable());82I2S_EX = MethodHandles.dropArguments(i2s_ex, 0, int.class);83} catch (Throwable ex) {84throw new ExceptionInInitializerError();85}86}8788static final VarHandle intHandleIndexed = MemoryLayout.sequenceLayout(MemoryLayouts.JAVA_INT)89.varHandle(int.class, MemoryLayout.PathElement.sequenceElement());9091static final VarHandle intHandle = MemoryLayouts.JAVA_INT.varHandle(int.class);9293static final VarHandle floatHandle = MemoryLayouts.JAVA_FLOAT.varHandle(float.class);9495@Test96public void testFilterValue() throws Throwable {97ValueLayout layout = MemoryLayouts.JAVA_INT;98MemorySegment segment = MemorySegment.allocateNative(layout, ResourceScope.newImplicitScope());99VarHandle intHandle = layout.varHandle(int.class);100VarHandle i2SHandle = MemoryHandles.filterValue(intHandle, S2I, I2S);101i2SHandle.set(segment, "1");102String oldValue = (String)i2SHandle.getAndAdd(segment, "42");103assertEquals(oldValue, "1");104String value = (String)i2SHandle.get(segment);105assertEquals(value, "43");106boolean swapped = (boolean)i2SHandle.compareAndSet(segment, "43", "12");107assertTrue(swapped);108oldValue = (String)i2SHandle.compareAndExchange(segment, "12", "42");109assertEquals(oldValue, "12");110value = (String)i2SHandle.toMethodHandle(VarHandle.AccessMode.GET).invokeExact(segment);111assertEquals(value, "42");112}113114@Test115public void testFilterValueComposite() throws Throwable {116ValueLayout layout = MemoryLayouts.JAVA_INT;117MemorySegment segment = MemorySegment.allocateNative(layout, ResourceScope.newImplicitScope());118VarHandle intHandle = layout.varHandle(int.class);119MethodHandle CTX_S2I = MethodHandles.dropArguments(S2I, 0, String.class, String.class);120VarHandle i2SHandle = MemoryHandles.filterValue(intHandle, CTX_S2I, CTX_I2S);121i2SHandle = MemoryHandles.insertCoordinates(i2SHandle, 1, "a", "b");122i2SHandle.set(segment, "1");123String oldValue = (String)i2SHandle.getAndAdd(segment, "42");124assertEquals(oldValue, "ab1");125String value = (String)i2SHandle.get(segment);126assertEquals(value, "ab43");127boolean swapped = (boolean)i2SHandle.compareAndSet(segment, "43", "12");128assertTrue(swapped);129oldValue = (String)i2SHandle.compareAndExchange(segment, "12", "42");130assertEquals(oldValue, "ab12");131value = (String)i2SHandle.toMethodHandle(VarHandle.AccessMode.GET).invokeExact(segment);132assertEquals(value, "ab42");133}134135@Test136public void testFilterValueLoose() throws Throwable {137ValueLayout layout = MemoryLayouts.JAVA_INT;138MemorySegment segment = MemorySegment.allocateNative(layout, ResourceScope.newImplicitScope());139VarHandle intHandle = layout.varHandle(int.class);140VarHandle i2SHandle = MemoryHandles.filterValue(intHandle, O2I, I2O);141i2SHandle.set(segment, "1");142String oldValue = (String)i2SHandle.getAndAdd(segment, "42");143assertEquals(oldValue, "1");144String value = (String)i2SHandle.get(segment);145assertEquals(value, "43");146boolean swapped = (boolean)i2SHandle.compareAndSet(segment, "43", "12");147assertTrue(swapped);148oldValue = (String)i2SHandle.compareAndExchange(segment, "12", "42");149assertEquals(oldValue, "12");150value = (String)(Object)i2SHandle.toMethodHandle(VarHandle.AccessMode.GET).invokeExact(segment);151assertEquals(value, "42");152}153154@Test(expectedExceptions = IllegalArgumentException.class)155public void testBadFilterCarrier() {156MemoryHandles.filterValue(floatHandle, S2I, I2S);157}158159@Test(expectedExceptions = IllegalArgumentException.class)160public void testBadFilterUnboxArity() {161VarHandle floatHandle = MemoryLayouts.JAVA_INT.varHandle(int.class);162MemoryHandles.filterValue(floatHandle, S2I.bindTo(""), I2S);163}164165@Test(expectedExceptions = IllegalArgumentException.class)166public void testBadFilterBoxArity() {167VarHandle intHandle = MemoryLayouts.JAVA_INT.varHandle(int.class);168MemoryHandles.filterValue(intHandle, S2I, I2S.bindTo(42));169}170171@Test(expectedExceptions = IllegalArgumentException.class)172public void testBadFilterBoxPrefixCoordinates() {173VarHandle intHandle = MemoryLayouts.JAVA_INT.varHandle(int.class);174MemoryHandles.filterValue(intHandle,175MethodHandles.dropArguments(S2I, 1, int.class),176MethodHandles.dropArguments(I2S, 1, long.class));177}178179@Test(expectedExceptions = IllegalArgumentException.class)180public void testBadFilterBoxException() {181VarHandle intHandle = MemoryLayouts.JAVA_INT.varHandle(int.class);182MemoryHandles.filterValue(intHandle, I2S, S2L_EX);183}184185@Test(expectedExceptions = IllegalArgumentException.class)186public void testBadFilterUnboxException() {187VarHandle intHandle = MemoryLayouts.JAVA_INT.varHandle(int.class);188MemoryHandles.filterValue(intHandle, S2L_EX, I2S);189}190191@Test(expectedExceptions = IllegalArgumentException.class)192public void testBadFilterBoxHandleException() {193VarHandle intHandle = MemoryLayouts.JAVA_INT.varHandle(int.class);194MemoryHandles.filterValue(intHandle, S2I, I2S_EX);195}196197@Test(expectedExceptions = IllegalArgumentException.class)198public void testBadFilterUnboxHandleException() {199VarHandle intHandle = MemoryLayouts.JAVA_INT.varHandle(int.class);200MemoryHandles.filterValue(intHandle, S2I_EX, I2S);201}202203@Test204public void testFilterCoordinates() throws Throwable {205ValueLayout layout = MemoryLayouts.JAVA_INT;206MemorySegment segment = MemorySegment.allocateNative(layout, ResourceScope.newImplicitScope());207VarHandle intHandle_longIndex = MemoryHandles.filterCoordinates(intHandleIndexed, 0, BASE_ADDR, S2L);208intHandle_longIndex.set(segment, "0", 1);209int oldValue = (int)intHandle_longIndex.getAndAdd(segment, "0", 42);210assertEquals(oldValue, 1);211int value = (int)intHandle_longIndex.get(segment, "0");212assertEquals(value, 43);213boolean swapped = (boolean)intHandle_longIndex.compareAndSet(segment, "0", 43, 12);214assertTrue(swapped);215oldValue = (int)intHandle_longIndex.compareAndExchange(segment, "0", 12, 42);216assertEquals(oldValue, 12);217value = (int)intHandle_longIndex.toMethodHandle(VarHandle.AccessMode.GET).invokeExact(segment, "0");218assertEquals(value, 42);219}220221@Test(expectedExceptions = IllegalArgumentException.class)222public void testBadFilterCoordinatesNegativePos() {223MemoryHandles.filterCoordinates(intHandle, -1, SUM_OFFSETS);224}225226@Test(expectedExceptions = IllegalArgumentException.class)227public void testBadFilterCoordinatesPosTooBig() {228MemoryHandles.filterCoordinates(intHandle, 1, SUM_OFFSETS);229}230231@Test(expectedExceptions = IllegalArgumentException.class)232public void testBadFilterCoordinatesWrongFilterType() {233MemoryHandles.filterCoordinates(intHandleIndexed, 1, S2I);234}235236@Test(expectedExceptions = IllegalArgumentException.class)237public void testBadFilterCoordinatesWrongFilterException() {238MemoryHandles.filterCoordinates(intHandleIndexed, 1, S2L_EX);239}240241@Test(expectedExceptions = IllegalArgumentException.class)242public void testBadFilterCoordinatesTooManyFilters() {243MemoryHandles.filterCoordinates(intHandleIndexed, 1, S2L, S2L);244}245246@Test247public void testInsertCoordinates() throws Throwable {248ValueLayout layout = MemoryLayouts.JAVA_INT;249MemorySegment segment = MemorySegment.allocateNative(layout, ResourceScope.newImplicitScope());250VarHandle intHandle_longIndex = MemoryHandles.insertCoordinates(intHandleIndexed, 0, segment, 0L);251intHandle_longIndex.set(1);252int oldValue = (int)intHandle_longIndex.getAndAdd(42);253assertEquals(oldValue, 1);254int value = (int)intHandle_longIndex.get();255assertEquals(value, 43);256boolean swapped = (boolean)intHandle_longIndex.compareAndSet(43, 12);257assertTrue(swapped);258oldValue = (int)intHandle_longIndex.compareAndExchange(12, 42);259assertEquals(oldValue, 12);260value = (int)intHandle_longIndex.toMethodHandle(VarHandle.AccessMode.GET).invokeExact();261assertEquals(value, 42);262}263264@Test(expectedExceptions = IllegalArgumentException.class)265public void testBadInsertCoordinatesNegativePos() {266MemoryHandles.insertCoordinates(intHandle, -1, 42);267}268269@Test(expectedExceptions = IllegalArgumentException.class)270public void testBadInsertCoordinatesPosTooBig() {271MemoryHandles.insertCoordinates(intHandle, 1, 42);272}273274@Test(expectedExceptions = ClassCastException.class)275public void testBadInsertCoordinatesWrongCoordinateType() {276MemoryHandles.insertCoordinates(intHandleIndexed, 1, "Hello");277}278279@Test(expectedExceptions = IllegalArgumentException.class)280public void testBadInsertCoordinatesTooManyValues() {281MemoryHandles.insertCoordinates(intHandleIndexed, 1, 0L, 0L);282}283284@Test285public void testPermuteCoordinates() throws Throwable {286ValueLayout layout = MemoryLayouts.JAVA_INT;287MemorySegment segment = MemorySegment.allocateNative(layout, ResourceScope.newImplicitScope());288VarHandle intHandle_swap = MemoryHandles.permuteCoordinates(intHandleIndexed,289List.of(long.class, MemorySegment.class), 1, 0);290intHandle_swap.set(0L, segment, 1);291int oldValue = (int)intHandle_swap.getAndAdd(0L, segment, 42);292assertEquals(oldValue, 1);293int value = (int)intHandle_swap.get(0L, segment);294assertEquals(value, 43);295boolean swapped = (boolean)intHandle_swap.compareAndSet(0L, segment, 43, 12);296assertTrue(swapped);297oldValue = (int)intHandle_swap.compareAndExchange(0L, segment, 12, 42);298assertEquals(oldValue, 12);299value = (int)intHandle_swap.toMethodHandle(VarHandle.AccessMode.GET).invokeExact(0L, segment);300assertEquals(value, 42);301}302303@Test(expectedExceptions = IllegalArgumentException.class)304public void testBadPermuteCoordinatesTooManyCoordinates() {305MemoryHandles.permuteCoordinates(intHandle, List.of(int.class, int.class), new int[2]);306}307308@Test(expectedExceptions = IllegalArgumentException.class)309public void testBadPermuteCoordinatesTooFewCoordinates() {310MemoryHandles.permuteCoordinates(intHandle, List.of());311}312313@Test(expectedExceptions = IllegalArgumentException.class)314public void testBadPermuteCoordinatesIndexTooBig() {315MemoryHandles.permuteCoordinates(intHandle, List.of(int.class, int.class), 3);316}317318@Test(expectedExceptions = IllegalArgumentException.class)319public void testBadPermuteCoordinatesIndexTooSmall() {320MemoryHandles.permuteCoordinates(intHandle, List.of(int.class, int.class), -1);321}322323@Test324public void testCollectCoordinates() throws Throwable {325ValueLayout layout = MemoryLayouts.JAVA_INT;326MemorySegment segment = MemorySegment.allocateNative(layout, ResourceScope.newImplicitScope());327VarHandle intHandle_sum = MemoryHandles.collectCoordinates(intHandleIndexed, 1, SUM_OFFSETS);328intHandle_sum.set(segment, -2L, 2L, 1);329int oldValue = (int)intHandle_sum.getAndAdd(segment, -2L, 2L, 42);330assertEquals(oldValue, 1);331int value = (int)intHandle_sum.get(segment, -2L, 2L);332assertEquals(value, 43);333boolean swapped = (boolean)intHandle_sum.compareAndSet(segment, -2L, 2L, 43, 12);334assertTrue(swapped);335oldValue = (int)intHandle_sum.compareAndExchange(segment, -2L, 2L, 12, 42);336assertEquals(oldValue, 12);337value = (int)intHandle_sum.toMethodHandle(VarHandle.AccessMode.GET).invokeExact(segment, -2L, 2L);338assertEquals(value, 42);339}340341@Test(expectedExceptions = IllegalArgumentException.class)342public void testBadCollectCoordinatesNegativePos() {343MemoryHandles.collectCoordinates(intHandle, -1, SUM_OFFSETS);344}345346@Test(expectedExceptions = IllegalArgumentException.class)347public void testBadCollectCoordinatesPosTooBig() {348MemoryHandles.collectCoordinates(intHandle, 1, SUM_OFFSETS);349}350351@Test(expectedExceptions = IllegalArgumentException.class)352public void testBadCollectCoordinatesWrongFilterType() {353MemoryHandles.collectCoordinates(intHandle, 0, SUM_OFFSETS);354}355356@Test(expectedExceptions = IllegalArgumentException.class)357public void testBadCollectCoordinatesWrongVoidFilterType() {358MemoryHandles.collectCoordinates(intHandle, 0, VOID_FILTER);359}360361@Test(expectedExceptions = IllegalArgumentException.class)362public void testBadCollectCoordinatesWrongFilterException() {363MemoryHandles.collectCoordinates(intHandle, 0, S2L_EX);364}365366@Test367public void testDropCoordinates() throws Throwable {368ValueLayout layout = MemoryLayouts.JAVA_INT;369MemorySegment segment = MemorySegment.allocateNative(layout, ResourceScope.newImplicitScope());370VarHandle intHandle_dummy = MemoryHandles.dropCoordinates(intHandleIndexed, 1, float.class, String.class);371intHandle_dummy.set(segment, 1f, "hello", 0L, 1);372int oldValue = (int)intHandle_dummy.getAndAdd(segment, 1f, "hello", 0L, 42);373assertEquals(oldValue, 1);374int value = (int)intHandle_dummy.get(segment, 1f, "hello", 0L);375assertEquals(value, 43);376boolean swapped = (boolean)intHandle_dummy.compareAndSet(segment, 1f, "hello", 0L, 43, 12);377assertTrue(swapped);378oldValue = (int)intHandle_dummy.compareAndExchange(segment, 1f, "hello", 0L, 12, 42);379assertEquals(oldValue, 12);380value = (int)intHandle_dummy.toMethodHandle(VarHandle.AccessMode.GET).invokeExact(segment, 1f, "hello", 0L);381assertEquals(value, 42);382}383384@Test(expectedExceptions = IllegalArgumentException.class)385public void testBadDropCoordinatesNegativePos() {386MemoryHandles.dropCoordinates(intHandle, -1);387}388389@Test(expectedExceptions = IllegalArgumentException.class)390public void testBadDropCoordinatesPosTooBig() {391MemoryHandles.dropCoordinates(intHandle, 2);392}393394//helper methods395396static int stringToInt(String s) {397return Integer.valueOf(s);398}399400static String intToString(int i) {401return String.valueOf(i);402}403404static long stringToLong(String s) {405return Long.valueOf(s);406}407408static long stringToLongException(String s) throws Throwable {409return Long.valueOf(s);410}411412static MemorySegment baseAddress(MemorySegment segment) {413return segment;414}415416static long sumOffsets(long l1, long l2) {417return l1 + l2;418}419420static void void_filter(String s) { }421422static String ctxIntToString(String a, String b, int i) {423return a + b + String.valueOf(i);424}425}426427428