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