Skip to content
This repository has been archived by the owner on May 29, 2024. It is now read-only.

Commit

Permalink
[GR-41977] Various JVMCI fixes and additions.
Browse files Browse the repository at this point in the history
PullRequest: labsjdk-ce-17/88
  • Loading branch information
dougxc committed Nov 17, 2022
2 parents 04b9d3b + ae3e3ab commit f6b18b5
Show file tree
Hide file tree
Showing 20 changed files with 715 additions and 132 deletions.
17 changes: 11 additions & 6 deletions src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,16 @@ C2V_VMENTRY_NULL(jobject, lookupClass, (JNIEnv* env, jobject, jclass mirror))
return JVMCIENV->get_jobject(result);
C2V_END

C2V_VMENTRY_NULL(jobject, getUncachedStringInPool, (JNIEnv* env, jobject, ARGUMENT_PAIR(cp), jint index))
constantPoolHandle cp(THREAD, UNPACK_PAIR(ConstantPool, cp));
constantTag tag = cp->tag_at(index);
if (!tag.is_string()) {
JVMCI_THROW_MSG_NULL(IllegalArgumentException, err_msg("Unexpected constant pool tag at index %d: %d", index, tag.value()));
}
oop obj = cp->uncached_string_at(index, CHECK_NULL);
return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(obj));
C2V_END

