1 /* 2 * Copyright (c) 2012, 2015, 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 /* 26 * @test 27 * @bug 7190310 28 * @summary Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops 29 * @modules java.base/jdk.internal.misc 30 * @run main/othervm -Xbatch Test7190310_unsafe 31 */ 32 33 import java.lang.ref.*; 34 import java.lang.reflect.*; 35 import jdk.internal.misc.Unsafe; 36 37 public class Test7190310_unsafe { 38 39 static class TestObject { 40 public String toString() { 41 return "TestObject"; 42 } 43 }; 44 45 private static TestObject str = new TestObject(); 46 private static final WeakReference ref = new WeakReference(str); 47 48 private TestObject obj; 49 50 public static void main(String[] args) throws Exception { 51 Class c = Test7190310_unsafe.class.getClassLoader().loadClass("jdk.internal.misc.Unsafe"); 52 Field f = c.getDeclaredField("theUnsafe"); 53 f.setAccessible(true); 54 Unsafe unsafe = (Unsafe)f.get(c); 55 56 f = Reference.class.getDeclaredField("referent"); 57 f.setAccessible(true); 58 long referent_offset = unsafe.objectFieldOffset(f); 59 60 Test7190310_unsafe t = new Test7190310_unsafe(); 61 TestObject o = new TestObject(); 62 t.obj = o; 63 64 // Warmup (compile methods) 65 System.err.println("Warmup"); 66 Object obj = null; 67 for (int i = 0; i < 11000; i++) { 68 obj = getRef0(ref); 69 } 70 for (int i = 0; i < 11000; i++) { 71 obj = getRef1(unsafe, ref, referent_offset); 72 } 73 for (int i = 0; i < 11000; i++) { 74 obj = getRef2(unsafe, ref, referent_offset); 75 } 76 for (int i = 0; i < 11000; i++) { 77 obj = getRef3(unsafe, ref, referent_offset); 78 } 79 for (int i = 0; i < 11000; i++) { 80 obj = getRef4(unsafe, t, referent_offset); 81 } 82 83 // Access verification 84 System.err.println("Verification"); 85 if (!verifyGet(referent_offset, unsafe)) { 86 System.exit(97); 87 } 88 89 obj = getRef3(unsafe, t, referent_offset); 90 if (obj != o) { 91 System.out.println("FAILED: unsafe.getObject(Object, " + referent_offset + ") " + obj + " != " + o); 92 System.exit(97); 93 } 94 obj = getRef4(unsafe, t, referent_offset); 95 if (obj != o) { 96 System.out.println("FAILED: unsafe.getObject(Test7190310, " + referent_offset + ") " + obj + " != " + o); 97 System.exit(97); 98 } 99 } 100 101 static boolean verifyGet(long referent_offset, Unsafe unsafe) throws Exception { 102 // Access verification 103 System.out.println("referent: " + str); 104 Object obj = getRef0(ref); 105 if (obj != str) { 106 System.out.println("FAILED: weakRef.get() " + obj + " != " + str); 107 return false; 108 } 109 obj = getRef1(unsafe, ref, referent_offset); 110 if (obj != str) { 111 System.out.println("FAILED: unsafe.getObject(weakRef, " + referent_offset + ") " + obj + " != " + str); 112 return false; 113 } 114 obj = getRef2(unsafe, ref, referent_offset); 115 if (obj != str) { 116 System.out.println("FAILED: unsafe.getObject(abstRef, " + referent_offset + ") " + obj + " != " + str); 117 return false; 118 } 119 obj = getRef3(unsafe, ref, referent_offset); 120 if (obj != str) { 121 System.out.println("FAILED: unsafe.getObject(Object, " + referent_offset + ") " + obj + " != " + str); 122 return false; 123 } 124 return true; 125 } 126 127 static Object getRef0(WeakReference ref) throws Exception { 128 return ref.get(); 129 } 130 static Object getRef1(Unsafe unsafe, WeakReference ref, long referent_offset) throws Exception { 131 return unsafe.getObject(ref, referent_offset); 132 } 133 static Object getRef2(Unsafe unsafe, Reference ref, long referent_offset) throws Exception { 134 return unsafe.getObject(ref, referent_offset); 135 } 136 static Object getRef3(Unsafe unsafe, Object ref, long referent_offset) throws Exception { 137 return unsafe.getObject(ref, referent_offset); 138 } 139 static Object getRef4(Unsafe unsafe, Test7190310_unsafe ref, long referent_offset) throws Exception { 140 return unsafe.getObject(ref, referent_offset); 141 } 142 } 143