changeset 15699:423bf61c9c32

use inner classes instead of reflection during matching
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Fri, 16 May 2014 00:12:41 -0700
parents eaeba148bb15
children 98423229008c
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchGenerator.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchProcessor.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatement.java
diffstat 3 files changed, 39 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchGenerator.java	Thu May 15 20:11:16 2014 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchGenerator.java	Fri May 16 00:12:41 2014 -0700
@@ -32,5 +32,10 @@
      * @returns null if the match can't be generated or a {@link ComplexMatchResult} that can be
      *          evaluated during LIR generation to produce the final LIR value.
      */
-    ComplexMatchResult match(NodeLIRBuilder gen);
+    ComplexMatchResult match(NodeLIRBuilder gen, Object... args);
+
+    /**
+     * @return a descriptive name meaningful to the user.
+     */
+    String getName();
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchProcessor.java	Thu May 15 20:11:16 2014 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchProcessor.java	Fri May 16 00:12:41 2014 -0700
@@ -331,7 +331,8 @@
     List<String> requiredPackages = new ArrayList<>();
 
     /**
-     * The java.lang.reflect.Method for invoking a method based MatchRule.
+     * The mapping between elements with MatchRules and the wrapper class used invoke the code
+     * generation after the match.
      */
     private Map<ExecutableElement, MethodInvokerItem> invokers = new LinkedHashMap<>();
 
@@ -486,9 +487,7 @@
             out.println("package " + pkg + ";");
             out.println("");
             out.println("import java.util.*;");
-            out.println("import java.lang.reflect.*;");
             out.println("import " + MatchStatementSet.class.getPackage().getName() + ".*;");
-            out.println("import " + GraalInternalError.class.getName() + ";");
             out.println("import " + NodeLIRBuilder.class.getName() + ";");
             out.println("import " + NodeClass.class.getName() + ";");
             for (String p : requiredPackages) {
@@ -498,33 +497,33 @@
             out.println("public class " + matchStatementClassName + " implements " + MatchStatementSet.class.getSimpleName() + " {");
 
             out.println();
-            out.println("    private static Method lookupMethod(Class<?> theClass, String name, Class<?>... args) {");
-            out.println("        try {");
-            out.println("            return theClass.getDeclaredMethod(name, args);");
-            out.println("        } catch (Exception e) {");
-            out.println("            throw new GraalInternalError(e);");
-            out.println("        }");
-            out.println("    }");
-            out.println();
 
-            // Generate declarations for the reflective invocation of the code generation methods.
+            // Generate declarations for the wrapper class to invoke the code generation methods.
             for (MethodInvokerItem invoker : invokers.values()) {
                 StringBuilder args = new StringBuilder();
                 StringBuilder types = new StringBuilder();
                 int count = invoker.fields.size();
+                int index = 0;
                 for (VariableElement arg : invoker.fields) {
                     args.append('"');
                     args.append(arg.getSimpleName());
                     args.append('"');
-                    types.append(fullClassName(typeUtils.asElement(arg.asType())));
-                    types.append(".class");
+                    types.append(String.format("(%s) args[%s]", fullClassName(typeUtils.asElement(arg.asType())), index++));
                     if (count-- > 1) {
                         args.append(", ");
                         types.append(", ");
                     }
                 }
                 out.printf("    private static final String[] %s = new String[] {%s};\n", invoker.argumentsListName(), args);
-                out.printf("    private static final Method %s = lookupMethod(%s.class, \"%s\", %s);\n", invoker.reflectiveMethodName(), invoker.nodeLIRBuilderClass, invoker.methodName, types);
+                out.printf("    private static final class %s implements MatchGenerator {\n", invoker.wrapperClass());
+                out.printf("        static MatchGenerator instance = new %s();\n", invoker.wrapperClass());
+                out.printf("        public ComplexMatchResult match(NodeLIRBuilder builder, Object...args) {\n");
+                out.printf("            return ((%s) builder).%s(%s);\n", invoker.nodeLIRBuilderClass, invoker.methodName, types);
+                out.printf("        }\n");
+                out.printf("        public String getName() {\n");
+                out.printf("             return \"%s\";\n", invoker.methodName);
+                out.printf("        }\n");
+                out.printf("    }\n");
                 out.println();
 
             }
@@ -606,13 +605,12 @@
          * @return a string which will construct the MatchStatement instance to match this pattern.
          */
         public String ruleBuilder() {
-            return String.format("new MatchStatement(\"%s\", %s, %s, %s)", invoker.name, matchPattern, invoker.reflectiveMethodName(), invoker.argumentsListName());
+            return String.format("new MatchStatement(\"%s\", %s, %s.instance, %s)", invoker.name, matchPattern, invoker.wrapperClass(), invoker.argumentsListName());
         }
     }
 
     /**
-     * Used to generate the declarations needed for reflective invocation of the code generation
-     * method.
+     * Used to generate the wrapper class to invoke the code generation method.
      */
     static class MethodInvokerItem {
         final String name;
@@ -627,8 +625,8 @@
             this.fields = fields;
         }
 
