< prev index next >
src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java
Print this page
@@ -20,22 +20,31 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.vm.ci.hotspot;
-import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
+import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
+import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
-import java.lang.invoke.*;
+import java.lang.invoke.MethodHandle;
-import jdk.vm.ci.common.*;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.ConstantPool;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaField;
+import jdk.vm.ci.meta.JavaMethod;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.Signature;
/**
* Implementation of {@link ConstantPool} for HotSpot.
*/
-public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified, MetaspaceWrapperObject {
+final class HotSpotConstantPool implements ConstantPool, HotSpotProxified, MetaspaceWrapperObject {
/**
* Subset of JVM bytecode opcodes used by {@link HotSpotConstantPool}.
*/
public static class Bytecodes {
@@ -119,14 +128,10 @@
private JVM_CONSTANT(int tag) {
this.tag = tag;
}
- private static HotSpotVMConfig config() {
- return runtime().getConfig();
- }
-
/**
* Maps JVM_CONSTANT tags to {@link JVM_CONSTANT} values. Using a separate class for lazy
* initialization.
*/
static class TagValueMap {
@@ -202,11 +207,11 @@
* Gets the holder for this constant pool as {@link HotSpotResolvedObjectTypeImpl}.
*
* @return holder for this constant pool
*/
private HotSpotResolvedObjectType getHolder() {
- return runtime().getCompilerToVM().getResolvedJavaType(this, runtime().getConfig().constantPoolHolderOffset, false);
+ return compilerToVM().getResolvedJavaType(this, config().constantPoolHolderOffset, false);
}
/**
* Converts a raw index from the bytecodes to a constant pool index by adding a
* {@link HotSpotVMConfig#constantPoolCpCacheIndexTag constant}.
@@ -222,11 +227,11 @@
// See: ConstantPool::is_invokedynamic_index
assert index < 0 : "not an invokedynamic constant pool index " + index;
} else {
assert opcode == Bytecodes.GETFIELD || opcode == Bytecodes.PUTFIELD || opcode == Bytecodes.GETSTATIC || opcode == Bytecodes.PUTSTATIC || opcode == Bytecodes.INVOKEINTERFACE ||
opcode == Bytecodes.INVOKEVIRTUAL || opcode == Bytecodes.INVOKESPECIAL || opcode == Bytecodes.INVOKESTATIC : "unexpected invoke opcode " + opcode;
- index = rawIndex + runtime().getConfig().constantPoolCpCacheIndexTag;
+ index = rawIndex + config().constantPoolCpCacheIndexTag;
}
return index;
}
/**
@@ -239,11 +244,11 @@
*/
private static int decodeConstantPoolCacheIndex(int index) {
if (isInvokedynamicIndex(index)) {
return decodeInvokedynamicIndex(index);
} else {
- return index - runtime().getConfig().constantPoolCpCacheIndexTag;
+ return index - config().constantPoolCpCacheIndexTag;
}
}
/**
* See {@code ConstantPool::is_invokedynamic_index}.
@@ -258,11 +263,11 @@
private static int decodeInvokedynamicIndex(int i) {
assert isInvokedynamicIndex(i) : i;
return ~i;
}
- public long getMetaspaceConstantPool() {
+ long getMetaspaceConstantPool() {
return metaspaceConstantPool;
}
public long getMetaspacePointer() {
return getMetaspaceConstantPool();
@@ -274,11 +279,11 @@
* @param index constant pool index
* @return constant pool tag
*/
private JVM_CONSTANT getTagAt(int index) {
assertBounds(index);
- HotSpotVMConfig config = runtime().getConfig();
+ HotSpotVMConfig config = config();
final long metaspaceConstantPoolTags = UNSAFE.getAddress(getMetaspaceConstantPool() + config.constantPoolTagsOffset);
final int tag = UNSAFE.getByteVolatile(null, metaspaceConstantPoolTags + config.arrayU1DataOffset + index);
if (tag == 0) {
return null;
}
@@ -291,88 +296,88 @@
* @param index constant pool index
* @return constant pool entry
*/
private long getEntryAt(int index) {
assertBounds(index);
- return UNSAFE.getAddress(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+ return UNSAFE.getAddress(getMetaspaceConstantPool() + config().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
}
/**
* Gets the integer constant pool entry at index {@code index}.
*
* @param index constant pool index
* @return integer constant pool entry at index
*/
private int getIntAt(int index) {
assertTag(index, JVM_CONSTANT.Integer);
- return UNSAFE.getInt(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+ return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
}
/**
* Gets the long constant pool entry at index {@code index}.
*
* @param index constant pool index
* @return long constant pool entry
*/
private long getLongAt(int index) {
assertTag(index, JVM_CONSTANT.Long);
- return UNSAFE.getLong(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+ return UNSAFE.getLong(getMetaspaceConstantPool() + config().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
}
/**
* Gets the float constant pool entry at index {@code index}.
*
* @param index constant pool index
* @return float constant pool entry
*/
private float getFloatAt(int index) {
assertTag(index, JVM_CONSTANT.Float);
- return UNSAFE.getFloat(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+ return UNSAFE.getFloat(getMetaspaceConstantPool() + config().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
}
/**
* Gets the double constant pool entry at index {@code index}.
*
* @param index constant pool index
* @return float constant pool entry
*/
private double getDoubleAt(int index) {
assertTag(index, JVM_CONSTANT.Double);
- return UNSAFE.getDouble(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+ return UNSAFE.getDouble(getMetaspaceConstantPool() + config().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
}
/**
* Gets the {@code JVM_CONSTANT_NameAndType} constant pool entry at index {@code index}.
*
* @param index constant pool index
* @return {@code JVM_CONSTANT_NameAndType} constant pool entry
*/
private int getNameAndTypeAt(int index) {
assertTag(index, JVM_CONSTANT.NameAndType);
- return UNSAFE.getInt(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+ return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
}
/**
* Gets the {@code JVM_CONSTANT_NameAndType} reference index constant pool entry at index
* {@code index}.
*
* @param index constant pool index
* @return {@code JVM_CONSTANT_NameAndType} reference constant pool entry
*/
private int getNameAndTypeRefIndexAt(int index) {
- return runtime().getCompilerToVM().lookupNameAndTypeRefIndexInPool(this, index);
+ return compilerToVM().lookupNameAndTypeRefIndexInPool(this, index);
}
/**
* Gets the name of a {@code JVM_CONSTANT_NameAndType} constant pool entry referenced by another
* entry denoted by {@code which}.
*
* @param which constant pool index or constant pool cache index
* @return name as {@link String}
*/
private String getNameOf(int which) {
- return runtime().getCompilerToVM().lookupNameInPool(this, which);
+ return compilerToVM().lookupNameInPool(this, which);
}
/**
* Gets the name reference index of a {@code JVM_CONSTANT_NameAndType} constant pool entry at
* index {@code index}.
@@ -392,11 +397,11 @@
*
* @param which constant pool index or constant pool cache index
* @return signature as {@link String}
*/
private String getSignatureOf(int which) {
- return runtime().getCompilerToVM().lookupSignatureInPool(this, which);
+ return compilerToVM().lookupSignatureInPool(this, which);
}
/**
* Gets the signature reference index of a {@code JVM_CONSTANT_NameAndType} constant pool entry
* at index {@code index}.
@@ -415,36 +420,25 @@
*
* @param index constant pool index
* @return klass reference index
*/
private int getKlassRefIndexAt(int index) {
- return runtime().getCompilerToVM().lookupKlassRefIndexInPool(this, index);
+ return compilerToVM().lookupKlassRefIndexInPool(this, index);
}
/**
* Gets the uncached klass reference index constant pool entry at index {@code index}. See:
* {@code ConstantPool::uncached_klass_ref_index_at}.
*
* @param index constant pool index
* @return klass reference index
*/
- private int getUncachedKlassRefIndexAt(int index, JVM_CONSTANT tag) {
- int resultIndex;
- if (tag == JVM_CONSTANT.MethodRef || tag == JVM_CONSTANT.Fieldref || tag == JVM_CONSTANT.InterfaceMethodref) {
+ private int getUncachedKlassRefIndexAt(int index) {
assertTagIsFieldOrMethod(index);
- final int refIndex = UNSAFE.getInt(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+ final int refIndex = UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
// klass ref index is in the low 16-bits.
- resultIndex = refIndex & 0xFFFF;
- } else {
- resultIndex = index;
- }
-
- // Read the tag only once because it could change between multiple reads.
- final JVM_CONSTANT klassTag = getTagAt(resultIndex);
- assert klassTag == JVM_CONSTANT.Class || klassTag == JVM_CONSTANT.UnresolvedClass || klassTag == JVM_CONSTANT.UnresolvedClassInError : klassTag;
-
- return resultIndex;
+ return refIndex & 0xFFFF;
}
/**
* Asserts that the constant pool index {@code index} is in the bounds of the constant pool.
*
@@ -476,11 +470,11 @@
assert tagAt == JVM_CONSTANT.Fieldref || tagAt == JVM_CONSTANT.MethodRef || tagAt == JVM_CONSTANT.InterfaceMethodref : tagAt;
}
@Override
public int length() {
- return UNSAFE.getInt(getMetaspaceConstantPool() + runtime().getConfig().constantPoolLengthOffset);
+ return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolLengthOffset);
}
@Override
public Object lookupConstant(int cpi) {
assert cpi != 0;
@@ -503,27 +497,27 @@
/*
* Normally, we would expect a String here, but anonymous classes can have
* "pseudo strings" (arbitrary live objects) patched into a String entry. Such
* entries do not have a symbol in the constant pool slot.
*/
- Object string = runtime().getCompilerToVM().resolvePossiblyCachedConstantInPool(this, cpi);
+ Object string = compilerToVM().resolvePossiblyCachedConstantInPool(this, cpi);
return HotSpotObjectConstantImpl.forObject(string);
case MethodHandle:
case MethodHandleInError:
case MethodType:
case MethodTypeInError:
- Object obj = runtime().getCompilerToVM().resolveConstantInPool(this, cpi);
+ Object obj = compilerToVM().resolveConstantInPool(this, cpi);
return HotSpotObjectConstantImpl.forObject(obj);
default:
throw new JVMCIError("Unknown constant pool tag %s", tag);
}
}
@Override
public String lookupUtf8(int cpi) {
assertTag(cpi, JVM_CONSTANT.Utf8);
- return runtime().getCompilerToVM().getSymbol(getEntryAt(cpi));
+ return compilerToVM().getSymbol(getEntryAt(cpi));
}
@Override
public Signature lookupSignature(int cpi) {
return new HotSpotSignature(runtime(), lookupUtf8(cpi));
@@ -531,11 +525,11 @@
@Override
public JavaConstant lookupAppendix(int cpi, int opcode) {
assert Bytecodes.isInvoke(opcode);
final int index = rawIndexToConstantPoolIndex(cpi, opcode);
- Object appendix = runtime().getCompilerToVM().lookupAppendixInPool(this, index);
+ Object appendix = compilerToVM().lookupAppendixInPool(this, index);
if (appendix == null) {
return null;
} else {
return HotSpotObjectConstantImpl.forObject(appendix);
}
@@ -556,11 +550,11 @@
}
@Override
public JavaMethod lookupMethod(int cpi, int opcode) {
final int index = rawIndexToConstantPoolIndex(cpi, opcode);
- final HotSpotResolvedJavaMethod method = runtime().getCompilerToVM().lookupMethodInPool(this, index, (byte) opcode);
+ final HotSpotResolvedJavaMethod method = compilerToVM().lookupMethodInPool(this, index, (byte) opcode);
if (method != null) {
return method;
} else {
// Get the method's name and signature.
String name = getNameOf(index);
@@ -568,11 +562,11 @@
if (opcode == Bytecodes.INVOKEDYNAMIC) {
HotSpotResolvedObjectType holder = HotSpotResolvedObjectTypeImpl.fromObjectClass(MethodHandle.class);
return new HotSpotMethodUnresolved(name, signature, holder);
} else {
final int klassIndex = getKlassRefIndexAt(index);
- final Object type = runtime().getCompilerToVM().lookupKlassInPool(this, klassIndex);
+ final Object type = compilerToVM().lookupKlassInPool(this, klassIndex);
JavaType holder = getJavaType(type);
return new HotSpotMethodUnresolved(name, signature, holder);
}
}
}
@@ -581,11 +575,11 @@
public JavaType lookupType(int cpi, int opcode) {
final LookupTypeCacheElement elem = this.lastLookupType;
if (elem != null && elem.lastCpi == cpi) {
return elem.javaType;
} else {
- final Object type = runtime().getCompilerToVM().lookupKlassInPool(this, cpi);
+ final Object type = compilerToVM().lookupKlassInPool(this, cpi);
JavaType result = getJavaType(type);
if (result instanceof ResolvedJavaType) {
this.lastLookupType = new LookupTypeCacheElement(cpi, result);
}
return result;
@@ -607,11 +601,11 @@
if (holder instanceof HotSpotResolvedObjectTypeImpl) {
long[] info = new long[2];
HotSpotResolvedObjectTypeImpl resolvedHolder;
try {
- resolvedHolder = runtime().getCompilerToVM().resolveFieldInPool(this, index, (byte) opcode, info);
+ resolvedHolder = compilerToVM().resolveFieldInPool(this, index, (byte) opcode, info);
} catch (Throwable t) {
/*
* If there was an exception resolving the field we give up and return an unresolved
* field.
*/
@@ -641,12 +635,12 @@
case Bytecodes.LDC2_W:
index = cpi;
break;
case Bytecodes.INVOKEDYNAMIC: {
// invokedynamic instructions point to a constant pool cache entry.
- index = decodeConstantPoolCacheIndex(cpi) + runtime().getConfig().constantPoolCpCacheIndexTag;
- index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(this, index);
+ index = decodeConstantPoolCacheIndex(cpi) + config().constantPoolCpCacheIndexTag;
+ index = compilerToVM().constantPoolRemapInstructionOperandFromCache(this, index);
break;
}
case Bytecodes.GETSTATIC:
case Bytecodes.PUTSTATIC:
case Bytecodes.GETFIELD:
@@ -655,11 +649,11 @@
case Bytecodes.INVOKESPECIAL:
case Bytecodes.INVOKESTATIC:
case Bytecodes.INVOKEINTERFACE: {
// invoke and field instructions point to a constant pool cache entry.
index = rawIndexToConstantPoolIndex(cpi, opcode);
- index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(this, index);
+ index = compilerToVM().constantPoolRemapInstructionOperandFromCache(this, index);
break;
}
default:
throw JVMCIError.shouldNotReachHere("Unexpected opcode " + opcode);
}
@@ -671,42 +665,46 @@
}
switch (tag) {
case MethodRef:
case Fieldref:
case InterfaceMethodref:
+ index = getUncachedKlassRefIndexAt(index);
+ // Read the tag only once because it could change between multiple reads.
+ final JVM_CONSTANT klassTag = getTagAt(index);
+ assert klassTag == JVM_CONSTANT.Class || klassTag == JVM_CONSTANT.UnresolvedClass || klassTag == JVM_CONSTANT.UnresolvedClassInError : klassTag;
+ // fall through
case Class:
case UnresolvedClass:
case UnresolvedClassInError:
- index = getUncachedKlassRefIndexAt(index, tag);
- final HotSpotResolvedObjectTypeImpl type = runtime().getCompilerToVM().resolveTypeInPool(this, index);
+ final HotSpotResolvedObjectTypeImpl type = compilerToVM().resolveTypeInPool(this, index);
Class<?> klass = type.mirror();
if (!klass.isPrimitive() && !klass.isArray()) {
UNSAFE.ensureClassInitialized(klass);
}
switch (tag) {
case MethodRef:
if (Bytecodes.isInvokeHandleAlias(opcode)) {
final int methodRefCacheIndex = rawIndexToConstantPoolIndex(cpi, opcode);
if (isInvokeHandle(methodRefCacheIndex, type)) {
- runtime().getCompilerToVM().resolveInvokeHandleInPool(this, methodRefCacheIndex);
+ compilerToVM().resolveInvokeHandleInPool(this, methodRefCacheIndex);
}
}
}
break;
case InvokeDynamic:
if (isInvokedynamicIndex(cpi)) {
- runtime().getCompilerToVM().resolveInvokeDynamicInPool(this, cpi);
+ compilerToVM().resolveInvokeDynamicInPool(this, cpi);
}
break;
default:
// nothing
break;
}
}
private boolean isInvokeHandle(int methodRefCacheIndex, HotSpotResolvedObjectTypeImpl klass) {
- assertTag(runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), JVM_CONSTANT.MethodRef);
+ assertTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), JVM_CONSTANT.MethodRef);
return ResolvedJavaMethod.isSignaturePolymorphic(klass, getNameOf(methodRefCacheIndex), runtime().getHostJVMCIBackend().getMetaAccess());
}
@Override
public String toString() {
< prev index next >