Path: blob/master/test/jdk/java/foreign/TestMemoryAlignment.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*/2223/*24* @test25* @run testng TestMemoryAlignment26*/2728import jdk.incubator.foreign.MemoryLayouts;29import jdk.incubator.foreign.MemoryLayout;3031import jdk.incubator.foreign.GroupLayout;32import jdk.incubator.foreign.MemoryLayout.PathElement;33import jdk.incubator.foreign.MemorySegment;34import jdk.incubator.foreign.ResourceScope;35import jdk.incubator.foreign.SequenceLayout;36import jdk.incubator.foreign.ValueLayout;37import java.lang.invoke.VarHandle;38import java.util.stream.LongStream;3940import org.testng.annotations.*;41import static org.testng.Assert.*;4243public class TestMemoryAlignment {4445@Test(dataProvider = "alignments")46public void testAlignedAccess(long align) {47ValueLayout layout = MemoryLayouts.BITS_32_BE;48assertEquals(layout.bitAlignment(), 32);49ValueLayout aligned = layout.withBitAlignment(align);50assertEquals(aligned.bitAlignment(), align); //unreasonable alignment here, to make sure access throws51VarHandle vh = aligned.varHandle(int.class);52try (ResourceScope scope = ResourceScope.newConfinedScope()) {53MemorySegment segment = MemorySegment.allocateNative(aligned, scope);54vh.set(segment, -42);55int val = (int)vh.get(segment);56assertEquals(val, -42);57}58}5960@Test(dataProvider = "alignments")61public void testUnalignedAccess(long align) {62ValueLayout layout = MemoryLayouts.BITS_32_BE;63assertEquals(layout.bitAlignment(), 32);64ValueLayout aligned = layout.withBitAlignment(align);65MemoryLayout alignedGroup = MemoryLayout.structLayout(MemoryLayouts.PAD_8, aligned);66assertEquals(alignedGroup.bitAlignment(), align);67VarHandle vh = aligned.varHandle(int.class);68try (ResourceScope scope = ResourceScope.newConfinedScope()) {69MemorySegment segment = MemorySegment.allocateNative(alignedGroup, scope);70vh.set(segment.asSlice(1L), -42);71assertEquals(align, 8); //this is the only case where access is aligned72} catch (IllegalStateException ex) {73assertNotEquals(align, 8); //if align != 8, access is always unaligned74}75}7677@Test(dataProvider = "alignments")78public void testUnalignedPath(long align) {79MemoryLayout layout = MemoryLayouts.BITS_32_BE;80MemoryLayout aligned = layout.withBitAlignment(align).withName("value");81GroupLayout alignedGroup = MemoryLayout.structLayout(MemoryLayouts.PAD_8, aligned);82try {83alignedGroup.varHandle(int.class, PathElement.groupElement("value"));84assertEquals(align, 8); //this is the only case where path is aligned85} catch (UnsupportedOperationException ex) {86assertNotEquals(align, 8); //if align != 8, path is always unaligned87}88}8990@Test(dataProvider = "alignments")91public void testUnalignedSequence(long align) {92SequenceLayout layout = MemoryLayout.sequenceLayout(5, MemoryLayouts.BITS_32_BE.withBitAlignment(align));93try {94VarHandle vh = layout.varHandle(int.class, PathElement.sequenceElement());95try (ResourceScope scope = ResourceScope.newConfinedScope()) {96MemorySegment segment = MemorySegment.allocateNative(layout, scope);97for (long i = 0 ; i < 5 ; i++) {98vh.set(segment, i, -42);99}100}101} catch (UnsupportedOperationException ex) {102assertTrue(align > 32); //if align > 32, access is always unaligned (for some elements)103}104}105106@Test107public void testPackedAccess() {108ValueLayout vChar = MemoryLayouts.BITS_8_BE;109ValueLayout vShort = MemoryLayouts.BITS_16_BE;110ValueLayout vInt = MemoryLayouts.BITS_32_BE;111//mimic pragma pack(1)112GroupLayout g = MemoryLayout.structLayout(vChar.withBitAlignment(8).withName("a"),113vShort.withBitAlignment(8).withName("b"),114vInt.withBitAlignment(8).withName("c"));115assertEquals(g.bitAlignment(), 8);116VarHandle vh_c = g.varHandle(byte.class, PathElement.groupElement("a"));117VarHandle vh_s = g.varHandle(short.class, PathElement.groupElement("b"));118VarHandle vh_i = g.varHandle(int.class, PathElement.groupElement("c"));119try (ResourceScope scope = ResourceScope.newConfinedScope()) {120MemorySegment segment = MemorySegment.allocateNative(g, scope);121vh_c.set(segment, Byte.MIN_VALUE);122assertEquals(vh_c.get(segment), Byte.MIN_VALUE);123vh_s.set(segment, Short.MIN_VALUE);124assertEquals(vh_s.get(segment), Short.MIN_VALUE);125vh_i.set(segment, Integer.MIN_VALUE);126assertEquals(vh_i.get(segment), Integer.MIN_VALUE);127}128}129130@DataProvider(name = "alignments")131public Object[][] createAlignments() {132return LongStream.range(3, 32)133.mapToObj(v -> new Object[] { 1L << v })134.toArray(Object[][]::new);135}136}137138139