8193930: [JVMCI] calling ResolvedTypeType.getClassInitializer on an array type crashes
Reviewed-by: never, dlong
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Wed Nov 29 13:58:28 2017 +0100
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Fri Dec 22 18:34:36 2017 +0100
@@ -749,8 +749,13 @@
C2V_END
C2V_VMENTRY(jobject, getImplementor, (JNIEnv *, jobject, jobject jvmci_type))
- InstanceKlass* klass = (InstanceKlass*) CompilerToVM::asKlass(jvmci_type);
- oop implementor = CompilerToVM::get_jvmci_type(klass->implementor(), CHECK_NULL);
+ Klass* klass = CompilerToVM::asKlass(jvmci_type);
+ 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);
C2V_END
@@ -989,8 +994,12 @@
C2V_END
C2V_VMENTRY(jobject, getClassInitializer, (JNIEnv *, jobject, jobject jvmci_type))
- InstanceKlass* klass = (InstanceKlass*) CompilerToVM::asKlass(jvmci_type);
- oop result = CompilerToVM::get_jvmci_method(klass->class_initializer(), CHECK_NULL);
+ Klass* klass = CompilerToVM::asKlass(jvmci_type);
+ 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);
C2V_END
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Wed Nov 29 13:58:28 2017 +0100
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Fri Dec 22 18:34:36 2017 +0100
@@ -135,8 +135,9 @@
/**
* 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
- * {@code type} itself if there is more than one implementor
+ * @return the implementor if there is a single implementor, {@code null} if there is no
+ * 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);
@@ -256,14 +257,13 @@
native void resolveInvokeHandleInPool(HotSpotConstantPool constantPool, int cpi);
/**
- * If {@code cpi} denotes an entry representing a resolved dynamic adapter
- * (see {@code resolveInvokeDynamicInPool} and {@code resolveInvokeHandleInPool}),
- * return the opcode of the instruction for which the resolution was performed
- * ({@code invokedynamic} or {@code invokevirtual}}, or {@code -1} otherwise.
+ * If {@code cpi} denotes an entry representing a resolved dynamic adapter (see
+ * {@code resolveInvokeDynamicInPool} and {@code resolveInvokeHandleInPool}), return the opcode
+ * of the instruction for which the resolution was performed ({@code invokedynamic} or
+ * {@code invokevirtual}}, or {@code -1} otherwise.
*/
native int isResolvedInvokeHandleInPool(HotSpotConstantPool constantPool, int cpi);
-
/**
* Gets the list of type names (in the format of {@link JavaType#getName()}) denoting the
* classes that define signature polymorphic methods.
@@ -388,7 +388,7 @@
/**
* 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);
@@ -468,7 +468,8 @@
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);
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Wed Nov 29 13:58:28 2017 +0100
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Fri Dec 22 18:34:36 2017 +0100
@@ -922,7 +922,10 @@
}
public ResolvedJavaMethod getClassInitializer() {
- return compilerToVM().getClassInitializer(this);
+ if (!isArray()) {
+ return compilerToVM().getClassInitializer(this);
+ }
+ return null;
}
@Override
--- a/test/hotspot/jtreg/compiler/jvmci/compilerToVM/GetImplementorTest.java Wed Nov 29 13:58:28 2017 +0100
+++ b/test/hotspot/jtreg/compiler/jvmci/compilerToVM/GetImplementorTest.java Fri Dec 22 18:34:36 2017 +0100
@@ -103,6 +103,14 @@
HotSpotResolvedObjectType resolvedIface = CompilerToVMHelper
.lookupTypeHelper(Utils.toJVMTypeSignature(tcase.anInterface),
getClass(), /* resolve = */ true);
+ if (!resolvedIface.isInterface()) {
+ try {
+ CompilerToVMHelper.getImplementor(resolvedIface);
+ Asserts.fail("Expected " + IllegalArgumentException.class.getName());
+ } catch (IllegalArgumentException e) {
+ }
+ return;
+ }
HotSpotResolvedObjectType resolvedImplementer = CompilerToVMHelper
.getImplementor(resolvedIface);
HotSpotResolvedObjectType resolvedExpected = null;
--- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java Wed Nov 29 13:58:28 2017 +0100
+++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java Fri Dec 22 18:34:36 2017 +0100
@@ -473,6 +473,20 @@
metaAccess.lookupJavaType(ConcreteTransitiveImplementor1.class);
metaAccess.lookupJavaType(ConcreteTransitiveImplementor2.class);
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)
@@ -830,6 +844,10 @@
assertNull(metaAccess.lookupJavaType(C.class).getClassInitializer());
assertNull(metaAccess.lookupJavaType(int.class).getClassInitializer());
assertNull(metaAccess.lookupJavaType(void.class).getClassInitializer());
+ for (Class<?> c : classes) {
+ ResolvedJavaType type = metaAccess.lookupJavaType(c);
+ type.getClassInitializer();
+ }
}
@Test