1 /* 2 * Copyright (c) 2021, 2023, 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 * @test 26 * @run testng/othervm TestSegmentOverlap 27 */ 28 29 import java.io.File; 30 import java.io.IOException; 31 import java.lang.foreign.Arena; 32 import java.nio.channels.FileChannel; 33 import java.nio.file.Files; 34 import java.nio.file.Path; 35 import java.nio.file.StandardOpenOption; 36 import java.util.List; 37 import java.util.function.Supplier; 38 import java.lang.foreign.MemorySegment; 39 40 import org.testng.annotations.Test; 41 import org.testng.annotations.DataProvider; 42 import static java.lang.System.out; 43 import static org.testng.Assert.*; 44 45 public class TestSegmentOverlap { 46 47 static Path tempPath; 48 49 static { 50 try { 51 File file = File.createTempFile("buffer", "txt"); 52 file.deleteOnExit(); 53 tempPath = file.toPath(); 54 Files.write(file.toPath(), new byte[16], StandardOpenOption.WRITE); 55 56 } catch (IOException ex) { 57 throw new ExceptionInInitializerError(ex); 58 } 59 } 60 61 @DataProvider(name = "segmentFactories") 62 public Object[][] segmentFactories() { 63 List<Supplier<MemorySegment>> l = List.of( 64 () -> Arena.ofAuto().allocate(16, 1), 65 () -> { 66 try (FileChannel fileChannel = FileChannel.open(tempPath, StandardOpenOption.READ, StandardOpenOption.WRITE)) { 67 return fileChannel.map(FileChannel.MapMode.READ_WRITE, 0L, 16L, Arena.ofAuto()); 68 } catch (IOException e) { 69 throw new RuntimeException(e); 70 } 71 }, 72 () -> MemorySegment.ofArray(new byte[] { 0x00, 0x01, 0x02, 0x03 } ), 73 () -> MemorySegment.ofArray(new char[] {'a', 'b', 'c', 'd' } ), 74 () -> MemorySegment.ofArray(new double[] { 1d, 2d, 3d, 4d} ), 75 () -> MemorySegment.ofArray(new float[] { 1.0f, 2.0f, 3.0f, 4.0f } ), 76 () -> MemorySegment.ofArray(new int[] { 1, 2, 3, 4 }), 77 () -> MemorySegment.ofArray(new long[] { 1L, 2L, 3L, 4L } ), 78 () -> MemorySegment.ofArray(new short[] { 1, 2, 3, 4 } ) 79 ); 80 return l.stream().map(s -> new Object[] { s }).toArray(Object[][]::new); 81 } 82 83 @Test(dataProvider="segmentFactories") 84 public void testBasic(Supplier<MemorySegment> segmentSupplier) { 85 var s1 = segmentSupplier.get(); 86 var s2 = segmentSupplier.get(); 87 var sOther = s1.isNative() ? OtherSegmentFactory.HEAP.factory.get() 88 : OtherSegmentFactory.NATIVE.factory.get(); 89 out.format("testBasic s1:%s, s2:%s, sOther:%s\n", s1, s2, sOther); 90 assertTrue(s1.asOverlappingSlice(s2).isEmpty()); 91 assertTrue(s2.asOverlappingSlice(s1).isEmpty()); 92 assertTrue(s1.asOverlappingSlice(sOther).isEmpty()); 93 } 94 95 @Test(dataProvider="segmentFactories") 96 public void testIdentical(Supplier<MemorySegment> segmentSupplier) { 97 var s1 = segmentSupplier.get(); 98 var s2 = s1.asReadOnly(); 99 out.format("testIdentical s1:%s, s2:%s\n", s1, s2); 100 assertEquals(s1.asOverlappingSlice(s2).get().byteSize(), s1.byteSize()); 101 assertEquals(s1.asOverlappingSlice(s2).get().scope(), s1.scope()); 102 103 assertEquals(s2.asOverlappingSlice(s1).get().byteSize(), s2.byteSize()); 104 assertEquals(s2.asOverlappingSlice(s1).get().scope(), s2.scope()); 105 106 if (s1.isNative()) { 107 assertEquals(s1.asOverlappingSlice(s2).get().address(), s1.address()); 108 assertEquals(s2.asOverlappingSlice(s1).get().address(), s2.address()); 109 } 110 } 111 112 @Test(dataProvider="segmentFactories") 113 public void testSlices(Supplier<MemorySegment> segmentSupplier) { 114 MemorySegment s1 = segmentSupplier.get(); 115 MemorySegment s2 = segmentSupplier.get(); 116 for (int offset = 0 ; offset < 4 ; offset++) { 117 MemorySegment slice = s1.asSlice(offset); 118 out.format("testSlices s1:%s, s2:%s, slice:%s, offset:%d\n", s1, s2, slice, offset); 119 assertEquals(s1.asOverlappingSlice(slice).get().byteSize(), s1.byteSize() - offset); 120 assertEquals(s1.asOverlappingSlice(slice).get().scope(), s1.scope()); 121 122 assertEquals(slice.asOverlappingSlice(s1).get().byteSize(), slice.byteSize()); 123 assertEquals(slice.asOverlappingSlice(s1).get().scope(), slice.scope()); 124 125 if (s1.isNative()) { 126 assertEquals(s1.asOverlappingSlice(slice).get().address(), s1.address() + offset); 127 assertEquals(slice.asOverlappingSlice(s1).get().address(), slice.address()); 128 } 129 assertTrue(s2.asOverlappingSlice(slice).isEmpty()); 130 } 131 } 132 133 enum OtherSegmentFactory { 134 NATIVE(() -> Arena.ofAuto().allocate(16, 1)), 135 HEAP(() -> MemorySegment.ofArray(new byte[]{16})); 136 137 final Supplier<MemorySegment> factory; 138 139 OtherSegmentFactory(Supplier<MemorySegment> segmentFactory) { 140 this.factory = segmentFactory; 141 } 142 } 143 }