# HG changeset patch # User Doug Simon # Date 1426675566 -3600 # Node ID 517cbecdc20f4ceb17de1e4088048b570184585b # Parent 575d7607f827484827e290d7a8143ce919fdca37 factored out assertion checks around application of an InvocationPlugin and added a check that all StateSplit nodes added by a plugin have a non-null frame state diff -r 575d7607f827 -r 517cbecdc20f graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Mar 18 02:15:37 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Mar 18 11:46: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,63 @@ } } + /** + * 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 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)); + } + } + } 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; } @@ -2392,4 +2434,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; + } }