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