1 /* 2 * Copyright (c) 2007, 2012, 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 package org.graalvm.compiler.jtt.optimize; 24 25 import java.lang.reflect.Field; 26 import java.nio.ByteBuffer; 27 28 import org.junit.Test; 29 import org.junit.internal.AssumptionViolatedException; 30 31 import org.graalvm.compiler.api.directives.GraalDirectives; 32 import org.graalvm.compiler.jtt.JTTTest; 33 34 import jdk.vm.ci.meta.ResolvedJavaMethod; 35 import sun.misc.Unsafe; 36 37 public class UnsafeDeopt extends JTTTest { 38 private static final Unsafe unsafe; 39 40 static { 41 try { 42 final Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); 43 unsafeField.setAccessible(true); 44 unsafe = (Unsafe) unsafeField.get(null); 45 } catch (Exception e) { 46 throw new Error(e); 47 } 48 } 49 50 public static int readWriteReadUnsafe(long addr, int m) { 51 int original = unsafe.getInt(addr); 52 if (original != 0) { 53 return -m; 54 } 55 unsafe.putInt(addr, m); 56 if (m > 10) { 57 if (m > 20) { 58 GraalDirectives.deoptimize(); 59 } 60 unsafe.putInt(addr + 4, m); 61 } 62 return unsafe.getInt(addr); 63 } 64 65 public static int readWriteReadByteBuffer(ByteBuffer buffer, int m) { 66 int original = buffer.getInt(0); 67 if (original != 0) { 68 return -m; 69 } 70 buffer.putInt(0, m); 71 if (m > 10) { 72 if (m > 20) { 73 GraalDirectives.deoptimize(); 74 buffer.putInt(4, m); 75 } 76 } 77 return buffer.getInt(0); 78 } 79 80 public long createBuffer() { 81 long addr = unsafe.allocateMemory(32); 82 unsafe.setMemory(addr, 32, (byte) 0); 83 return addr; 84 } 85 86 public void disposeBuffer(long addr) { 87 unsafe.freeMemory(addr); 88 } 89 90 @Test 91 public void testUnsafe() { 92 int m = 42; 93 long addr1 = createBuffer(); 94 long addr2 = createBuffer(); 95 try { 96 ResolvedJavaMethod method = getResolvedJavaMethod("readWriteReadUnsafe"); 97 Object receiver = method.isStatic() ? null : this; 98 Result expect = executeExpected(method, receiver, addr1, m); 99 if (getCodeCache() == null) { 100 return; 101 } 102 testAgainstExpected(method, expect, receiver, addr2, m); 103 } catch (AssumptionViolatedException e) { 104 // Suppress so that subsequent calls to this method within the 105 // same Junit @Test annotated method can proceed. 106 } finally { 107 disposeBuffer(addr1); 108 disposeBuffer(addr2); 109 } 110 } 111 112 @Test 113 public void testByteBuffer() { 114 int m = 42; 115 try { 116 ResolvedJavaMethod method = getResolvedJavaMethod("readWriteReadByteBuffer"); 117 Object receiver = method.isStatic() ? null : this; 118 Result expect = executeExpected(method, receiver, ByteBuffer.allocateDirect(32), m); 119 if (getCodeCache() == null) { 120 return; 121 } 122 ByteBuffer warmupBuffer = ByteBuffer.allocateDirect(32); 123 for (int i = 0; i < 10000; ++i) { 124 readWriteReadByteBuffer(warmupBuffer, (i % 50) + 1); 125 warmupBuffer.putInt(0, 0); 126 } 127 testAgainstExpected(method, expect, receiver, ByteBuffer.allocateDirect(32), m); 128 } catch (AssumptionViolatedException e) { 129 // Suppress so that subsequent calls to this method within the 130 // same Junit @Test annotated method can proceed. 131 } 132 } 133 }