# HG changeset patch # User Tom Rodriguez # Date 1404268513 25200 # Node ID 5d7b90ab9787671db148c40429590f9baae763ef # Parent 657ff04a7b7369d4c0db941fcd464cd3f9003298 Ensure that uniqueConcreteMethod is called with a resolved concrete method diff -r 657ff04a7b73 -r 5d7b90ab9787 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Tue Jul 01 12:37:58 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Tue Jul 01 19:35:13 2014 -0700 @@ -356,6 +356,22 @@ @Override public ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method, ResolvedJavaType callerType) { + ResolvedJavaMethod resolvedMethod = resolveMethodInternal(method, callerType); + if (resolvedMethod == null || resolvedMethod.isAbstract()) { + return null; + } + return resolvedMethod; + } + + /** + * Resolve the method against the current type and return the method found, including any + * abstract methods. + * + * @param method + * @param callerType + * @return the method found + */ + private ResolvedJavaMethod resolveMethodInternal(ResolvedJavaMethod method, ResolvedJavaType callerType) { assert !callerType.isArray(); if (!method.isAbstract() && method.getDeclaringClass().equals(this) && method.isPublic()) { return method; @@ -369,11 +385,7 @@ if (resolvedMetaspaceMethod == 0) { return null; } - HotSpotResolvedJavaMethod resolvedMethod = HotSpotResolvedJavaMethod.fromMetaspace(resolvedMetaspaceMethod); - if (resolvedMethod.isAbstract()) { - return null; - } - return resolvedMethod; + return HotSpotResolvedJavaMethod.fromMetaspace(resolvedMetaspaceMethod); } public ConstantPool constantPool() { @@ -464,21 +476,24 @@ /* * Sometimes the receiver type in the graph hasn't stabilized to a subtype of declared * holder, usually because of phis, so make sure that the type is related to the declared - * type before using it for lookup. + * type before using it for lookup. Unlinked types should also be ignored because we can't + * resolve the proper method to invoke. Generally unlinked types in invokes should result in + * a deopt instead since they can't really be used if they aren't linked yet. */ - if (!declaredHolder.isAssignableFrom(this) || this.isArray() || this.equals(declaredHolder)) { + if (!declaredHolder.isAssignableFrom(this) || this.isArray() || this.equals(declaredHolder) || !isLinked() || isInterface()) { return hmethod.uniqueConcreteMethod(declaredHolder); } /* * The holder may be a subtype of the decaredHolder so make sure to resolve the method to * the correct method for the subtype. */ - HotSpotResolvedJavaMethod newMethod = (HotSpotResolvedJavaMethod) resolveMethod(hmethod, this); - if (newMethod != null && !hmethod.equals(newMethod)) { - hmethod = newMethod; + HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) resolveMethodInternal(hmethod, this); + if (resolvedMethod == null) { + // The type isn't known to implement the method. + return null; } - return hmethod.uniqueConcreteMethod(this); + return resolvedMethod.uniqueConcreteMethod(this); } /**