GetConstantPoolTest.java revision 9814:22fd02fad88b
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.simpleArch == "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 */
41package compiler.jvmci.compilerToVM;
42
43import java.lang.reflect.Field;
44import jdk.vm.ci.meta.ConstantPool;
45import jdk.vm.ci.hotspot.CompilerToVMHelper;
46import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
47import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
48import jdk.vm.ci.hotspot.PublicMetaspaceWrapperObject;
49import jdk.test.lib.Utils;
50import sun.hotspot.WhiteBox;
51import sun.misc.Unsafe;
52
53/**
54 * Tests for jdk.vm.ci.hotspot.CompilerToVM::getConstantPool method
55 */
56public 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}
222