changeset 8175:11298242e782

removed use of NonConstantParameterError (GRAAL-147)
author Doug Simon <doug.simon@oracle.com>
date Thu, 07 Mar 2013 11:44:36 +0100
parents 42927585be33
children 2cd58a5c8791
files graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationVerificationPhase.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java
diffstat 4 files changed, 81 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java	Thu Mar 07 10:18:34 2013 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java	Thu Mar 07 11:44:36 2013 +0100
@@ -198,7 +198,8 @@
             public StructuredGraph call() throws Exception {
                 StructuredGraph graph = parseGraph(method, policy);
 
-                new SnippetIntrinsificationPhase(runtime, pool, SnippetTemplate.hasConstantParameter(method)).apply(graph);
+                new SnippetIntrinsificationPhase(runtime, pool).apply(graph);
+                assert SnippetTemplate.hasConstantParameter(method) || SnippetIntrinsificationVerificationPhase.verify(graph);
 
                 new SnippetFrameStateCleanupPhase().apply(graph);
                 new DeadCodeEliminationPhase().apply(graph);
@@ -232,7 +233,7 @@
 
         new WordTypeVerificationPhase(runtime, target.wordKind).apply(graph);
 
-        new SnippetIntrinsificationPhase(runtime, pool, true).apply(graph);
+        new SnippetIntrinsificationPhase(runtime, pool).apply(graph);
 
         for (Invoke invoke : graph.getInvokes()) {
             MethodCallTargetNode callTarget = invoke.methodCallTarget();
@@ -260,7 +261,7 @@
             }
         }
 
-        new SnippetIntrinsificationPhase(runtime, pool, true).apply(graph);
+        new SnippetIntrinsificationPhase(runtime, pool).apply(graph);
 
         new WordTypeRewriterPhase(runtime, target.wordKind).apply(graph);
 
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java	Thu Mar 07 10:18:34 2013 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java	Thu Mar 07 11:44:36 2013 +0100
@@ -43,45 +43,21 @@
 
     private final MetaAccessProvider runtime;
     private final BoxingMethodPool pool;
-    private final boolean intrinsificationOrFoldingCanBeDeferred;
 
