# HG changeset patch # User Doug Simon # Date 1339535473 -7200 # Node ID eddf8a51be38d6bcd4ec2a7c38bd19e9570ab5f5 # Parent 13624e51918ac5e698e589d4f1b3e706b37f4925 added support for a flexible inlining policy during snippet installation diff -r 13624e51918a -r eddf8a51be38 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java Tue Jun 12 23:05:42 2012 +0200 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java Tue Jun 12 23:11:13 2012 +0200 @@ -25,6 +25,7 @@ import java.lang.annotation.*; import java.lang.reflect.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.snippets.nodes.*; @@ -41,6 +42,51 @@ public @interface Snippet { /** + * Specifies the class defining the inlining policy for this snippet. + * A {@linkplain InliningPolicy#Default default} policy is used if none is supplied. + */ + Class inlining() default InliningPolicy.class; + + /** + * Guides inlining decisions used when installing a snippet. + */ + public interface InliningPolicy { + /** + * Determines if {@code method} should be inlined into {@code caller}. + */ + boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller); + + /** + * The default inlining policy which inlines everything except for + * constructors of {@link Throwable} classes. + */ + InliningPolicy Default = new InliningPolicy() { + public boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller) { + if (Throwable.class.isAssignableFrom(method.holder().toJava())) { + if (method.name().equals("")) { + return false; + } + } + return true; + } + }; + } + + + /** + * Annotates a method replaced by a compile-time constant. + * A (resolved) call to the annotated method is replaced + * with a constant obtained by calling the annotated method via reflection. + * + * All arguments to such a method (including the receiver if applicable) + * must be compile-time constants. + */ + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + public static @interface Fold { + } + + /** * Denotes a snippet parameter that will be bound during snippet * template {@linkplain SnippetTemplate#instantiate instantiation}. */ diff -r 13624e51918a -r eddf8a51be38 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippets.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippets.java Tue Jun 12 23:05:42 2012 +0200 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippets.java Tue Jun 12 23:11:13 2012 +0200 @@ -37,6 +37,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; +import com.oracle.graal.snippets.Snippet.InliningPolicy; /** * Utilities for snippet installation and management. @@ -63,12 +64,28 @@ } ResolvedJavaMethod snippetRiMethod = runtime.getResolvedJavaMethod(snippet); if (snippetRiMethod.compilerStorage().get(Graph.class) == null) { - buildSnippetGraph(snippetRiMethod, runtime, target, pool); + buildSnippetGraph(snippetRiMethod, runtime, target, pool, inliningPolicy(snippetRiMethod)); } } } } + private static InliningPolicy inliningPolicy(ResolvedJavaMethod method) { + Class policyClass = InliningPolicy.class; + Snippet snippet = method.getAnnotation(Snippet.class); + if (snippet != null) { + policyClass = snippet.inlining(); + } + if (policyClass == InliningPolicy.class) { + return InliningPolicy.Default; + } + try { + return policyClass.getConstructor().newInstance(); + } catch (Exception e) { + throw new GraalInternalError(e); + } + } + private static void installSubstitution(ExtendedRiRuntime runtime, TargetDescription target, Class< ? extends SnippetsInterface> clazz, BoxingMethodPool pool, Class original) throws GraalInternalError { for (Method snippet : clazz.getDeclaredMethods()) { @@ -82,7 +99,7 @@ throw new RuntimeException("Snippet must not be abstract or native"); } ResolvedJavaMethod snippetRiMethod = runtime.getResolvedJavaMethod(snippet); - StructuredGraph graph = buildSnippetGraph(snippetRiMethod, runtime, target, pool); + StructuredGraph graph = buildSnippetGraph(snippetRiMethod, runtime, target, pool, inliningPolicy(snippetRiMethod)); runtime.getResolvedJavaMethod(method).compilerStorage().put(Graph.class, graph); } catch (NoSuchMethodException e) { throw new RuntimeException("Could not resolve method to substitute with: " + snippet.getName(), e); @@ -90,7 +107,7 @@ } } - private static StructuredGraph buildSnippetGraph(final ResolvedJavaMethod snippetRiMethod, final ExtendedRiRuntime runtime, final TargetDescription target, final BoxingMethodPool pool) { + private static StructuredGraph buildSnippetGraph(final ResolvedJavaMethod snippetRiMethod, final ExtendedRiRuntime runtime, final TargetDescription target, final BoxingMethodPool pool, final InliningPolicy policy) { final StructuredGraph graph = new StructuredGraph(snippetRiMethod); return Debug.scope("BuildSnippetGraph", new Object[] {snippetRiMethod, graph}, new Callable() { @Override @@ -105,15 +122,14 @@ for (Invoke invoke : graph.getInvokes()) { MethodCallTargetNode callTarget = invoke.callTarget(); - ResolvedJavaMethod targetMethod = callTarget.targetMethod(); - ResolvedJavaType holder = targetMethod.holder(); - if (enclosedInSnippetsClass(holder)) { - StructuredGraph targetGraph = (StructuredGraph) targetMethod.compilerStorage().get(Graph.class); + ResolvedJavaMethod method = callTarget.targetMethod(); + if (policy.shouldInline(method, snippetRiMethod)) { + StructuredGraph targetGraph = (StructuredGraph) method.compilerStorage().get(Graph.class); if (targetGraph == null) { - targetGraph = buildSnippetGraph(targetMethod, runtime, target, pool); + targetGraph = buildSnippetGraph(method, runtime, target, pool, policy); } InliningUtil.inline(invoke, targetGraph, true); - Debug.dump(graph, "after inlining %s", targetMethod); + Debug.dump(graph, "after inlining %s", method); if (GraalOptions.OptCanonicalizer) { new WordTypeRewriterPhase(target).apply(graph); new CanonicalizerPhase(target, runtime, null).apply(graph); @@ -142,17 +158,6 @@ return graph; } - - private boolean enclosedInSnippetsClass(ResolvedJavaType holder) { - Class enclosingClass = holder.toJava(); - while (enclosingClass != null) { - if (SnippetsInterface.class.isAssignableFrom(enclosingClass)) { - return true; - } - enclosingClass = enclosingClass.getEnclosingClass(); - } - return false; - } }); }