1/* 2 * Copyright (c) 2007, 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/* @test 25 * @bug 6565543 26 * @summary Minimal test for unsafe.copyMemory() and unsafe.setMemory() 27 * @modules java.base/sun.nio.ch 28 * jdk.unsupported 29 * @key randomness 30 */ 31 32import java.util.*; 33import java.lang.reflect.*; 34import java.nio.*; 35 36import sun.misc.Unsafe; 37 38import sun.nio.ch.DirectBuffer; 39 40public class CopyMemory { 41 42 private final static int BUFFER_SIZE = 1024; 43 private final static int N = 16 * 1024; 44 45 private final static int FILLER = 0x55; 46 private final static int FILLER2 = 0x33; 47 48 private final static Random random = new Random(); 49 50 private static void set(byte[] b, int ofs, int len, int value) { 51 for (int i = 0; i < len; i++) { 52 b[ofs + i] = (byte)value; 53 } 54 } 55 56 private static void check(byte[] b, int ofs, int len, int value) { 57 for (int i = 0; i < len; i++) { 58 int r = b[ofs + i] & 0xff; 59 if (r != value) { 60 throw new RuntimeException("mismatch"); 61 } 62 } 63 } 64 65 private static void set(Unsafe unsafe, long addr, int ofs, int len, int value) { 66 for (int i = 0; i < len; i++) { 67 unsafe.putByte(null, addr + ofs + i, (byte)value); 68 } 69 } 70 71 private static void check(Unsafe unsafe, long addr, int ofs, int len, int value) { 72 for (int i = 0; i < len; i++) { 73 int r = unsafe.getByte(null, addr + ofs + i) & 0xff; 74 if (r != value) { 75 throw new RuntimeException("mismatch"); 76 } 77 } 78 } 79 80 private static final List<ByteBuffer> buffers = new ArrayList<ByteBuffer>(); 81 82 private static long getMemory(int n) { 83 ByteBuffer b = ByteBuffer.allocateDirect(n); 84 if (b instanceof DirectBuffer == false) { 85 throw new RuntimeException("Not a direct buffer"); 86 } 87 buffers.add(b); // make sure the buffer does not get GCed 88 return ((DirectBuffer)b).address(); 89 } 90 91 private static void testSetByteArray(Unsafe unsafe) throws Exception { 92 System.out.println("Testing setMemory() for byte[]..."); 93 byte[] b = new byte[BUFFER_SIZE]; 94 for (int i = 0; i < N; i++) { 95 set(b, 0, BUFFER_SIZE, FILLER); 96 int ofs = random.nextInt(BUFFER_SIZE / 2); 97 int len = random.nextInt(BUFFER_SIZE / 2); 98 int val = random.nextInt(256); 99 unsafe.setMemory(b, Unsafe.ARRAY_BYTE_BASE_OFFSET + ofs, len, (byte)val); 100 check(b, 0, ofs - 1, FILLER); 101 check(b, ofs, len, val); 102 check(b, ofs + len, BUFFER_SIZE - (ofs + len), FILLER); 103 } 104 } 105 106 private static void testSetRawMemory(Unsafe unsafe) throws Exception { 107 System.out.println("Testing setMemory() for raw memory..."); 108 long b = getMemory(BUFFER_SIZE); 109 for (int i = 0; i < N; i++) { 110 set(unsafe, b, 0, BUFFER_SIZE, FILLER); 111 int ofs = random.nextInt(BUFFER_SIZE / 2); 112 int len = random.nextInt(BUFFER_SIZE / 2); 113 int val = random.nextInt(256); 114 unsafe.setMemory(null, b + ofs, len, (byte)val); 115 check(unsafe, b, 0, ofs - 1, FILLER); 116 check(unsafe, b, ofs, len, val); 117 check(unsafe, b, ofs + len, BUFFER_SIZE - (ofs + len), FILLER); 118 } 119 } 120 121 private static void testCopyByteArrayToByteArray(Unsafe unsafe) throws Exception { 122 System.out.println("Testing copyMemory() for byte[] to byte[]..."); 123 byte[] b1 = new byte[BUFFER_SIZE]; 124 byte[] b2 = new byte[BUFFER_SIZE]; 125 for (int i = 0; i < N; i++) { 126 set(b1, 0, BUFFER_SIZE, FILLER); 127 set(b2, 0, BUFFER_SIZE, FILLER2); 128 int ofs = random.nextInt(BUFFER_SIZE / 2); 129 int len = random.nextInt(BUFFER_SIZE / 2); 130 int val = random.nextInt(256); 131 set(b1, ofs, len, val); 132 int ofs2 = random.nextInt(BUFFER_SIZE / 2); 133 unsafe.copyMemory(b1, Unsafe.ARRAY_BYTE_BASE_OFFSET + ofs, 134 b2, Unsafe.ARRAY_BYTE_BASE_OFFSET + ofs2, len); 135 check(b2, 0, ofs2 - 1, FILLER2); 136 check(b2, ofs2, len, val); 137 check(b2, ofs2 + len, BUFFER_SIZE - (ofs2 + len), FILLER2); 138 } 139 } 140 141 private static void testCopyByteArrayToRawMemory(Unsafe unsafe) throws Exception { 142 System.out.println("Testing copyMemory() for byte[] to raw memory..."); 143 byte[] b1 = new byte[BUFFER_SIZE]; 144 long b2 = getMemory(BUFFER_SIZE); 145 for (int i = 0; i < N; i++) { 146 set(b1, 0, BUFFER_SIZE, FILLER); 147 set(unsafe, b2, 0, BUFFER_SIZE, FILLER2); 148 int ofs = random.nextInt(BUFFER_SIZE / 2); 149 int len = random.nextInt(BUFFER_SIZE / 2); 150 int val = random.nextInt(256); 151 set(b1, ofs, len, val); 152 int ofs2 = random.nextInt(BUFFER_SIZE / 2); 153 unsafe.copyMemory(b1, Unsafe.ARRAY_BYTE_BASE_OFFSET + ofs, 154 null, b2 + ofs2, len); 155 check(unsafe, b2, 0, ofs2 - 1, FILLER2); 156 check(unsafe, b2, ofs2, len, val); 157 check(unsafe, b2, ofs2 + len, BUFFER_SIZE - (ofs2 + len), FILLER2); 158 } 159 } 160 161 private static void testCopyRawMemoryToByteArray(Unsafe unsafe) throws Exception { 162 System.out.println("Testing copyMemory() for raw memory to byte[]..."); 163 long b1 = getMemory(BUFFER_SIZE); 164 byte[] b2 = new byte[BUFFER_SIZE]; 165 for (int i = 0; i < N; i++) { 166 set(unsafe, b1, 0, BUFFER_SIZE, FILLER); 167 set(b2, 0, BUFFER_SIZE, FILLER2); 168 int ofs = random.nextInt(BUFFER_SIZE / 2); 169 int len = random.nextInt(BUFFER_SIZE / 2); 170 int val = random.nextInt(256); 171 set(unsafe, b1, ofs, len, val); 172 int ofs2 = random.nextInt(BUFFER_SIZE / 2); 173 unsafe.copyMemory(null, b1 + ofs, 174 b2, Unsafe.ARRAY_BYTE_BASE_OFFSET + ofs2, len); 175 check(b2, 0, ofs2 - 1, FILLER2); 176 check(b2, ofs2, len, val); 177 check(b2, ofs2 + len, BUFFER_SIZE - (ofs2 + len), FILLER2); 178 } 179 } 180 181 private static void testCopyRawMemoryToRawMemory(Unsafe unsafe) throws Exception { 182 System.out.println("Testing copyMemory() for raw memory to raw memory..."); 183 long b1 = getMemory(BUFFER_SIZE); 184 long b2 = getMemory(BUFFER_SIZE); 185 for (int i = 0; i < N; i++) { 186 set(unsafe, b1, 0, BUFFER_SIZE, FILLER); 187 set(unsafe, b2, 0, BUFFER_SIZE, FILLER2); 188 int ofs = random.nextInt(BUFFER_SIZE / 2); 189 int len = random.nextInt(BUFFER_SIZE / 2); 190 int val = random.nextInt(256); 191 set(unsafe, b1, ofs, len, val); 192 int ofs2 = random.nextInt(BUFFER_SIZE / 2); 193 unsafe.copyMemory(null, b1 + ofs, 194 null, b2 + ofs2, len); 195 check(unsafe, b2, 0, ofs2 - 1, FILLER2); 196 check(unsafe, b2, ofs2, len, val); 197 check(unsafe, b2, ofs2 + len, BUFFER_SIZE - (ofs2 + len), FILLER2); 198 } 199 } 200 201 private static Unsafe getUnsafe() throws Exception { 202 Field f = Unsafe.class.getDeclaredField("theUnsafe"); 203 f.setAccessible(true); 204 return (Unsafe)f.get(null); 205 } 206 207 public static void main(String[] args) throws Exception { 208 Unsafe unsafe = getUnsafe(); 209 210 testSetByteArray(unsafe); 211 testSetRawMemory(unsafe); 212 testCopyByteArrayToByteArray(unsafe); 213 testCopyByteArrayToRawMemory(unsafe); 214 testCopyRawMemoryToByteArray(unsafe); 215 testCopyRawMemoryToRawMemory(unsafe); 216 217 System.out.println("OK"); 218 } 219 220} 221