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