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