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 package compiler.jvmci.compilerToVM;
25
26 import compiler.jvmci.common.testcases.MultipleAbstractImplementer;
27 import compiler.jvmci.common.testcases.MultipleImplementer2;
28 import compiler.jvmci.common.testcases.MultipleImplementersInterface;
29 import compiler.jvmci.compilerToVM.ConstantPoolTestCase.ConstantTypes;
30 import static compiler.jvmci.compilerToVM.ConstantPoolTestCase.ConstantTypes.*;
31 import compiler.jvmci.compilerToVM.ConstantPoolTestCase.TestedCPEntry;
32 import java.util.HashMap;
33 import java.util.Map;
34 import jdk.internal.misc.SharedSecrets;
35 import jdk.internal.org.objectweb.asm.Opcodes;
36 import sun.hotspot.WhiteBox;
37 import jdk.internal.reflect.ConstantPool;
38 import jdk.internal.reflect.ConstantPool.Tag;
39
40 /**
41 * Class contains hard-coded constant pool tables for dummy classes used for
42 * jdk.vm.ci.hotspot.CompilerToVM constant pool methods
43 */
44 public class ConstantPoolTestsHelper {
45
46 public static final int NO_CP_CACHE_PRESENT = Integer.MAX_VALUE;
47
48 public enum DummyClasses {
49 DUMMY_CLASS(MultipleImplementer2.class, CP_MAP_FOR_CLASS),
50 DUMMY_ABS_CLASS(MultipleAbstractImplementer.class, CP_MAP_FOR_ABS_CLASS),
51 DUMMY_INTERFACE(MultipleImplementersInterface.class, CP_MAP_FOR_INTERFACE);
52
53 private static final WhiteBox WB = WhiteBox.getWhiteBox();
54 public final Class<?> klass;
55 public final ConstantPool constantPoolSS;
56 public final Map<ConstantTypes, TestedCPEntry[]> testedCP;
57
58 DummyClasses(Class<?> klass, Map<ConstantTypes, TestedCPEntry[]> testedCP) {
59 this.klass = klass;
60 this.constantPoolSS = SharedSecrets.getJavaLangAccess().getConstantPool(klass);
61 this.testedCP = testedCP;
62 }
63
64 public int getCPCacheIndex(int cpi) {
65 int cacheLength = WB.getConstantPoolCacheLength(this.klass);
66 int indexTag = WB.getConstantPoolCacheIndexTag();
67 for (int cpci = indexTag; cpci < cacheLength + indexTag; cpci++) {
68 if (WB.remapInstructionOperandFromCPCache(this.klass, cpci) == cpi) {
69 if (constantPoolSS.getTagAt(cpi).equals(Tag.INVOKEDYNAMIC)) {
70 return WB.encodeConstantPoolIndyIndex(cpci) + indexTag;
71 }
72 return cpci;
73 }
74 }
75 return NO_CP_CACHE_PRESENT;
76 }
77 }
78
79 private static final Map<ConstantTypes, TestedCPEntry[]> CP_MAP_FOR_CLASS = new HashMap<>();
80 static {
81 CP_MAP_FOR_CLASS.put(CONSTANT_CLASS,
82 new TestedCPEntry[] {
83 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementersInterface", null, null),
84 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2", null, null),
85 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2$1", null, null),
86 new TestedCPEntry("java/lang/invoke/MethodHandles$Lookup", null, null),
87 }
88 );
89 CP_MAP_FOR_CLASS.put(CONSTANT_FIELDREF,
90 new TestedCPEntry[] {
91 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2",
92 "intStaticField",
93 "I",
94 new byte[] {(byte) Opcodes.PUTSTATIC, (byte) Opcodes.GETSTATIC},
95 Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC),
96 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2",
97 "longStaticField",
98 "J",
124 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
125 Opcodes.ACC_PUBLIC),
126 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2",
127 "longField",
128 "J",
129 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
130 Opcodes.ACC_PRIVATE),
131 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2",
132 "floatField",
133 "F",
134 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
135 Opcodes.ACC_PROTECTED),
136 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2",
137 "doubleField",
138 "D",
139 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
140 Opcodes.ACC_TRANSIENT),
141 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2",
142 "objectField",
143 "Ljava/lang/Object;",
144 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
145 Opcodes.ACC_FINAL),
146 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2",
147 "stringField",
148 "Ljava/lang/String;",
149 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
150 Opcodes.ACC_VOLATILE),
151 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2",
152 "stringFieldEmpty",
153 "Ljava/lang/String;",
154 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
155 0L),
156 }
157 );
158 CP_MAP_FOR_CLASS.put(CONSTANT_METHODREF,
159 new TestedCPEntry[] {
160 new TestedCPEntry("java/lang/System",
161 "getProperties",
162 "()Ljava/util/Properties;",
163 new byte[] {(byte) Opcodes.INVOKESTATIC}),
279 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
280 Opcodes.ACC_PUBLIC),
281 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer",
282 "longField",
283 "J",
284 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
285 Opcodes.ACC_PRIVATE),
286 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer",
287 "floatField",
288 "F",
289 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
290 Opcodes.ACC_PROTECTED),
291 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer",
292 "doubleField",
293 "D",
294 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
295 Opcodes.ACC_TRANSIENT),
296 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer",
297 "objectField",
298 "Ljava/lang/Object;",
299 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
300 Opcodes.ACC_FINAL),
301 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer",
302 "stringField",
303 "Ljava/lang/String;",
304 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
305 Opcodes.ACC_VOLATILE),
306 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer",
307 "stringFieldEmpty",
308 "Ljava/lang/String;",
309 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
310 0L),
311 }
312 );
313 CP_MAP_FOR_ABS_CLASS.put(CONSTANT_METHODREF,
314 new TestedCPEntry[] {
315 new TestedCPEntry("java/lang/System",
316 "getProperties",
317 "()Ljava/util/Properties;",
318 new byte[] {(byte) Opcodes.INVOKESTATIC}),
384 }
385 );
386 }
387
388 private static final Map<ConstantTypes, TestedCPEntry[]> CP_MAP_FOR_INTERFACE
389 = new HashMap<>();
390 static {
391 CP_MAP_FOR_INTERFACE.put(CONSTANT_CLASS,
392 new TestedCPEntry[] {
393 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementersInterface", null, null),
394 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementersInterface$1", null, null),
395 new TestedCPEntry("java/lang/Object", null, null),
396 new TestedCPEntry("java/lang/invoke/MethodHandles$Lookup", null, null),
397 }
398 );
399 CP_MAP_FOR_INTERFACE.put(CONSTANT_FIELDREF,
400 new TestedCPEntry[] {
401 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementersInterface",
402 "OBJECT_CONSTANT",
403 "Ljava/lang/Object;",
404 new byte[] {(byte) Opcodes.PUTSTATIC, (byte) Opcodes.GETSTATIC},
405 Opcodes.ACC_STATIC | Opcodes.ACC_FINAL | Opcodes.ACC_PUBLIC),
406 }
407 );
408 CP_MAP_FOR_INTERFACE.put(CONSTANT_METHODREF,
409 new TestedCPEntry[] {
410 new TestedCPEntry("java/lang/System",
411 "getProperties",
412 "()Ljava/util/Properties;",
413 new byte[] {(byte) Opcodes.INVOKESTATIC}),
414 new TestedCPEntry("java/util/HashMap",
415 "<init>",
416 "()V",
417 new byte[] {(byte) Opcodes.INVOKESPECIAL}),
418 new TestedCPEntry("java/lang/Object",
419 "toString",
420 "()Ljava/lang/String;",
421 new byte[] {(byte) Opcodes.INVOKEVIRTUAL}),
422 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer$1",
423 "<init>",
|
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 package compiler.jvmci.compilerToVM;
25
26 import compiler.jvmci.common.testcases.MultipleAbstractImplementer;
27 import compiler.jvmci.common.testcases.MultipleImplementer2;
28 import compiler.jvmci.common.testcases.MultipleImplementersInterface;
29 import compiler.jvmci.compilerToVM.ConstantPoolTestCase.ConstantTypes;
30 import static compiler.jvmci.compilerToVM.ConstantPoolTestCase.ConstantTypes.*;
31 import compiler.jvmci.compilerToVM.ConstantPoolTestCase.TestedCPEntry;
32 import java.util.HashMap;
33 import java.util.Map;
34 import jdk.vm.ci.meta.MetaAccessProvider;
35 import jdk.vm.ci.meta.ResolvedJavaMethod;
36 import jdk.vm.ci.meta.ResolvedJavaType;
37 import jdk.vm.ci.runtime.JVMCI;
38 import jdk.internal.misc.SharedSecrets;
39 import jdk.internal.org.objectweb.asm.Opcodes;
40 import sun.hotspot.WhiteBox;
41 import jdk.internal.reflect.ConstantPool;
42 import jdk.internal.reflect.ConstantPool.Tag;
43
44 /**
45 * Class contains hard-coded constant pool tables for dummy classes used for
46 * jdk.vm.ci.hotspot.CompilerToVM constant pool methods
47 */
48 public class ConstantPoolTestsHelper {
49
50 public static final int NO_CP_CACHE_PRESENT = Integer.MAX_VALUE;
51 private static final MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess();
52
53 public enum DummyClasses {
54 DUMMY_CLASS(MultipleImplementer2.class, CP_MAP_FOR_CLASS),
55 DUMMY_ABS_CLASS(MultipleAbstractImplementer.class, CP_MAP_FOR_ABS_CLASS),
56 DUMMY_INTERFACE(MultipleImplementersInterface.class, CP_MAP_FOR_INTERFACE);
57
58 private static final WhiteBox WB = WhiteBox.getWhiteBox();
59 public final Class<?> klass;
60 public final ConstantPool constantPoolSS;
61 public final Map<ConstantTypes, TestedCPEntry[]> testedCP;
62
63 DummyClasses(Class<?> klass, Map<ConstantTypes, TestedCPEntry[]> testedCP) {
64 this.klass = klass;
65 this.constantPoolSS = SharedSecrets.getJavaLangAccess().getConstantPool(klass);
66 this.testedCP = testedCP;
67 }
68
69 public int getCPCacheIndex(int cpi) {
70 int cacheLength = WB.getConstantPoolCacheLength(this.klass);
71 int indexTag = WB.getConstantPoolCacheIndexTag();
72 for (int cpci = indexTag; cpci < cacheLength + indexTag; cpci++) {
73 if (WB.remapInstructionOperandFromCPCache(this.klass, cpci) == cpi) {
74 if (constantPoolSS.getTagAt(cpi).equals(Tag.INVOKEDYNAMIC)) {
75 return WB.encodeConstantPoolIndyIndex(cpci) + indexTag;
76 }
77 return cpci;
78 }
79 }
80 return NO_CP_CACHE_PRESENT;
81 }
82 }
83
84 /**
85 * Obtain a resolved Java method declared by a given type.
86 *
87 * @param type the declaring type
88 * @param the method's name
89 *
90 * Currently, the lookup is based only on the method's name
91 * but not on the method's signature (i.e., the first method
92 * with a matching name declared on {@code type} is returned).
93 */
94 private static ResolvedJavaMethod getMethod(ResolvedJavaType type, String methodName) {
95 if (methodName.equals("<clinit>")) {
96 return type.getClassInitializer();
97 }
98
99 if (methodName.equals("<init>")) {
100 ResolvedJavaMethod[] initializers = type.getDeclaredConstructors();
101 if (initializers.length >= 0) {
102 return initializers[0];
103 } else {
104 throw new IllegalArgumentException();
105 }
106 }
107
108 for (ResolvedJavaMethod method : type.getDeclaredMethods()) {
109 if (method.getName().equals(methodName)) {
110 return method;
111 }
112 }
113
114 throw new IllegalArgumentException();
115 }
116
117 private static ResolvedJavaType getType(Class<?> clazz) {
118 ResolvedJavaType type = metaAccess.lookupJavaType(clazz);
119 type.initialize();
120 return type;
121 }
122
123 private static final Map<ConstantTypes, TestedCPEntry[]> CP_MAP_FOR_CLASS = new HashMap<>();
124 static {
125 CP_MAP_FOR_CLASS.put(CONSTANT_CLASS,
126 new TestedCPEntry[] {
127 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementersInterface", null, null),
128 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2", null, null),
129 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2$1", null, null),
130 new TestedCPEntry("java/lang/invoke/MethodHandles$Lookup", null, null),
131 }
132 );
133 CP_MAP_FOR_CLASS.put(CONSTANT_FIELDREF,
134 new TestedCPEntry[] {
135 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2",
136 "intStaticField",
137 "I",
138 new byte[] {(byte) Opcodes.PUTSTATIC, (byte) Opcodes.GETSTATIC},
139 Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC),
140 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2",
141 "longStaticField",
142 "J",
168 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
169 Opcodes.ACC_PUBLIC),
170 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2",
171 "longField",
172 "J",
173 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
174 Opcodes.ACC_PRIVATE),
175 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2",
176 "floatField",
177 "F",
178 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
179 Opcodes.ACC_PROTECTED),
180 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2",
181 "doubleField",
182 "D",
183 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
184 Opcodes.ACC_TRANSIENT),
185 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2",
186 "objectField",
187 "Ljava/lang/Object;",
188 new ResolvedJavaMethod[] { getMethod(getType(MultipleImplementer2.class), "<init>"), null },
189 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
190 Opcodes.ACC_FINAL),
191 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2",
192 "stringField",
193 "Ljava/lang/String;",
194 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
195 Opcodes.ACC_VOLATILE),
196 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2",
197 "stringFieldEmpty",
198 "Ljava/lang/String;",
199 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
200 0L),
201 }
202 );
203 CP_MAP_FOR_CLASS.put(CONSTANT_METHODREF,
204 new TestedCPEntry[] {
205 new TestedCPEntry("java/lang/System",
206 "getProperties",
207 "()Ljava/util/Properties;",
208 new byte[] {(byte) Opcodes.INVOKESTATIC}),
324 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
325 Opcodes.ACC_PUBLIC),
326 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer",
327 "longField",
328 "J",
329 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
330 Opcodes.ACC_PRIVATE),
331 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer",
332 "floatField",
333 "F",
334 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
335 Opcodes.ACC_PROTECTED),
336 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer",
337 "doubleField",
338 "D",
339 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
340 Opcodes.ACC_TRANSIENT),
341 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer",
342 "objectField",
343 "Ljava/lang/Object;",
344 new ResolvedJavaMethod[] { getMethod(getType(MultipleAbstractImplementer.class), "<init>"), null },
345 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
346 Opcodes.ACC_FINAL),
347 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer",
348 "stringField",
349 "Ljava/lang/String;",
350 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
351 Opcodes.ACC_VOLATILE),
352 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer",
353 "stringFieldEmpty",
354 "Ljava/lang/String;",
355 new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
356 0L),
357 }
358 );
359 CP_MAP_FOR_ABS_CLASS.put(CONSTANT_METHODREF,
360 new TestedCPEntry[] {
361 new TestedCPEntry("java/lang/System",
362 "getProperties",
363 "()Ljava/util/Properties;",
364 new byte[] {(byte) Opcodes.INVOKESTATIC}),
430 }
431 );
432 }
433
434 private static final Map<ConstantTypes, TestedCPEntry[]> CP_MAP_FOR_INTERFACE
435 = new HashMap<>();
436 static {
437 CP_MAP_FOR_INTERFACE.put(CONSTANT_CLASS,
438 new TestedCPEntry[] {
439 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementersInterface", null, null),
440 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementersInterface$1", null, null),
441 new TestedCPEntry("java/lang/Object", null, null),
442 new TestedCPEntry("java/lang/invoke/MethodHandles$Lookup", null, null),
443 }
444 );
445 CP_MAP_FOR_INTERFACE.put(CONSTANT_FIELDREF,
446 new TestedCPEntry[] {
447 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementersInterface",
448 "OBJECT_CONSTANT",
449 "Ljava/lang/Object;",
450 new ResolvedJavaMethod[] { getMethod(getType(MultipleImplementersInterface.class), "<clinit>"), null },
451 new byte[] {(byte) Opcodes.PUTSTATIC, (byte) Opcodes.GETSTATIC},
452 Opcodes.ACC_STATIC | Opcodes.ACC_FINAL | Opcodes.ACC_PUBLIC),
453 }
454 );
455 CP_MAP_FOR_INTERFACE.put(CONSTANT_METHODREF,
456 new TestedCPEntry[] {
457 new TestedCPEntry("java/lang/System",
458 "getProperties",
459 "()Ljava/util/Properties;",
460 new byte[] {(byte) Opcodes.INVOKESTATIC}),
461 new TestedCPEntry("java/util/HashMap",
462 "<init>",
463 "()V",
464 new byte[] {(byte) Opcodes.INVOKESPECIAL}),
465 new TestedCPEntry("java/lang/Object",
466 "toString",
467 "()Ljava/lang/String;",
468 new byte[] {(byte) Opcodes.INVOKEVIRTUAL}),
469 new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer$1",
470 "<init>",
|