Mercurial > hg > truffle
changeset 16183:b1be2a46cc5c
canonicalize LoadMethodNodes
author | Tom Rodriguez <tom.rodriguez@oracle.com> |
---|---|
date | Tue, 24 Jun 2014 11:28:00 -0700 |
parents | 0a7e9347f8d0 |
children | 8fde32ece68e |
files | graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java |
diffstat | 2 files changed, 54 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java Tue Jun 24 13:23:58 2014 -0400 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java Tue Jun 24 11:28:00 2014 -0700 @@ -229,6 +229,12 @@ return runtime.getHostProviders().getMetaAccess().lookupJavaType((Class<?>) obj); } } + if (constant instanceof HotSpotMetaspaceConstant) { + Object obj = HotSpotMetaspaceConstant.getMetaspaceObject(constant); + if (obj instanceof HotSpotResolvedObjectType) { + return (ResolvedJavaType) obj; + } + } return null; } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java Tue Jun 24 13:23:58 2014 -0400 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java Tue Jun 24 11:28:00 2014 -0700 @@ -24,13 +24,16 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; /** * Loads a method from the virtual method table of a given hub. */ -public final class LoadMethodNode extends FixedWithNextNode implements Lowerable { +public final class LoadMethodNode extends FixedWithNextNode implements Lowerable, Canonicalizable { @Input private ValueNode hub; private final ResolvedJavaMethod method; @@ -55,6 +58,50 @@ tool.getLowerer().lower(this, tool); } + @Override + public Node canonical(CanonicalizerTool tool) { + if (hub instanceof LoadHubNode) { + ValueNode object = ((LoadHubNode) hub).object(); + ResolvedJavaType type = StampTool.typeOrNull(object); + if (StampTool.isExactType(object)) { + return resolveExactMethod(tool, type); + } + if (type != null && tool.assumptions().useOptimisticAssumptions()) { + ResolvedJavaMethod resolvedMethod = type.findUniqueConcreteMethod(method); + if (resolvedMethod != null && !type.isInterface() && method.getDeclaringClass().isAssignableFrom(type)) { + tool.assumptions().recordConcreteMethod(method, type, resolvedMethod); + return ConstantNode.forConstant(resolvedMethod.getEncoding(), tool.getMetaAccess(), graph()); + } + } + } + if (hub.isConstant()) { + return resolveExactMethod(tool, tool.getConstantReflection().asJavaType(hub.asConstant())); + } + + return this; + } + + /** + * Find the method which would be loaded. + * + * @param tool + * @param type the exact type of object being loaded from + * @return the method which would be invoked for {@code type} or null if it doesn't implement + * the method + */ + private Node resolveExactMethod(CanonicalizerTool tool, ResolvedJavaType type) { + ResolvedJavaMethod newMethod = type.resolveMethod(method, type); + if (newMethod == null) { + /* + * This really represent a misuse of LoadMethod since we're loading from a class which + * isn't known to implement the original method but for now at least fold it away. + */ + return ConstantNode.forConstant(Constant.NULL_OBJECT, null, graph()); + } else { + return ConstantNode.forConstant(newMethod.getEncoding(), tool.getMetaAccess(), graph()); + } + } + public ResolvedJavaMethod getMethod() { return method; }