-    /**
-     * @param intrinsificationOrFoldingCanBeDeferred if true, then {@link NonConstantParameterError}
-     *            s are not fatal
-     */
-    public SnippetIntrinsificationPhase(MetaAccessProvider runtime, BoxingMethodPool pool, boolean intrinsificationOrFoldingCanBeDeferred) {
+    public SnippetIntrinsificationPhase(MetaAccessProvider runtime, BoxingMethodPool pool) {
         this.runtime = runtime;
         this.pool = pool;
-        this.intrinsificationOrFoldingCanBeDeferred = intrinsificationOrFoldingCanBeDeferred;
     }
 
     @Override
     protected void run(StructuredGraph graph) {
         for (Invoke i : graph.getInvokes()) {
-            try {
-                if (i.callTarget() instanceof MethodCallTargetNode) {
-                    tryIntrinsify(i);
-                }
-            } catch (NonConstantParameterError t) {
-                if (!intrinsificationOrFoldingCanBeDeferred) {
-                    throw t;
-                }
+            if (i.callTarget() instanceof MethodCallTargetNode) {
+                tryIntrinsify(i);
             }
         }
     }
 
-    /**
-     * Exception raised when an argument to a {@linkplain Fold foldable} or {@link NodeIntrinsic}
-     * method is not a constant.
-     */
-    @SuppressWarnings("serial")
-    public static class NonConstantParameterError extends Error {
-
-        public NonConstantParameterError(String message) {
-            super(message);
-        }
-    }
-
     public static Class<?>[] signatureToTypes(Signature signature, ResolvedJavaType accessingClass) {
         int count = signature.getParameterCount(false);
         Class<?>[] result = new Class<?>[count];
@@ -91,7 +67,7 @@
         return result;
     }
 
-    private void tryIntrinsify(Invoke invoke) {
+    private boolean tryIntrinsify(Invoke invoke) {
         ResolvedJavaMethod target = invoke.methodCallTarget().targetMethod();
         NodeIntrinsic intrinsic = target.getAnnotation(Node.NodeIntrinsic.class);
         ResolvedJavaType declaringClass = target.getDeclaringClass();
@@ -104,6 +80,9 @@
 
             // Prepare the arguments for the reflective constructor call on the node class.
             Object[] nodeConstructorArguments = prepareArguments(invoke, parameterTypes, target, false);
+            if (nodeConstructorArguments == null) {
+                return false;
+            }
 
             // Create the new node instance.
             Class<?> c = getNodeClass(target, intrinsic);
@@ -120,6 +99,9 @@
 
             // Prepare the arguments for the reflective method call
             Object[] arguments = prepareArguments(invoke, parameterTypes, target, true);
+            if (arguments == null) {
+                return false;
+            }
             Object receiver = null;
             if (!invoke.methodCallTarget().isStatic()) {
                 receiver = arguments[0];
@@ -142,6 +124,7 @@
                 invoke.intrinsify(null);
             }
         }
+        return true;
     }
 
     /**
@@ -149,6 +132,8 @@
      * to a reflective invocation of a Java constructor or method.
      * 
      * @param folding specifies if the invocation is for handling a {@link Fold} annotation
+     * @return the arguments for the reflective invocation or null if an argument of {@code invoke}
+     *         that is expected to be constant isn't
      */
     private Object[] prepareArguments(Invoke invoke, Class<?>[] parameterTypes, ResolvedJavaMethod target, boolean folding) {
         NodeInputList<ValueNode> arguments = invoke.callTarget().arguments();
@@ -161,8 +146,7 @@
             ValueNode argument = tryBoxingElimination(parameterIndex, target, arguments.get(i));
             if (folding || MetaUtil.getParameterAnnotation(ConstantNodeParameter.class, parameterIndex, target) != null) {
                 if (!(argument instanceof ConstantNode)) {
-                    throw new NonConstantParameterError("parameter " + parameterIndex + " must be a compile time constant for calling " + invoke.methodCallTarget().targetMethod() + " at " +
-                                    sourceLocation(invoke.node()) + ": " + argument);
+                    return null;
                 }
                 ConstantNode constantNode = (ConstantNode) argument;
                 Constant constant = constantNode.asConstant();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationVerificationPhase.java	Thu Mar 07 11:44:36 2013 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.snippets;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.snippets.Snippet.Fold;
+
+/**
+ * Checks that a graph contains no calls to {@link NodeIntrinsic} or {@link Fold} methods.
+ */
+public class SnippetIntrinsificationVerificationPhase extends Phase {
+
+    public static boolean verify(StructuredGraph graph) {
+        new SnippetIntrinsificationVerificationPhase().apply(graph);
+        return true;
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        for (Invoke i : graph.getInvokes()) {
+            if (i.callTarget() instanceof MethodCallTargetNode) {
+                checkInvoke(i);
+            }
+        }
+    }
+
+    private static void checkInvoke(Invoke invoke) {
+        ResolvedJavaMethod target = invoke.methodCallTarget().targetMethod();
+        NodeIntrinsic intrinsic = target.getAnnotation(Node.NodeIntrinsic.class);
+        if (intrinsic != null) {
+            throw new GraalInternalError("Illegal call to node intrinsic in " + invoke.graph() + ": " + invoke);
+        } else if (target.getAnnotation(Fold.class) != null) {
+            throw new GraalInternalError("Illegal call to foldable method in " + invoke.graph() + ": " + invoke);
+        }
+    }
+}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java	Thu Mar 07 10:18:34 2013 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java	Thu Mar 07 11:44:36 2013 +0100
@@ -282,11 +282,12 @@
         Debug.dump(snippetCopy, "Before specialization");
         if (!replacements.isEmpty()) {
             // Do deferred intrinsification of node intrinsics
-            new SnippetIntrinsificationPhase(runtime, new BoxingMethodPool(runtime), false).apply(snippetCopy);
+            new SnippetIntrinsificationPhase(runtime, new BoxingMethodPool(runtime)).apply(snippetCopy);
             new WordTypeRewriterPhase(runtime, target.wordKind).apply(snippetCopy);
 
             new CanonicalizerPhase(runtime, assumptions, 0, null).apply(snippetCopy);
         }
+        assert SnippetIntrinsificationVerificationPhase.verify(snippetCopy);
 
         // Gather the template parameters
         parameters = new HashMap<>();