1 /* 2 * Copyright (c) 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 8136421 28 * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64" 29 * @library /testlibrary /../../test/lib / 30 * @compile ../common/CompilerToVMHelper.java ../common/PublicMetaspaceWrapperObject.java 31 * @build sun.hotspot.WhiteBox 32 * compiler.jvmci.compilerToVM.GetConstantPoolTest 33 * @run main ClassFileInstaller sun.hotspot.WhiteBox 34 * sun.hotspot.WhiteBox$WhiteBoxPermission 35 * jdk.vm.ci.hotspot.CompilerToVMHelper 36 * jdk.vm.ci.hotspot.PublicMetaspaceWrapperObject 37 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions 38 * -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions 39 * -XX:+EnableJVMCI compiler.jvmci.compilerToVM.GetConstantPoolTest 40 */ 41 package compiler.jvmci.compilerToVM; 42 43 import java.lang.reflect.Field; 44 import jdk.vm.ci.meta.ConstantPool; 45 import jdk.vm.ci.hotspot.CompilerToVMHelper; 46 import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; 47 import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; 48 import jdk.vm.ci.hotspot.PublicMetaspaceWrapperObject; 49 import jdk.test.lib.Utils; 50 import sun.hotspot.WhiteBox; 51 import sun.misc.Unsafe; 52 53 /** 54 * Tests for jdk.vm.ci.hotspot.CompilerToVM::getConstantPool method 55 */ 56 public class GetConstantPoolTest { 57 private static enum TestCase { 58 NULL_BASE { 59 @Override 60 ConstantPool getConstantPool() { 61 return CompilerToVMHelper.getConstantPool(null, 62 getPtrToCpAddress()); 63 } 64 }, 65 JAVA_METHOD_BASE { 66 @Override 67 ConstantPool getConstantPool() { 68 HotSpotResolvedJavaMethod methodInstance 69 = CompilerToVMHelper.getResolvedJavaMethodAtSlot( 70 TEST_CLASS, 0); 71 Field field; 72 try { 73 // jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl.metaspaceMethod 74 field = methodInstance.getClass() 75 .getDeclaredField("metaspaceMethod"); 76 field.setAccessible(true); 77 field.set(methodInstance, getPtrToCpAddress()); 78 } catch (ReflectiveOperationException e) { 79 throw new Error("TESTBUG : " + e, e); 80 } 81 82 return CompilerToVMHelper.getConstantPool(methodInstance, 0L); 83 } 84 }, 85 CONSTANT_POOL_BASE { 86 @Override 87 ConstantPool getConstantPool() { 88 ConstantPool cpInst; 89 try { 90 cpInst = CompilerToVMHelper.getConstantPool(null, 91 getPtrToCpAddress()); 92 Field field = CompilerToVMHelper.HotSpotConstantPoolClass() 93 .getDeclaredField("metaspaceConstantPool"); 94 field.setAccessible(true); 95 field.set(cpInst, getPtrToCpAddress()); 96 } catch (ReflectiveOperationException e) { 97 throw new Error("TESTBUG : " + e.getMessage(), e); 98 } 99 return CompilerToVMHelper.getConstantPool(cpInst, 0L); 100 } 101 }, 102 CONSTANT_POOL_BASE_IN_TWO { 103 @Override 104 ConstantPool getConstantPool() { 105 long ptr = getPtrToCpAddress(); 106 ConstantPool cpInst; 107 try { 108 cpInst = CompilerToVMHelper.getConstantPool(null, ptr); 109 Field field = CompilerToVMHelper.HotSpotConstantPoolClass() 110 .getDeclaredField("metaspaceConstantPool"); 111 field.setAccessible(true); 112 field.set(cpInst, ptr / 2L); 113 } catch (ReflectiveOperationException e) { 114 throw new Error("TESTBUG : " + e.getMessage(), e); 115 } 116 return CompilerToVMHelper.getConstantPool(cpInst, 117 ptr - ptr / 2L); 118 } 119 }, 120 CONSTANT_POOL_BASE_ZERO { 121 @Override 122 ConstantPool getConstantPool() { 123 long ptr = getPtrToCpAddress(); 124 ConstantPool cpInst; 125 try { 126 cpInst = CompilerToVMHelper.getConstantPool(null, ptr); 127 Field field = CompilerToVMHelper.HotSpotConstantPoolClass() 128 .getDeclaredField("metaspaceConstantPool"); 129 field.setAccessible(true); 130 field.set(cpInst, 0L); 131 } catch (ReflectiveOperationException e) { 132 throw new Error("TESTBUG : " + e.getMessage(), e); 133 } 134 return CompilerToVMHelper.getConstantPool(cpInst, ptr); 135 } 136 }, 137 OBJECT_TYPE_BASE { 138 @Override 139 ConstantPool getConstantPool() { 140 HotSpotResolvedObjectType type 141 = HotSpotResolvedObjectType.fromObjectClass( 142 OBJECT_TYPE_BASE.getClass()); 143 long ptrToClass = UNSAFE.getKlassPointer(OBJECT_TYPE_BASE); 144 return CompilerToVMHelper.getConstantPool(type, 145 getPtrToCpAddress() - ptrToClass); 146 } 147 }, 148 ; 149 abstract ConstantPool getConstantPool(); 150 } 151 152 private static final WhiteBox WB = WhiteBox.getWhiteBox(); 153 private static final Unsafe UNSAFE = Utils.getUnsafe(); 154 155 private static final Class TEST_CLASS = GetConstantPoolTest.class; 156 private static final long CP_ADDRESS 157 = WB.getConstantPool(GetConstantPoolTest.class); 158 159 public void test(TestCase testCase) { 160 System.out.println(testCase.name()); 161 ConstantPool cp = testCase.getConstantPool(); 162 String cpStringRep = cp.toString(); 163 String cpClassSimpleName 164 = CompilerToVMHelper.HotSpotConstantPoolClass().getSimpleName(); 165 if (!cpStringRep.contains(cpClassSimpleName) 166 || !cpStringRep.contains(TEST_CLASS.getName())) { 167 String msg = String.format("%s : " 168 + " Constant pool is not valid." 169 + " String representation should contain \"%s\" and \"%s\"", 170 testCase.name(), cpClassSimpleName, 171 TEST_CLASS.getName()); 172 throw new AssertionError(msg); 173 } 174 } 175 176 public static void main(String[] args) { 177 GetConstantPoolTest test = new GetConstantPoolTest(); 178 for (TestCase testCase : TestCase.values()) { 179 test.test(testCase); 180 } 181 testObjectBase(); 182 testMetaspaceWrapperBase(); 183 } 184 185 private static void testObjectBase() { 186 try { 187 Object cp = CompilerToVMHelper.getConstantPool(new Object(), 0L); 188 throw new AssertionError("Test OBJECT_BASE." 189 + " Expected IllegalArgumentException has not been caught"); 190 } catch (IllegalArgumentException iae) { 191 // expected 192 } 193 } 194 private static void testMetaspaceWrapperBase() { 195 try { 196 Object cp = CompilerToVMHelper.getConstantPool( 197 new PublicMetaspaceWrapperObject() { 198 @Override 199 public long getMetaspacePointer() { 200 return getPtrToCpAddress(); 201 } 202 }, 0L); 203 throw new AssertionError("Test METASPACE_WRAPPER_BASE." 204 + " Expected IllegalArgumentException has not been caught"); 205 } catch (IllegalArgumentException iae) { 206 // expected 207 } 208 } 209 210 private static long getPtrToCpAddress() { 211 Field field; 212 try { 213 field = TEST_CLASS.getDeclaredField("CP_ADDRESS"); 214 } catch (NoSuchFieldException nsfe) { 215 throw new Error("TESTBUG : cannot find field \"CP_ADDRESS\" : " 216 + nsfe.getMessage(), nsfe); 217 } 218 Object base = UNSAFE.staticFieldBase(field); 219 return WB.getObjectAddress(base) + UNSAFE.staticFieldOffset(field); 220 } 221 }