# HG changeset patch # User Christian Wimmer # Date 1432944091 25200 # Node ID 4a8d4ee0fdd657cc0558ee104ec28f6e24982512 # Parent 71b338926f2efc14724cdbd24a8b52e42cfe4e15 Allow multiple ParameterPlugin and InlineInvokePlugin in graph builder plugins; cleanup InlineInvokePlugin and implementations, including in Truffle diff -r 71b338926f2e -r 4a8d4ee0fdd6 graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderConfiguration.java --- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderConfiguration.java Fri May 29 22:27:38 2015 +0200 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderConfiguration.java Fri May 29 17:01:31 2015 -0700 @@ -33,8 +33,8 @@ public static class Plugins { private final InvocationPlugins invocationPlugins; private NodePlugin[] nodePlugins; - private ParameterPlugin parameterPlugin; - private InlineInvokePlugin inlineInvokePlugin; + private ParameterPlugin[] parameterPlugins; + private InlineInvokePlugin[] inlineInvokePlugins; private LoopExplosionPlugin loopExplosionPlugin; /** @@ -44,9 +44,9 @@ */ public Plugins(Plugins copyFrom) { this.invocationPlugins = new InvocationPlugins(copyFrom.invocationPlugins); - this.parameterPlugin = copyFrom.parameterPlugin; this.nodePlugins = copyFrom.nodePlugins; - this.inlineInvokePlugin = copyFrom.inlineInvokePlugin; + this.parameterPlugins = copyFrom.parameterPlugins; + this.inlineInvokePlugins = copyFrom.inlineInvokePlugins; this.loopExplosionPlugin = copyFrom.loopExplosionPlugin; } @@ -59,6 +59,8 @@ public Plugins(InvocationPlugins invocationPlugins) { this.invocationPlugins = invocationPlugins; this.nodePlugins = new NodePlugin[0]; + this.parameterPlugins = new ParameterPlugin[0]; + this.inlineInvokePlugins = new InlineInvokePlugin[0]; } public InvocationPlugins getInvocationPlugins() { @@ -74,20 +76,55 @@ nodePlugins[nodePlugins.length - 1] = plugin; } - public ParameterPlugin getParameterPlugin() { - return parameterPlugin; + public void prependNodePlugin(NodePlugin plugin) { + NodePlugin[] newPlugins = new NodePlugin[nodePlugins.length + 1]; + System.arraycopy(nodePlugins, 0, newPlugins, 1, nodePlugins.length); + newPlugins[0] = plugin; + nodePlugins = newPlugins; + } + + public void clearNodePlugin() { + nodePlugins = new NodePlugin[0]; + } + + public ParameterPlugin[] getParameterPlugins() { + return parameterPlugins; + } + + public void appendParameterPlugin(ParameterPlugin plugin) { + parameterPlugins = Arrays.copyOf(parameterPlugins, parameterPlugins.length + 1); + parameterPlugins[parameterPlugins.length - 1] = plugin; } - public void setParameterPlugin(ParameterPlugin plugin) { - this.parameterPlugin = plugin; + public void prependParameterPlugin(ParameterPlugin plugin) { + ParameterPlugin[] newPlugins = new ParameterPlugin[parameterPlugins.length + 1]; + System.arraycopy(parameterPlugins, 0, newPlugins, 1, parameterPlugins.length); + newPlugins[0] = plugin; + parameterPlugins = newPlugins; + } + + public void clearParameterPlugin() { + parameterPlugins = new ParameterPlugin[0]; + } + + public InlineInvokePlugin[] getInlineInvokePlugins() { + return inlineInvokePlugins; } - public InlineInvokePlugin getInlineInvokePlugin() { - return inlineInvokePlugin; + public void appendInlineInvokePlugin(InlineInvokePlugin plugin) { + inlineInvokePlugins = Arrays.copyOf(inlineInvokePlugins, inlineInvokePlugins.length + 1); + inlineInvokePlugins[inlineInvokePlugins.length - 1] = plugin; } - public void setInlineInvokePlugin(InlineInvokePlugin plugin) { - this.inlineInvokePlugin = plugin; + public void prependInlineInvokePlugin(InlineInvokePlugin plugin) { + InlineInvokePlugin[] newPlugins = new InlineInvokePlugin[inlineInvokePlugins.length + 1]; + System.arraycopy(inlineInvokePlugins, 0, newPlugins, 1, inlineInvokePlugins.length); + newPlugins[0] = plugin; + inlineInvokePlugins = newPlugins; + } + + public void clearInlineInvokePlugins() { + inlineInvokePlugins = new InlineInvokePlugin[0]; } public LoopExplosionPlugin getLoopExplosionPlugin() { diff -r 71b338926f2e -r 4a8d4ee0fdd6 graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InlineInvokePlugin.java --- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InlineInvokePlugin.java Fri May 29 22:27:38 2015 +0200 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InlineInvokePlugin.java Fri May 29 17:01:31 2015 -0700 @@ -27,55 +27,93 @@ import com.oracle.graal.nodes.*; /** - * Plugin for specifying what is inlined during graph parsing. This plugin is also - * {@linkplain #notifyOfNoninlinedInvoke notified} of non-inlined invocations (i.e., those for which - * an {@link Invoke} node is created). + * Plugin for specifying what is inlined during graph parsing. This plugin is also notified + * {@link #notifyBeforeInline before} and {@link #notifyAfterInline} the inlining, as well as of + * {@link #notifyNotInlined non-inlined} invocations (i.e., those for which an {@link Invoke} node + * is created). */ public interface InlineInvokePlugin extends GraphBuilderPlugin { + /** + * Result of a {@link #shouldInlineInvoke inlining decision}. + */ public static class InlineInfo { - /** - * The method to be inlined. - */ - public final ResolvedJavaMethod methodToInline; + /** Marker return value to use when the call site must not be inlined. */ + public static final InlineInfo DO_NOT_INLINE = new InlineInfo(null, false); - /** - * Specifies if {@link #methodToInline} is an intrinsic for the original method (i.e., the - * {@code method} passed to {@link InlineInvokePlugin#getInlineInfo}). - */ - public final boolean isIntrinsic; + private final ResolvedJavaMethod methodToInline; + private final boolean isIntrinsic; public InlineInfo(ResolvedJavaMethod methodToInline, boolean isIntrinsic) { this.methodToInline = methodToInline; this.isIntrinsic = isIntrinsic; } + + /** + * Returns the method to be inlined, or {@code null} if the call site must not be inlined. + */ + public ResolvedJavaMethod getMethodToInline() { + return methodToInline; + } + + /** + * Specifies if {@link #methodToInline} is an intrinsic for the original method (i.e., the + * {@code method} passed to {@link InlineInvokePlugin#shouldInlineInvoke}). + */ + public boolean isIntrinsic() { + return isIntrinsic; + } } /** - * Determines whether a call to a given method is to be inlined. + * Determines whether a call to a given method is to be inlined. The return value is a + * tri-state: + *

