Mercurial > hg > truffle
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<>()); } }