-        String reflectiveMethodName() {
-            return methodName + "_invoke";
+        String wrapperClass() {
+            return "MatchGenerator_" + methodName;
         }
 
         String argumentsListName() {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatement.java	Thu May 15 20:11:16 2014 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatement.java	Fri May 16 00:12:41 2014 -0700
@@ -24,11 +24,9 @@
 
 import static com.oracle.graal.compiler.GraalDebugConfig.*;
 
-import java.lang.reflect.*;
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.match.MatchPattern.MatchResultCode;
 import com.oracle.graal.compiler.match.MatchPattern.Result;
@@ -59,14 +57,14 @@
     /**
      * The method in the {@link NodeLIRBuilder} subclass that will actually do the code emission.
      */
-    private Method generatorMethod;
+    private MatchGenerator generatorMethod;
 
     /**
      * The name of arguments in the order they are expected to be passed to the generator method.
      */
     private String[] arguments;
 
-    public MatchStatement(String name, MatchPattern pattern, Method generator, String[] arguments) {
+    public MatchStatement(String name, MatchPattern pattern, MatchGenerator generator, String[] arguments) {
         this.name = name;
         this.pattern = pattern;
         this.generatorMethod = generator;
@@ -93,23 +91,19 @@
         MatchContext context = new MatchContext(builder, this, index, node, nodes);
         result = pattern.matchUsage(node, context);
         if (result == Result.OK) {
-            try {
-                // Invoke the generator method and set the result if it's non null.
-                ComplexMatchResult value = (ComplexMatchResult) generatorMethod.invoke(builder, buildArgList(context));
-                if (value != null) {
-                    context.setResult(value);
-                    MatchStatementSuccess.increment();
-                    Debug.metric("MatchStatement[%s]", getName()).increment();
-                    return true;
-                }
-                // The pattern matched but some other code generation constraint disallowed code
-                // generation for the pattern.
-                if (LogVerbose.getValue()) {
-                    Debug.log("while matching %s|%s %s %s returned null", context.getRoot().toString(Verbosity.Id), context.getRoot().getClass().getSimpleName(), getName(), generatorMethod.getName());
-                    Debug.log("with nodes %s", formatMatch(node));
-                }
-            } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
-                throw new GraalInternalError(e);
+            // Invoke the generator method and set the result if it's non null.
+            ComplexMatchResult value = generatorMethod.match(builder, buildArgList(context));
+            if (value != null) {
+                context.setResult(value);
+                MatchStatementSuccess.increment();
+                Debug.metric("MatchStatement[%s]", getName()).increment();
+                return true;
+            }
+            // The pattern matched but some other code generation constraint disallowed code
+            // generation for the pattern.
+            if (LogVerbose.getValue()) {
+                Debug.log("while matching %s|%s %s %s returned null", context.getRoot().toString(Verbosity.Id), context.getRoot().getClass().getSimpleName(), getName(), generatorMethod.getName());
+                Debug.log("with nodes %s", formatMatch(node));
             }
         } else {
             if (LogVerbose.getValue() && result.code != MatchResultCode.WRONG_CLASS) {