comparison graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotConstantPool.java @ 21551:5324104ac4f3

moved com.oracle.graal.hotspot.jvmci classes to com.oracle.jvmci.hotspot module (JBS:GRAAL-53)
author Doug Simon <doug.simon@oracle.com>
date Tue, 26 May 2015 17:13:37 +0200
parents
children
comparison
equal deleted inserted replaced
21550:f48a6cea31eb 21551:5324104ac4f3
1 /*
2 * Copyright (c) 2011, 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 package com.oracle.jvmci.hotspot;
24
25 import static com.oracle.jvmci.common.UnsafeAccess.*;
26 import static com.oracle.jvmci.hotspot.HotSpotJVMCIRuntime.*;
27
28 import java.lang.invoke.*;
29
30 import com.oracle.graal.api.meta.*;
31 import com.oracle.jvmci.common.*;
32
33 /**
34 * Implementation of {@link ConstantPool} for HotSpot.
35 */
36 public class HotSpotConstantPool implements ConstantPool, HotSpotProxified {
37
38 /**
39 * Subset of JVM bytecode opcodes used by {@link HotSpotConstantPool}.
40 */
41 static class Bytecodes {
42 public static final int LDC = 18; // 0x12
43 public static final int LDC_W = 19; // 0x13
44 public static final int LDC2_W = 20; // 0x14
45 public static final int GETSTATIC = 178; // 0xB2
46 public static final int PUTSTATIC = 179; // 0xB3
47 public static final int GETFIELD = 180; // 0xB4
48 public static final int PUTFIELD = 181; // 0xB5
49 public static final int INVOKEVIRTUAL = 182; // 0xB6
50 public static final int INVOKESPECIAL = 183; // 0xB7
51 public static final int INVOKESTATIC = 184; // 0xB8
52 public static final int INVOKEINTERFACE = 185; // 0xB9
53 public static final int INVOKEDYNAMIC = 186; // 0xBA
54 public static final int NEW = 187; // 0xBB
55 public static final int NEWARRAY = 188; // 0xBC
56 public static final int ANEWARRAY = 189; // 0xBD
57 public static final int CHECKCAST = 192; // 0xC0
58 public static final int INSTANCEOF = 193; // 0xC1
59 public static final int MULTIANEWARRAY = 197; // 0xC5
60
61 static boolean isInvoke(int opcode) {
62 switch (opcode) {
63 case INVOKEVIRTUAL:
64 case INVOKESPECIAL:
65 case INVOKESTATIC:
66 case INVOKEINTERFACE:
67 case INVOKEDYNAMIC:
68 return true;
69 default:
70 return false;
71 }
72 }
73 }
74
75 /**
76 * Enum of all {@code JVM_CONSTANT} constants used in the VM. This includes the public and
77 * internal ones.
78 */
79 private enum JVM_CONSTANT {
80 // @formatter:off
81 Utf8(config().jvmConstantUtf8),
82 Integer(config().jvmConstantInteger),
83 Long(config().jvmConstantLong),
84 Float(config().jvmConstantFloat),
85 Double(config().jvmConstantDouble),
86 Class(config().jvmConstantClass),
87 UnresolvedClass(config().jvmConstantUnresolvedClass),
88 UnresolvedClassInError(config().jvmConstantUnresolvedClassInError),
89 String(config().jvmConstantString),
90 Fieldref(config().jvmConstantFieldref),
91 MethodRef(config().jvmConstantMethodref),
92 InterfaceMethodref(config().jvmConstantInterfaceMethodref),
93 NameAndType(config().jvmConstantNameAndType),
94 MethodHandle(config().jvmConstantMethodHandle),
95 MethodHandleInError(config().jvmConstantMethodHandleInError),
96 MethodType(config().jvmConstantMethodType),
97 MethodTypeInError(config().jvmConstantMethodTypeInError),
98 InvokeDynamic(config().jvmConstantInvokeDynamic);
99 // @formatter:on
100
101 private final int tag;
102
103 private static final int ExternalMax = config().jvmConstantExternalMax;
104 private static final int InternalMin = config().jvmConstantInternalMin;
105 private static final int InternalMax = config().jvmConstantInternalMax;
106
107 private JVM_CONSTANT(int tag) {
108 this.tag = tag;
109 }
110
111 private static HotSpotVMConfig config() {
112 return runtime().getConfig();
113 }
114
115 /**
116 * Maps JVM_CONSTANT tags to {@link JVM_CONSTANT} values. Using a separate class for lazy
117 * initialization.
118 */
119 static class TagValueMap {
120 private static final JVM_CONSTANT[] table = new JVM_CONSTANT[ExternalMax + 1 + (InternalMax - InternalMin) + 1];
121 static {
122 assert InternalMin > ExternalMax;
123 for (JVM_CONSTANT e : values()) {
124 table[indexOf(e.tag)] = e;
125 }
126 }
127
128 private static int indexOf(int tag) {
129 if (tag >= InternalMin) {
130 return tag - InternalMin + ExternalMax + 1;
131 } else {
132 assert tag <= ExternalMax;
133 }
134 return tag;
135 }
136
137 static JVM_CONSTANT get(int tag) {
138 JVM_CONSTANT res = table[indexOf(tag)];
139 if (res != null) {
140 return res;
141 }
142 throw new JVMCIError("Unknown JVM_CONSTANT tag %s", tag);
143 }
144 }
145
146 public static JVM_CONSTANT getEnum(int tag) {
147 return TagValueMap.get(tag);
148 }
149 }
150
151 private static class LookupTypeCacheElement {
152 int lastCpi = Integer.MIN_VALUE;
153 JavaType javaType;
154
155 public LookupTypeCacheElement(int lastCpi, JavaType javaType) {
156 super();
157 this.lastCpi = lastCpi;
158 this.javaType = javaType;
159 }
160 }
161
162 /**
163 * Reference to the C++ ConstantPool object.
164 */
165 private final long metaspaceConstantPool;
166 private final Object[] cache;
167 private volatile LookupTypeCacheElement lastLookupType;
168
169 public HotSpotConstantPool(long metaspaceConstantPool) {
170 this.metaspaceConstantPool = metaspaceConstantPool;
171 cache = new Object[length()];
172 }
173
174 /**
175 * Gets the holder for this constant pool as {@link HotSpotResolvedObjectTypeImpl}.
176 *
177 * @return holder for this constant pool
178 */
179 private HotSpotResolvedObjectType getHolder() {
180 final long metaspaceKlass = unsafe.getAddress(metaspaceConstantPool + runtime().getConfig().constantPoolHolderOffset);
181 return HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(metaspaceKlass);
182 }
183
184 /**
185 * Converts a raw index from the bytecodes to a constant pool index by adding a
186 * {@link HotSpotVMConfig#constantPoolCpCacheIndexTag constant}.
187 *
188 * @param rawIndex index from the bytecode
189 * @param opcode bytecode to convert the index for
190 * @return constant pool index
191 */
192 private static int toConstantPoolIndex(int rawIndex, int opcode) {
193 int index;
194 if (opcode == Bytecodes.INVOKEDYNAMIC) {
195 index = rawIndex;
196 // See: ConstantPool::is_invokedynamic_index
197 assert index < 0 : "not an invokedynamic constant pool index " + index;
198 } else {
199 assert opcode == Bytecodes.GETFIELD || opcode == Bytecodes.PUTFIELD || opcode == Bytecodes.GETSTATIC || opcode == Bytecodes.PUTSTATIC || opcode == Bytecodes.INVOKEINTERFACE ||
200 opcode == Bytecodes.INVOKEVIRTUAL || opcode == Bytecodes.INVOKESPECIAL || opcode == Bytecodes.INVOKESTATIC : "unexpected invoke opcode " + opcode;
201 index = rawIndex + runtime().getConfig().constantPoolCpCacheIndexTag;
202 }
203 return index;
204 }
205
206 /**
207 * Decode a constant pool cache index to a constant pool index.
208 *
209 * See {@code ConstantPool::decode_cpcache_index}.
210 *
211 * @param index constant pool cache index
212 * @return decoded index
213 */
214 private static int decodeConstantPoolCacheIndex(int index) {
215 if (isInvokedynamicIndex(index)) {
216 return decodeInvokedynamicIndex(index);
217 } else {
218 return index - runtime().getConfig().constantPoolCpCacheIndexTag;
219 }
220 }
221
222 /**
223 * See {@code ConstantPool::is_invokedynamic_index}.
224 */
225 private static boolean isInvokedynamicIndex(int index) {
226 return index < 0;
227 }
228
229 /**
230 * See {@code ConstantPool::decode_invokedynamic_index}.
231 */
232 private static int decodeInvokedynamicIndex(int i) {
233 assert isInvokedynamicIndex(i) : i;
234 return ~i;
235 }
236
237 /**
238 * Gets the constant pool tag at index {@code index}.
239 *
240 * @param index constant pool index
241 * @return constant pool tag
242 */
243 private JVM_CONSTANT getTagAt(int index) {
244 assertBounds(index);
245 HotSpotVMConfig config = runtime().getConfig();
246 final long metaspaceConstantPoolTags = unsafe.getAddress(metaspaceConstantPool + config.constantPoolTagsOffset);
247 final int tag = unsafe.getByteVolatile(null, metaspaceConstantPoolTags + config.arrayU1DataOffset + index);
248 if (tag == 0) {
249 return null;
250 }
251 return JVM_CONSTANT.getEnum(tag);
252 }
253
254 /**
255 * Gets the constant pool entry at index {@code index}.
256 *
257 * @param index constant pool index
258 * @return constant pool entry
259 */
260 private long getEntryAt(int index) {
261 assertBounds(index);
262 return unsafe.getAddress(metaspaceConstantPool + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
263 }
264
265 /**
266 * Gets the integer constant pool entry at index {@code index}.
267 *
268 * @param index constant pool index
269 * @return integer constant pool entry at index
270 */
271 private int getIntAt(int index) {
272 assertTag(index, JVM_CONSTANT.Integer);
273 return unsafe.getInt(metaspaceConstantPool + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
274 }
275
276 /**
277 * Gets the long constant pool entry at index {@code index}.
278 *
279 * @param index constant pool index
280 * @return long constant pool entry
281 */
282 private long getLongAt(int index) {
283 assertTag(index, JVM_CONSTANT.Long);
284 return unsafe.getLong(metaspaceConstantPool + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
285 }
286
287 /**
288 * Gets the float constant pool entry at index {@code index}.
289 *
290 * @param index constant pool index
291 * @return float constant pool entry
292 */
293 private float getFloatAt(int index) {
294 assertTag(index, JVM_CONSTANT.Float);
295 return unsafe.getFloat(metaspaceConstantPool + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
296 }
297
298 /**
299 * Gets the double constant pool entry at index {@code index}.
300 *
301 * @param index constant pool index
302 * @return float constant pool entry
303 */
304 private double getDoubleAt(int index) {
305 assertTag(index, JVM_CONSTANT.Double);
306 return unsafe.getDouble(metaspaceConstantPool + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
307 }
308
309 /**
310 * Gets the {@code JVM_CONSTANT_NameAndType} constant pool entry at index {@code index}.
311 *
312 * @param index constant pool index
313 * @return {@code JVM_CONSTANT_NameAndType} constant pool entry
314 */
315 private int getNameAndTypeAt(int index) {
316 assertTag(index, JVM_CONSTANT.NameAndType);
317 return unsafe.getInt(metaspaceConstantPool + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
318 }
319
320 /**
321 * Gets the {@code JVM_CONSTANT_NameAndType} reference index constant pool entry at index
322 * {@code index}.
323 *
324 * @param index constant pool index
325 * @return {@code JVM_CONSTANT_NameAndType} reference constant pool entry
326 */
327 private int getNameAndTypeRefIndexAt(int index) {
328 return runtime().getCompilerToVM().lookupNameAndTypeRefIndexInPool(metaspaceConstantPool, index);
329 }
330
331 /**
332 * Gets the name of a {@code JVM_CONSTANT_NameAndType} constant pool entry at index
333 * {@code index}.
334 *
335 * @param index constant pool index
336 * @return name as {@link String}
337 */
338 private String getNameRefAt(int index) {
339 return runtime().getCompilerToVM().lookupNameRefInPool(metaspaceConstantPool, index);
340 }
341
342 /**
343 * Gets the name reference index of a {@code JVM_CONSTANT_NameAndType} constant pool entry at
344 * index {@code index}.
345 *
346 * @param index constant pool index
347 * @return name reference index
348 */
349 private int getNameRefIndexAt(int index) {
350 final int refIndex = getNameAndTypeAt(index);
351 // name ref index is in the low 16-bits.
352 return refIndex & 0xFFFF;
353 }
354
355 /**
356 * Gets the signature of a {@code JVM_CONSTANT_NameAndType} constant pool entry at index
357 * {@code index}.
358 *
359 * @param index constant pool index
360 * @return signature as {@link String}
361 */
362 private String getSignatureRefAt(int index) {
363 return runtime().getCompilerToVM().lookupSignatureRefInPool(metaspaceConstantPool, index);
364 }
365
366 /**
367 * Gets the signature reference index of a {@code JVM_CONSTANT_NameAndType} constant pool entry
368 * at index {@code index}.
369 *
370 * @param index constant pool index
371 * @return signature reference index
372 */
373 private int getSignatureRefIndexAt(int index) {
374 final int refIndex = getNameAndTypeAt(index);
375 // signature ref index is in the high 16-bits.
376 return refIndex >>> 16;
377 }
378
379 /**
380 * Gets the klass reference index constant pool entry at index {@code index}.
381 *
382 * @param index constant pool index
383 * @return klass reference index
384 */
385 private int getKlassRefIndexAt(int index) {
386 return runtime().getCompilerToVM().lookupKlassRefIndexInPool(metaspaceConstantPool, index);
387 }
388
389 /**
390 * Gets the uncached klass reference index constant pool entry at index {@code index}. See:
391 * {@code ConstantPool::uncached_klass_ref_index_at}.
392 *
393 * @param index constant pool index
394 * @return klass reference index
395 */
396 private int getUncachedKlassRefIndexAt(int index) {
397 assert getTagAt(index) == JVM_CONSTANT.Fieldref || getTagAt(index) == JVM_CONSTANT.MethodRef || getTagAt(index) == JVM_CONSTANT.InterfaceMethodref;
398 final int refIndex = unsafe.getInt(metaspaceConstantPool + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
399 // klass ref index is in the low 16-bits.
400 return refIndex & 0xFFFF;
401 }
402
403 /**
404 * Asserts that the constant pool index {@code index} is in the bounds of the constant pool.
405 *
406 * @param index constant pool index
407 */
408 private void assertBounds(int index) {
409 assert 0 <= index && index < length() : "index " + index + " not between 0 and " + length();
410 }
411
412 /**
413 * Asserts that the constant pool tag at index {@code index} is equal to {@code tag}.
414 *
415 * @param index constant pool index
416 * @param tag expected tag
417 */
418 private void assertTag(int index, JVM_CONSTANT tag) {
419 assert getTagAt(index) == tag : "constant pool tag at index " + index + " is " + getTagAt(index) + " but expected " + tag;
420 }
421
422 @Override
423 public int length() {
424 return unsafe.getInt(metaspaceConstantPool + runtime().getConfig().constantPoolLengthOffset);
425 }
426
427 @Override
428 public Object lookupConstant(int cpi) {
429 assert cpi != 0;
430 final JVM_CONSTANT tag = getTagAt(cpi);
431 switch (tag) {
432 case Integer:
433 return JavaConstant.forInt(getIntAt(cpi));
434 case Long:
435 return JavaConstant.forLong(getLongAt(cpi));
436 case Float:
437 return JavaConstant.forFloat(getFloatAt(cpi));
438 case Double:
439 return JavaConstant.forDouble(getDoubleAt(cpi));
440 case Class:
441 case UnresolvedClass:
442 case UnresolvedClassInError:
443 final int opcode = -1; // opcode is not used
444 return lookupType(cpi, opcode);
445 case String:
446 Object string = runtime().getCompilerToVM().resolvePossiblyCachedConstantInPool(metaspaceConstantPool, cpi);
447 return HotSpotObjectConstantImpl.forObject(string);
448 case MethodHandle:
449 case MethodHandleInError:
450 case MethodType:
451 case MethodTypeInError:
452 Object obj = runtime().getCompilerToVM().resolveConstantInPool(metaspaceConstantPool, cpi);
453 return HotSpotObjectConstantImpl.forObject(obj);
454 default:
455 throw new JVMCIError("Unknown constant pool tag %s", tag);
456 }
457 }
458
459 @Override
460 public String lookupUtf8(int cpi) {
461 assertTag(cpi, JVM_CONSTANT.Utf8);
462 return runtime().getCompilerToVM().getSymbol(getEntryAt(cpi));
463 }
464
465 @Override
466 public Signature lookupSignature(int cpi) {
467 return new HotSpotSignature(runtime(), lookupUtf8(cpi));
468 }
469
470 @Override
471 public JavaConstant lookupAppendix(int cpi, int opcode) {
472 assert Bytecodes.isInvoke(opcode);
473 final int index = toConstantPoolIndex(cpi, opcode);
474 Object result = runtime().getCompilerToVM().lookupAppendixInPool(metaspaceConstantPool, index);
475 if (result == null) {
476 return null;
477 } else {
478 return HotSpotObjectConstantImpl.forObject(result);
479 }
480 }
481
482 /**
483 * Gets a {@link JavaType} corresponding a given metaspace Klass or a metaspace Symbol depending
484 * on the {@link HotSpotVMConfig#compilerToVMKlassTag tag}.
485 *
486 * @param metaspacePointer either a metaspace Klass or a metaspace Symbol
487 */
488 private static JavaType getJavaType(final long metaspacePointer) {
489 HotSpotJVMCIRuntime runtime = runtime();
490 HotSpotVMConfig config = runtime.getConfig();
491 if ((metaspacePointer & config.compilerToVMSymbolTag) != 0) {
492 final long metaspaceSymbol = metaspacePointer & ~config.compilerToVMSymbolTag;
493 String name = runtime.getCompilerToVM().getSymbol(metaspaceSymbol);
494 return HotSpotUnresolvedJavaType.create(runtime(), "L" + name + ";");
495 } else {
496 assert (metaspacePointer & config.compilerToVMKlassTag) == 0;
497 return HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(metaspacePointer);
498 }
499 }
500
501 @Override
502 public JavaMethod lookupMethod(int cpi, int opcode) {
503 if (opcode != Bytecodes.INVOKEDYNAMIC) {
504 Object result = cache[cpi];
505 if (result != null) {
506 return (ResolvedJavaMethod) result;
507 }
508 }
509 final int index = toConstantPoolIndex(cpi, opcode);
510 final long metaspaceMethod = runtime().getCompilerToVM().lookupMethodInPool(metaspaceConstantPool, index, (byte) opcode);
511 if (metaspaceMethod != 0L) {
512 HotSpotResolvedJavaMethod result = HotSpotResolvedJavaMethodImpl.fromMetaspace(metaspaceMethod);
513 if (opcode != Bytecodes.INVOKEDYNAMIC) {
514 cache[cpi] = result;
515 }
516 return result;
517 } else {
518 // Get the method's name and signature.
519 String name = getNameRefAt(index);
520 HotSpotSignature signature = new HotSpotSignature(runtime(), getSignatureRefAt(index));
521 if (opcode == Bytecodes.INVOKEDYNAMIC) {
522 HotSpotResolvedObjectType holder = HotSpotResolvedObjectTypeImpl.fromObjectClass(MethodHandle.class);
523 return new HotSpotMethodUnresolved(name, signature, holder);
524 } else {
525 final int klassIndex = getKlassRefIndexAt(index);
526 final long metaspacePointer = runtime().getCompilerToVM().lookupKlassInPool(metaspaceConstantPool, klassIndex);
527 JavaType holder = getJavaType(metaspacePointer);
528 return new HotSpotMethodUnresolved(name, signature, holder);
529 }
530 }
531 }
532
533 @Override
534 public JavaType lookupType(int cpi, int opcode) {
535 final LookupTypeCacheElement elem = this.lastLookupType;
536 if (elem != null && elem.lastCpi == cpi) {
537 return elem.javaType;
538 } else {
539 final long metaspacePointer = runtime().getCompilerToVM().lookupKlassInPool(metaspaceConstantPool, cpi);
540 JavaType result = getJavaType(metaspacePointer);
541 if (result instanceof ResolvedJavaType) {
542 this.lastLookupType = new LookupTypeCacheElement(cpi, result);
543 }
544 return result;
545 }
546 }
547
548 @Override
549 public JavaField lookupField(int cpi, int opcode) {
550 Object resolvedJavaField = cache[cpi];
551 if (resolvedJavaField != null) {
552 return (ResolvedJavaField) resolvedJavaField;
553 }
554 final int index = toConstantPoolIndex(cpi, opcode);
555 final int nameAndTypeIndex = getNameAndTypeRefIndexAt(index);
556 final int nameIndex = getNameRefIndexAt(nameAndTypeIndex);
557 String name = lookupUtf8(nameIndex);
558 final int typeIndex = getSignatureRefIndexAt(nameAndTypeIndex);
559 String typeName = lookupUtf8(typeIndex);
560 JavaType type = runtime().lookupType(typeName, getHolder(), false);
561
562 final int holderIndex = getKlassRefIndexAt(index);
563 JavaType holder = lookupType(holderIndex, opcode);
564
565 if (holder instanceof HotSpotResolvedObjectTypeImpl) {
566 long[] info = new long[2];
567 long metaspaceKlass;
568 try {
569 metaspaceKlass = runtime().getCompilerToVM().resolveField(metaspaceConstantPool, index, (byte) opcode, info);
570 } catch (Throwable t) {
571 /*
572 * If there was an exception resolving the field we give up and return an unresolved
573 * field.
574 */
575 return new HotSpotUnresolvedField(holder, name, type);
576 }
577 HotSpotResolvedObjectTypeImpl resolvedHolder = HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(metaspaceKlass);
578 final int flags = (int) info[0];
579 final long offset = info[1];
580 HotSpotResolvedJavaField result = resolvedHolder.createField(name, type, offset, flags);
581 if (type instanceof ResolvedJavaType) {
582 cache[cpi] = result;
583 }
584 return result;
585 } else {
586 return new HotSpotUnresolvedField(holder, name, type);
587 }
588 }
589
590 @Override
591 public void loadReferencedType(int cpi, int opcode) {
592 int index;
593 switch (opcode) {
594 case Bytecodes.CHECKCAST:
595 case Bytecodes.INSTANCEOF:
596 case Bytecodes.NEW:
597 case Bytecodes.ANEWARRAY:
598 case Bytecodes.MULTIANEWARRAY:
599 case Bytecodes.LDC:
600 case Bytecodes.LDC_W:
601 case Bytecodes.LDC2_W:
602 index = cpi;
603 break;
604 case Bytecodes.INVOKEDYNAMIC:
605 // invokedynamic instructions point to a constant pool cache entry.
606 index = decodeConstantPoolCacheIndex(cpi) + runtime().getConfig().constantPoolCpCacheIndexTag;
607 index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(metaspaceConstantPool, index);
608 break;
609 default:
610 index = toConstantPoolIndex(cpi, opcode);
611 index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(metaspaceConstantPool, index);
612 }
613
614 JVM_CONSTANT tag = getTagAt(index);
615 if (tag == null) {
616 assert getTagAt(index - 1) == JVM_CONSTANT.Double || getTagAt(index - 1) == JVM_CONSTANT.Long;
617 return;
618 }
619 switch (tag) {
620 case Fieldref:
621 case MethodRef:
622 case InterfaceMethodref:
623 index = getUncachedKlassRefIndexAt(index);
624 tag = getTagAt(index);
625 assert tag == JVM_CONSTANT.Class || tag == JVM_CONSTANT.UnresolvedClass || tag == JVM_CONSTANT.UnresolvedClassInError : tag;
626 // fall through
627 case Class:
628 case UnresolvedClass:
629 case UnresolvedClassInError:
630 final long metaspaceKlass = runtime().getCompilerToVM().constantPoolKlassAt(metaspaceConstantPool, index);
631 HotSpotResolvedObjectTypeImpl type = HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(metaspaceKlass);
632 Class<?> klass = type.mirror();
633 if (!klass.isPrimitive() && !klass.isArray()) {
634 unsafe.ensureClassInitialized(klass);
635 }
636 break;
637 case InvokeDynamic:
638 if (isInvokedynamicIndex(cpi)) {
639 runtime().getCompilerToVM().resolveInvokeDynamic(metaspaceConstantPool, cpi);
640 }
641 break;
642 default:
643 // nothing
644 break;
645 }
646 }
647
648 @Override
649 public String toString() {
650 HotSpotResolvedObjectType holder = getHolder();
651 return "HotSpotConstantPool<" + holder.toJavaName() + ">";
652 }
653 }