mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8193930: [JVMCI] calling ResolvedTypeType.getClassInitializer on an array type crashes
Reviewed-by: never, dlong
This commit is contained in:
parent
3b3ebcd097
commit
77eb30dae3
5 changed files with 53 additions and 14 deletions
|
@ -749,8 +749,13 @@ C2V_VMENTRY(jobject, findUniqueConcreteMethod, (JNIEnv *, jobject, jobject jvmci
|
||||||
C2V_END
|
C2V_END
|
||||||
|
|
||||||
C2V_VMENTRY(jobject, getImplementor, (JNIEnv *, jobject, jobject jvmci_type))
|
C2V_VMENTRY(jobject, getImplementor, (JNIEnv *, jobject, jobject jvmci_type))
|
||||||
InstanceKlass* klass = (InstanceKlass*) CompilerToVM::asKlass(jvmci_type);
|
Klass* klass = CompilerToVM::asKlass(jvmci_type);
|
||||||
oop implementor = CompilerToVM::get_jvmci_type(klass->implementor(), CHECK_NULL);
|
if (!klass->is_interface()) {
|
||||||
|
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
|
||||||
|
err_msg("Expected interface type, got %s", klass->external_name()));
|
||||||
|
}
|
||||||
|
InstanceKlass* iklass = InstanceKlass::cast(klass);
|
||||||
|
oop implementor = CompilerToVM::get_jvmci_type(iklass->implementor(), CHECK_NULL);
|
||||||
return JNIHandles::make_local(THREAD, implementor);
|
return JNIHandles::make_local(THREAD, implementor);
|
||||||
C2V_END
|
C2V_END
|
||||||
|
|
||||||
|
@ -989,8 +994,12 @@ C2V_VMENTRY(jboolean, hasFinalizableSubclass,(JNIEnv *, jobject, jobject jvmci_t
|
||||||
C2V_END
|
C2V_END
|
||||||
|
|
||||||
C2V_VMENTRY(jobject, getClassInitializer, (JNIEnv *, jobject, jobject jvmci_type))
|
C2V_VMENTRY(jobject, getClassInitializer, (JNIEnv *, jobject, jobject jvmci_type))
|
||||||
InstanceKlass* klass = (InstanceKlass*) CompilerToVM::asKlass(jvmci_type);
|
Klass* klass = CompilerToVM::asKlass(jvmci_type);
|
||||||
oop result = CompilerToVM::get_jvmci_method(klass->class_initializer(), CHECK_NULL);
|
if (!klass->is_instance_klass()) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
InstanceKlass* iklass = InstanceKlass::cast(klass);
|
||||||
|
oop result = CompilerToVM::get_jvmci_method(iklass->class_initializer(), CHECK_NULL);
|
||||||
return JNIHandles::make_local(THREAD, result);
|
return JNIHandles::make_local(THREAD, result);
|
||||||
C2V_END
|
C2V_END
|
||||||
|
|
||||||
|
|
|
@ -135,8 +135,9 @@ final class CompilerToVM {
|
||||||
/**
|
/**
|
||||||
* Gets the implementor for the interface class {@code type}.
|
* Gets the implementor for the interface class {@code type}.
|
||||||
*
|
*
|
||||||
* @return the implementor if there is a single implementor, 0 if there is no implementor, or
|
* @return the implementor if there is a single implementor, {@code null} if there is no
|
||||||
* {@code type} itself if there is more than one implementor
|
* implementor, or {@code type} itself if there is more than one implementor
|
||||||
|
* @throws IllegalArgumentException if type is not an interface type
|
||||||
*/
|
*/
|
||||||
native HotSpotResolvedObjectTypeImpl getImplementor(HotSpotResolvedObjectTypeImpl type);
|
native HotSpotResolvedObjectTypeImpl getImplementor(HotSpotResolvedObjectTypeImpl type);
|
||||||
|
|
||||||
|
@ -256,14 +257,13 @@ final class CompilerToVM {
|
||||||
native void resolveInvokeHandleInPool(HotSpotConstantPool constantPool, int cpi);
|
native void resolveInvokeHandleInPool(HotSpotConstantPool constantPool, int cpi);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If {@code cpi} denotes an entry representing a resolved dynamic adapter
|
* If {@code cpi} denotes an entry representing a resolved dynamic adapter (see
|
||||||
* (see {@code resolveInvokeDynamicInPool} and {@code resolveInvokeHandleInPool}),
|
* {@code resolveInvokeDynamicInPool} and {@code resolveInvokeHandleInPool}), return the opcode
|
||||||
* return the opcode of the instruction for which the resolution was performed
|
* of the instruction for which the resolution was performed ({@code invokedynamic} or
|
||||||
* ({@code invokedynamic} or {@code invokevirtual}}, or {@code -1} otherwise.
|
* {@code invokevirtual}}, or {@code -1} otherwise.
|
||||||
*/
|
*/
|
||||||
native int isResolvedInvokeHandleInPool(HotSpotConstantPool constantPool, int cpi);
|
native int isResolvedInvokeHandleInPool(HotSpotConstantPool constantPool, int cpi);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the list of type names (in the format of {@link JavaType#getName()}) denoting the
|
* Gets the list of type names (in the format of {@link JavaType#getName()}) denoting the
|
||||||
* classes that define signature polymorphic methods.
|
* classes that define signature polymorphic methods.
|
||||||
|
@ -388,7 +388,7 @@ final class CompilerToVM {
|
||||||
/**
|
/**
|
||||||
* Gets the static initializer of {@code type}.
|
* Gets the static initializer of {@code type}.
|
||||||
*
|
*
|
||||||
* @return 0 if {@code type} has no static initializer
|
* @return {@code null} if {@code type} has no static initializer
|
||||||
*/
|
*/
|
||||||
native HotSpotResolvedJavaMethodImpl getClassInitializer(HotSpotResolvedObjectTypeImpl type);
|
native HotSpotResolvedJavaMethodImpl getClassInitializer(HotSpotResolvedObjectTypeImpl type);
|
||||||
|
|
||||||
|
@ -468,7 +468,8 @@ final class CompilerToVM {
|
||||||
native long getLocalVariableTableStart(HotSpotResolvedJavaMethodImpl method);
|
native long getLocalVariableTableStart(HotSpotResolvedJavaMethodImpl method);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets flags on {@code method} indicating that it should never be inlined or compiled by the VM.
|
* Sets flags on {@code method} indicating that it should never be inlined or compiled by the
|
||||||
|
* VM.
|
||||||
*/
|
*/
|
||||||
native void setNotInlinableOrCompilable(HotSpotResolvedJavaMethodImpl method);
|
native void setNotInlinableOrCompilable(HotSpotResolvedJavaMethodImpl method);
|
||||||
|
|
||||||
|
|
|
@ -922,7 +922,10 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResolvedJavaMethod getClassInitializer() {
|
public ResolvedJavaMethod getClassInitializer() {
|
||||||
return compilerToVM().getClassInitializer(this);
|
if (!isArray()) {
|
||||||
|
return compilerToVM().getClassInitializer(this);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -103,6 +103,14 @@ public class GetImplementorTest {
|
||||||
HotSpotResolvedObjectType resolvedIface = CompilerToVMHelper
|
HotSpotResolvedObjectType resolvedIface = CompilerToVMHelper
|
||||||
.lookupTypeHelper(Utils.toJVMTypeSignature(tcase.anInterface),
|
.lookupTypeHelper(Utils.toJVMTypeSignature(tcase.anInterface),
|
||||||
getClass(), /* resolve = */ true);
|
getClass(), /* resolve = */ true);
|
||||||
|
if (!resolvedIface.isInterface()) {
|
||||||
|
try {
|
||||||
|
CompilerToVMHelper.getImplementor(resolvedIface);
|
||||||
|
Asserts.fail("Expected " + IllegalArgumentException.class.getName());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
HotSpotResolvedObjectType resolvedImplementer = CompilerToVMHelper
|
HotSpotResolvedObjectType resolvedImplementer = CompilerToVMHelper
|
||||||
.getImplementor(resolvedIface);
|
.getImplementor(resolvedIface);
|
||||||
HotSpotResolvedObjectType resolvedExpected = null;
|
HotSpotResolvedObjectType resolvedExpected = null;
|
||||||
|
|
|
@ -473,6 +473,20 @@ public class TestResolvedJavaType extends TypeUniverse {
|
||||||
metaAccess.lookupJavaType(ConcreteTransitiveImplementor1.class);
|
metaAccess.lookupJavaType(ConcreteTransitiveImplementor1.class);
|
||||||
metaAccess.lookupJavaType(ConcreteTransitiveImplementor2.class);
|
metaAccess.lookupJavaType(ConcreteTransitiveImplementor2.class);
|
||||||
assertEquals(aSai2, iSai2.getSingleImplementor());
|
assertEquals(aSai2, iSai2.getSingleImplementor());
|
||||||
|
|
||||||
|
for (Class<?> c : classes) {
|
||||||
|
ResolvedJavaType type = metaAccess.lookupJavaType(c);
|
||||||
|
try {
|
||||||
|
type.getSingleImplementor();
|
||||||
|
if (!c.isInterface()) {
|
||||||
|
throw new AssertionError("Expected exception for calling getSingleImplmentor on " + c.getName());
|
||||||
|
}
|
||||||
|
} catch (JVMCIError e) {
|
||||||
|
if (c.isInterface()) {
|
||||||
|
throw new AssertionError("Unexpected exception", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = JVMCIError.class)
|
@Test(expected = JVMCIError.class)
|
||||||
|
@ -830,6 +844,10 @@ public class TestResolvedJavaType extends TypeUniverse {
|
||||||
assertNull(metaAccess.lookupJavaType(C.class).getClassInitializer());
|
assertNull(metaAccess.lookupJavaType(C.class).getClassInitializer());
|
||||||
assertNull(metaAccess.lookupJavaType(int.class).getClassInitializer());
|
assertNull(metaAccess.lookupJavaType(int.class).getClassInitializer());
|
||||||
assertNull(metaAccess.lookupJavaType(void.class).getClassInitializer());
|
assertNull(metaAccess.lookupJavaType(void.class).getClassInitializer());
|
||||||
|
for (Class<?> c : classes) {
|
||||||
|
ResolvedJavaType type = metaAccess.lookupJavaType(c);
|
||||||
|
type.getClassInitializer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue