changeset 19959:812fc403db8c

Merge.
author Doug Simon <doug.simon@oracle.com>
date Thu, 19 Mar 2015 12:47:06 +0100
parents e018185695f6 (diff) c39d8bafd342 (current diff)
children 999430bcc941
files graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInvocationPlugins.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARCScratchRegister.java
diffstat 7 files changed, 125 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java	Thu Mar 19 11:53:36 2015 +0100
+++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java	Thu Mar 19 12:47:06 2015 +0100
@@ -30,6 +30,8 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.graph.Node;
+import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.nodes.*;
 
 /**
@@ -381,4 +383,18 @@
     public int size() {
         return registrations.size();
     }
+
+    /**
+     * Checks a set of nodes added to the graph by an {@link InvocationPlugin}.
+     *
+     * @param b the graph builder that applied the plugin
+     * @param plugin a plugin that was just applied
+     * @param newNodes the nodes added to the graph by {@code plugin}
+     * @throws AssertionError if any check fail
+     */
+    public void checkNewNodes(GraphBuilderContext b, InvocationPlugin plugin, NodeIterable<Node> newNodes) {
+        if (parent != null) {
+            parent.checkNewNodes(b, plugin, newNodes);
+        }
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInvocationPlugins.java	Thu Mar 19 11:53:36 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInvocationPlugins.java	Thu Mar 19 12:47:06 2015 +0100
@@ -23,8 +23,13 @@
 package com.oracle.graal.hotspot.meta;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.graphbuilderconf.*;
 import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.phases.*;
+import com.oracle.graal.nodes.*;
 import com.oracle.graal.replacements.StandardGraphBuilderPlugins.BoxPlugin;
 
 /**
@@ -65,6 +70,22 @@
                 return;
             }
         }
+
         super.register(plugin, declaringClass, name, argumentTypes);
     }
+
+    @Override
+    public void checkNewNodes(GraphBuilderContext b, InvocationPlugin plugin, NodeIterable<Node> newNodes) {
+        if (GraalOptions.ImmutableCode.getValue()) {
+            for (Node node : newNodes) {
+                if (node instanceof ConstantNode) {
+                    ConstantNode c = (ConstantNode) node;
+                    if (c.getKind() == Kind.Object && !AheadOfTimeVerificationPhase.isLegalObjectConstant(c)) {
+                        throw new AssertionError("illegal constant node in AOT: " + node);
+                    }
+                }
+            }
+        }
+        super.checkNewNodes(b, plugin, newNodes);
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/AheadOfTimeVerificationPhase.java	Thu Mar 19 11:53:36 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/AheadOfTimeVerificationPhase.java	Thu Mar 19 12:47:06 2015 +0100
@@ -32,9 +32,8 @@
 import com.oracle.graal.phases.tiers.*;
 
 /**
- * Checks for illegal object constants in a graph processed for AOT compilation. The only legal
- * object constants are {@linkplain String#intern() interned} strings as they will be installed in
- * the Class Data Sharing (CDS) space.
+ * Checks for {@link #isLegalObjectConstant(ConstantNode) illegal} object constants in a graph
+ * processed for AOT compilation.
  *
  * @see LoadJavaMirrorWithKlassPhase
  */
@@ -43,13 +42,17 @@
     @Override
     protected boolean verify(StructuredGraph graph, PhaseContext context) {
         for (ConstantNode node : getConstantNodes(graph)) {
-            if (isObject(node) && !isNullReference(node) && !isInternedString(node) && !isDirectMethodHandle(node) && !isBoundMethodHandle(node)) {
+            if (isLegalObjectConstant(node)) {
                 throw new VerificationError("illegal object constant: " + node);
             }
         }
         return true;
     }
 
+    public static boolean isLegalObjectConstant(ConstantNode node) {
+        return isObject(node) && !isNullReference(node) && !isInternedString(node) && !isDirectMethodHandle(node) && !isBoundMethodHandle(node);
+    }
+
     private static boolean isObject(ConstantNode node) {
         return node.getKind() == Kind.Object;
     }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Thu Mar 19 11:53:36 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Thu Mar 19 12:47:06 2015 +0100
@@ -25,6 +25,7 @@
 import static com.oracle.graal.api.meta.DeoptimizationAction.*;
 import static com.oracle.graal.api.meta.DeoptimizationReason.*;
 import static com.oracle.graal.bytecode.Bytecodes.*;
+import static com.oracle.graal.compiler.common.GraalInternalError.*;
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.graph.iterators.NodePredicates.*;
 import static com.oracle.graal.java.AbstractBytecodeParser.Options.*;
@@ -1149,22 +1150,64 @@
                 }
             }
 
+            /**
+             * Contains all the assertion checking logic around the application of an
+             * {@link InvocationPlugin}. This class is only loaded when assertions are enabled.
+             */
+            class InvocationPluginAssertions {
+                final InvocationPlugin plugin;
+                final ValueNode[] args;
+                final ResolvedJavaMethod targetMethod;
+                final Kind resultType;
+                final int beforeStackSize;
+                final boolean needsNullCheck;
+                final int nodeCount;
+                final Mark mark;
+
+                public InvocationPluginAssertions(InvocationPlugin plugin, ValueNode[] args, ResolvedJavaMethod targetMethod, Kind resultType) {
+                    guarantee(assertionsEnabled(), "%s should only be loaded and instantiated if assertions are enabled", getClass().getSimpleName());
+                    this.plugin = plugin;
+                    this.targetMethod = targetMethod;
+                    this.args = args;
+                    this.resultType = resultType;
+                    this.beforeStackSize = frameState.stackSize;
+                    this.needsNullCheck = !targetMethod.isStatic() && args[0].getKind() == Kind.Object && !StampTool.isPointerNonNull(args[0].stamp());
+                    this.nodeCount = currentGraph.getNodeCount();
+                    this.mark = currentGraph.getMark();
+                }
+
+                boolean check(boolean pluginResult) {
+                    if (pluginResult == true) {
+                        assert beforeStackSize + resultType.getSlotCount() == frameState.stackSize : "plugin manipulated the stack incorrectly " + targetMethod;
+                        NodeIterable<Node> newNodes = currentGraph.getNewNodes(mark);
+                        assert !needsNullCheck || args[0].usages().filter(isNotA(FrameState.class)).isEmpty() || containsNullCheckOf(newNodes, args[0]) : format(
+                                        "plugin needs to null check the receiver of %s: receiver=%s%n\tplugin at %s", targetMethod.format("%H.%n(%p)"), args[0],
+                                        plugin.getApplySourceLocation(metaAccess));
+                        for (Node n : newNodes) {
+                            if (n instanceof StateSplit) {
+                                StateSplit stateSplit = (StateSplit) n;
+                                assert stateSplit.stateAfter() != null : format("%s node added by plugin for %s need to have a non-null frame state: %s%n\tplugin at %s",
+                                                StateSplit.class.getSimpleName(), targetMethod.format("%H.%n(%p)"), stateSplit, plugin.getApplySourceLocation(metaAccess));
+                            }
+                        }
+                        graphBuilderConfig.getPlugins().getInvocationPlugins().checkNewNodes(BytecodeParser.this, plugin, newNodes);
+                    } else {
+                        assert nodeCount == currentGraph.getNodeCount() : "plugin that returns false must not create new nodes";
+                        assert beforeStackSize == frameState.stackSize : "plugin that returns false must modify the stack";
+                    }
+                    return true;
+                }
+            }
+
             private boolean tryInvocationPlugin(ValueNode[] args, ResolvedJavaMethod targetMethod, Kind resultType) {
                 InvocationPlugin plugin = graphBuilderConfig.getPlugins().getInvocationPlugins().lookupInvocation(targetMethod);
                 if (plugin != null) {
-                    int beforeStackSize = frameState.stackSize;
-                    boolean needsNullCheck = !targetMethod.isStatic() && args[0].getKind() == Kind.Object && !StampTool.isPointerNonNull(args[0].stamp());
-                    int nodeCount = currentGraph.getNodeCount();
-                    Mark mark = needsNullCheck ? currentGraph.getMark() : null;
+                    InvocationPluginAssertions assertions = assertionsEnabled() ? new InvocationPluginAssertions(plugin, args, targetMethod, resultType) : null;
                     if (InvocationPlugin.execute(this, targetMethod, plugin, args)) {
-                        assert beforeStackSize + resultType.getSlotCount() == frameState.stackSize : "plugin manipulated the stack incorrectly " + targetMethod;
-                        assert !needsNullCheck || args[0].usages().filter(isNotA(FrameState.class)).isEmpty() || containsNullCheckOf(currentGraph.getNewNodes(mark), args[0]) : format(
-                                        "plugin needs to null check the receiver of %s: receiver=%s%n\tplugin at %s", targetMethod.format("%H.%n(%p)"), args[0],
-                                        plugin.getApplySourceLocation(metaAccess));
+                        assert assertions.check(true);
                         return true;
                     }
-                    assert nodeCount == currentGraph.getNodeCount() : "plugin that returns false must not create new nodes";
-                    assert beforeStackSize == frameState.stackSize : "plugin that returns false must modify the stack";
+                    assert assertions.check(false);
                 }
                 return false;
             }
