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