Path: blob/master/test/jdk/java/foreign/TestRebase.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 TestRebase27*/2829import jdk.incubator.foreign.MemoryAccess;30import jdk.incubator.foreign.MemoryAddress;31import jdk.incubator.foreign.MemorySegment;32import jdk.incubator.foreign.ResourceScope;33import org.testng.annotations.DataProvider;34import org.testng.annotations.Test;3536import java.util.ArrayList;37import java.util.List;38import java.util.function.IntFunction;3940import static org.testng.Assert.*;4142public class TestRebase {4344@Test(dataProvider = "slices")45public void testRebase(SegmentSlice s1, SegmentSlice s2) {46if (s1.contains(s2)) {47//check that an address and its rebased counterpart point to same element48MemoryAddress base = s2.segment.address();49long offset = base.segmentOffset(s1.segment);50for (int i = 0; i < s2.size(); i++) {51int expected = MemoryAccess.getByteAtOffset(s2.segment, i);52int found = (int)MemoryAccess.getByteAtOffset(s1.segment, i + offset);53assertEquals(found, expected);54}55} else if (s1.kind != s2.kind) {56// check that rebase s1 to s2 fails57try {58s1.segment.address().segmentOffset(s2.segment);59fail("Rebase unexpectedly passed!");60} catch (IllegalArgumentException ex) {61assertTrue(true);62}63} else if (!s2.contains(s1)) {64//disjoint segments - check that rebased address is out of bounds65MemoryAddress base = s2.segment.address();66long offset = base.segmentOffset(s1.segment);67for (int i = 0; i < s2.size(); i++) {68MemoryAccess.getByteAtOffset(s2.segment, i);69try {70MemoryAccess.getByteAtOffset(s1.segment, i + offset);71fail("Rebased address on a disjoint segment is not out of bounds!");72} catch (IndexOutOfBoundsException ex) {73assertTrue(true);74}75}76}77}7879static class SegmentSlice {8081enum Kind {82NATIVE(i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope())),83ARRAY(i -> MemorySegment.ofArray(new byte[i]));8485final IntFunction<MemorySegment> segmentFactory;8687Kind(IntFunction<MemorySegment> segmentFactory) {88this.segmentFactory = segmentFactory;89}9091MemorySegment makeSegment(int elems) {92return segmentFactory.apply(elems);93}94}9596final Kind kind;97final int first;98final int last;99final MemorySegment segment;100101public SegmentSlice(Kind kind, int first, int last, MemorySegment segment) {102this.kind = kind;103this.first = first;104this.last = last;105this.segment = segment;106}107108boolean contains(SegmentSlice other) {109return kind == other.kind &&110first <= other.first &&111last >= other.last;112}113114int size() {115return last - first + 1;116}117}118119@DataProvider(name = "slices")120static Object[][] slices() {121int[] sizes = { 16, 8, 4, 2, 1 };122List<SegmentSlice> slices = new ArrayList<>();123for (SegmentSlice.Kind kind : SegmentSlice.Kind.values()) {124//init root segment125MemorySegment segment = kind.makeSegment(16);126for (int i = 0 ; i < 16 ; i++) {127MemoryAccess.setByteAtOffset(segment, i, (byte)i);128}129//compute all slices130for (int size : sizes) {131for (int index = 0 ; index < 16 ; index += size) {132MemorySegment slice = segment.asSlice(index, size);133slices.add(new SegmentSlice(kind, index, index + size - 1, slice));134}135}136}137Object[][] sliceArray = new Object[slices.size() * slices.size()][];138for (int i = 0 ; i < slices.size() ; i++) {139for (int j = 0 ; j < slices.size() ; j++) {140sliceArray[i * slices.size() + j] = new Object[] { slices.get(i), slices.get(j) };141}142}143return sliceArray;144}145}146147148