C2V_VMENTRY_NULL(jobject, resolvePossiblyCachedConstantInPool, (JNIEnv* env, jobject, ARGUMENT_PAIR(cp), jint index))
constantPoolHandle cp(THREAD, UNPACK_PAIR(ConstantPool, cp));
oop obj = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL);
Expand Down Expand Up @@ -1918,9 +1928,6 @@ C2V_VMENTRY_NULL(jobjectArray, getDeclaredConstructors, (JNIEnv* env, jobject, A
}

InstanceKlass* iklass = InstanceKlass::cast(klass);
// Ensure class is linked
iklass->link_class(CHECK_NULL);

GrowableArray<Method*> constructors_array;
for (int i = 0; i < iklass->methods()->length(); i++) {
Method* m = iklass->methods()->at(i);
Expand Down Expand Up @@ -1948,9 +1955,6 @@ C2V_VMENTRY_NULL(jobjectArray, getDeclaredMethods, (JNIEnv* env, jobject, ARGUME
}

InstanceKlass* iklass = InstanceKlass::cast(klass);
// Ensure class is linked
iklass->link_class(CHECK_NULL);

GrowableArray<Method*> methods_array;
for (int i = 0; i < iklass->methods()->length(); i++) {
Method* m = iklass->methods()->at(i);
Expand Down Expand Up @@ -2870,6 +2874,7 @@ JNINativeMethod CompilerToVM::methods[] = {
{CC "lookupMethodInPool", CC "(" HS_CONSTANT_POOL2 "IB)" HS_METHOD, FN_PTR(lookupMethodInPool)},
{CC "constantPoolRemapInstructionOperandFromCache", CC "(" HS_CONSTANT_POOL2 "I)I", FN_PTR(constantPoolRemapInstructionOperandFromCache)},
{CC "resolveBootstrapMethod", CC "(" HS_CONSTANT_POOL2 "I)[" OBJECT, FN_PTR(resolveBootstrapMethod)},
{CC "getUncachedStringInPool", CC "(" HS_CONSTANT_POOL2 "I)" JAVACONSTANT, FN_PTR(getUncachedStringInPool)},
{CC "resolvePossiblyCachedConstantInPool", CC "(" HS_CONSTANT_POOL2 "I)" JAVACONSTANT, FN_PTR(resolvePossiblyCachedConstantInPool)},
{CC "resolveTypeInPool", CC "(" HS_CONSTANT_POOL2 "I)" HS_KLASS, FN_PTR(resolveTypeInPool)},
{CC "resolveFieldInPool", CC "(" HS_CONSTANT_POOL2 "I" HS_METHOD2 "B[I)" HS_KLASS, FN_PTR(resolveFieldInPool)},
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/runtime/fieldDescriptor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class fieldDescriptor {

AccessFlags access_flags() const { return _access_flags; }
oop loader() const;
// Offset (in words) of field from start of instanceOop / Klass*
// Offset (in bytes) of field from start of instanceOop / Klass*
inline int offset() const;
Symbol* generic_signature() const;
int index() const { return _index; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,18 @@ HotSpotResolvedJavaType lookupType(String name, HotSpotResolvedObjectTypeImpl ac

native HotSpotResolvedJavaType lookupClass(Class<?> javaClass);

/**
* Resolves the entry at index {@code cpi} in {@code constantPool} to an interned String object.
*
* The behavior of this method is undefined if {@code cpi} does not denote an
* {@code JVM_CONSTANT_String}.
*/
JavaConstant getUncachedStringInPool(HotSpotConstantPool constantPool, int cpi) {
return getUncachedStringInPool(constantPool, constantPool.getConstantPoolPointer(), cpi);
}

private native JavaConstant getUncachedStringInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int cpi);

/**
* Resolves the entry at index {@code cpi} in {@code constantPool} to an object, looking in the
* constant pool cache first.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,11 +256,23 @@ private static int rawIndexToConstantPoolCacheIndex(int rawIndex, int opcode) {
if (opcode == Bytecodes.INVOKEDYNAMIC) {
index = rawIndex;
// See: ConstantPool::is_invokedynamic_index
assert index < 0 : "not an invokedynamic constant pool index " + index;
if (index >= 0) {
throw new IllegalArgumentException("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 + config().constantPoolCpCacheIndexTag;
if (opcode == Bytecodes.GETFIELD ||
opcode == Bytecodes.PUTFIELD ||
opcode == Bytecodes.GETSTATIC ||
opcode == Bytecodes.PUTSTATIC ||
opcode == Bytecodes.INVOKEINTERFACE ||
opcode == Bytecodes.INVOKEVIRTUAL ||
opcode == Bytecodes.INVOKESPECIAL ||
opcode == Bytecodes.INVOKESTATIC) {
index = rawIndex + config().constantPoolCpCacheIndexTag;
} else {
throw new IllegalArgumentException("unexpected opcode " + opcode);

}
}
return index;
}
Expand Down Expand Up @@ -292,7 +304,9 @@ private static boolean isInvokedynamicIndex(int index) {
* See {@code ConstantPool::decode_invokedynamic_index}.
*/
private static int decodeInvokedynamicIndex(int i) {
assert isInvokedynamicIndex(i) : i;
if (!isInvokedynamicIndex(i)) {
throw new IllegalArgumentException("not an invokedynamic index: " + i);
}
return ~i;
}

Expand All @@ -315,7 +329,7 @@ public long getMetadataHandle() {
* @return constant pool tag
*/
private JvmConstant getTagAt(int index) {
assert checkBounds(index);
checkBounds(index);
HotSpotVMConfig config = config();
final long metaspaceConstantPoolTags = UNSAFE.getAddress(getConstantPoolPointer() + config.constantPoolTagsOffset);
final int tag = UNSAFE.getByteVolatile(null, metaspaceConstantPoolTags + config.arrayU1DataOffset + index);
Expand All @@ -332,7 +346,7 @@ private JvmConstant getTagAt(int index) {
* @return constant pool entry
*/
long getEntryAt(int index) {
assert checkBounds(index);
checkBounds(index);
int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
return UNSAFE.getAddress(getConstantPoolPointer() + config().constantPoolSize + offset);
}
Expand All @@ -344,7 +358,7 @@ long getEntryAt(int index) {
* @return integer constant pool entry at index
*/
private int getIntAt(int index) {
assert checkTag(index, constants.jvmInteger);
checkTag(index, constants.jvmInteger);
int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
return UNSAFE.getInt(getConstantPoolPointer() + config().constantPoolSize + offset);
}
Expand All @@ -356,7 +370,7 @@ private int getIntAt(int index) {
* @return long constant pool entry
*/
private long getLongAt(int index) {
assert checkTag(index, constants.jvmLong);
checkTag(index, constants.jvmLong);
int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
return UNSAFE.getLong(getConstantPoolPointer() + config().constantPoolSize + offset);
}
Expand All @@ -368,7 +382,7 @@ private long getLongAt(int index) {
* @return float constant pool entry
*/
private float getFloatAt(int index) {
assert checkTag(index, constants.jvmFloat);
checkTag(index, constants.jvmFloat);
int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
return UNSAFE.getFloat(getConstantPoolPointer() + config().constantPoolSize + offset);
}
Expand All @@ -380,7 +394,7 @@ private float getFloatAt(int index) {
* @return float constant pool entry
*/
private double getDoubleAt(int index) {
assert checkTag(index, constants.jvmDouble);
checkTag(index, constants.jvmDouble);
int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
return UNSAFE.getDouble(getConstantPoolPointer() + config().constantPoolSize + offset);
}
Expand All @@ -392,7 +406,7 @@ private double getDoubleAt(int index) {
* @return {@code JVM_CONSTANT_NameAndType} constant pool entry
*/
private int getNameAndTypeAt(int index) {
assert checkTag(index, constants.jvmNameAndType);
checkTag(index, constants.jvmNameAndType);
int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
return UNSAFE.getInt(getConstantPoolPointer() + config().constantPoolSize + offset);
}
Expand Down Expand Up @@ -474,7 +488,7 @@ private int getKlassRefIndexAt(int index) {
* @return klass reference index
*/
private int getUncachedKlassRefIndexAt(int index) {
assert checkTagIsFieldOrMethod(index);
checkTagIsFieldOrMethod(index);
int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
final int refIndex = UNSAFE.getInt(getConstantPoolPointer() + config().constantPoolSize + offset);
// klass ref index is in the low 16-bits.
Expand All @@ -485,24 +499,26 @@ private int getUncachedKlassRefIndexAt(int index) {
* Checks that the constant pool index {@code index} is in the bounds of the constant pool.
*
* @param index constant pool index
* @throws AssertionError if the check fails
* @throws IndexOutOfBoundsException if the check fails
*/
private boolean checkBounds(int index) {
assert 0 <= index && index < length() : "index " + index + " not between 0 and " + length();
return true;
private void checkBounds(int index) {
if (index < 1 || index >= length()) {
throw new IndexOutOfBoundsException("index " + index + " not between 1 and " + length());
}
}

/**
* Checks that the constant pool tag at index {@code index} is equal to {@code tag}.
*
* @param index constant pool index
* @param tag expected tag
* @throws AssertionError if the check fails
* @throws IllegalArgumentException if the check fails
*/
private boolean checkTag(int index, JvmConstant tag) {
private void checkTag(int index, JvmConstant tag) {
final JvmConstant tagAt = getTagAt(index);
assert tagAt == tag : "constant pool tag at index " + index + " is " + tagAt + " but expected " + tag;
return true;
if (tagAt != tag) {
throw new IllegalArgumentException("constant pool tag at index " + index + " is " + tagAt + " but expected " + tag);
}
}

/**
Expand All @@ -511,12 +527,13 @@ private boolean checkTag(int index, JvmConstant tag) {
* {@link JvmConstants#jvmInterfaceMethodref}.
*
* @param index constant pool index
* @throws AssertionError if the check fails
* @throws IllegalArgumentException if the check fails
*/
private boolean checkTagIsFieldOrMethod(int index) {
private void checkTagIsFieldOrMethod(int index) {
final JvmConstant tagAt = getTagAt(index);
assert tagAt == constants.jvmFieldref || tagAt == constants.jvmMethodref || tagAt == constants.jvmInterfaceMethodref : tagAt;
return true;
if (tagAt != constants.jvmFieldref && tagAt != constants.jvmMethodref && tagAt != constants.jvmInterfaceMethodref) {
throw new IllegalArgumentException("constant pool tag at index " + index + " is " + tagAt);
}
}

@Override
Expand Down Expand Up @@ -619,9 +636,29 @@ public BootstrapMethodInvocation lookupBootstrapMethodInvocation(int rawCpi, int
}
}

/**
* Gets the {@link JavaConstant} for the {@code ConstantValue} attribute of a field.
*/
JavaConstant getStaticFieldConstantValue(int cpi) {
final JvmConstant tag = getTagAt(cpi);
switch (tag.name) {
case "Integer":
return JavaConstant.forInt(getIntAt(cpi));
case "Long":
return JavaConstant.forLong(getLongAt(cpi));
case "Float":
return JavaConstant.forFloat(getFloatAt(cpi));
case "Double":
return JavaConstant.forDouble(getDoubleAt(cpi));
case "String":
return compilerToVM().getUncachedStringInPool(this, cpi);
default:
throw new IllegalArgumentException("Illegal entry for a ConstantValue attribute:" + tag);
}
}

@Override
public Object lookupConstant(int cpi) {
assert cpi != 0;
final JvmConstant tag = getTagAt(cpi);
switch (tag.name) {
case "Integer":
Expand Down Expand Up @@ -658,7 +695,7 @@ public Object lookupConstant(int cpi) {

@Override
public String lookupUtf8(int cpi) {
assert checkTag(cpi, constants.jvmUtf8);
checkTag(cpi, constants.jvmUtf8);
return compilerToVM().getSymbol(getEntryAt(cpi));
}

Expand All @@ -669,7 +706,10 @@ public Signature lookupSignature(int cpi) {

@Override
public JavaConstant lookupAppendix(int cpi, int opcode) {
assert Bytecodes.isInvoke(opcode);
if (!Bytecodes.isInvoke(opcode)) {
throw new IllegalArgumentException("expected an invoke bytecode at " + cpi + ", got " + opcode);
}

final int index = rawIndexToConstantPoolCacheIndex(cpi, opcode);
return compilerToVM().lookupAppendixInPool(this, index);
}
Expand Down Expand Up @@ -801,10 +841,14 @@ public JavaField lookupField(int cpi, ResolvedJavaMethod method, int opcode) {
public int rawIndexToConstantPoolIndex(int rawIndex, int opcode) {
int index;
if (isInvokedynamicIndex(rawIndex)) {
assert opcode == Bytecodes.INVOKEDYNAMIC;
if (opcode != Bytecodes.INVOKEDYNAMIC) {
throw new IllegalArgumentException("expected INVOKEDYNAMIC at " + rawIndex + ", got " + opcode);
}
index = decodeInvokedynamicIndex(rawIndex) + config().constantPoolCpCacheIndexTag;
} else {
assert opcode != Bytecodes.INVOKEDYNAMIC;
if (opcode == Bytecodes.INVOKEDYNAMIC) {
throw new IllegalArgumentException("unexpected INVOKEDYNAMIC at " + rawIndex);
}
index = rawIndexToConstantPoolCacheIndex(rawIndex, opcode);
}
return compilerToVM().constantPoolRemapInstructionOperandFromCache(this, index);
Expand All @@ -815,6 +859,7 @@ public void loadReferencedType(int cpi, int opcode) {
loadReferencedType(cpi, opcode, true /* initialize */);
}

@Override
@SuppressWarnings("fallthrough")
public void loadReferencedType(int cpi, int opcode, boolean initialize) {
int index;
Expand Down Expand Up @@ -876,7 +921,7 @@ public void loadReferencedType(int cpi, int opcode, boolean initialize) {
if (tag == constants.jvmMethodref) {
if (Bytecodes.isInvokeHandleAlias(opcode) && isSignaturePolymorphicHolder(type)) {
final int methodRefCacheIndex = rawIndexToConstantPoolCacheIndex(cpi, opcode);
assert checkTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), constants.jvmMethodref);
checkTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), constants.jvmMethodref);
compilerToVM().resolveInvokeHandleInPool(this, methodRefCacheIndex);
}
}
Expand Down Expand Up @@ -928,7 +973,7 @@ static boolean isSignaturePolymorphicHolder(final ResolvedJavaType type) {
public boolean isResolvedDynamicInvoke(int cpi, int opcode) {
if (Bytecodes.isInvokeHandleAlias(opcode)) {
final int methodRefCacheIndex = rawIndexToConstantPoolCacheIndex(cpi, opcode);
assert checkTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), constants.jvmMethodref);
checkTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), constants.jvmMethodref);
int op = compilerToVM().isResolvedInvokeHandleInPool(this, methodRefCacheIndex);
return op == opcode;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ JavaConstant boxPrimitive(JavaConstant source) {
* Gets a {@link Method} object corresponding to {@code method}. This method guarantees the same
* {@link Method} object is returned if called twice on the same {@code method} value.
*/
private static Executable getMethod(HotSpotResolvedJavaMethodImpl method) {
static Executable getMethod(HotSpotResolvedJavaMethodImpl method) {
assert !method.isClassInitializer() : method;
if (method.toJavaCache == null) {
synchronized (method) {
Expand All @@ -303,7 +303,7 @@ private static Executable getMethod(HotSpotResolvedJavaMethodImpl method) {
* {@code f} and annotation class {@code a}, the same object is returned for each call to
* {@code f.getAnnotation(a)}).
*/
private static Field getField(HotSpotResolvedJavaFieldImpl field) {
static Field getField(HotSpotResolvedJavaFieldImpl field) {
HotSpotResolvedObjectTypeImpl declaringClass = field.getDeclaringClass();
synchronized (declaringClass) {
HashMap<HotSpotResolvedJavaFieldImpl, Field> cache = declaringClass.reflectionFieldCache;
Expand Down
Loading

0 comments on commit f6b18b5

Please sign in to comment.