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