+ * Non-null return value with a non-null {@link InlineInfo#getMethodToInline method}: That + * {@link InlineInfo#getMethodToInline method} is inlined. Note that it can be a different + * method than the one specified here as the parameter, which allows method substitutions. + *

+ * Non-null return value with a null {@link InlineInfo#getMethodToInline method}, e.g., + * {@link InlineInfo#DO_NOT_INLINE}: The method is not inlined, and other plugins with a lower + * priority cannot overwrite this decision. + *

+ * Null return value: This plugin made no decision, other plugins with a lower priority are + * asked. * + * @param b the context * @param method the target method of an invoke * @param args the arguments to the invoke * @param returnType the return type derived from {@code method}'s signature */ - default InlineInvokePlugin.InlineInfo getInlineInfo(@SuppressWarnings("unused") GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType) { + default InlineInfo shouldInlineInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType) { return null; } /** - * @param inlinedTargetMethod + * Notification that a method is about to be inlined. + * + * @param methodToInline the inlined method */ - default void postInline(ResolvedJavaMethod inlinedTargetMethod) { + default void notifyBeforeInline(ResolvedJavaMethod methodToInline) { + } + + /** + * Notification that a method was inlined. + * + * @param methodToInline the inlined method + */ + default void notifyAfterInline(ResolvedJavaMethod methodToInline) { } /** * Notifies this plugin of the {@link Invoke} node created for a method that was not inlined per - * {@link #getInlineInfo}. + * {@link #shouldInlineInvoke}. * + * @param b the context * @param method the method that was not inlined * @param invoke the invoke node created for the call to {@code method} */ - default void notifyOfNoninlinedInvoke(@SuppressWarnings("unused") GraphBuilderContext b, ResolvedJavaMethod method, Invoke invoke) { + default void notifyNotInlined(GraphBuilderContext b, ResolvedJavaMethod method, Invoke invoke) { } } diff -r 71b338926f2e -r 4a8d4ee0fdd6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Fri May 29 22:27:38 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Fri May 29 17:01:31 2015 -0700 @@ -28,8 +28,10 @@ import com.oracle.jvmci.meta.ConstantReflectionProvider; import com.oracle.jvmci.meta.ResolvedJavaMethod; import com.oracle.jvmci.meta.Kind; + import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.hotspot.replacements.SystemSubstitutions.*; +import static com.oracle.graal.java.GraphBuilderPhase.Options.*; import java.lang.invoke.*; import java.util.zip.*; @@ -78,10 +80,14 @@ HotSpotWordOperationPlugin wordOperationPlugin = new HotSpotWordOperationPlugin(snippetReflection, wordTypes); HotSpotNodePlugin nodePlugin = new HotSpotNodePlugin(metaAccess, constantReflection, wordOperationPlugin, nodeIntrinsificationPlugin); - plugins.setParameterPlugin(nodePlugin); + plugins.appendParameterPlugin(nodePlugin); plugins.appendNodePlugin(nodePlugin); plugins.appendNodePlugin(new MethodHandlePlugin(constantReflection.getMethodHandleAccess())); - plugins.setInlineInvokePlugin(new DefaultInlineInvokePlugin(replacements)); + + plugins.appendInlineInvokePlugin(replacements); + if (InlineDuringParsing.getValue()) { + plugins.appendInlineInvokePlugin(new InlineDuringParsingPlugin()); + } registerObjectPlugins(invocationPlugins); registerClassPlugins(plugins); diff -r 71b338926f2e -r 4a8d4ee0fdd6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java Fri May 29 22:27:38 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java Fri May 29 17:01:31 2015 -0700 @@ -95,7 +95,7 @@ Plugins defaultPlugins = providers.getGraphBuilderPlugins(); MetaAccessProvider metaAccess = providers.getMetaAccess(); Plugins plugins = new Plugins(defaultPlugins); - plugins.setParameterPlugin(new ConstantBindingParameterPlugin(makeConstArgs(), plugins.getParameterPlugin(), metaAccess, providers.getSnippetReflection())); + plugins.prependParameterPlugin(new ConstantBindingParameterPlugin(makeConstArgs(), metaAccess, providers.getSnippetReflection())); GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(plugins); // Stubs cannot have optimistic assumptions since they have diff -r 71b338926f2e -r 4a8d4ee0fdd6 graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java Fri May 29 22:27:38 2015 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java Fri May 29 17:01:31 2015 -0700 @@ -109,7 +109,7 @@ } } - public void initializeForMethodStart(boolean eagerResolve, ParameterPlugin parameterPlugin) { + public void initializeForMethodStart(boolean eagerResolve, ParameterPlugin[] parameterPlugins) { int javaIndex = 0; int index = 0; @@ -117,8 +117,11 @@ // add the receiver FloatingNode receiver = null; Stamp receiverStamp = StampFactory.declaredNonNull(method.getDeclaringClass()); - if (parameterPlugin != null) { - receiver = parameterPlugin.interceptParameter(parser, index, receiverStamp); + for (ParameterPlugin plugin : parameterPlugins) { + receiver = plugin.interceptParameter(parser, index, receiverStamp); + if (receiver != null) { + break; + } } if (receiver == null) { receiver = new ParameterNode(javaIndex, receiverStamp); @@ -143,8 +146,11 @@ stamp = StampFactory.forKind(kind); } FloatingNode param = null; - if (parameterPlugin != null) { - param = parameterPlugin.interceptParameter(parser, index, stamp); + for (ParameterPlugin plugin : parameterPlugins) { + param = plugin.interceptParameter(parser, index, stamp); + if (param != null) { + break; + } } if (param == null) { param = new ParameterNode(index, stamp); diff -r 71b338926f2e -r 4a8d4ee0fdd6 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 Fri May 29 22:27:38 2015 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri May 29 17:01:31 2015 -0700 @@ -345,7 +345,7 @@ BytecodeParser parser = new BytecodeParser(null, metaAccess, method, graphBuilderConfig, optimisticOpts, entryBCI, intrinsicContext); FrameStateBuilder frameState = new FrameStateBuilder(parser, method, graph); - frameState.initializeForMethodStart(graphBuilderConfig.eagerResolving() || intrinsicContext != null, graphBuilderConfig.getPlugins().getParameterPlugin()); + frameState.initializeForMethodStart(graphBuilderConfig.eagerResolving() || intrinsicContext != null, graphBuilderConfig.getPlugins().getParameterPlugins()); try (IntrinsicScope s = intrinsicContext != null ? new IntrinsicScope(parser) : null) { parser.build(graph.start(), frameState); @@ -1401,12 +1401,8 @@ lastInstr = beginNode; } - InlineInvokePlugin plugin = graphBuilderConfig.getPlugins().getInlineInvokePlugin(); - if (plugin != null) { - if (TraceParserPlugins.getValue()) { - traceWithContext("did not inline %s", targetMethod.format("%h.%n(%p)")); - } - plugin.notifyOfNoninlinedInvoke(this, targetMethod, invoke); + for (InlineInvokePlugin plugin : graphBuilderConfig.getPlugins().getInlineInvokePlugins()) { + plugin.notifyNotInlined(this, targetMethod, invoke); } } @@ -1497,24 +1493,30 @@ } private boolean tryInline(ValueNode[] args, ResolvedJavaMethod targetMethod, JavaType returnType) { - InlineInvokePlugin plugin = graphBuilderConfig.getPlugins().getInlineInvokePlugin(); boolean canBeInlined = parsingIntrinsic() || targetMethod.canBeInlined(); - if (plugin == null || !canBeInlined) { + if (!canBeInlined) { return false; } - InlineInfo inlineInfo = plugin.getInlineInfo(this, targetMethod, args, returnType); - if (inlineInfo != null) { - return inline(plugin, targetMethod, inlineInfo.methodToInline, inlineInfo.isIntrinsic, args); + for (InlineInvokePlugin plugin : graphBuilderConfig.getPlugins().getInlineInvokePlugins()) { + InlineInfo inlineInfo = plugin.shouldInlineInvoke(this, targetMethod, args, returnType); + if (inlineInfo != null) { + if (inlineInfo.getMethodToInline() == null) { + /* Do not inline, and do not ask the remaining plugins. */ + return false; + } else { + return inline(targetMethod, inlineInfo.getMethodToInline(), inlineInfo.isIntrinsic(), args); + } + } } return false; } public void intrinsify(ResolvedJavaMethod targetMethod, ResolvedJavaMethod substitute, ValueNode[] args) { - boolean res = inline(null, targetMethod, substitute, true, args); + boolean res = inline(targetMethod, substitute, true, args); assert res : "failed to inline " + substitute; } - private boolean inline(InlineInvokePlugin plugin, ResolvedJavaMethod targetMethod, ResolvedJavaMethod inlinedMethod, boolean isIntrinsic, ValueNode[] args) { + private boolean inline(ResolvedJavaMethod targetMethod, ResolvedJavaMethod inlinedMethod, boolean isIntrinsic, ValueNode[] args) { if (TraceInlineDuringParsing.getValue() || TraceParserPlugins.getValue()) { if (targetMethod.equals(inlinedMethod)) { traceWithContext("inlining call to %s", inlinedMethod.format("%h.%n(%p)")); @@ -1547,9 +1549,12 @@ intrinsic = new IntrinsicContext(targetMethod, inlinedMethod, INLINE_DURING_PARSING); } if (inlinedMethod.hasBytecodes()) { + for (InlineInvokePlugin plugin : graphBuilderConfig.getPlugins().getInlineInvokePlugins()) { + plugin.notifyBeforeInline(targetMethod); + } parseAndInlineCallee(inlinedMethod, args, intrinsic); - if (plugin != null) { - plugin.postInline(inlinedMethod); + for (InlineInvokePlugin plugin : graphBuilderConfig.getPlugins().getInlineInvokePlugins()) { + plugin.notifyAfterInline(targetMethod); } } else { return false; diff -r 71b338926f2e -r 4a8d4ee0fdd6 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PEGraphDecoderTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PEGraphDecoderTest.java Fri May 29 22:27:38 2015 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PEGraphDecoderTest.java Fri May 29 17:01:31 2015 -0700 @@ -109,7 +109,7 @@ class InlineAll implements InlineInvokePlugin { @Override - public InlineInfo getInlineInfo(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType) { + public InlineInfo shouldInlineInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType) { return new InlineInfo(method, false); } } @@ -124,7 +124,7 @@ CachingPEGraphDecoder decoder = new CachingPEGraphDecoder(getProviders(), graphBuilderConfig, OptimisticOptimizations.NONE, AllowAssumptions.YES, getTarget().arch); targetGraph = new StructuredGraph(testMethod, AllowAssumptions.YES); - decoder.decode(targetGraph, testMethod, null, null, new InlineAll(), null); + decoder.decode(targetGraph, testMethod, null, null, new InlineInvokePlugin[]{new InlineAll()}, null); Debug.dump(targetGraph, "Target Graph"); targetGraph.verify(); diff -r 71b338926f2e -r 4a8d4ee0fdd6 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ConstantBindingParameterPlugin.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ConstantBindingParameterPlugin.java Fri May 29 22:27:38 2015 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ConstantBindingParameterPlugin.java Fri May 29 17:01:31 2015 -0700 @@ -34,19 +34,16 @@ */ public class ConstantBindingParameterPlugin implements ParameterPlugin { private final Object[] constantArgs; - private final ParameterPlugin delegate; private final MetaAccessProvider metaAccess; private final SnippetReflectionProvider snippetReflection; /** * Creates a plugin that will create {@link ConstantNode}s for each parameter with an index * equal to that of a non-null object in {@code constantArgs} (from which the - * {@link ConstantNode} is created if it isn't already a {@link ConstantNode}). For all other - * parameter indexes, {@code delegate} is applied if it is non-null. + * {@link ConstantNode} is created if it isn't already a {@link ConstantNode}). */ - public ConstantBindingParameterPlugin(Object[] constantArgs, ParameterPlugin delegate, MetaAccessProvider metaAccess, SnippetReflectionProvider snippetReflection) { + public ConstantBindingParameterPlugin(Object[] constantArgs, MetaAccessProvider metaAccess, SnippetReflectionProvider snippetReflection) { this.constantArgs = constantArgs; - this.delegate = delegate; this.metaAccess = metaAccess; this.snippetReflection = snippetReflection; } @@ -64,9 +61,6 @@ } return constantNode; } - if (delegate != null) { - return delegate.interceptParameter(b, index, stamp); - } return null; } } diff -r 71b338926f2e -r 4a8d4ee0fdd6 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultInlineInvokePlugin.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultInlineInvokePlugin.java Fri May 29 22:27:38 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2013, 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.replacements; - -import static com.oracle.graal.compiler.common.GraalOptions.*; -import static com.oracle.graal.java.GraphBuilderPhase.Options.*; - -import com.oracle.graal.graphbuilderconf.*; -import com.oracle.graal.nodes.*; -import com.oracle.jvmci.meta.*; - -public final class DefaultInlineInvokePlugin implements InlineInvokePlugin { - private final ReplacementsImpl replacements; - - public DefaultInlineInvokePlugin(ReplacementsImpl replacements) { - this.replacements = replacements; - } - - public InlineInfo getInlineInfo(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType) { - InlineInfo inlineInfo = replacements.getInlineInfo(b, method, args, returnType); - if (inlineInfo == null) { - if (InlineDuringParsing.getValue() && method.hasBytecodes() && !method.isSynchronized() && method.getCode().length <= TrivialInliningSize.getValue() && - b.getDepth() < InlineDuringParsingMaxDepth.getValue()) { - return new InlineInfo(method, false); - } - } - return inlineInfo; - } - - public void notifyOfNoninlinedInvoke(GraphBuilderContext b, ResolvedJavaMethod method, Invoke invoke) { - replacements.notifyOfNoninlinedInvoke(b, method, invoke); - } -} diff -r 71b338926f2e -r 4a8d4ee0fdd6 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InlineDuringParsingPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InlineDuringParsingPlugin.java Fri May 29 17:01:31 2015 -0700 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013, 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.replacements; + +import static com.oracle.graal.compiler.common.GraalOptions.*; +import static com.oracle.graal.java.GraphBuilderPhase.Options.*; + +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.nodes.*; +import com.oracle.jvmci.meta.*; + +public final class InlineDuringParsingPlugin implements InlineInvokePlugin { + + @Override + public InlineInfo shouldInlineInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType) { + if (method.hasBytecodes() && !method.isSynchronized() && method.getCode().length <= TrivialInliningSize.getValue() && b.getDepth() < InlineDuringParsingMaxDepth.getValue()) { + return new InlineInfo(method, false); + } + return null; + } +} diff -r 71b338926f2e -r 4a8d4ee0fdd6 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/PEGraphDecoder.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/PEGraphDecoder.java Fri May 29 22:27:38 2015 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/PEGraphDecoder.java Fri May 29 17:01:31 2015 -0700 @@ -69,7 +69,7 @@ protected final LoopExplosionPlugin loopExplosionPlugin; protected final InvocationPlugins invocationPlugins; - protected final InlineInvokePlugin inlineInvokePlugin; + protected final InlineInvokePlugin[] inlineInvokePlugins; protected final ParameterPlugin parameterPlugin; protected final ValueNode[] arguments; @@ -79,7 +79,7 @@ protected BytecodePosition bytecodePosition; protected PEMethodScope(StructuredGraph targetGraph, PEMethodScope caller, LoopScope callerLoopScope, EncodedGraph encodedGraph, ResolvedJavaMethod method, InvokeData invokeData, - int inliningDepth, LoopExplosionPlugin loopExplosionPlugin, InvocationPlugins invocationPlugins, InlineInvokePlugin inlineInvokePlugin, ParameterPlugin parameterPlugin, + int inliningDepth, LoopExplosionPlugin loopExplosionPlugin, InvocationPlugins invocationPlugins, InlineInvokePlugin[] inlineInvokePlugins, ParameterPlugin parameterPlugin, ValueNode[] arguments) { super(targetGraph, encodedGraph, loopExplosionKind(method, loopExplosionPlugin)); @@ -90,7 +90,7 @@ this.inliningDepth = inliningDepth; this.loopExplosionPlugin = loopExplosionPlugin; this.invocationPlugins = invocationPlugins; - this.inlineInvokePlugin = inlineInvokePlugin; + this.inlineInvokePlugins = inlineInvokePlugins; this.parameterPlugin = parameterPlugin; this.arguments = arguments; } @@ -298,9 +298,9 @@ } } - public void decode(StructuredGraph targetGraph, ResolvedJavaMethod method, LoopExplosionPlugin loopExplosionPlugin, InvocationPlugins invocationPlugins, InlineInvokePlugin inlineInvokePlugin, + public void decode(StructuredGraph targetGraph, ResolvedJavaMethod method, LoopExplosionPlugin loopExplosionPlugin, InvocationPlugins invocationPlugins, InlineInvokePlugin[] inlineInvokePlugins, ParameterPlugin parameterPlugin) { - PEMethodScope methodScope = new PEMethodScope(targetGraph, null, null, lookupEncodedGraph(method), method, null, 0, loopExplosionPlugin, invocationPlugins, inlineInvokePlugin, + PEMethodScope methodScope = new PEMethodScope(targetGraph, null, null, lookupEncodedGraph(method), method, null, 0, loopExplosionPlugin, invocationPlugins, inlineInvokePlugins, parameterPlugin, null); decode(methodScope, null); cleanupGraph(methodScope, null); @@ -355,8 +355,8 @@ return true; } - if (methodScope.inlineInvokePlugin != null) { - methodScope.inlineInvokePlugin.notifyOfNoninlinedInvoke(new PENonAppendGraphBuilderContext(methodScope, invokeData.invoke), callTarget.targetMethod(), invokeData.invoke); + for (InlineInvokePlugin plugin : methodScope.inlineInvokePlugins) { + plugin.notifyNotInlined(new PENonAppendGraphBuilderContext(methodScope, invokeData.invoke), callTarget.targetMethod(), invokeData.invoke); } return false; } @@ -381,7 +381,7 @@ invoke.asNode().replaceAtPredecessor(null); PEMethodScope inlineScope = new PEMethodScope(methodScope.graph, methodScope, loopScope, null, targetMethod, invokeData, methodScope.inliningDepth + 1, methodScope.loopExplosionPlugin, - methodScope.invocationPlugins, methodScope.inlineInvokePlugin, null, arguments); + methodScope.invocationPlugins, methodScope.inlineInvokePlugins, null, arguments); PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(inlineScope, invokePredecessor); InvocationPluginReceiver invocationPluginReceiver = new InvocationPluginReceiver(graphBuilderContext); @@ -407,7 +407,7 @@ } protected boolean tryInline(PEMethodScope methodScope, LoopScope loopScope, InvokeData invokeData, MethodCallTargetNode callTarget) { - if (methodScope.inlineInvokePlugin == null || !callTarget.invokeKind().isDirect()) { + if (!callTarget.invokeKind().isDirect()) { return false; } @@ -418,25 +418,38 @@ ValueNode[] arguments = callTarget.arguments().toArray(new ValueNode[0]); GraphBuilderContext graphBuilderContext = new PENonAppendGraphBuilderContext(methodScope, invokeData.invoke); - InlineInfo inlineInfo = methodScope.inlineInvokePlugin.getInlineInfo(graphBuilderContext, targetMethod, arguments, callTarget.returnType()); - if (inlineInfo == null) { - return false; + + for (InlineInvokePlugin plugin : methodScope.inlineInvokePlugins) { + InlineInfo inlineInfo = plugin.shouldInlineInvoke(graphBuilderContext, targetMethod, arguments, callTarget.returnType()); + if (inlineInfo != null) { + if (inlineInfo.getMethodToInline() == null) { + return false; + } else { + assert !inlineInfo.isIntrinsic() : "not supported"; + return doInline(methodScope, loopScope, invokeData, inlineInfo.getMethodToInline(), arguments); + } + } } - assert !inlineInfo.isIntrinsic : "not supported"; + return false; + } - ResolvedJavaMethod inlineMethod = inlineInfo.methodToInline; + protected boolean doInline(PEMethodScope methodScope, LoopScope loopScope, InvokeData invokeData, ResolvedJavaMethod inlineMethod, ValueNode[] arguments) { EncodedGraph graphToInline = lookupEncodedGraph(inlineMethod); if (graphToInline == null) { return false; } + for (InlineInvokePlugin plugin : methodScope.inlineInvokePlugins) { + plugin.notifyBeforeInline(inlineMethod); + } + Invoke invoke = invokeData.invoke; FixedNode invokeNode = invoke.asNode(); FixedWithNextNode predecessor = (FixedWithNextNode) invokeNode.predecessor(); invokeNode.replaceAtPredecessor(null); PEMethodScope inlineScope = new PEMethodScope(methodScope.graph, methodScope, loopScope, graphToInline, inlineMethod, invokeData, methodScope.inliningDepth + 1, - methodScope.loopExplosionPlugin, methodScope.invocationPlugins, methodScope.inlineInvokePlugin, null, arguments); + methodScope.loopExplosionPlugin, methodScope.invocationPlugins, methodScope.inlineInvokePlugins, null, arguments); /* Do the actual inlining by decoding the inlineMethod */ decode(inlineScope, predecessor); @@ -500,7 +513,9 @@ } deleteInvoke(invoke); - methodScope.inlineInvokePlugin.postInline(inlineMethod); + for (InlineInvokePlugin plugin : methodScope.inlineInvokePlugins) { + plugin.notifyAfterInline(inlineMethod); + } if (Debug.isDumpEnabled() && DumpDuringGraphBuilding.getValue()) { Debug.dump(methodScope.graph, "Inline finished: " + inlineMethod.getDeclaringClass().getUnqualifiedName() + "." + inlineMethod.getName()); diff -r 71b338926f2e -r 4a8d4ee0fdd6 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Fri May 29 22:27:38 2015 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Fri May 29 17:01:31 2015 -0700 @@ -95,7 +95,8 @@ * @return an object specifying how {@code method} is to be inlined or null if it should not be * inlined based on substitution related criteria */ - public InlineInfo getInlineInfo(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType) { + @Override + public InlineInfo shouldInlineInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType) { ResolvedJavaMethod subst = getSubstitutionMethod(method); if (subst != null) { if (b.parsingIntrinsic() || InlineDuringParsing.getValue() || InlineIntrinsicsDuringParsing.getValue()) { @@ -123,7 +124,8 @@ return null; } - public void notifyOfNoninlinedInvoke(GraphBuilderContext b, ResolvedJavaMethod method, Invoke invoke) { + @Override + public void notifyNotInlined(GraphBuilderContext b, ResolvedJavaMethod method, Invoke invoke) { if (b.parsingIntrinsic()) { IntrinsicContext intrinsic = b.getIntrinsic(); assert intrinsic.isCallToOriginal(method) : format("All non-recursive calls in the intrinsic %s must be inlined or intrinsified: found call to %s", @@ -556,7 +558,7 @@ Plugins plugins = new Plugins(replacements.graphBuilderPlugins); GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(plugins); if (args != null) { - plugins.setParameterPlugin(new ConstantBindingParameterPlugin(args, plugins.getParameterPlugin(), metaAccess, replacements.snippetReflection)); + plugins.prependParameterPlugin(new ConstantBindingParameterPlugin(args, metaAccess, replacements.snippetReflection)); } IntrinsicContext initialIntrinsicContext = null; diff -r 71b338926f2e -r 4a8d4ee0fdd6 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java Fri May 29 22:27:38 2015 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java Fri May 29 17:01:31 2015 -0700 @@ -85,7 +85,7 @@ } @Override - public void notifyOfNoninlinedInvoke(GraphBuilderContext b, ResolvedJavaMethod method, Invoke invoke) { + public void notifyNotInlined(GraphBuilderContext b, ResolvedJavaMethod method, Invoke invoke) { if (wordTypes.isWord(invoke.asNode())) { invoke.asNode().setStamp(wordTypes.getWordStamp(StampTool.typeOrNull(invoke.asNode()))); } diff -r 71b338926f2e -r 4a8d4ee0fdd6 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ConditionAnchoringTest.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ConditionAnchoringTest.java Fri May 29 22:27:38 2015 +0200 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ConditionAnchoringTest.java Fri May 29 17:01:31 2015 -0700 @@ -140,12 +140,13 @@ // get UnsafeAccessImpl.unsafeGetInt intrinsified TruffleGraphBuilderPlugins.registerUnsafeAccessImplPlugins(conf.getPlugins().getInvocationPlugins(), false); // get UnsafeAccess.getInt inlined - conf.getPlugins().setInlineInvokePlugin(new InlineEverythingPlugin()); + conf.getPlugins().appendInlineInvokePlugin(new InlineEverythingPlugin()); return super.editGraphBuilderConfiguration(conf); } private static final class InlineEverythingPlugin implements InlineInvokePlugin { - public InlineInfo getInlineInfo(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType) { + @Override + public InlineInfo shouldInlineInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType) { assert method.hasBytecodes(); return new InlineInfo(method, false); } diff -r 71b338926f2e -r 4a8d4ee0fdd6 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Fri May 29 22:27:38 2015 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Fri May 29 17:01:31 2015 -0700 @@ -22,8 +22,6 @@ */ package com.oracle.graal.truffle; -import static com.oracle.graal.compiler.common.GraalOptions.*; -import static com.oracle.graal.java.GraphBuilderPhase.Options.*; import static com.oracle.graal.truffle.TruffleCompilerOptions.*; import java.lang.invoke.*; @@ -158,17 +156,12 @@ } @Override - public InlineInfo getInlineInfo(GraphBuilderContext builder, ResolvedJavaMethod original, ValueNode[] arguments, JavaType returnType) { - InlineInfo inlineInfo = replacements.getInlineInfo(builder, original, arguments, returnType); - if (inlineInfo != null) { - return inlineInfo; - } - + public InlineInfo shouldInlineInvoke(GraphBuilderContext builder, ResolvedJavaMethod original, ValueNode[] arguments, JavaType returnType) { if (original.getAnnotation(TruffleBoundary.class) != null) { - return null; + return InlineInfo.DO_NOT_INLINE; } if (replacements.hasSubstitution(original, builder.bci())) { - return null; + return InlineInfo.DO_NOT_INLINE; } assert !builder.parsingIntrinsic(); @@ -199,7 +192,7 @@ } @Override - public void postInline(ResolvedJavaMethod inlinedTargetMethod) { + public void notifyAfterInline(ResolvedJavaMethod inlinedTargetMethod) { if (inlinedTargetMethod.equals(callInlinedMethod)) { inlining.pop(); } @@ -211,13 +204,11 @@ private final ReplacementsImpl replacements; private final InvocationPlugins invocationPlugins; private final LoopExplosionPlugin loopExplosionPlugin; - private final boolean inlineDuringParsing; - public ParsingInlineInvokePlugin(ReplacementsImpl replacements, InvocationPlugins invocationPlugins, LoopExplosionPlugin loopExplosionPlugin, boolean inlineDuringParsing) { + public ParsingInlineInvokePlugin(ReplacementsImpl replacements, InvocationPlugins invocationPlugins, LoopExplosionPlugin loopExplosionPlugin) { this.replacements = replacements; this.invocationPlugins = invocationPlugins; this.loopExplosionPlugin = loopExplosionPlugin; - this.inlineDuringParsing = inlineDuringParsing; } private boolean hasMethodHandleArgument(ValueNode[] arguments) { @@ -233,24 +224,19 @@ } @Override - public InlineInfo getInlineInfo(GraphBuilderContext builder, ResolvedJavaMethod original, ValueNode[] arguments, JavaType returnType) { - InlineInfo inlineInfo = replacements.getInlineInfo(builder, original, arguments, returnType); - if (inlineInfo != null) { - return inlineInfo; - } - + public InlineInfo shouldInlineInvoke(GraphBuilderContext builder, ResolvedJavaMethod original, ValueNode[] arguments, JavaType returnType) { if (invocationPlugins.lookupInvocation(original) != null || loopExplosionPlugin.shouldExplodeLoops(original)) { - return null; + return InlineInfo.DO_NOT_INLINE; } if (original.getAnnotation(TruffleBoundary.class) != null) { - return null; + return InlineInfo.DO_NOT_INLINE; } if (replacements.hasSubstitution(original, builder.bci())) { - return null; + return InlineInfo.DO_NOT_INLINE; } if (original.equals(callSiteProxyMethod) || original.equals(callDirectMethod)) { - return null; + return InlineInfo.DO_NOT_INLINE; } if (hasMethodHandleArgument(arguments)) { /* @@ -259,9 +245,6 @@ */ return new InlineInfo(original, false); } - if (inlineDuringParsing && original.hasBytecodes() && original.getCode().length < TrivialInliningSize.getValue() && builder.getDepth() < InlineDuringParsingMaxDepth.getValue()) { - return new InlineInfo(original, false); - } return null; } } @@ -289,18 +272,24 @@ newConfig.setUseProfiling(false); Plugins plugins = newConfig.getPlugins(); - plugins.setParameterPlugin(new InterceptReceiverPlugin(callTarget)); + plugins.prependParameterPlugin(new InterceptReceiverPlugin(callTarget)); callTarget.setInlining(new TruffleInlining(callTarget, new DefaultInliningPolicy())); + plugins.setLoopExplosionPlugin(new PELoopExplosionPlugin()); - InlineInvokePlugin inlinePlugin = new PEInlineInvokePlugin(callTarget.getInlining(), (ReplacementsImpl) providers.getReplacements()); + ReplacementsImpl replacements = (ReplacementsImpl) providers.getReplacements(); + plugins.clearInlineInvokePlugins(); + plugins.appendInlineInvokePlugin(replacements); + plugins.appendInlineInvokePlugin(new PEInlineInvokePlugin(callTarget.getInlining(), replacements)); + HistogramInlineInvokePlugin histogramPlugin = null; if (PrintTruffleExpansionHistogram.getValue()) { - inlinePlugin = new HistogramInlineInvokePlugin(graph, inlinePlugin); + histogramPlugin = new HistogramInlineInvokePlugin(graph); + plugins.appendInlineInvokePlugin(histogramPlugin); } - plugins.setInlineInvokePlugin(inlinePlugin); - plugins.setLoopExplosionPlugin(new PELoopExplosionPlugin()); + new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), providers.getConstantReflection(), newConfig, TruffleCompiler.Optimizations, null).apply(graph); + if (PrintTruffleExpansionHistogram.getValue()) { - ((HistogramInlineInvokePlugin) inlinePlugin).print(callTarget, System.out); + histogramPlugin.print(callTarget, System.out); } } @@ -313,8 +302,11 @@ newConfig.setUseProfiling(false); Plugins plugins = newConfig.getPlugins(); - plugins.setInlineInvokePlugin(new ParsingInlineInvokePlugin((ReplacementsImpl) providers.getReplacements(), parsingInvocationPlugins, loopExplosionPlugin, - !PrintTruffleExpansionHistogram.getValue())); + plugins.clearInlineInvokePlugins(); + plugins.appendInlineInvokePlugin(new ParsingInlineInvokePlugin((ReplacementsImpl) providers.getReplacements(), parsingInvocationPlugins, loopExplosionPlugin)); + if (!PrintTruffleExpansionHistogram.getValue()) { + plugins.appendInlineInvokePlugin(new InlineDuringParsingPlugin()); + } return new CachingPEGraphDecoder(providers, newConfig, TruffleCompiler.Optimizations, AllowAssumptions.from(graph.getAssumptions() != null), architecture); } @@ -326,17 +318,24 @@ LoopExplosionPlugin loopExplosionPlugin = new PELoopExplosionPlugin(); ParameterPlugin parameterPlugin = new InterceptReceiverPlugin(callTarget); + InvocationPlugins invocationPlugins = createDecodingInvocationPlugins(); - InvocationPlugins decodingInvocationPlugins = createDecodingInvocationPlugins(); - InlineInvokePlugin decodingInlinePlugin = new PEInlineInvokePlugin(callTarget.getInlining(), (ReplacementsImpl) providers.getReplacements()); + ReplacementsImpl replacements = (ReplacementsImpl) providers.getReplacements(); + InlineInvokePlugin[] inlineInvokePlugins; + InlineInvokePlugin inlineInvokePlugin = new PEInlineInvokePlugin(callTarget.getInlining(), replacements); + + HistogramInlineInvokePlugin histogramPlugin = null; if (PrintTruffleExpansionHistogram.getValue()) { - decodingInlinePlugin = new HistogramInlineInvokePlugin(graph, decodingInlinePlugin); + histogramPlugin = new HistogramInlineInvokePlugin(graph); + inlineInvokePlugins = new InlineInvokePlugin[]{replacements, inlineInvokePlugin, histogramPlugin}; + } else { + inlineInvokePlugins = new InlineInvokePlugin[]{replacements, inlineInvokePlugin}; } - decoder.decode(graph, graph.method(), loopExplosionPlugin, decodingInvocationPlugins, decodingInlinePlugin, parameterPlugin); + decoder.decode(graph, graph.method(), loopExplosionPlugin, invocationPlugins, inlineInvokePlugins, parameterPlugin); if (PrintTruffleExpansionHistogram.getValue()) { - ((HistogramInlineInvokePlugin) decodingInlinePlugin).print(callTarget, System.out); + histogramPlugin.print(callTarget, System.out); } } diff -r 71b338926f2e -r 4a8d4ee0fdd6 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/HistogramInlineInvokePlugin.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/HistogramInlineInvokePlugin.java Fri May 29 22:27:38 2015 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/HistogramInlineInvokePlugin.java Fri May 29 17:01:31 2015 -0700 @@ -22,8 +22,6 @@ */ package com.oracle.graal.truffle.debug; -import com.oracle.jvmci.meta.JavaType; -import com.oracle.jvmci.meta.ResolvedJavaMethod; import java.io.*; import java.util.*; @@ -33,37 +31,32 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.truffle.*; +import com.oracle.jvmci.meta.*; public class HistogramInlineInvokePlugin implements InlineInvokePlugin { private final Map histogram = new HashMap<>(); private final StructuredGraph graph; - private final InlineInvokePlugin delegate; private HistogramInlineInvokePlugin.MethodStatistic currentStatistic; - public HistogramInlineInvokePlugin(StructuredGraph graph, InlineInvokePlugin delegate) { + public HistogramInlineInvokePlugin(StructuredGraph graph) { this.graph = graph; - this.delegate = delegate; + } + + @Override + public void notifyBeforeInline(ResolvedJavaMethod methodToInline) { + currentStatistic = new MethodStatistic(currentStatistic, methodToInline, countNodes(), countCalls()); } - public InlineInfo getInlineInfo(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType) { - InlineInfo inlineInfo = delegate.getInlineInfo(b, method, args, returnType); - if (inlineInfo != null) { - currentStatistic = new MethodStatistic(currentStatistic, inlineInfo.methodToInline, countNodes(), countCalls()); - } - return inlineInfo; - } + @Override + public void notifyAfterInline(ResolvedJavaMethod methodToInline) { + assert methodToInline.equals(currentStatistic.method); - public void postInline(ResolvedJavaMethod inlinedTargetMethod) { - delegate.postInline(inlinedTargetMethod); - - if (currentStatistic != null) { - currentStatistic.applyNodeCountAfter(countNodes()); - currentStatistic.applyCallsAfter(countCalls()); - accept(currentStatistic); - currentStatistic = currentStatistic.getParent(); - } + currentStatistic.applyNodeCountAfter(countNodes()); + currentStatistic.applyCallsAfter(countCalls()); + accept(currentStatistic); + currentStatistic = currentStatistic.getParent(); } private int countNodes() {