# HG changeset patch # User dnsimon # Date 1513964076 -3600 # Node ID 614068b0ddd75edda97df7486e325900a39354d9 # Parent 7b5c930b878c5ac0394f385d1cc9da8a006ab869 8193930: [JVMCI] calling ResolvedTypeType.getClassInitializer on an array type crashes Reviewed-by: never, dlong diff -r 7b5c930b878c -r 614068b0ddd7 src/hotspot/share/jvmci/jvmciCompilerToVM.cpp --- 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 diff -r 7b5c930b878c -r 614068b0ddd7 src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java --- 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); diff -r 7b5c930b878c -r 614068b0ddd7 src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java --- 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 diff -r 7b5c930b878c -r 614068b0ddd7 test/hotspot/jtreg/compiler/jvmci/compilerToVM/GetImplementorTest.java --- 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; diff -r 7b5c930b878c -r 614068b0ddd7 test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java --- 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