@@ -2372,4 +2415,11 @@
     static String nSpaces(int n) {
         return n == 0 ? "" : format("%" + n + "s", "");
     }
+
+    @SuppressWarnings("all")
+    private static boolean assertionsEnabled() {
+        boolean assertionsEnabled = false;
+        assert assertionsEnabled = true;
+        return assertionsEnabled;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java	Thu Mar 19 11:53:36 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java	Thu Mar 19 12:47:06 2015 +0100
@@ -28,7 +28,6 @@
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
 
 /**
  * The {@code InstanceOfDynamicNode} represents a type check where the type being checked is not
@@ -56,8 +55,6 @@
         this.mirror = mirror;
         this.object = object;
         assert mirror.getKind() == Kind.Object : mirror.getKind();
-        assert StampTool.isExactType(mirror);
-        assert StampTool.typeOrNull(mirror).getName().equals("Ljava/lang/Class;");
     }
 
     @Override
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Thu Mar 19 11:53:36 2015 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Thu Mar 19 12:47:06 2015 +0100
@@ -543,7 +543,7 @@
     }
 
     public static boolean canIntrinsify(Replacements replacements, ResolvedJavaMethod target) {
-        return getIntrinsicGraph(replacements, target) != null || getMacroNodeClass(replacements, target) != null;
+        return replacements.getMethodSubstitutionMethod(target) != null || getMacroNodeClass(replacements, target) != null;
     }
 
     public static StructuredGraph getIntrinsicGraph(Replacements replacements, ResolvedJavaMethod target) {
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java	Thu Mar 19 11:53:36 2015 +0100
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java	Thu Mar 19 12:47:06 2015 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.replacements.test;
 
+import java.util.*;
+
 import org.junit.*;
 
 import com.oracle.graal.api.code.*;
@@ -230,6 +232,16 @@
         return clazz.isInstance(object);
     }
 
+    public static boolean isInstance2(boolean cond, Object object) {
+        Class<?> clazz;
+        if (cond) {
+            clazz = String.class;
+        } else {
+            clazz = java.util.HashMap.class;
+        }
+        return clazz.isInstance(object);
+    }
+
     public static boolean isAssignableFrom(Class<?> clazz, Class<?> other) {
         return clazz.isAssignableFrom(other);
     }
@@ -237,6 +249,7 @@
     @Test
     public void testClassSubstitutions() {
         testGraph("isInstance");
+        testGraph("isInstance2");
         testGraph("isAssignableFrom");
         for (Class<?> c : new Class[]{getClass(), Cloneable.class, int[].class, String[][].class}) {
             for (Object o : new Object[]{this, new int[5], new String[2][], new Object()}) {
@@ -244,5 +257,12 @@
                 test("isAssignableFrom", c, o.getClass());
             }
         }
+
+        test("isInstance2", true, null);
+        test("isInstance2", false, null);
+        test("isInstance2", true, "string");
+        test("isInstance2", false, "string");
+        test("isInstance2", true, new HashMap<>());
+        test("isInstance2", false, new HashMap<>());
     }
 }