Mercurial > hg > graal-jvmci-8
changeset 24100:839dcc4f2cf6 jvmci-0.24
handle signature polymorphic methods correctly (JDK-8161550)
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 08 Feb 2017 23:49:32 +0100 |
parents | 955ebad35cba |
children | efea6cfade16 |
files | jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java src/share/vm/jvmci/jvmciCompilerToVM.cpp |
diffstat | 4 files changed, 54 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java Wed Feb 08 23:25:01 2017 +0100 +++ b/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java Wed Feb 08 23:49:32 2017 +0100 @@ -715,16 +715,20 @@ } - static class Lazy { - static final String[] signaturePolymorphicHolders = compilerToVM().getSignaturePolymorphicHolders(); - } + // Lazily initialized. + private static String[] signaturePolymorphicHolders; /** * Determines if {@code type} contains signature polymorphic methods. */ - private static boolean isSignaturePolymorphicHolder(final HotSpotResolvedObjectTypeImpl type) { + @SuppressFBWarnings(value = "LI_LAZY_INIT_STATIC", justification = "signaturePolymorphicHolders is a cache, not a singleton that must be constructed exactly once" + + "and compiler re-ordering is not an issue due to the VM call") + static boolean isSignaturePolymorphicHolder(final ResolvedJavaType type) { String name = type.getName(); - for (String holder : Lazy.signaturePolymorphicHolders) { + if (signaturePolymorphicHolders == null) { + signaturePolymorphicHolders = compilerToVM().getSignaturePolymorphicHolders(); + } + for (String holder : signaturePolymorphicHolders) { if (name.equals(holder)) { return true; }
--- a/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Wed Feb 08 23:25:01 2017 +0100 +++ b/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Wed Feb 08 23:49:32 2017 +0100 @@ -24,6 +24,7 @@ import static java.util.Objects.requireNonNull; import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; +import static jdk.vm.ci.hotspot.HotSpotConstantPool.isSignaturePolymorphicHolder; import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; import static jdk.vm.ci.hotspot.HotSpotModifiers.jvmClassModifiers; import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; @@ -427,7 +428,7 @@ // Methods can only be resolved against concrete types return null; } - if (method.isConcrete() && method.getDeclaringClass().equals(this) && method.isPublic()) { + if (method.isConcrete() && method.getDeclaringClass().equals(this) && method.isPublic() && !isSignaturePolymorphicHolder(method.getDeclaringClass())) { return method; } if (!method.getDeclaringClass().isAssignableFrom(this)) {
--- a/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java Wed Feb 08 23:25:01 2017 +0100 +++ b/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java Wed Feb 08 23:49:32 2017 +0100 @@ -68,10 +68,28 @@ * Tests for {@link ResolvedJavaType}. */ public class TestResolvedJavaType extends TypeUniverse { + private static final Class<? extends Annotation> SIGNATURE_POLYMORPHIC_CLASS = findPolymorphicSignatureClass(); public TestResolvedJavaType() { } + @SuppressWarnings("unchecked") + private static Class<? extends Annotation> findPolymorphicSignatureClass() { + Class<? extends Annotation> signaturePolyAnnotation = null; + try { + for (Class<?> clazz : TestResolvedJavaType.class.getClassLoader().loadClass("java.lang.invoke.MethodHandle").getDeclaredClasses()) { + if (clazz.getName().endsWith("PolymorphicSignature") && Annotation.class.isAssignableFrom(clazz)) { + signaturePolyAnnotation = (Class<? extends Annotation>) clazz; + break; + } + } + } catch (Throwable e) { + throw new AssertionError("Could not find annotation PolymorphicSignature in java.lang.invoke.MethodHandle", e); + } + assertNotNull(signaturePolyAnnotation); + return signaturePolyAnnotation; + } + @Test public void findInstanceFieldWithOffsetTest() { for (Class<?> c : classes) { @@ -571,8 +589,14 @@ for (Method decl : decls) { ResolvedJavaMethod m = metaAccess.lookupJavaMethod(decl); if (m.isPublic()) { - ResolvedJavaMethod i = metaAccess.lookupJavaMethod(impl); - assertEquals(m.toString(), i, type.resolveMethod(m, context)); + ResolvedJavaMethod resolvedMethod = type.resolveMethod(m, context); + if (isSignaturePolymorphic(m)) { + // Signature polymorphic methods must not be resolved + assertNull(resolvedMethod); + } else { + ResolvedJavaMethod i = metaAccess.lookupJavaMethod(impl); + assertEquals(m.toString(), i, resolvedMethod); + } } } } @@ -600,8 +624,14 @@ for (Method decl : decls) { ResolvedJavaMethod m = metaAccess.lookupJavaMethod(decl); if (m.isPublic()) { - ResolvedJavaMethod i = metaAccess.lookupJavaMethod(impl); - assertEquals(i, type.resolveConcreteMethod(m, context)); + ResolvedJavaMethod resolvedMethod = type.resolveConcreteMethod(m, context); + if (isSignaturePolymorphic(m)) { + // Signature polymorphic methods must not be resolved + assertNull(String.format("Got: %s", resolvedMethod), resolvedMethod); + } else { + ResolvedJavaMethod i = metaAccess.lookupJavaMethod(impl); + assertEquals(i, resolvedMethod); + } } } } @@ -919,4 +949,8 @@ } } } + + private static boolean isSignaturePolymorphic(ResolvedJavaMethod method) { + return method.getAnnotation(SIGNATURE_POLYMORPHIC_CLASS) != null; + } }
--- a/src/share/vm/jvmci/jvmciCompilerToVM.cpp Wed Feb 08 23:25:01 2017 +0100 +++ b/src/share/vm/jvmci/jvmciCompilerToVM.cpp Wed Feb 08 23:49:32 2017 +0100 @@ -938,6 +938,11 @@ Symbol* h_name = method->name(); Symbol* h_signature = method->signature(); + vmIntrinsics::ID iid = method()->intrinsic_id(); + if (MethodHandles::is_signature_polymorphic(iid) && MethodHandles::is_signature_polymorphic_intrinsic(iid)) { + // Signature polymorphic methods are already resolved, JVMCI just returns NULL in this case. + return NULL; + } methodHandle m; // Only do exact lookup if receiver klass has been linked. Otherwise, // the vtable has not been setup, and the LinkResolver will fail.