1 /* 2 * Copyright (c) 2016 SAP SE. 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 * @bug 8158260 27 * @summary Test unaligned Unsafe accesses 28 * @modules java.base/jdk.internal.misc 29 * @run main/othervm -Diters=20000 -XX:-UseOnStackReplacement -XX:-BackgroundCompilation JdkInternalMiscUnsafeUnalignedAccess 30 * @author volker.simonis@gmail.com 31 */ 32 33 import java.lang.reflect.Field; 34 import java.nio.ByteOrder; 35 import jdk.internal.misc.Unsafe; 36 37 public class JdkInternalMiscUnsafeUnalignedAccess { 38 static final int ITERS = Integer.getInteger("iters", 20_000); 39 private static final boolean BIG_ENDIAN = ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN); 40 private static final Unsafe UNSAFE; 41 private static final int SIZE = 1024; 42 private static long memory; 43 44 static { 45 try { 46 Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); 47 unsafeField.setAccessible(true); 48 UNSAFE = (Unsafe) unsafeField.get(null); 49 } 50 catch (Exception e) { 51 throw new RuntimeException("Unable to get Unsafe instance.", e); 52 } 53 } 54 55 static int getInt_0() { 56 return UNSAFE.getInt(memory + 0); 57 } 58 static int getInt_1() { 59 return UNSAFE.getInt(memory + 1); 60 } 61 static int getInt_4() { 62 return UNSAFE.getInt(memory + 4); 63 } 64 static int getInt_17() { 65 return UNSAFE.getInt(memory + 17); 66 } 67 68 static long getIntAsLong_0() { 69 return UNSAFE.getInt(memory + 0); 70 } 71 static long getIntAsLong_1() { 72 return UNSAFE.getInt(memory + 1); 73 } 74 static long getIntAsLong_4() { 75 return UNSAFE.getInt(memory + 4); 76 } 77 static long getIntAsLong_17() { 78 return UNSAFE.getInt(memory + 17); 79 } 80 81 static long getLong_0() { 82 return UNSAFE.getLong(memory + 0); 83 } 84 static long getLong_1() { 85 return UNSAFE.getLong(memory + 1); 86 } 87 static long getLong_4() { 88 return UNSAFE.getLong(memory + 4); 89 } 90 static long getLong_8() { 91 return UNSAFE.getLong(memory + 8); 92 } 93 static long getLong_17() { 94 return UNSAFE.getLong(memory + 17); 95 } 96 97 static void putInt_0(int i) { 98 UNSAFE.putInt(memory + 0, i); 99 } 100 static void putInt_1(int i) { 101 UNSAFE.putInt(memory + 1, i); 102 } 103 static void putInt_4(int i) { 104 UNSAFE.putInt(memory + 4, i); 105 } 106 static void putInt_17(int i) { 107 UNSAFE.putInt(memory + 17, i); 108 } 109 110 static void putLong_0(long l) { 111 UNSAFE.putLong(memory + 0, l); 112 } 113 static void putLong_1(long l) { 114 UNSAFE.putLong(memory + 1, l); 115 } 116 static void putLong_4(long l) { 117 UNSAFE.putLong(memory + 4, l); 118 } 119 static void putLong_8(long l) { 120 UNSAFE.putLong(memory + 8, l); 121 } 122 static void putLong_17(long l) { 123 UNSAFE.putLong(memory + 17, l); 124 } 125 126 public static void main(String[] args) throws Exception { 127 128 if (!UNSAFE.unalignedAccess()) { 129 System.out.println("Platform is not supporting unaligned access - nothing to test."); 130 return; 131 } 132 133 memory = UNSAFE.allocateMemory(SIZE); 134 135 UNSAFE.putInt(memory + 0, 0x00112233); 136 UNSAFE.putInt(memory + 4, 0x44556677); 137 UNSAFE.putInt(memory + 8, 0x8899aabb); 138 UNSAFE.putInt(memory + 12, 0xccddeeff); 139 UNSAFE.putInt(memory + 16, 0x01234567); 140 UNSAFE.putInt(memory + 20, 0x89abcdef); 141 UNSAFE.putInt(memory + 24, 0x01234567); 142 143 // Unsafe.getInt() 144 int res; 145 for (int i = 0; i < ITERS; i++) { 146 res = getInt_0(); 147 if (res != 0x00112233) { 148 throw new Exception(res + " != 0x00112233"); 149 } 150 } 151 152 for (int i = 0; i < ITERS; i++) { 153 res = getInt_1(); 154 if (res != (BIG_ENDIAN ? 0x11223344 : 0x77001122)) { 155 throw new Exception(res + " != " + (BIG_ENDIAN ? 0x11223344 : 0x77001122)); 156 } 157 } 158 159 for (int i = 0; i < ITERS; i++) { 160 res = getInt_4(); 161 if (res != 0x44556677) { 162 throw new Exception(res + " != 0x44556677"); 163 } 164 } 165 166 for (int i = 0; i < ITERS; i++) { 167 res = getInt_17(); 168 if (res != (BIG_ENDIAN ? 0x23456789 : 0xef012345)) { 169 throw new Exception(res + " != " + (BIG_ENDIAN ? 0x23456789 : 0xef012345)); 170 } 171 } 172 173 // (long)Unsafe.getInt() 174 long lres; 175 for (int i = 0; i < ITERS; i++) { 176 lres = getIntAsLong_0(); 177 if (lres != (long)0x00112233) { 178 throw new Exception(lres + " != 0x00112233"); 179 } 180 } 181 182 for (int i = 0; i < ITERS; i++) { 183 lres = getIntAsLong_1(); 184 if (lres != (BIG_ENDIAN ? (long)0x11223344 : (long)0x77001122)) { 185 throw new Exception(lres + " != " + (BIG_ENDIAN ? (long)0x11223344 : (long)0x77001122)); 186 } 187 } 188 189 for (int i = 0; i < ITERS; i++) { 190 lres = getIntAsLong_4(); 191 if (lres != (long)0x44556677) { 192 throw new Exception(lres + " != 0x44556677"); 193 } 194 } 195 196 for (int i = 0; i < ITERS; i++) { 197 lres = getIntAsLong_17(); 198 if (lres != (BIG_ENDIAN ? (long)0x23456789 : (long)0xef012345)) { 199 throw new Exception(lres + " != " + (BIG_ENDIAN ? (long)0x23456789 : (long)0xef012345)); 200 } 201 } 202 203 // Unsafe.getLong() 204 for (int i = 0; i < ITERS; i++) { 205 lres = getLong_0(); 206 if (lres != (BIG_ENDIAN ? 0x0011223344556677L : 0x4455667700112233L)) { 207 throw new Exception(lres + " != " + (BIG_ENDIAN ? 0x0011223344556677L : 0x4455667700112233L)); 208 } 209 } 210 211 for (int i = 0; i < ITERS; i++) { 212 lres = getLong_1(); 213 if (lres != (BIG_ENDIAN ? 0x1122334455667788L : 0xbb44556677001122L)) { 214 throw new Exception(lres + " != " + (BIG_ENDIAN ? 0x1122334455667788L : 0xbb44556677001122L)); 215 } 216 } 217 218 for (int i = 0; i < ITERS; i++) { 219 lres = getLong_4(); 220 if (lres != (BIG_ENDIAN ? 0x445566778899aabbL : 0x8899aabb44556677L)) { 221 throw new Exception(lres + " != " + (BIG_ENDIAN ? 0x445566778899aabbL : 0x8899aabb44556677L)); 222 } 223 } 224 225 for (int i = 0; i < ITERS; i++) { 226 lres = getLong_8(); 227 if (lres != (BIG_ENDIAN ? 0x8899aabbccddeeffL : 0xccddeeff8899aabbL)) { 228 throw new Exception(lres + " != " + (BIG_ENDIAN ? 0x8899aabbccddeeffL : 0xccddeeff8899aabbL)); 229 } 230 } 231 232 for (int i = 0; i < ITERS; i++) { 233 lres = getLong_17(); 234 if (lres != (BIG_ENDIAN ? 0x23456789abcdef01L : 0x6789abcdef012345L)) { 235 throw new Exception(lres + " != " + (BIG_ENDIAN ? 0x23456789abcdef01L : 0x6789abcdef012345L)); 236 } 237 } 238 239 // Unsafe.putInt() 240 for (int i = 0; i < ITERS; i++) { 241 putInt_0(0x00112233); 242 res = getInt_0(); 243 if (res != 0x00112233) { 244 throw new Exception(res + " != 0x00112233"); 245 } 246 } 247 248 for (int i = 0; i < ITERS; i++) { 249 putInt_1(BIG_ENDIAN ? 0x11223344 : 0x77001122); 250 res = getInt_1(); 251 if (res != (BIG_ENDIAN ? 0x11223344 : 0x77001122)) { 252 throw new Exception(res + " != " + (BIG_ENDIAN ? 0x11223344 : 0x77001122)); 253 } 254 } 255 256 for (int i = 0; i < ITERS; i++) { 257 putInt_4(0x44556677); 258 res = getInt_4(); 259 if (res != 0x44556677) { 260 throw new Exception(res + " != 0x44556677"); 261 } 262 } 263 264 for (int i = 0; i < ITERS; i++) { 265 putInt_17(BIG_ENDIAN ? 0x23456789 : 0xef012345); 266 res = getInt_17(); 267 if (res != (BIG_ENDIAN ? 0x23456789 : 0xef012345)) { 268 throw new Exception(res + " != " + (BIG_ENDIAN ? 0x23456789 : 0xef012345)); 269 } 270 } 271 272 273 // Unsafe.putLong() 274 for (int i = 0; i < ITERS; i++) { 275 putLong_0(BIG_ENDIAN ? 0x0011223344556677L : 0x4455667700112233L); 276 lres = getLong_0(); 277 if (lres != (BIG_ENDIAN ? 0x0011223344556677L : 0x4455667700112233L)) { 278 throw new Exception(lres + " != " + (BIG_ENDIAN ? 0x0011223344556677L : 0x4455667700112233L)); 279 } 280 } 281 282 for (int i = 0; i < ITERS; i++) { 283 putLong_1(BIG_ENDIAN ? 0x1122334455667788L : 0xbb44556677001122L); 284 lres = getLong_1(); 285 if (lres != (BIG_ENDIAN ? 0x1122334455667788L : 0xbb44556677001122L)) { 286 throw new Exception(lres + " != " + (BIG_ENDIAN ? 0x1122334455667788L : 0xbb44556677001122L)); 287 } 288 } 289 290 for (int i = 0; i < ITERS; i++) { 291 putLong_4(BIG_ENDIAN ? 0x445566778899aabbL : 0x8899aabb44556677L); 292 lres = getLong_4(); 293 if (lres != (BIG_ENDIAN ? 0x445566778899aabbL : 0x8899aabb44556677L)) { 294 throw new Exception(lres + " != " + (BIG_ENDIAN ? 0x445566778899aabbL : 0x8899aabb44556677L)); 295 } 296 } 297 298 for (int i = 0; i < ITERS; i++) { 299 putLong_8(BIG_ENDIAN ? 0x8899aabbccddeeffL : 0xccddeeff8899aabbL); 300 lres = getLong_8(); 301 if (lres != (BIG_ENDIAN ? 0x8899aabbccddeeffL : 0xccddeeff8899aabbL)) { 302 throw new Exception(lres + " != " + (BIG_ENDIAN ? 0x8899aabbccddeeffL : 0xccddeeff8899aabbL)); 303 } 304 } 305 306 for (int i = 0; i < ITERS; i++) { 307 putLong_17(BIG_ENDIAN ? 0x23456789abcdef01L : 0x6789abcdef012345L); 308 lres = getLong_17(); 309 if (lres != (BIG_ENDIAN ? 0x23456789abcdef01L : 0x6789abcdef012345L)) { 310 throw new Exception(lres + " != " + (BIG_ENDIAN ? 0x23456789abcdef01L : 0x6789abcdef012345L)); 311 } 312 } 313 } 314 315 }