# HG changeset patch # User Doug Simon # Date 1426597053 -3600 # Node ID 1eea5182d1024f5130632a7277c4da6e7ba1feac # Parent e1584086dc20318226f6f1e20ec4432f4b81fc2d# Parent 71f64b487b11f8c03eeec56314ed44a357c485ef Merge. diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Tue Mar 17 13:57:33 2015 +0100 @@ -41,6 +41,8 @@ import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; import com.oracle.graal.java.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; @@ -68,7 +70,8 @@ MetaAccessProvider metaAccess = providers.getMetaAccess(); PhaseSuite graphBuilderSuite = new PhaseSuite<>(); - graphBuilderSuite.appendPhase(new GraphBuilderPhase(GraphBuilderConfiguration.getEagerDefault())); + GraphBuilderConfiguration config = GraphBuilderConfiguration.getEagerDefault(new Plugins(new InvocationPlugins(metaAccess))); + graphBuilderSuite.appendPhase(new GraphBuilderPhase(config)); HighTierContext context = new HighTierContext(providers, null, graphBuilderSuite, OptimisticOptimizations.NONE); Assume.assumeTrue(VerifyPhase.class.desiredAssertionStatus()); diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Tue Mar 17 13:57:33 2015 +0100 @@ -28,10 +28,11 @@ import org.junit.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.Assumptions.Assumption; import com.oracle.graal.api.meta.Assumptions.NoFinalizableSubclass; -import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; @@ -66,7 +67,7 @@ final ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(constructors[0]); StructuredGraph graph = new StructuredGraph(javaMethod, allowAssumptions); - GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault(); + GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault(getDefaultGraphBuilderPlugins()); new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), getProviders().getConstantReflection(), conf, OptimisticOptimizations.ALL, null).apply(graph); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); new InliningPhase(new CanonicalizerPhase()).apply(graph, context); diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Tue Mar 17 13:57:33 2015 +0100 @@ -48,6 +48,8 @@ import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; import com.oracle.graal.java.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.phases.*; @@ -61,7 +63,7 @@ import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.schedule.*; -import com.oracle.graal.phases.schedule.SchedulePhase.*; +import com.oracle.graal.phases.schedule.SchedulePhase.SchedulingStrategy; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.printer.*; @@ -773,7 +775,7 @@ } /** - * Parses a Java method in {@linkplain GraphBuilderConfiguration#getDefault() default} mode to + * Parses a Java method in {@linkplain GraphBuilderConfiguration#getDefault default} mode to * produce a graph. * * @param methodName the name of the method in {@code this.getClass()} to be parsed @@ -783,7 +785,7 @@ } /** - * Parses a Java method in {@linkplain GraphBuilderConfiguration#getDefault() default} mode to + * Parses a Java method in {@linkplain GraphBuilderConfiguration#getDefault default} mode to * produce a graph. */ protected StructuredGraph parseProfiled(ResolvedJavaMethod m, AllowAssumptions allowAssumptions) { @@ -791,8 +793,8 @@ } /** - * Parses a Java method in {@linkplain GraphBuilderConfiguration#getEagerDefault() eager} mode - * to produce a graph. + * Parses a Java method in {@linkplain GraphBuilderConfiguration#getEagerDefault eager} mode to + * produce a graph. * * @param methodName the name of the method in {@code this.getClass()} to be parsed */ @@ -801,19 +803,19 @@ } /** - * Parses a Java method in {@linkplain GraphBuilderConfiguration#getEagerDefault() eager} mode - * to produce a graph. + * Parses a Java method in {@linkplain GraphBuilderConfiguration#getEagerDefault eager} mode to + * produce a graph. */ protected StructuredGraph parseEager(ResolvedJavaMethod m, AllowAssumptions allowAssumptions) { - return parse1(m, getCustomGraphBuilderSuite(GraphBuilderConfiguration.getEagerDefault()), allowAssumptions); + return parse1(m, getCustomGraphBuilderSuite(GraphBuilderConfiguration.getEagerDefault(getDefaultGraphBuilderPlugins())), allowAssumptions); } /** - * Parses a Java method in {@linkplain GraphBuilderConfiguration#getFullDebugDefault() full - * debug} mode to produce a graph. + * Parses a Java method in {@linkplain GraphBuilderConfiguration#getFullDebugDefault full debug} + * mode to produce a graph. */ protected StructuredGraph parseDebug(ResolvedJavaMethod m, AllowAssumptions allowAssumptions) { - return parse1(m, getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault()), allowAssumptions); + return parse1(m, getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault(getDefaultGraphBuilderPlugins())), allowAssumptions); } private StructuredGraph parse1(ResolvedJavaMethod javaMethod, PhaseSuite graphBuilderSuite, AllowAssumptions allowAssumptions) { @@ -827,32 +829,31 @@ } } + protected Plugins getDefaultGraphBuilderPlugins() { + PhaseSuite suite = backend.getSuites().getDefaultGraphBuilderSuite(); + Plugins defaultPlugins = ((GraphBuilderPhase) suite.findPhase(GraphBuilderPhase.class).previous()).getGraphBuilderConfig().getPlugins(); + // defensive copying + return new Plugins(defaultPlugins); + } + protected PhaseSuite getDefaultGraphBuilderSuite() { // defensive copying return backend.getSuites().getDefaultGraphBuilderSuite().copy(); } protected PhaseSuite getCustomGraphBuilderSuite(GraphBuilderConfiguration gbConf) { - PhaseSuite suite = getDefaultGraphBuilderSuite().copy(); + PhaseSuite suite = getDefaultGraphBuilderSuite(); ListIterator> iterator = suite.findPhase(GraphBuilderPhase.class); - GraphBuilderPhase graphBuilderPhase = (GraphBuilderPhase) iterator.previous(); - GraphBuilderConfiguration gbConfCopy = editGraphBuilderConfiguration(gbConf.copy().copyPluginsFrom(graphBuilderPhase.getGraphBuilderConfig())); + GraphBuilderConfiguration gbConfCopy = editGraphBuilderConfiguration(gbConf.copy()); iterator.remove(); iterator.add(new GraphBuilderPhase(gbConfCopy)); return suite; } protected GraphBuilderConfiguration editGraphBuilderConfiguration(GraphBuilderConfiguration conf) { - editGraphBuilderPlugins(conf.getPlugins()); return conf; } - /** - * @param plugins - */ - protected void editGraphBuilderPlugins(GraphBuilderConfiguration.Plugins plugins) { - } - protected Replacements getReplacements() { return getProviders().getReplacements(); } diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java Tue Mar 17 13:57:33 2015 +0100 @@ -34,7 +34,7 @@ import com.oracle.graal.api.code.CompilationResult.Call; import com.oracle.graal.api.code.CompilationResult.Infopoint; import com.oracle.graal.api.meta.*; -import com.oracle.graal.java.*; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; @@ -84,7 +84,7 @@ } assertTrue(graphLineSPs > 0); CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false); - PhaseSuite graphBuilderSuite = getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault()); + PhaseSuite graphBuilderSuite = getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault(getDefaultGraphBuilderPlugins())); final CompilationResult cr = compileGraph(graph, cc, graph.method(), getProviders(), getBackend(), getCodeCache().getTarget(), null, graphBuilderSuite, OptimisticOptimizations.ALL, getProfilingInfo(graph), getSpeculationLog(), getSuites(), getLIRSuites(), new CompilationResult(), CompilationResultBuilderFactory.Default); int lineSPs = 0; diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java Tue Mar 17 13:57:33 2015 +0100 @@ -30,7 +30,7 @@ import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; -import com.oracle.graal.java.*; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.phases.*; @@ -231,7 +231,8 @@ try (Scope s = Debug.scope("InliningTest", new DebugDumpScope(snippet))) { ResolvedJavaMethod method = getResolvedJavaMethod(snippet); StructuredGraph graph = eagerInfopointMode ? parseDebug(method, AllowAssumptions.YES) : parseEager(method, AllowAssumptions.YES); - PhaseSuite graphBuilderSuite = eagerInfopointMode ? getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault()) : getDefaultGraphBuilderSuite(); + PhaseSuite graphBuilderSuite = eagerInfopointMode ? getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault(getDefaultGraphBuilderPlugins())) + : getDefaultGraphBuilderSuite(); HighTierContext context = new HighTierContext(getProviders(), null, graphBuilderSuite, OptimisticOptimizations.ALL); Debug.dump(graph, "Graph"); new CanonicalizerPhase().apply(graph, context); diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysis.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysis.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysis.java Tue Mar 17 13:57:33 2015 +0100 @@ -29,6 +29,8 @@ import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.CallTargetNode.InvokeKind; import com.oracle.graal.nodes.*; @@ -222,7 +224,7 @@ * the code before static analysis, the classes would otherwise be not loaded * yet and the bytecode parser would only create a graph. */ - GraphBuilderConfiguration graphBuilderConfig = GraphBuilderConfiguration.getEagerDefault(); + GraphBuilderConfiguration graphBuilderConfig = GraphBuilderConfiguration.getEagerDefault(new Plugins(new InvocationPlugins(metaAccess))); /* * For simplicity, we ignore all exception handling during the static analysis. * This is a constraint of this example code, a real static analysis needs to diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GenericInvocationPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GenericInvocationPlugin.java Tue Mar 17 13:57:33 2015 +0100 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2015, 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.graphbuilderconf; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; + +/** + * Plugin for handling an invocation based on some property of the method being invoked such as any + * annotations it may have. + */ +public interface GenericInvocationPlugin extends GraphBuilderPlugin { + /** + * Executes this plugin for an invocation of a given method with a given set of arguments. + * + * @return {@code true} if this plugin handled the invocation, {@code false} if not + */ + boolean apply(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args); +} diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderConfiguration.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderConfiguration.java Tue Mar 17 13:57:33 2015 +0100 @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2011, 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.graphbuilderconf; + +import java.util.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.nodes.*; + +public class GraphBuilderConfiguration { + + public static class Plugins { + private final InvocationPlugins invocationPlugins; + private LoadFieldPlugin loadFieldPlugin; + private LoadIndexedPlugin loadIndexedPlugin; + private ParameterPlugin parameterPlugin; + private InlineInvokePlugin inlineInvokePlugin; + private GenericInvocationPlugin genericInvocationPlugin; + private LoopExplosionPlugin loopExplosionPlugin; + + /** + * Creates a copy of a given set of plugins. The {@link InvocationPlugins} in + * {@code copyFrom} become the {@linkplain InvocationPlugins#getParent() default} + * {@linkplain #getInvocationPlugins() invocation plugins} in this object. + */ + public Plugins(Plugins copyFrom) { + this.invocationPlugins = new InvocationPlugins(copyFrom.invocationPlugins); + this.parameterPlugin = copyFrom.parameterPlugin; + this.loadFieldPlugin = copyFrom.loadFieldPlugin; + this.loadIndexedPlugin = copyFrom.loadIndexedPlugin; + this.inlineInvokePlugin = copyFrom.inlineInvokePlugin; + this.loopExplosionPlugin = copyFrom.loopExplosionPlugin; + this.genericInvocationPlugin = copyFrom.genericInvocationPlugin; + } + + /** + * Creates a new set of plugins. + * + * @param invocationPlugins the {@linkplain #getInvocationPlugins() invocation plugins} in + * this object + */ + public Plugins(InvocationPlugins invocationPlugins) { + this.invocationPlugins = invocationPlugins; + } + + public InvocationPlugins getInvocationPlugins() { + return invocationPlugins; + } + + public GenericInvocationPlugin getGenericInvocationPlugin() { + return genericInvocationPlugin; + } + + public void setGenericInvocationPlugin(GenericInvocationPlugin plugin) { + this.genericInvocationPlugin = plugin; + } + + public LoadFieldPlugin getLoadFieldPlugin() { + return loadFieldPlugin; + } + + public void setLoadFieldPlugin(LoadFieldPlugin plugin) { + this.loadFieldPlugin = plugin; + } + + public LoadIndexedPlugin getLoadIndexedPlugin() { + return loadIndexedPlugin; + } + + public void setLoadIndexedPlugin(LoadIndexedPlugin plugin) { + this.loadIndexedPlugin = plugin; + } + + public ParameterPlugin getParameterPlugin() { + return parameterPlugin; + } + + public void setParameterPlugin(ParameterPlugin plugin) { + this.parameterPlugin = plugin; + } + + public InlineInvokePlugin getInlineInvokePlugin() { + return inlineInvokePlugin; + } + + public void setInlineInvokePlugin(InlineInvokePlugin plugin) { + this.inlineInvokePlugin = plugin; + } + + public LoopExplosionPlugin getLoopExplosionPlugin() { + return loopExplosionPlugin; + } + + public void setLoopExplosionPlugin(LoopExplosionPlugin plugin) { + this.loopExplosionPlugin = plugin; + } + } + + private static final ResolvedJavaType[] EMPTY = new ResolvedJavaType[]{}; + + private final boolean eagerResolving; + private final boolean omitAllExceptionEdges; + private final ResolvedJavaType[] skippedExceptionTypes; + private final DebugInfoMode debugInfoMode; + private final boolean doLivenessAnalysis; + private boolean useProfiling; + private final Plugins plugins; + + public static enum DebugInfoMode { + SafePointsOnly, + /** + * This mode inserts {@link SimpleInfopointNode}s in places where no safepoints would be + * inserted: inlining boundaries, and line number switches. + *

+ * In this mode the infopoint only have a location (method and bytecode index) and no + * values. + *

+ * This is useful to have better program counter to bci mapping and has no influence on the + * generated code. However it can increase the amount of metadata and does not allow access + * to accessing values at runtime. + */ + Simple, + /** + * In this mode, {@link FullInfopointNode}s are generated in the same locations as in + * {@link #Simple} mode but the infopoints have access to the runtime values. + *

+ * This is relevant when code is to be generated for native, machine-code level debugging + * but can have a limit the amount of optimization applied to the code. + */ + Full, + } + + protected GraphBuilderConfiguration(boolean eagerResolving, boolean omitAllExceptionEdges, DebugInfoMode debugInfoMode, ResolvedJavaType[] skippedExceptionTypes, boolean doLivenessAnalysis, + Plugins plugins) { + this.eagerResolving = eagerResolving; + this.omitAllExceptionEdges = omitAllExceptionEdges; + this.debugInfoMode = debugInfoMode; + this.skippedExceptionTypes = skippedExceptionTypes; + this.doLivenessAnalysis = doLivenessAnalysis; + this.useProfiling = true; + this.plugins = plugins; + } + + /** + * Creates a copy of this configuration with all its plugins. The {@link InvocationPlugins} in + * this configuration become the {@linkplain InvocationPlugins#getParent() parent} of the + * {@link InvocationPlugins} in the copy. + */ + public GraphBuilderConfiguration copy() { + Plugins newPlugins = new Plugins(new InvocationPlugins(plugins.getInvocationPlugins())); + GraphBuilderConfiguration result = new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, doLivenessAnalysis, newPlugins); + result.useProfiling = useProfiling; + return result; + } + + public boolean getUseProfiling() { + return useProfiling; + } + + public void setUseProfiling(boolean b) { + this.useProfiling = b; + } + + public GraphBuilderConfiguration withSkippedExceptionTypes(ResolvedJavaType[] newSkippedExceptionTypes) { + return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, newSkippedExceptionTypes, doLivenessAnalysis, plugins); + } + + public GraphBuilderConfiguration withOmitAllExceptionEdges(boolean newOmitAllExceptionEdges) { + return new GraphBuilderConfiguration(eagerResolving, newOmitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, doLivenessAnalysis, plugins); + } + + public GraphBuilderConfiguration withDebugInfoMode(DebugInfoMode newDebugInfoMode) { + ResolvedJavaType[] newSkippedExceptionTypes = skippedExceptionTypes == EMPTY ? EMPTY : Arrays.copyOf(skippedExceptionTypes, skippedExceptionTypes.length); + return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, newDebugInfoMode, newSkippedExceptionTypes, doLivenessAnalysis, plugins); + } + + public GraphBuilderConfiguration withDoLivenessAnalysis(boolean newLivenessAnalysis) { + return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, newLivenessAnalysis, plugins); + } + + public ResolvedJavaType[] getSkippedExceptionTypes() { + return skippedExceptionTypes; + } + + public boolean eagerResolving() { + return eagerResolving; + } + + public boolean omitAllExceptionEdges() { + return omitAllExceptionEdges; + } + + public boolean insertNonSafepointDebugInfo() { + return debugInfoMode.ordinal() >= DebugInfoMode.Simple.ordinal(); + } + + public boolean insertFullDebugInfo() { + return debugInfoMode.ordinal() >= DebugInfoMode.Full.ordinal(); + } + + public boolean doLivenessAnalysis() { + return doLivenessAnalysis; + } + + public static GraphBuilderConfiguration getDefault(Plugins plugins) { + return new GraphBuilderConfiguration(false, false, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptLivenessAnalysis.getValue(), plugins); + } + + public static GraphBuilderConfiguration getEagerDefault(Plugins plugins) { + return new GraphBuilderConfiguration(true, false, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptLivenessAnalysis.getValue(), plugins); + } + + public static GraphBuilderConfiguration getSnippetDefault(Plugins plugins) { + return new GraphBuilderConfiguration(true, true, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptLivenessAnalysis.getValue(), plugins); + } + + public static GraphBuilderConfiguration getFullDebugDefault(Plugins plugins) { + return new GraphBuilderConfiguration(true, false, DebugInfoMode.Full, EMPTY, GraalOptions.OptLivenessAnalysis.getValue(), plugins); + } + + /** + * Returns {@code true} if it is an error for a class/field/method resolution to fail. The + * default is the same result as returned by {@link #eagerResolving()}. However, it may be + * overridden to allow failure even when {@link #eagerResolving} is {@code true}. + */ + public boolean unresolvedIsError() { + return eagerResolving; + } + + public Plugins getPlugins() { + return plugins; + } +} diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderContext.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderContext.java Tue Mar 17 13:57:33 2015 +0100 @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2015, 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.graphbuilderconf; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; + +/** + * Used by a {@link GraphBuilderPlugin} to interface with a graph builder object. + */ +public interface GraphBuilderContext { + + /** + * Information about a snippet or method substitution currently being processed by the graph + * builder. When in the scope of a replacement, the graph builder does not check the value kinds + * flowing through the JVM state since replacements can employ non-Java kinds to represent + * values such as raw machine words and pointers. + */ + public interface Replacement { + + /** + * Gets the method being replaced. + */ + ResolvedJavaMethod getOriginalMethod(); + + /** + * Gets the replacement method. + */ + ResolvedJavaMethod getReplacementMethod(); + + /** + * Determines if this replacement is being inlined as a compiler intrinsic. A compiler + * intrinsic is atomic with respect to deoptimization. Deoptimization within a compiler + * intrinsic will restart the interpreter at the intrinsified call. + */ + boolean isIntrinsic(); + } + + T append(T fixed); + + T append(T fixed); + + T append(T fixed); + + T append(T value); + + T append(T value); + + StampProvider getStampProvider(); + + MetaAccessProvider getMetaAccess(); + + Assumptions getAssumptions(); + + ConstantReflectionProvider getConstantReflection(); + + SnippetReflectionProvider getSnippetReflection(); + + void push(Kind kind, ValueNode value); + + StructuredGraph getGraph(); + + FrameState createStateAfter(); + + /** + * Gets the parsing context for the method that inlines the method being parsed by this context. + */ + GraphBuilderContext getParent(); + + /** + * Gets the root method for the graph building process. + */ + ResolvedJavaMethod getRootMethod(); + + /** + * Gets the method currently being parsed. + */ + ResolvedJavaMethod getMethod(); + + /** + * Gets the index of the bytecode instruction currently being parsed. + */ + int bci(); + + /** + * Gets the inline depth of this context. 0 implies this is the context for the + * {@linkplain #getRootMethod() root method}. + */ + int getDepth(); + + /** + * Determines if the current parsing context is a snippet or method substitution. + */ + default boolean parsingReplacement() { + return getReplacement() == null; + } + + /** + * Gets the replacement of the current parsing context or {@code null} if not + * {@link #parsingReplacement() parsing a replacement}. + */ + Replacement getReplacement(); + + /** + * @see GuardingPiNode#nullCheckedValue(ValueNode) + */ + static ValueNode nullCheckedValue(GraphBuilderContext builder, ValueNode value) { + ValueNode nonNullValue = GuardingPiNode.nullCheckedValue(value); + if (nonNullValue != value) { + builder.append((FixedWithNextNode) nonNullValue); + } + return nonNullValue; + } + + boolean eagerResolving(); + + BailoutException bailout(String string); +} diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderPlugin.java Tue Mar 17 13:57:33 2015 +0100 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2015, 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.graphbuilderconf; + +/** + * Marker interface for graph builder plugins. + */ +public interface GraphBuilderPlugin { +} diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InlineInvokePlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InlineInvokePlugin.java Tue Mar 17 13:57:33 2015 +0100 @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2015, 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.graphbuilderconf; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; + +/** + * Plugin for specifying what is inlined during graph parsing or for post-processing non-inlined + * invocations that result in {@link Invoke} nodes. + */ +public interface InlineInvokePlugin extends GraphBuilderPlugin { + + public static class InlineInfo { + + /** + * The method to be inlined. + */ + public final ResolvedJavaMethod methodToInline; + + /** + * Specifies if {@link #methodToInline} is to be considered a + * {@linkplain GraphBuilderContext.Replacement replacement} for the {@code method} passed to + * {@link InlineInvokePlugin#getInlineInfo}. + */ + public final boolean isReplacement; + + /** + * Specifies if {@link #methodToInline} is an intrinsic for the original method. If so, any + * {@link StateSplit} node created in the (recursive) inlining scope will be given a frame + * state that restarts the interpreter just before the intrinsified invocation. + */ + public final boolean isIntrinsic; + + public InlineInfo(ResolvedJavaMethod methodToInline, boolean isReplacement, boolean isIntrinsic) { + this.methodToInline = methodToInline; + this.isIntrinsic = isIntrinsic; + this.isReplacement = isReplacement; + assert !isIntrinsic || isReplacement : "cannot be an intrinsic without also being a replacement"; + } + } + + /** + * Determines whether a call to a given method is to be inlined. + * + * @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) { + return null; + } + + /** + * @param inlinedTargetMethod + */ + default void postInline(ResolvedJavaMethod inlinedTargetMethod) { + } + + /** + * Notifies this plugin of the {@link Invoke} node created for a method that was not inlined per + * {@link #getInlineInfo}. + * + * @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) { + } +} diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugin.java Tue Mar 17 13:57:33 2015 +0100 @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2015, 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.graphbuilderconf; + +import java.lang.reflect.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.nodes.*; + +/** + * Plugin for handling a specific method invocation. + */ +public interface InvocationPlugin extends GraphBuilderPlugin { + + /** + * @see #execute + */ + default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod) { + throw invalidHandler(b, targetMethod); + } + + /** + * @see #execute + */ + default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode arg) { + throw invalidHandler(b, targetMethod, arg); + } + + /** + * @see #execute + */ + default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode arg1, ValueNode arg2) { + throw invalidHandler(b, targetMethod, arg1, arg2); + } + + /** + * @see #execute + */ + default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode arg1, ValueNode arg2, ValueNode arg3) { + throw invalidHandler(b, targetMethod, arg1, arg2, arg3); + } + + /** + * @see #execute + */ + default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode arg1, ValueNode arg2, ValueNode arg3, ValueNode arg4) { + throw invalidHandler(b, targetMethod, arg1, arg2, arg3, arg4); + } + + /** + * @see #execute + */ + default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode arg1, ValueNode arg2, ValueNode arg3, ValueNode arg4, ValueNode arg5) { + throw invalidHandler(b, targetMethod, arg1, arg2, arg3, arg4, arg5); + } + + default ResolvedJavaMethod getSubstitute() { + return null; + } + + /** + * Executes a given plugin against a set of invocation arguments by dispatching to the + * {@code apply(...)} method that matches the number of arguments. + * + * @param targetMethod the method for which plugin is being applied + * @return {@code true} if the plugin handled the invocation of {@code targetMethod} + * {@code false} if the graph builder should process the invoke further (e.g., by + * inlining it or creating an {@link Invoke} node). A plugin that does not handle an + * invocation must not modify the graph being constructed. + */ + static boolean execute(GraphBuilderContext b, ResolvedJavaMethod targetMethod, InvocationPlugin plugin, ValueNode[] args) { + if (args.length == 0) { + return plugin.apply(b, targetMethod); + } else if (args.length == 1) { + return plugin.apply(b, targetMethod, args[0]); + } else if (args.length == 2) { + return plugin.apply(b, targetMethod, args[0], args[1]); + } else if (args.length == 3) { + return plugin.apply(b, targetMethod, args[0], args[1], args[2]); + } else if (args.length == 4) { + return plugin.apply(b, targetMethod, args[0], args[1], args[2], args[3]); + } else if (args.length == 5) { + return plugin.apply(b, targetMethod, args[0], args[1], args[2], args[3], args[4]); + } else { + throw plugin.invalidHandler(b, targetMethod, args); + } + } + + default Error invalidHandler(@SuppressWarnings("unused") GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode... args) { + return new GraalInternalError("Invocation plugin for %s does not handle invocations with %d arguments", targetMethod.format("%H.%n(%p)"), args.length); + } + + default StackTraceElement getApplySourceLocation(MetaAccessProvider metaAccess) { + Class c = getClass(); + for (Method m : c.getDeclaredMethods()) { + if (m.getName().equals("apply")) { + return metaAccess.lookupJavaMethod(m).asStackTraceElement(0); + } + } + throw new GraalInternalError("could not find method named \"apply\" in " + c.getName()); + } +} diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPluginIdHolder.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPluginIdHolder.java Tue Mar 17 13:57:33 2015 +0100 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2015, 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.graphbuilderconf; + +import com.oracle.graal.api.meta.*; + +/** + * {@link ResolvedJavaMethod}s that can assign themselves an identifier for use in a side table + * mapping methods to {@link InvocationPlugin}s. + */ +public interface InvocationPluginIdHolder extends ResolvedJavaMethod { + /** + * Sets the unique, positive, non-zero identifier for this method. + */ + void setInvocationPluginId(int id); + + /** + * Gets the identifier set by {@link #setInvocationPluginId(int)} or 0 if no + * {@link InvocationPlugin} identifier was assigned to this method. + */ + int getInvocationPluginId(); +} diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java Tue Mar 17 13:57:33 2015 +0100 @@ -0,0 +1,388 @@ +/* + * Copyright (c) 2015, 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.graphbuilderconf; + +import static java.lang.String.*; + +import java.lang.reflect.*; +import java.util.*; +import java.util.stream.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.nodes.*; + +/** + * Manages a set of {@link InvocationPlugin}s. + */ +public class InvocationPlugins { + + /** + * Sentinel class for use with + * {@link InvocationPlugins#register(InvocationPlugin, Class, String, Class...)} to denote the + * receiver argument for a non-static method. + */ + public static final class Receiver { + private Receiver() { + throw GraalInternalError.shouldNotReachHere(); + } + } + + /** + * Utility for + * {@linkplain InvocationPlugins#register(InvocationPlugin, Class, String, Class...) + * registration} of invocation plugins. + */ + public static class Registration { + + private final InvocationPlugins plugins; + private final Class declaringClass; + + /** + * Creates an object for registering {@link InvocationPlugin}s for methods declared by a + * given class. + * + * @param plugins where to register the plugins + * @param declaringClass the class declaring the methods for which plugins will be + * registered via this object + */ + public Registration(InvocationPlugins plugins, Class declaringClass) { + this.plugins = plugins; + this.declaringClass = declaringClass; + } + + /** + * Registers a plugin for a method with no arguments. + * + * @param name the name of the method + * @param plugin the plugin to be registered + */ + public void register0(String name, InvocationPlugin plugin) { + plugins.register(plugin, declaringClass, name); + } + + /** + * Registers a plugin for a method with 1 argument. + * + * @param name the name of the method + * @param plugin the plugin to be registered + */ + public void register1(String name, Class arg, InvocationPlugin plugin) { + plugins.register(plugin, declaringClass, name, arg); + } + + /** + * Registers a plugin for a method with 2 arguments. + * + * @param name the name of the method + * @param plugin the plugin to be registered + */ + public void register2(String name, Class arg1, Class arg2, InvocationPlugin plugin) { + plugins.register(plugin, declaringClass, name, arg1, arg2); + } + + /** + * Registers a plugin for a method with 3 arguments. + * + * @param name the name of the method + * @param plugin the plugin to be registered + */ + public void register3(String name, Class arg1, Class arg2, Class arg3, InvocationPlugin plugin) { + plugins.register(plugin, declaringClass, name, arg1, arg2, arg3); + } + + /** + * Registers a plugin for a method with 4 arguments. + * + * @param name the name of the method + * @param plugin the plugin to be registered + */ + public void register4(String name, Class arg1, Class arg2, Class arg3, Class arg4, InvocationPlugin plugin) { + plugins.register(plugin, declaringClass, name, arg1, arg2, arg3, arg4); + } + + /** + * Registers a plugin for a method with 5 arguments. + * + * @param name the name of the method + * @param plugin the plugin to be registered + */ + public void register5(String name, Class arg1, Class arg2, Class arg3, Class arg4, Class arg5, InvocationPlugin plugin) { + plugins.register(plugin, declaringClass, name, arg1, arg2, arg3, arg4, arg5); + } + } + + static final class MethodInfo { + final boolean isStatic; + final Class declaringClass; + final String name; + final Class[] argumentTypes; + final InvocationPlugin plugin; + + int id; + + MethodInfo(InvocationPlugin plugin, Class declaringClass, String name, Class... argumentTypes) { + this.plugin = plugin; + this.isStatic = argumentTypes.length == 0 || argumentTypes[0] != Receiver.class; + this.declaringClass = declaringClass; + this.name = name; + this.argumentTypes = argumentTypes; + if (!isStatic) { + argumentTypes[0] = declaringClass; + } + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof MethodInfo) { + MethodInfo that = (MethodInfo) obj; + boolean res = this.name.equals(that.name) && this.declaringClass.equals(that.declaringClass) && Arrays.equals(this.argumentTypes, that.argumentTypes); + assert !res || this.isStatic == that.isStatic; + return res; + } + return false; + } + + @Override + public int hashCode() { + // Replay compilation mandates use of stable hash codes + return declaringClass.getName().hashCode() ^ name.hashCode(); + } + + ResolvedJavaMethod resolve(MetaAccessProvider metaAccess) { + try { + ResolvedJavaMethod method; + Class[] parameterTypes = isStatic ? argumentTypes : Arrays.copyOfRange(argumentTypes, 1, argumentTypes.length); + if (name.equals("")) { + method = metaAccess.lookupJavaMethod(declaringClass.getDeclaredConstructor(parameterTypes)); + } else { + method = metaAccess.lookupJavaMethod(declaringClass.getDeclaredMethod(name, parameterTypes)); + } + assert method.isStatic() == isStatic; + return method; + } catch (NoSuchMethodException | SecurityException e) { + throw new GraalInternalError(e); + } + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(declaringClass.getName()).append('.').append(name).append('('); + for (Class p : argumentTypes) { + if (sb.charAt(sb.length() - 1) != '(') { + sb.append(", "); + } + sb.append(p.getSimpleName()); + } + return sb.append(')').toString(); + } + } + + protected final MetaAccessProvider metaAccess; + private final List registrations; + private final Thread registrationThread; + + /** + * The minimum {@linkplain InvocationPluginIdHolder#getInvocationPluginId() id} for a method + * associated with a plugin in {@link #plugins}. + */ + private int minId = Integer.MAX_VALUE; + + /** + * Resolved methods to plugins map. The keys (i.e., indexes) are derived from + * {@link InvocationPluginIdHolder#getInvocationPluginId()}. + */ + private volatile InvocationPlugin[] plugins; + + /** + * The plugins {@linkplain #lookupInvocation(ResolvedJavaMethod) searched} before searching in + * this object. + */ + private InvocationPlugins parent; + + private InvocationPlugins(InvocationPlugins parent, MetaAccessProvider metaAccess, int estimatePluginCount) { + this.registrationThread = Thread.currentThread(); + this.metaAccess = metaAccess; + this.registrations = new ArrayList<>(estimatePluginCount); + InvocationPlugins p = parent; + // Only adopt a non-empty parent + while (p != null && p.size() == 0) { + p = p.parent; + } + this.parent = p; + } + + private static final int DEFAULT_ESTIMATE_PLUGIN_COUNT = 16; + + /** + * Creates a set of invocation plugins with a non-null {@linkplain #getParent() parent}. + */ + public InvocationPlugins(InvocationPlugins parent) { + this(parent, parent.metaAccess, DEFAULT_ESTIMATE_PLUGIN_COUNT); + } + + public InvocationPlugins(MetaAccessProvider metaAccess) { + this(metaAccess, DEFAULT_ESTIMATE_PLUGIN_COUNT); + } + + public InvocationPlugins(MetaAccessProvider metaAccess, int estimatePluginCount) { + this(null, metaAccess, estimatePluginCount); + } + + /** + * Registers an invocation plugin for a given method. There must be no plugin currently + * registered for {@code method}. + */ + public void register(InvocationPlugin plugin, Class declaringClass, String name, Class... argumentTypes) { + assert Thread.currentThread() == registrationThread : "invocation plugin registration must be single threaded"; + MethodInfo methodInfo = new MethodInfo(plugin, declaringClass, name, argumentTypes); + assert Checker.check(this, methodInfo, plugin); + assert plugins == null : "invocation plugin registration is closed"; + registrations.add(methodInfo); + } + + private static int nextInvocationPluginId = 1; + + /** + * Gets the plugin for a given method. + * + * @param method the method to lookup + * @return the plugin associated with {@code method} or {@code null} if none exists + */ + public InvocationPlugin lookupInvocation(ResolvedJavaMethod method) { + assert method instanceof InvocationPluginIdHolder; + if (parent != null) { + InvocationPlugin plugin = parent.lookupInvocation(method); + if (plugin != null) { + return plugin; + } + } + InvocationPluginIdHolder pluggable = (InvocationPluginIdHolder) method; + if (plugins == null) { + // Must synchronize across all InvocationPlugins objects to ensure thread safe + // allocation of InvocationPlugin identifiers + synchronized (InvocationPlugins.class) { + if (plugins == null) { + if (registrations.isEmpty()) { + plugins = new InvocationPlugin[0]; + } else { + int max = Integer.MIN_VALUE; + for (MethodInfo methodInfo : registrations) { + InvocationPluginIdHolder p = (InvocationPluginIdHolder) methodInfo.resolve(metaAccess); + int id = p.getInvocationPluginId(); + if (id == 0) { + id = nextInvocationPluginId++; + p.setInvocationPluginId(id); + } + if (id < minId) { + minId = id; + } + if (id > max) { + max = id; + + } + methodInfo.id = id; + } + + int length = (max - minId) + 1; + plugins = new InvocationPlugin[length]; + for (MethodInfo m : registrations) { + int index = m.id - minId; + plugins[index] = m.plugin; + } + } + } + } + } + + int id = pluggable.getInvocationPluginId(); + int index = id - minId; + return index >= 0 && index < plugins.length ? plugins[index] : null; + } + + /** + * Gets the invocation plugins {@linkplain #lookupInvocation(ResolvedJavaMethod) searched} + * before searching in this object. + */ + public InvocationPlugins getParent() { + return parent; + } + + @Override + public String toString() { + return registrations.stream().map(MethodInfo::toString).collect(Collectors.joining(", ")) + " / parent: " + this.parent; + } + + private static class Checker { + private static final int MAX_ARITY = 5; + /** + * The set of all {@link InvocationPlugin#apply} method signatures. + */ + static final Class[][] SIGS; + static { + ArrayList[]> sigs = new ArrayList<>(MAX_ARITY); + for (Method method : InvocationPlugin.class.getDeclaredMethods()) { + if (!Modifier.isStatic(method.getModifiers()) && method.getName().equals("apply")) { + Class[] sig = method.getParameterTypes(); + assert sig[0] == GraphBuilderContext.class; + assert sig[1] == ResolvedJavaMethod.class; + assert Arrays.asList(Arrays.copyOfRange(sig, 2, sig.length)).stream().allMatch(c -> c == ValueNode.class); + while (sigs.size() < sig.length - 1) { + sigs.add(null); + } + sigs.set(sig.length - 2, sig); + } + } + assert sigs.indexOf(null) == -1 : format("need to add an apply() method to %s that takes %d %s arguments ", InvocationPlugin.class.getName(), sigs.indexOf(null), + ValueNode.class.getSimpleName()); + SIGS = sigs.toArray(new Class[sigs.size()][]); + } + + public static boolean check(InvocationPlugins plugins, MethodInfo method, InvocationPlugin plugin) { + InvocationPlugins p = plugins; + while (p != null) { + assert !p.registrations.contains(method) : "a plugin is already registered for " + method; + p = p.parent; + } + int arguments = method.argumentTypes.length; + assert arguments < SIGS.length : format("need to extend %s to support method with %d arguments: %s", InvocationPlugin.class.getSimpleName(), arguments, method); + for (Method m : plugin.getClass().getDeclaredMethods()) { + if (m.getName().equals("apply")) { + Class[] parameterTypes = m.getParameterTypes(); + if (Arrays.equals(SIGS[arguments], parameterTypes)) { + return true; + } + } + } + throw new AssertionError(format("graph builder plugin for %s not found", method)); + } + } + + public MetaAccessProvider getMetaAccess() { + return metaAccess; + } + + public int size() { + return registrations.size(); + } +} diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/LoadFieldPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/LoadFieldPlugin.java Tue Mar 17 13:57:33 2015 +0100 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015, 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.graphbuilderconf; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; + +public interface LoadFieldPlugin extends GraphBuilderPlugin { + @SuppressWarnings("unused") + default boolean apply(GraphBuilderContext b, ValueNode receiver, ResolvedJavaField field) { + return false; + } + + @SuppressWarnings("unused") + default boolean apply(GraphBuilderContext graphBuilderContext, ResolvedJavaField staticField) { + return false; + } + + default boolean tryConstantFold(GraphBuilderContext b, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ResolvedJavaField field, JavaConstant receiver) { + JavaConstant result = constantReflection.readConstantFieldValue(field, receiver); + if (result != null) { + ConstantNode constantNode = b.append(ConstantNode.forConstant(result, metaAccess)); + b.push(constantNode.getKind().getStackKind(), constantNode); + return true; + } + return false; + } +} diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/LoadIndexedPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/LoadIndexedPlugin.java Tue Mar 17 13:57:33 2015 +0100 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2015, 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.graphbuilderconf; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; + +public interface LoadIndexedPlugin extends GraphBuilderPlugin { + @SuppressWarnings("unused") + default boolean apply(GraphBuilderContext b, ValueNode array, ValueNode index, Kind elementKind) { + return false; + } +} diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/LoopExplosionPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/LoopExplosionPlugin.java Tue Mar 17 13:57:33 2015 +0100 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2015, 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.graphbuilderconf; + +import com.oracle.graal.api.meta.*; + +public interface LoopExplosionPlugin extends GraphBuilderPlugin { + boolean shouldExplodeLoops(ResolvedJavaMethod method); + + boolean shouldMergeExplosions(ResolvedJavaMethod method); +} diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/ParameterPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/ParameterPlugin.java Tue Mar 17 13:57:33 2015 +0100 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2015, 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.graphbuilderconf; + +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.nodes.calc.*; + +public interface ParameterPlugin extends GraphBuilderPlugin { + FloatingNode interceptParameter(GraphBuilderContext b, int index, Stamp stamp); +} diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Tue Mar 17 13:57:33 2015 +0100 @@ -31,9 +31,10 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.api.runtime.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.hotspot.word.*; import com.oracle.graal.phases.util.*; @ServiceProvider(HotSpotBackendFactory.class) @@ -124,9 +125,11 @@ HotSpotMetaAccessProvider metaAccess; HotSpotLoweringProvider lowerer; HotSpotSnippetReflectionProvider snippetReflection; - Replacements replacements; + HotSpotReplacementsImpl replacements; HotSpotDisassemblerProvider disassembler; HotSpotSuitesProvider suites; + HotSpotWordTypes wordTypes; + Plugins plugins; try (InitTimer t = timer("create providers")) { try (InitTimer rt = timer("create HotSpotRegisters provider")) { registers = createRegisters(); @@ -152,7 +155,8 @@ try (InitTimer rt = timer("create Lowerer provider")) { lowerer = createLowerer(runtime, metaAccess, foreignCalls, registers, target); } - Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null, new HotSpotStampProvider()); + HotSpotStampProvider stampProvider = new HotSpotStampProvider(); + Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null, stampProvider); try (InitTimer rt = timer("create SnippetReflection provider")) { snippetReflection = createSnippetReflection(runtime); @@ -163,10 +167,17 @@ try (InitTimer rt = timer("create Disassembler provider")) { disassembler = createDisassembler(runtime); } + try (InitTimer rt = timer("create WordTypes")) { + wordTypes = new HotSpotWordTypes(metaAccess, target.wordKind); + } + try (InitTimer rt = timer("create GraphBuilderPhase plugins")) { + plugins = HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch); + replacements.setGraphBuilderPlugins(plugins); + } try (InitTimer rt = timer("create Suites provider")) { - suites = createSuites(runtime); + suites = createSuites(runtime, plugins); } - providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, snippetReflection); + providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, snippetReflection, wordTypes, plugins); } try (InitTimer rt = timer("instantiate backend")) { return createBackend(runtime, providers); @@ -185,7 +196,7 @@ return new HotSpotDisassemblerProvider(runtime); } - protected Replacements createReplacements(HotSpotGraalRuntimeProvider runtime, Providers p, SnippetReflectionProvider snippetReflection) { + protected HotSpotReplacementsImpl createReplacements(HotSpotGraalRuntimeProvider runtime, Providers p, SnippetReflectionProvider snippetReflection) { return new HotSpotReplacementsImpl(p, snippetReflection, runtime.getConfig(), p.getCodeCache().getTarget()); } @@ -210,8 +221,8 @@ return new HotSpotMetaAccessProvider(runtime); } - protected HotSpotSuitesProvider createSuites(HotSpotGraalRuntimeProvider runtime) { - return new HotSpotSuitesProvider(runtime); + protected HotSpotSuitesProvider createSuites(HotSpotGraalRuntimeProvider runtime, Plugins plugins) { + return new HotSpotSuitesProvider(runtime, plugins); } protected HotSpotSnippetReflectionProvider createSnippetReflection(HotSpotGraalRuntimeProvider runtime) { @@ -249,15 +260,15 @@ } else { /* * System V Application Binary Interface, AMD64 Architecture Processor Supplement - * + * * Draft Version 0.96 - * + * * http://www.uclibc.org/docs/psABI-x86_64.pdf - * + * * 3.2.1 - * + * * ... - * + * * This subsection discusses usage of each register. Registers %rbp, %rbx and %r12 * through %r15 "belong" to the calling function and the called function is required to * preserve their values. In other words, a called function must preserve these diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Tue Mar 17 13:57:33 2015 +0100 @@ -27,8 +27,10 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.word.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.sparc.*; @@ -60,18 +62,23 @@ Value[] nativeABICallerSaveRegisters = createNativeABICallerSaveRegisters(runtime.getConfig(), codeCache.getRegisterConfig()); HotSpotForeignCallsProvider foreignCalls = new SPARCHotSpotForeignCallsProvider(runtime, metaAccess, codeCache, nativeABICallerSaveRegisters); LoweringProvider lowerer = createLowerer(runtime, metaAccess, foreignCalls, registers, target); - Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null, new HotSpotStampProvider()); + HotSpotStampProvider stampProvider = new HotSpotStampProvider(); + Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null, stampProvider); HotSpotSnippetReflectionProvider snippetReflection = new HotSpotSnippetReflectionProvider(runtime); HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, snippetReflection, runtime.getConfig(), target); HotSpotDisassemblerProvider disassembler = new HotSpotDisassemblerProvider(runtime); - HotSpotSuitesProvider suites = createSuites(runtime); - HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, snippetReflection); + HotSpotWordTypes wordTypes = new HotSpotWordTypes(metaAccess, target.wordKind); + Plugins plugins = HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch); + replacements.setGraphBuilderPlugins(plugins); + HotSpotSuitesProvider suites = createSuites(runtime, plugins); + HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, snippetReflection, + wordTypes, plugins); return createBackend(runtime, providers); } - protected HotSpotSuitesProvider createSuites(HotSpotGraalRuntimeProvider runtime) { - return new HotSpotSuitesProvider(runtime); + protected HotSpotSuitesProvider createSuites(HotSpotGraalRuntimeProvider runtime, Plugins plugins) { + return new HotSpotSuitesProvider(runtime, plugins); } protected HotSpotCodeCacheProvider createCodeCache(HotSpotGraalRuntimeProvider runtime, TargetDescription target, RegisterConfig regConfig) { diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Tue Mar 17 13:57:33 2015 +0100 @@ -251,7 +251,7 @@ StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO); HighTierContext highContext = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); MidTierContext midContext = new MidTierContext(getProviders(), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo(), null); - new NodeIntrinsificationPhase(getProviders(), getSnippetReflection()).apply(graph); + new NodeIntrinsificationPhase(getMetaAccess(), getConstantReflection(), getSnippetReflection(), getProviders().getForeignCalls(), getProviders().getStampProvider()).apply(graph); new InliningPhase(new InlineEverythingPolicy(), new CanonicalizerPhase()).apply(graph, highContext); new CanonicalizerPhase().apply(graph, highContext); new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highContext); diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java Tue Mar 17 13:57:33 2015 +0100 @@ -31,8 +31,6 @@ import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.stubs.*; -import com.oracle.graal.java.GraphBuilderConfiguration.Plugins; -import com.oracle.graal.java.*; import com.oracle.graal.nodes.spi.*; /** @@ -72,14 +70,6 @@ final HotSpotLoweringProvider lowerer = (HotSpotLoweringProvider) providers.getLowerer(); HotSpotReplacementsImpl replacements = (HotSpotReplacementsImpl) providers.getReplacements(); - try (InitTimer st = timer("graphBuilderPlugins.initialize")) { - Plugins plugins = HotSpotGraphBuilderPlugins.create(config, providers); - providers.setGraphBuilderPlugins(plugins); - GraphBuilderPhase phase = (GraphBuilderPhase) providers.getSuites().getDefaultGraphBuilderSuite().findPhase(GraphBuilderPhase.class).previous(); - phase.getGraphBuilderConfig().setPlugins(plugins); - replacements.completeInitialization(plugins); - } - try (InitTimer st = timer("foreignCalls.initialize")) { foreignCalls.initialize(providers, config); } diff -r 71f64b487b11 -r 1eea5182d102 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 Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Tue Mar 17 13:57:33 2015 +0100 @@ -22,21 +22,20 @@ */ package com.oracle.graal.hotspot.meta; +import static com.oracle.graal.graphbuilderconf.GraphBuilderContext.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; -import static com.oracle.graal.java.GraphBuilderContext.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; +import com.oracle.graal.graphbuilderconf.InvocationPlugins.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.hotspot.word.*; -import com.oracle.graal.java.GraphBuilderConfiguration.Plugins; -import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderPlugin.InvocationPlugin; -import com.oracle.graal.java.InvocationPlugins.Registration; -import com.oracle.graal.java.InvocationPlugins.Registration.Receiver; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.HeapAccess.BarrierType; import com.oracle.graal.nodes.extended.*; @@ -50,36 +49,45 @@ */ public class HotSpotGraphBuilderPlugins { + private static final int PLUGIN_COUNT_ESTIMATE = 160; + /** * Creates a {@link Plugins} object that should be used when running on HotSpot. + * + * @param constantReflection + * @param snippetReflection + * @param foreignCalls + * @param stampProvider */ - public static Plugins create(HotSpotVMConfig config, HotSpotProviders providers) { + public static Plugins create(HotSpotVMConfig config, HotSpotWordTypes wordTypes, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, + SnippetReflectionProvider snippetReflection, ForeignCallsProvider foreignCalls, StampProvider stampProvider, ReplacementsImpl replacements, Architecture arch) { - MetaAccessProvider metaAccess = providers.getMetaAccess(); - HotSpotWordTypes wordTypes = providers.getWordTypes(); - InvocationPlugins invocationPlugins = new HotSpotInvocationPlugins(config, metaAccess); + InvocationPlugins invocationPlugins = new HotSpotInvocationPlugins(config, metaAccess, PLUGIN_COUNT_ESTIMATE); Plugins plugins = new Plugins(invocationPlugins); - NodeIntrinsificationPhase nodeIntrinsification = new NodeIntrinsificationPhase(providers, providers.getSnippetReflection()); - ConstantReflectionProvider constantReflection = providers.getConstantReflection(); - HotSpotWordOperationPlugin wordOperationPlugin = new HotSpotWordOperationPlugin(providers.getSnippetReflection(), wordTypes); + NodeIntrinsificationPhase nodeIntrinsification = new NodeIntrinsificationPhase(metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider); + HotSpotWordOperationPlugin wordOperationPlugin = new HotSpotWordOperationPlugin(snippetReflection, wordTypes); plugins.setParameterPlugin(new HotSpotParameterPlugin(wordTypes)); plugins.setLoadFieldPlugin(new HotSpotLoadFieldPlugin(metaAccess, constantReflection)); plugins.setLoadIndexedPlugin(new HotSpotLoadIndexedPlugin(wordTypes)); - plugins.setInlineInvokePlugin(new HotSpotInlineInvokePlugin(nodeIntrinsification, (ReplacementsImpl) providers.getReplacements())); + plugins.setInlineInvokePlugin(new HotSpotInlineInvokePlugin(nodeIntrinsification, replacements)); plugins.setGenericInvocationPlugin(new DefaultGenericInvocationPlugin(nodeIntrinsification, wordOperationPlugin)); - registerObjectPlugins(invocationPlugins, metaAccess); - registerSystemPlugins(invocationPlugins, metaAccess, providers.getForeignCalls()); + registerObjectPlugins(invocationPlugins); + registerSystemPlugins(invocationPlugins, foreignCalls); registerThreadPlugins(invocationPlugins, metaAccess, wordTypes, config); - registerStableOptionPlugins(invocationPlugins, metaAccess); - StandardGraphBuilderPlugins.registerInvocationPlugins(providers.getMetaAccess(), providers.getCodeCache().target.arch, invocationPlugins, !config.useHeapProfiler); + registerStableOptionPlugins(invocationPlugins); + StandardGraphBuilderPlugins.registerInvocationPlugins(metaAccess, arch, invocationPlugins, !config.useHeapProfiler); + + int size = invocationPlugins.size(); + assert PLUGIN_COUNT_ESTIMATE >= size : String.format("adjust %s.PLUGIN_COUNT_ESTIMATE to be above or equal to %d", HotSpotGraphBuilderPlugins.class.getSimpleName(), size); + assert PLUGIN_COUNT_ESTIMATE - size < 20 : String.format("adjust %s.PLUGIN_COUNT_ESTIMATE to be closer to %d", HotSpotGraphBuilderPlugins.class.getSimpleName(), size); return plugins; } - private static void registerObjectPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess) { - Registration r = new Registration(plugins, metaAccess, Object.class); + private static void registerObjectPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, Object.class); r.register1("getClass", Receiver.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode rcvr) { ObjectStamp objectStamp = (ObjectStamp) rcvr.stamp(); @@ -97,8 +105,8 @@ }); } - private static void registerSystemPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls) { - Registration r = new Registration(plugins, metaAccess, System.class); + private static void registerSystemPlugins(InvocationPlugins plugins, ForeignCallsProvider foreignCalls) { + Registration r = new Registration(plugins, System.class); r.register0("currentTimeMillis", new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod) { ForeignCallNode foreignCall = new ForeignCallNode(foreignCalls, SystemSubstitutions.JAVA_TIME_MILLIS, StampFactory.forKind(Kind.Long)); @@ -118,7 +126,7 @@ } private static void registerThreadPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess, WordTypes wordTypes, HotSpotVMConfig config) { - Registration r = new Registration(plugins, metaAccess, Thread.class); + Registration r = new Registration(plugins, Thread.class); r.register0("currentThread", new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod) { CurrentJavaThreadNode thread = b.append(new CurrentJavaThreadNode(wordTypes.getWordKind())); @@ -133,8 +141,8 @@ }); } - private static void registerStableOptionPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess) { - Registration r = new Registration(plugins, metaAccess, StableOptionValue.class); + private static void registerStableOptionPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, StableOptionValue.class); r.register1("getValue", Receiver.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode rcvr) { if (rcvr.isConstant() && !rcvr.isNullConstant()) { diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInlineInvokePlugin.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInlineInvokePlugin.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInlineInvokePlugin.java Tue Mar 17 13:57:33 2015 +0100 @@ -28,10 +28,9 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.Node.NodeIntrinsic; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderContext.Replacement; import com.oracle.graal.hotspot.word.*; -import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderContext.Replacement; -import com.oracle.graal.java.GraphBuilderPlugin.InlineInvokePlugin; import com.oracle.graal.nodes.*; import com.oracle.graal.replacements.*; import com.oracle.graal.word.*; diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInvocationPlugins.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInvocationPlugins.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInvocationPlugins.java Tue Mar 17 13:57:33 2015 +0100 @@ -23,40 +23,38 @@ package com.oracle.graal.hotspot.meta; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderPlugin.*; -import com.oracle.graal.replacements.StandardGraphBuilderPlugins.*; +import com.oracle.graal.replacements.StandardGraphBuilderPlugins.BoxPlugin; /** * Extension of {@link InvocationPlugins} that disables plugins based on runtime configuration. */ final class HotSpotInvocationPlugins extends InvocationPlugins { final HotSpotVMConfig config; - final MetaAccessProvider metaAccess; - public HotSpotInvocationPlugins(HotSpotVMConfig config, MetaAccessProvider metaAccess) { + public HotSpotInvocationPlugins(HotSpotVMConfig config, MetaAccessProvider metaAccess, int estimatePluginCount) { + super(metaAccess, estimatePluginCount); this.config = config; - this.metaAccess = metaAccess; } @Override - public void register(ResolvedJavaMethod method, InvocationPlugin plugin) { + public void register(InvocationPlugin plugin, Class declaringClass, String name, Class... argumentTypes) { if (!config.usePopCountInstruction) { - if (method.getName().equals("bitCount")) { - assert method.getDeclaringClass().equals(metaAccess.lookupJavaType(Integer.class)) || method.getDeclaringClass().equals(metaAccess.lookupJavaType(Long.class)); + if (name.equals("bitCount")) { + assert declaringClass.equals(Integer.class) || declaringClass.equals(Long.class); return; } } if (!config.useCountLeadingZerosInstruction) { - if (method.getName().equals("numberOfLeadingZeros")) { - assert method.getDeclaringClass().equals(metaAccess.lookupJavaType(Integer.class)) || method.getDeclaringClass().equals(metaAccess.lookupJavaType(Long.class)); + if (name.equals("numberOfLeadingZeros")) { + assert declaringClass.equals(Integer.class) || declaringClass.equals(Long.class); return; } } if (!config.useCountTrailingZerosInstruction) { - if (method.getName().equals("numberOfTrailingZeros")) { - assert method.getDeclaringClass().equals(metaAccess.lookupJavaType(Integer.class)); + if (name.equals("numberOfTrailingZeros")) { + assert declaringClass.equals(Integer.class); return; } } @@ -67,6 +65,6 @@ return; } } - super.register(method, plugin); + super.register(plugin, declaringClass, name, argumentTypes); } } diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadFieldPlugin.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadFieldPlugin.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadFieldPlugin.java Tue Mar 17 13:57:33 2015 +0100 @@ -27,8 +27,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; -import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderPlugin.LoadFieldPlugin; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.nodes.*; public final class HotSpotLoadFieldPlugin implements LoadFieldPlugin { diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadIndexedPlugin.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadIndexedPlugin.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadIndexedPlugin.java Tue Mar 17 13:57:33 2015 +0100 @@ -24,11 +24,10 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.hotspot.word.*; -import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderPlugin.LoadIndexedPlugin; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.type.*; diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotParameterPlugin.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotParameterPlugin.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotParameterPlugin.java Tue Mar 17 13:57:33 2015 +0100 @@ -24,8 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderPlugin.ParameterPlugin; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.type.*; diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProviders.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProviders.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProviders.java Tue Mar 17 13:57:33 2015 +0100 @@ -24,8 +24,8 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; import com.oracle.graal.hotspot.word.*; -import com.oracle.graal.java.GraphBuilderConfiguration.Plugins; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; @@ -41,17 +41,18 @@ private final HotSpotRegistersProvider registers; private final SnippetReflectionProvider snippetReflection; private final HotSpotWordTypes wordTypes; - private Plugins graphBuilderPlugins; + private final Plugins graphBuilderPlugins; public HotSpotProviders(MetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, HotSpotForeignCallsProvider foreignCalls, LoweringProvider lowerer, Replacements replacements, HotSpotDisassemblerProvider disassembler, SuitesProvider suites, HotSpotRegistersProvider registers, - SnippetReflectionProvider snippetReflection) { + SnippetReflectionProvider snippetReflection, HotSpotWordTypes wordTypes, Plugins graphBuilderPlugins) { super(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, new HotSpotStampProvider()); this.disassembler = disassembler; this.suites = suites; this.registers = registers; this.snippetReflection = snippetReflection; - this.wordTypes = new HotSpotWordTypes(metaAccess, codeCache.getTarget().wordKind); + this.wordTypes = wordTypes; + this.graphBuilderPlugins = graphBuilderPlugins; } @Override @@ -80,12 +81,7 @@ return snippetReflection; } - public void setGraphBuilderPlugins(Plugins plugins) { - graphBuilderPlugins = plugins; - } - public Plugins getGraphBuilderPlugins() { - assert graphBuilderPlugins != null; return graphBuilderPlugins; } diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java Tue Mar 17 13:57:33 2015 +0100 @@ -34,6 +34,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.debug.*; import com.oracle.graal.nodes.*; @@ -41,7 +42,7 @@ /** * Implementation of {@link JavaMethod} for resolved HotSpot methods. */ -public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, HotSpotProxified { +public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, HotSpotProxified, InvocationPluginIdHolder { private static final long serialVersionUID = -5486975070147586588L; @@ -740,4 +741,15 @@ } return runtime().getCompilerToVM().hasCompiledCodeForOSR(metaspaceMethod, entryBCI, level); } + + private int invocationPluginId; + + public void setInvocationPluginId(int id) { + assert invocationPluginId == 0; + invocationPluginId = id; + } + + public int getInvocationPluginId() { + return invocationPluginId; + } } diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java Tue Mar 17 13:57:33 2015 +0100 @@ -24,11 +24,12 @@ import static com.oracle.graal.compiler.common.GraalOptions.*; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.phases.*; import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderConfiguration.DebugInfoMode; import com.oracle.graal.lir.phases.*; import com.oracle.graal.options.*; import com.oracle.graal.options.DerivedOptionValue.OptionSupplier; @@ -65,9 +66,9 @@ } - public HotSpotSuitesProvider(HotSpotGraalRuntimeProvider runtime) { + public HotSpotSuitesProvider(HotSpotGraalRuntimeProvider runtime, Plugins plugins) { this.runtime = runtime; - this.defaultGraphBuilderSuite = createGraphBuilderSuite(); + this.defaultGraphBuilderSuite = createGraphBuilderSuite(plugins); this.defaultSuites = new DerivedOptionValue<>(new SuitesSupplier()); this.defaultLIRSuites = new DerivedOptionValue<>(new LIRSuitesSupplier()); } @@ -99,9 +100,9 @@ return ret; } - protected PhaseSuite createGraphBuilderSuite() { + protected PhaseSuite createGraphBuilderSuite(Plugins plugins) { PhaseSuite suite = new PhaseSuite<>(); - GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(); + GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(plugins); suite.appendPhase(new GraphBuilderPhase(config)); return suite; } diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotWordOperationPlugin.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotWordOperationPlugin.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotWordOperationPlugin.java Tue Mar 17 13:57:33 2015 +0100 @@ -30,10 +30,10 @@ import com.oracle.graal.api.replacements.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.hotspot.word.*; import com.oracle.graal.hotspot.word.HotSpotOperation.HotspotOpcode; -import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.HeapAccess.BarrierType; import com.oracle.graal.nodes.calc.*; diff -r 71f64b487b11 -r 1eea5182d102 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 Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java Tue Mar 17 13:57:33 2015 +0100 @@ -28,10 +28,11 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderConfiguration.Plugins; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.nodes.StructuredGraph.GuardsStage; @@ -79,11 +80,11 @@ @Override protected StructuredGraph getGraph() { - GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(); Plugins defaultPlugins = providers.getGraphBuilderPlugins(); - Plugins plugins = config.getPlugins().updateFrom(defaultPlugins, false); - plugins.getInvocationPlugins().setDefaults(defaultPlugins.getInvocationPlugins()); - plugins.setParameterPlugin(new ConstantBindingParameterPlugin(makeConstArgs(), plugins.getParameterPlugin(), providers.getMetaAccess(), providers.getSnippetReflection())); + MetaAccessProvider metaAccess = providers.getMetaAccess(); + Plugins plugins = new Plugins(defaultPlugins); + plugins.setParameterPlugin(new ConstantBindingParameterPlugin(makeConstArgs(), plugins.getParameterPlugin(), metaAccess, providers.getSnippetReflection())); + GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(plugins); // Stubs cannot have optimistic assumptions since they have // to be valid for the entire run of the VM. Nor can they be @@ -93,7 +94,7 @@ assert SnippetGraphUnderConstruction.get() == null; SnippetGraphUnderConstruction.set(graph); - new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), providers.getConstantReflection(), config, OptimisticOptimizations.NONE, method).apply(graph); + new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), providers.getConstantReflection(), config, OptimisticOptimizations.NONE, method).apply(graph); SnippetGraphUnderConstruction.set(null); graph.setGuardsStage(GuardsStage.FLOATING_GUARDS); diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Tue Mar 17 13:57:33 2015 +0100 @@ -37,11 +37,10 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.debug.*; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderContext.*; import com.oracle.graal.java.BciBlockMapping.BciBlock; -import com.oracle.graal.java.GraphBuilderContext.Replacement; import com.oracle.graal.java.GraphBuilderPhase.Instance.BytecodeParser; -import com.oracle.graal.java.GraphBuilderPlugin.LoadFieldPlugin; -import com.oracle.graal.java.GraphBuilderPlugin.LoadIndexedPlugin; import com.oracle.graal.nodes.*; import com.oracle.graal.options.*; import com.oracle.graal.phases.*; diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.java/src/com/oracle/graal/java/DefaultSuitesProvider.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/DefaultSuitesProvider.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/DefaultSuitesProvider.java Tue Mar 17 13:57:33 2015 +0100 @@ -22,6 +22,8 @@ */ package com.oracle.graal.java; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; import com.oracle.graal.lir.phases.*; import com.oracle.graal.options.*; import com.oracle.graal.options.DerivedOptionValue.OptionSupplier; @@ -54,8 +56,8 @@ } - public DefaultSuitesProvider() { - this.defaultGraphBuilderSuite = createGraphBuilderSuite(); + public DefaultSuitesProvider(Plugins plugins) { + this.defaultGraphBuilderSuite = createGraphBuilderSuite(plugins); this.defaultSuites = new DerivedOptionValue<>(new SuitesSupplier()); this.defaultLIRSuites = new DerivedOptionValue<>(new LIRSuitesSupplier()); } @@ -72,9 +74,9 @@ return defaultGraphBuilderSuite; } - protected PhaseSuite createGraphBuilderSuite() { + protected PhaseSuite createGraphBuilderSuite(Plugins plugins) { PhaseSuite suite = new PhaseSuite<>(); - suite.appendPhase(new GraphBuilderPhase(GraphBuilderConfiguration.getDefault())); + suite.appendPhase(new GraphBuilderPhase(GraphBuilderConfiguration.getDefault(plugins))); return suite; } diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java Tue Mar 17 13:27:50 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,258 +0,0 @@ -/* - * Copyright (c) 2011, 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.java; - -import java.util.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.*; -import com.oracle.graal.java.GraphBuilderPlugin.GenericInvocationPlugin; -import com.oracle.graal.java.GraphBuilderPlugin.InlineInvokePlugin; -import com.oracle.graal.java.GraphBuilderPlugin.LoadFieldPlugin; -import com.oracle.graal.java.GraphBuilderPlugin.LoadIndexedPlugin; -import com.oracle.graal.java.GraphBuilderPlugin.LoopExplosionPlugin; -import com.oracle.graal.java.GraphBuilderPlugin.ParameterPlugin; -import com.oracle.graal.nodes.*; - -public class GraphBuilderConfiguration { - - public static class Plugins { - private InvocationPlugins invocationPlugins; - private LoadFieldPlugin loadFieldPlugin; - private LoadIndexedPlugin loadIndexedPlugin; - private ParameterPlugin parameterPlugin; - private InlineInvokePlugin inlineInvokePlugin; - private GenericInvocationPlugin genericInvocationPlugin; - private LoopExplosionPlugin loopExplosionPlugin; - - public Plugins() { - invocationPlugins = new InvocationPlugins(); - } - - public Plugins(InvocationPlugins invocationPlugins) { - this.invocationPlugins = invocationPlugins; - } - - public InvocationPlugins getInvocationPlugins() { - return invocationPlugins; - } - - public GenericInvocationPlugin getGenericInvocationPlugin() { - return genericInvocationPlugin; - } - - public void setGenericInvocationPlugin(GenericInvocationPlugin plugin) { - this.genericInvocationPlugin = plugin; - } - - public LoadFieldPlugin getLoadFieldPlugin() { - return loadFieldPlugin; - } - - public void setLoadFieldPlugin(LoadFieldPlugin plugin) { - this.loadFieldPlugin = plugin; - } - - public LoadIndexedPlugin getLoadIndexedPlugin() { - return loadIndexedPlugin; - } - - public void setLoadIndexedPlugin(LoadIndexedPlugin plugin) { - this.loadIndexedPlugin = plugin; - } - - public ParameterPlugin getParameterPlugin() { - return parameterPlugin; - } - - public void setParameterPlugin(ParameterPlugin plugin) { - this.parameterPlugin = plugin; - } - - public InlineInvokePlugin getInlineInvokePlugin() { - return inlineInvokePlugin; - } - - public void setInlineInvokePlugin(InlineInvokePlugin plugin) { - this.inlineInvokePlugin = plugin; - } - - public LoopExplosionPlugin getLoopExplosionPlugin() { - return loopExplosionPlugin; - } - - public void setLoopExplosionPlugin(LoopExplosionPlugin plugin) { - this.loopExplosionPlugin = plugin; - } - - public Plugins updateFrom(Plugins other, boolean includeInvocationPlugins) { - if (includeInvocationPlugins) { - this.invocationPlugins.updateFrom(other.getInvocationPlugins()); - } - this.parameterPlugin = other.parameterPlugin; - this.loadFieldPlugin = other.loadFieldPlugin; - this.loadIndexedPlugin = other.loadIndexedPlugin; - this.inlineInvokePlugin = other.inlineInvokePlugin; - this.loopExplosionPlugin = other.loopExplosionPlugin; - this.genericInvocationPlugin = other.genericInvocationPlugin; - return this; - } - } - - private static final ResolvedJavaType[] EMPTY = new ResolvedJavaType[]{}; - - private final boolean eagerResolving; - private final boolean omitAllExceptionEdges; - private final ResolvedJavaType[] skippedExceptionTypes; - private final DebugInfoMode debugInfoMode; - private final boolean doLivenessAnalysis; - private boolean useProfiling; - private Plugins plugins = new Plugins(); - - public static enum DebugInfoMode { - SafePointsOnly, - /** - * This mode inserts {@link SimpleInfopointNode}s in places where no safepoints would be - * inserted: inlining boundaries, and line number switches. - *

- * In this mode the infopoint only have a location (method and bytecode index) and no - * values. - *

- * This is useful to have better program counter to bci mapping and has no influence on the - * generated code. However it can increase the amount of metadata and does not allow access - * to accessing values at runtime. - */ - Simple, - /** - * In this mode, {@link FullInfopointNode}s are generated in the same locations as in - * {@link #Simple} mode but the infopoints have access to the runtime values. - *

- * This is relevant when code is to be generated for native, machine-code level debugging - * but can have a limit the amount of optimization applied to the code. - */ - Full, - } - - protected GraphBuilderConfiguration(boolean eagerResolving, boolean omitAllExceptionEdges, DebugInfoMode debugInfoMode, ResolvedJavaType[] skippedExceptionTypes, boolean doLivenessAnalysis) { - this.eagerResolving = eagerResolving; - this.omitAllExceptionEdges = omitAllExceptionEdges; - this.debugInfoMode = debugInfoMode; - this.skippedExceptionTypes = skippedExceptionTypes; - this.doLivenessAnalysis = doLivenessAnalysis; - this.useProfiling = true; - } - - public GraphBuilderConfiguration copy() { - GraphBuilderConfiguration result = new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, doLivenessAnalysis); - result.useProfiling = useProfiling; - result.copyPluginsFrom(this); - return result; - } - - public boolean getUseProfiling() { - return useProfiling; - } - - public void setUseProfiling(boolean b) { - this.useProfiling = b; - } - - public GraphBuilderConfiguration withSkippedExceptionTypes(ResolvedJavaType[] newSkippedExceptionTypes) { - return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, newSkippedExceptionTypes, doLivenessAnalysis); - } - - public GraphBuilderConfiguration withOmitAllExceptionEdges(boolean newOmitAllExceptionEdges) { - return new GraphBuilderConfiguration(eagerResolving, newOmitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, doLivenessAnalysis); - } - - public GraphBuilderConfiguration withDebugInfoMode(DebugInfoMode newDebugInfoMode) { - ResolvedJavaType[] newSkippedExceptionTypes = skippedExceptionTypes == EMPTY ? EMPTY : Arrays.copyOf(skippedExceptionTypes, skippedExceptionTypes.length); - return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, newDebugInfoMode, newSkippedExceptionTypes, doLivenessAnalysis); - } - - public GraphBuilderConfiguration withDoLivenessAnalysis(boolean newLivenessAnalysis) { - return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, newLivenessAnalysis); - } - - public ResolvedJavaType[] getSkippedExceptionTypes() { - return skippedExceptionTypes; - } - - public boolean eagerResolving() { - return eagerResolving; - } - - public boolean omitAllExceptionEdges() { - return omitAllExceptionEdges; - } - - public boolean insertNonSafepointDebugInfo() { - return debugInfoMode.ordinal() >= DebugInfoMode.Simple.ordinal(); - } - - public boolean insertFullDebugInfo() { - return debugInfoMode.ordinal() >= DebugInfoMode.Full.ordinal(); - } - - public boolean doLivenessAnalysis() { - return doLivenessAnalysis; - } - - public static GraphBuilderConfiguration getDefault() { - return new GraphBuilderConfiguration(false, false, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptLivenessAnalysis.getValue()); - } - - public static GraphBuilderConfiguration getEagerDefault() { - return new GraphBuilderConfiguration(true, false, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptLivenessAnalysis.getValue()); - } - - public static GraphBuilderConfiguration getSnippetDefault() { - return new GraphBuilderConfiguration(true, true, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptLivenessAnalysis.getValue()); - } - - public static GraphBuilderConfiguration getFullDebugDefault() { - return new GraphBuilderConfiguration(true, false, DebugInfoMode.Full, EMPTY, GraalOptions.OptLivenessAnalysis.getValue()); - } - - /** - * Returns {@code true} if it is an error for a class/field/method resolution to fail. The - * default is the same result as returned by {@link #eagerResolving()}. However, it may be - * overridden to allow failure even when {@link #eagerResolving} is {@code true}. - */ - public boolean unresolvedIsError() { - return eagerResolving; - } - - public Plugins getPlugins() { - return plugins; - } - - public void setPlugins(Plugins plugins) { - this.plugins = plugins; - } - - public GraphBuilderConfiguration copyPluginsFrom(GraphBuilderConfiguration other) { - this.plugins.updateFrom(other.plugins, true); - return this; - } -} diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderContext.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderContext.java Tue Mar 17 13:27:50 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2015, 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.java; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.replacements.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; - -/** - * Used by a {@link GraphBuilderPlugin} to interface with a graph builder object. - */ -public interface GraphBuilderContext { - - /** - * Information about a snippet or method substitution currently being processed by the graph - * builder. When in the scope of a replacement, the graph builder does not check the value kinds - * flowing through the JVM state since replacements can employ non-Java kinds to represent - * values such as raw machine words and pointers. - */ - public interface Replacement { - - /** - * Gets the method being replaced. - */ - ResolvedJavaMethod getOriginalMethod(); - - /** - * Gets the replacement method. - */ - ResolvedJavaMethod getReplacementMethod(); - - /** - * Determines if this replacement is being inlined as a compiler intrinsic. A compiler - * intrinsic is atomic with respect to deoptimization. Deoptimization within a compiler - * intrinsic will restart the interpreter at the intrinsified call. - */ - boolean isIntrinsic(); - } - - T append(T fixed); - - T append(T fixed); - - T append(T fixed); - - T append(T value); - - T append(T value); - - StampProvider getStampProvider(); - - MetaAccessProvider getMetaAccess(); - - Assumptions getAssumptions(); - - ConstantReflectionProvider getConstantReflection(); - - SnippetReflectionProvider getSnippetReflection(); - - void push(Kind kind, ValueNode value); - - StructuredGraph getGraph(); - - FrameState createStateAfter(); - - /** - * Gets the parsing context for the method that inlines the method being parsed by this context. - */ - GraphBuilderContext getParent(); - - /** - * Gets the root method for the graph building process. - */ - ResolvedJavaMethod getRootMethod(); - - /** - * Gets the method currently being parsed. - */ - ResolvedJavaMethod getMethod(); - - /** - * Gets the index of the bytecode instruction currently being parsed. - */ - int bci(); - - /** - * Gets the inline depth of this context. 0 implies this is the context for the - * {@linkplain #getRootMethod() root method}. - */ - int getDepth(); - - /** - * Determines if the current parsing context is a snippet or method substitution. - */ - default boolean parsingReplacement() { - return getReplacement() == null; - } - - /** - * Gets the replacement of the current parsing context or {@code null} if not - * {@link #parsingReplacement() parsing a replacement}. - */ - Replacement getReplacement(); - - /** - * @see GuardingPiNode#nullCheckedValue(ValueNode) - */ - static ValueNode nullCheckedValue(GraphBuilderContext builder, ValueNode value) { - ValueNode nonNullValue = GuardingPiNode.nullCheckedValue(value); - if (nonNullValue != value) { - builder.append((FixedWithNextNode) nonNullValue); - } - return nonNullValue; - } - - boolean eagerResolving(); - - BailoutException bailout(String string); -} diff -r 71f64b487b11 -r 1eea5182d102 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 Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Mar 17 13:57:33 2015 +0100 @@ -46,14 +46,11 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.ValueNumberable; import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.InlineInvokePlugin.InlineInfo; import com.oracle.graal.java.AbstractBytecodeParser.ReplacementContext; import com.oracle.graal.java.BciBlockMapping.BciBlock; import com.oracle.graal.java.BciBlockMapping.ExceptionDispatchBlock; -import com.oracle.graal.java.GraphBuilderPlugin.GenericInvocationPlugin; -import com.oracle.graal.java.GraphBuilderPlugin.InlineInvokePlugin; -import com.oracle.graal.java.GraphBuilderPlugin.InlineInvokePlugin.InlineInfo; -import com.oracle.graal.java.GraphBuilderPlugin.InvocationPlugin; -import com.oracle.graal.java.GraphBuilderPlugin.LoopExplosionPlugin; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.CallTargetNode.InvokeKind; diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugin.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugin.java Tue Mar 17 13:27:50 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,255 +0,0 @@ -/* - * Copyright (c) 2015, 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.java; - -import java.lang.reflect.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.*; -import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.java.GraphBuilderPhase.Instance.BytecodeParser; -import com.oracle.graal.java.GraphBuilderPlugin.InlineInvokePlugin.InlineInfo; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; - -/** - * Marker interface for graph builder plugins. - */ -public interface GraphBuilderPlugin { - - public interface LoadFieldPlugin extends GraphBuilderPlugin { - @SuppressWarnings("unused") - default boolean apply(GraphBuilderContext b, ValueNode receiver, ResolvedJavaField field) { - return false; - } - - @SuppressWarnings("unused") - default boolean apply(GraphBuilderContext graphBuilderContext, ResolvedJavaField staticField) { - return false; - } - - default boolean tryConstantFold(GraphBuilderContext b, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ResolvedJavaField field, JavaConstant receiver) { - JavaConstant result = constantReflection.readConstantFieldValue(field, receiver); - if (result != null) { - ConstantNode constantNode = b.append(ConstantNode.forConstant(result, metaAccess)); - b.push(constantNode.getKind().getStackKind(), constantNode); - return true; - } - return false; - } - } - - public interface LoadIndexedPlugin extends GraphBuilderPlugin { - @SuppressWarnings("unused") - default boolean apply(GraphBuilderContext b, ValueNode array, ValueNode index, Kind elementKind) { - return false; - } - } - - /** - * Plugin for specifying what is inlined during graph parsing or for post-processing non-inlined - * invocations that result in {@link Invoke} nodes. - */ - public interface InlineInvokePlugin extends GraphBuilderPlugin { - - public static class InlineInfo { - - /** - * The method to be inlined. - */ - public final ResolvedJavaMethod methodToInline; - - /** - * Specifies if {@link #methodToInline} is to be considered a - * {@linkplain GraphBuilderContext.Replacement replacement} for the {@code method} - * passed to {@link InlineInvokePlugin#getInlineInfo}. - */ - public final boolean isReplacement; - - /** - * Specifies if {@link #methodToInline} is an intrinsic for the original method. If so, - * any {@link StateSplit} node created in the (recursive) inlining scope will be given a - * frame state that restarts the interpreter just before the intrinsified invocation. - */ - public final boolean isIntrinsic; - - public InlineInfo(ResolvedJavaMethod methodToInline, boolean isReplacement, boolean isIntrinsic) { - this.methodToInline = methodToInline; - this.isIntrinsic = isIntrinsic; - this.isReplacement = isReplacement; - assert !isIntrinsic || isReplacement : "cannot be an intrinsic without also being a replacement"; - } - } - - /** - * Determines whether a call to a given method is to be inlined. - * - * @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 InlineInfo getInlineInfo(@SuppressWarnings("unused") GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType) { - return null; - } - - /** - * @param inlinedTargetMethod - */ - default void postInline(ResolvedJavaMethod inlinedTargetMethod) { - } - - /** - * Notifies this plugin of the {@link Invoke} node created for a method that was not inlined - * per {@link #getInlineInfo}. - * - * @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) { - } - } - - public interface LoopExplosionPlugin extends GraphBuilderPlugin { - boolean shouldExplodeLoops(ResolvedJavaMethod method); - - boolean shouldMergeExplosions(ResolvedJavaMethod method); - } - - public interface ParameterPlugin extends GraphBuilderPlugin { - FloatingNode interceptParameter(GraphBuilderContext b, int index, Stamp stamp); - } - - /** - * Plugin for handling an invocation based on some property of the method being invoked such as - * any annotations it may have. - */ - public interface GenericInvocationPlugin extends GraphBuilderPlugin { - /** - * Executes this plugin for an invocation of a given method with a given set of arguments. - * - * @return {@code true} if this plugin handled the invocation, {@code false} if not - */ - boolean apply(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args); - } - - /** - * Plugin for handling a specific method invocation. - */ - public interface InvocationPlugin extends GraphBuilderPlugin { - /** - * @see #execute - */ - default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod) { - throw invalidHandler(b, targetMethod); - } - - /** - * @see #execute - */ - default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode arg) { - throw invalidHandler(b, targetMethod, arg); - } - - /** - * @see #execute - */ - default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode arg1, ValueNode arg2) { - throw invalidHandler(b, targetMethod, arg1, arg2); - } - - /** - * @see #execute - */ - default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode arg1, ValueNode arg2, ValueNode arg3) { - throw invalidHandler(b, targetMethod, arg1, arg2, arg3); - } - - /** - * @see #execute - */ - default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode arg1, ValueNode arg2, ValueNode arg3, ValueNode arg4) { - throw invalidHandler(b, targetMethod, arg1, arg2, arg3, arg4); - } - - /** - * @see #execute - */ - default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode arg1, ValueNode arg2, ValueNode arg3, ValueNode arg4, ValueNode arg5) { - throw invalidHandler(b, targetMethod, arg1, arg2, arg3, arg4, arg5); - } - - default ResolvedJavaMethod getSubstitute() { - return null; - } - - boolean ALLOW_INVOCATION_PLUGIN_TO_DO_INLINING = false; - - /** - * Executes a given plugin against a set of invocation arguments by dispatching to the - * {@code apply(...)} method that matches the number of arguments. - * - * @param targetMethod the method for which plugin is being applied - * @return {@code true} if the plugin handled the invocation of {@code targetMethod} - * {@code false} if the graph builder should process the invoke further (e.g., by - * inlining it or creating an {@link Invoke} node). A plugin that does not handle an - * invocation must not modify the graph being constructed. - */ - static boolean execute(GraphBuilderContext b, ResolvedJavaMethod targetMethod, InvocationPlugin plugin, ValueNode[] args) { - if (ALLOW_INVOCATION_PLUGIN_TO_DO_INLINING) { - ResolvedJavaMethod subst = plugin.getSubstitute(); - if (subst != null) { - return ((BytecodeParser) b).inline(null, targetMethod, new InlineInfo(subst, true, false), args); - } - } - if (args.length == 0) { - return plugin.apply(b, targetMethod); - } else if (args.length == 1) { - return plugin.apply(b, targetMethod, args[0]); - } else if (args.length == 2) { - return plugin.apply(b, targetMethod, args[0], args[1]); - } else if (args.length == 3) { - return plugin.apply(b, targetMethod, args[0], args[1], args[2]); - } else if (args.length == 4) { - return plugin.apply(b, targetMethod, args[0], args[1], args[2], args[3]); - } else if (args.length == 5) { - return plugin.apply(b, targetMethod, args[0], args[1], args[2], args[3], args[4]); - } else { - throw plugin.invalidHandler(b, targetMethod, args); - } - } - - default Error invalidHandler(@SuppressWarnings("unused") GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode... args) { - return new GraalInternalError("Invocation plugin for %s does not handle invocations with %d arguments", targetMethod.format("%H.%n(%p)"), args.length); - } - - default StackTraceElement getApplySourceLocation(MetaAccessProvider metaAccess) { - Class c = getClass(); - for (Method m : c.getDeclaredMethods()) { - if (m.getName().equals("apply")) { - return metaAccess.lookupJavaMethod(m).asStackTraceElement(0); - } - } - throw new GraalInternalError("could not find method named \"apply\" in " + c.getName()); - } - } -} diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java Tue Mar 17 13:57:33 2015 +0100 @@ -31,10 +31,10 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.java.AbstractBytecodeParser.IntrinsicContext; import com.oracle.graal.java.BciBlockMapping.BciBlock; import com.oracle.graal.java.GraphBuilderPhase.Instance.BytecodeParser; -import com.oracle.graal.java.GraphBuilderPlugin.ParameterPlugin; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.java/src/com/oracle/graal/java/InvocationPlugins.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/InvocationPlugins.java Tue Mar 17 13:27:50 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,245 +0,0 @@ -/* - * Copyright (c) 2015, 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.java; - -import static java.lang.String.*; - -import java.lang.reflect.*; -import java.util.*; -import java.util.stream.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.*; -import com.oracle.graal.java.GraphBuilderPlugin.InvocationPlugin; -import com.oracle.graal.nodes.*; - -/** - * Manages a set of {@link InvocationPlugin}s. - */ -public class InvocationPlugins { - /** - * Utility for {@linkplain InvocationPlugins#register(ResolvedJavaMethod, InvocationPlugin) - * registration} of invocation plugins. - */ - public static class Registration { - - /** - * Sentinel class for use with {@link Registration#register1}, - * {@link Registration#register2} or {@link Registration#register3} to denote the receiver - * argument for a non-static method. - */ - public static final class Receiver { - private Receiver() { - throw GraalInternalError.shouldNotReachHere(); - } - } - - private final InvocationPlugins plugins; - private final MetaAccessProvider metaAccess; - private final Class declaringClass; - - /** - * Creates an object for registering {@link InvocationPlugin}s for methods declared by a - * given class. - * - * @param plugins where to register the plugins - * @param metaAccess used to resolve classes and methods - * @param declaringClass the class declaring the methods for which plugins will be - * registered via this object - */ - public Registration(InvocationPlugins plugins, MetaAccessProvider metaAccess, Class declaringClass) { - this.plugins = plugins; - this.metaAccess = metaAccess; - this.declaringClass = declaringClass; - } - - /** - * Registers a plugin for a method with no arguments. - * - * @param name the name of the method - * @param plugin the plugin to be registered - */ - public void register0(String name, InvocationPlugin plugin) { - plugins.register(resolve(metaAccess, declaringClass, name), plugin); - } - - /** - * Registers a plugin for a method with 1 argument. - * - * @param name the name of the method - * @param plugin the plugin to be registered - */ - public void register1(String name, Class arg, InvocationPlugin plugin) { - plugins.register(arg == Receiver.class ? resolve(metaAccess, declaringClass, name) : resolve(metaAccess, declaringClass, name, arg), plugin); - } - - /** - * Registers a plugin for a method with 2 arguments. - * - * @param name the name of the method - * @param plugin the plugin to be registered - */ - public void register2(String name, Class arg1, Class arg2, InvocationPlugin plugin) { - plugins.register(arg1 == Receiver.class ? resolve(metaAccess, declaringClass, name, arg2) : resolve(metaAccess, declaringClass, name, arg1, arg2), plugin); - } - - /** - * Registers a plugin for a method with 3 arguments. - * - * @param name the name of the method - * @param plugin the plugin to be registered - */ - public void register3(String name, Class arg1, Class arg2, Class arg3, InvocationPlugin plugin) { - plugins.register(arg1 == Receiver.class ? resolve(metaAccess, declaringClass, name, arg2, arg3) : resolve(metaAccess, declaringClass, name, arg1, arg2, arg3), plugin); - } - - /** - * Registers a plugin for a method with 4 arguments. - * - * @param name the name of the method - * @param plugin the plugin to be registered - */ - public void register4(String name, Class arg1, Class arg2, Class arg3, Class arg4, InvocationPlugin plugin) { - plugins.register(arg1 == Receiver.class ? resolve(metaAccess, declaringClass, name, arg2, arg3, arg4) : resolve(metaAccess, declaringClass, name, arg1, arg2, arg3, arg4), plugin); - } - - /** - * Registers a plugin for a method with 5 arguments. - * - * @param name the name of the method - * @param plugin the plugin to be registered - */ - public void register5(String name, Class arg1, Class arg2, Class arg3, Class arg4, Class arg5, InvocationPlugin plugin) { - plugins.register(arg1 == Receiver.class ? resolve(metaAccess, declaringClass, name, arg2, arg3, arg4, arg5) : resolve(metaAccess, declaringClass, name, arg1, arg2, arg3, arg4, arg5), - plugin); - } - - /** - * Resolves a method given a declaring class, name and parameter types. - */ - public static ResolvedJavaMethod resolve(MetaAccessProvider metaAccess, Class declaringClass, String name, Class... parameterTypes) { - try { - return metaAccess.lookupJavaMethod(name.equals("") ? declaringClass.getDeclaredConstructor(parameterTypes) : declaringClass.getDeclaredMethod(name, parameterTypes)); - } catch (NoSuchMethodException | SecurityException e) { - throw new GraalInternalError(e); - } - } - } - - private final Map plugins = new HashMap<>(); - - /** - * The invocation plugins deferred to if a plugin is not found in this object. - */ - private InvocationPlugins defaults; - - /** - * Registers an invocation plugin for a given method. There must be no plugin currently - * registered for {@code method}. - */ - public void register(ResolvedJavaMethod method, InvocationPlugin plugin) { - assert Checker.check(method, plugin); - GraphBuilderPlugin oldValue = plugins.put(method, plugin); - // System.out.println("registered: " + plugin); - assert oldValue == null; - } - - /** - * Gets the plugin for a given method. - * - * @param method the method to lookup - * @return the plugin associated with {@code method} or {@code null} if none exists - */ - public InvocationPlugin lookupInvocation(ResolvedJavaMethod method) { - InvocationPlugin res = plugins.get(method); - if (res == null && defaults != null) { - return defaults.lookupInvocation(method); - } - return res; - } - - /** - * Sets the invocation plugins {@linkplain #lookupInvocation(ResolvedJavaMethod) searched} if a - * plugin is not found in this object. - */ - public InvocationPlugins setDefaults(InvocationPlugins defaults) { - InvocationPlugins old = this.defaults; - this.defaults = defaults; - return old; - } - - /** - * Adds all the plugins from {@code other} to this object. - */ - public void updateFrom(InvocationPlugins other) { - this.plugins.putAll(other.plugins); - if (other.defaults != null) { - updateFrom(other.defaults); - } - } - - @Override - public String toString() { - return plugins.keySet().stream().map(m -> m.format("%H.%n(%p)")).collect(Collectors.joining(", ")) + " / defaults: " + this.defaults; - } - - private static class Checker { - private static final int MAX_ARITY = 5; - /** - * The set of all {@link InvocationPlugin#apply} method signatures. - */ - static final Class[][] SIGS; - static { - ArrayList[]> sigs = new ArrayList<>(MAX_ARITY); - for (Method method : InvocationPlugin.class.getDeclaredMethods()) { - if (!Modifier.isStatic(method.getModifiers()) && method.getName().equals("apply")) { - Class[] sig = method.getParameterTypes(); - assert sig[0] == GraphBuilderContext.class; - assert sig[1] == ResolvedJavaMethod.class; - assert Arrays.asList(Arrays.copyOfRange(sig, 2, sig.length)).stream().allMatch(c -> c == ValueNode.class); - while (sigs.size() < sig.length - 1) { - sigs.add(null); - } - sigs.set(sig.length - 2, sig); - } - } - assert sigs.indexOf(null) == -1 : format("need to add an apply() method to %s that takes %d %s arguments ", InvocationPlugin.class.getName(), sigs.indexOf(null), - ValueNode.class.getSimpleName()); - SIGS = sigs.toArray(new Class[sigs.size()][]); - } - - public static boolean check(ResolvedJavaMethod method, InvocationPlugin plugin) { - int arguments = method.getSignature().getParameterCount(!method.isStatic()); - assert arguments < SIGS.length : format("need to extend %s to support method with %d arguments: %s", InvocationPlugin.class.getSimpleName(), arguments, method.format("%H.%n(%p)")); - for (Method m : plugin.getClass().getDeclaredMethods()) { - if (m.getName().equals("apply")) { - Class[] parameterTypes = m.getParameterTypes(); - if (Arrays.equals(SIGS[arguments], parameterTypes)) { - return true; - } - } - } - throw new AssertionError(format("graph builder plugin for %s not found", method.format("%H.%n(%p)"))); - } - } -} diff -r 71f64b487b11 -r 1eea5182d102 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 Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ConstantBindingParameterPlugin.java Tue Mar 17 13:57:33 2015 +0100 @@ -25,8 +25,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderPlugin.ParameterPlugin; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultGenericInvocationPlugin.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultGenericInvocationPlugin.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultGenericInvocationPlugin.java Tue Mar 17 13:57:33 2015 +0100 @@ -31,8 +31,7 @@ import com.oracle.graal.api.replacements.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.Node.NodeIntrinsic; -import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderPlugin.GenericInvocationPlugin; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.word.*; diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Tue Mar 17 13:57:33 2015 +0100 @@ -45,7 +45,6 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.*; -import com.oracle.graal.phases.util.*; /** * Replaces calls to {@link NodeIntrinsic}s with nodes and calls to methods annotated with @@ -53,12 +52,19 @@ */ public class NodeIntrinsificationPhase extends Phase { - private final Providers providers; + private final MetaAccessProvider metaAccess; + private final ConstantReflectionProvider constantReflection; private final SnippetReflectionProvider snippetReflection; + private final ForeignCallsProvider foreignCalls; + private final StampProvider stampProvider; - public NodeIntrinsificationPhase(Providers providers, SnippetReflectionProvider snippetReflection) { - this.providers = providers; + public NodeIntrinsificationPhase(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, SnippetReflectionProvider snippetReflection, ForeignCallsProvider foreignCalls, + StampProvider stampProvider) { + this.metaAccess = metaAccess; + this.constantReflection = constantReflection; this.snippetReflection = snippetReflection; + this.foreignCalls = foreignCalls; + this.stampProvider = stampProvider; } @Override @@ -101,7 +107,7 @@ if (constant != null) { // Replace the invoke with the result of the call - ConstantNode node = ConstantNode.forConstant(constant, providers.getMetaAccess(), methodCallTargetNode.graph()); + ConstantNode node = ConstantNode.forConstant(constant, metaAccess, methodCallTargetNode.graph()); methodCallTargetNode.invoke().intrinsify(node); // Clean up checkcast instructions inserted by javac if the return type is generic. @@ -165,7 +171,7 @@ if (intrinsic.foldable() && areAllConstant(arguments)) { JavaConstant res = tryFold(arguments, parameterTypes, method); if (!res.equals(COULD_NOT_FOLD)) { - return ConstantNode.forConstant(res, providers.getMetaAccess()); + return ConstantNode.forConstant(res, metaAccess); } } @@ -220,12 +226,12 @@ * For intrinsification (but not for folding) if we have a Class object we want * the corresponding ResolvedJavaType. */ - ResolvedJavaType type = folding ? null : providers.getConstantReflection().asJavaType(constant); + ResolvedJavaType type = folding ? null : constantReflection.asJavaType(constant); Object arg; if (type != null) { /* If we found such a type then it's our arg */ arg = type; - parameterTypes[i] = providers.getMetaAccess().lookupJavaType(ResolvedJavaType.class); + parameterTypes[i] = metaAccess.lookupJavaType(ResolvedJavaType.class); } else { JavaConstant javaConstant = (JavaConstant) constant; if (folding) { @@ -253,7 +259,7 @@ reflectionCallArguments[i] = arg; } else { reflectionCallArguments[i] = argument; - parameterTypes[i] = providers.getMetaAccess().lookupJavaType(ValueNode.class); + parameterTypes[i] = metaAccess.lookupJavaType(ValueNode.class); } } return reflectionCallArguments; @@ -264,10 +270,10 @@ if (intrinsic.value() == NodeIntrinsic.class) { result = target.getDeclaringClass(); } else { - result = providers.getMetaAccess().lookupJavaType(intrinsic.value()); + result = metaAccess.lookupJavaType(intrinsic.value()); } - assert providers.getMetaAccess().lookupJavaType(ValueNode.class).isAssignableFrom(result) : "Node intrinsic class " + result.toJavaName(false) + " derived from @" + - NodeIntrinsic.class.getSimpleName() + " annotation on " + target.format("%H.%n(%p)") + " is not a subclass of " + ValueNode.class; + assert metaAccess.lookupJavaType(ValueNode.class).isAssignableFrom(result) : "Node intrinsic class " + result.toJavaName(false) + " derived from @" + NodeIntrinsic.class.getSimpleName() + + " annotation on " + target.format("%H.%n(%p)") + " is not a subclass of " + ValueNode.class; return result; } @@ -339,7 +345,6 @@ Object[] injected = null; ResolvedJavaType[] signature = resolveJavaTypes(c.getSignature().toParameterTypes(null), c.getDeclaringClass()); - MetaAccessProvider metaAccess = providers.getMetaAccess(); for (int i = 0; i < signature.length; i++) { if (c.getParameterAnnotation(InjectedNodeParameter.class, i) != null) { injected = injected == null ? new Object[1] : Arrays.copyOf(injected, injected.length + 1); @@ -351,13 +356,13 @@ } else if (signature[i].equals(metaAccess.lookupJavaType(StructuredGraph.class))) { injected[injected.length - 1] = graph; } else if (signature[i].equals(metaAccess.lookupJavaType(ForeignCallsProvider.class))) { - injected[injected.length - 1] = providers.getForeignCalls(); + injected[injected.length - 1] = foreignCalls; } else if (signature[i].equals(metaAccess.lookupJavaType(SnippetReflectionProvider.class))) { injected[injected.length - 1] = snippetReflection; } else if (signature[i].isAssignableFrom(metaAccess.lookupJavaType(Stamp.class))) { injected[injected.length - 1] = invokeStamp; } else if (signature[i].isAssignableFrom(metaAccess.lookupJavaType(StampProvider.class))) { - injected[injected.length - 1] = providers.getStampProvider(); + injected[injected.length - 1] = stampProvider; } else { throw new GraalInternalError("Cannot handle injected argument of type %s in %s", signature[i].toJavaName(), c.format("%H.%n(%p)")); } diff -r 71f64b487b11 -r 1eea5182d102 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 Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Tue Mar 17 13:57:33 2015 +0100 @@ -42,9 +42,10 @@ import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.Graph.Mark; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; import com.oracle.graal.graph.*; import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderConfiguration.Plugins; import com.oracle.graal.java.GraphBuilderPhase.Instance; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; @@ -71,7 +72,8 @@ */ protected final ConcurrentMap graphs; - public void completeInitialization(GraphBuilderConfiguration.Plugins plugins) { + public void setGraphBuilderPlugins(GraphBuilderConfiguration.Plugins plugins) { + assert this.graphBuilderPlugins == null; this.graphBuilderPlugins = plugins; } @@ -299,7 +301,7 @@ } protected NodeIntrinsificationPhase createNodeIntrinsificationPhase() { - return new NodeIntrinsificationPhase(providers, snippetReflection); + return new NodeIntrinsificationPhase(providers.getMetaAccess(), providers.getConstantReflection(), snippetReflection, providers.getForeignCalls(), providers.getStampProvider()); } @Override @@ -640,9 +642,8 @@ if (MethodsElidedInSnippets != null && methodToParse.getSignature().getReturnKind() == Kind.Void && MethodFilter.matches(MethodsElidedInSnippets, methodToParse)) { graph.addAfterFixed(graph.start(), graph.add(new ReturnNode(null))); } else { - GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(); - Plugins plugins = config.getPlugins().updateFrom(replacements.graphBuilderPlugins, false); - plugins.getInvocationPlugins().setDefaults(replacements.graphBuilderPlugins.getInvocationPlugins()); + Plugins plugins = new Plugins(replacements.graphBuilderPlugins); + GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(plugins); if (args != null) { plugins.setParameterPlugin(new ConstantBindingParameterPlugin(args, plugins.getParameterPlugin(), metaAccess, replacements.snippetReflection)); } diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java Tue Mar 17 13:57:33 2015 +0100 @@ -23,7 +23,7 @@ package com.oracle.graal.replacements; import static com.oracle.graal.api.code.MemoryBarriers.*; -import static com.oracle.graal.java.GraphBuilderContext.*; +import static com.oracle.graal.graphbuilderconf.GraphBuilderContext.*; import static com.oracle.graal.replacements.nodes.MathIntrinsicNode.Operation.*; import sun.misc.*; @@ -32,10 +32,8 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.graph.*; -import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderPlugin.InvocationPlugin; -import com.oracle.graal.java.InvocationPlugins.Registration; -import com.oracle.graal.java.InvocationPlugins.Registration.Receiver; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.InvocationPlugins.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.debug.*; @@ -57,29 +55,29 @@ // @formatter:on public static void registerInvocationPlugins(MetaAccessProvider metaAccess, Architecture arch, InvocationPlugins plugins, boolean useBoxingPlugins) { - registerObjectPlugins(metaAccess, plugins); - registerClassPlugins(metaAccess, plugins); - registerMathPlugins(metaAccess, arch, plugins); - registerUnsignedMathPlugins(metaAccess, plugins); - registerCharacterPlugins(metaAccess, plugins); - registerShortPlugins(metaAccess, plugins); - registerIntegerLongPlugins(metaAccess, plugins, Kind.Int); - registerIntegerLongPlugins(metaAccess, plugins, Kind.Long); - registerFloatPlugins(metaAccess, plugins); - registerDoublePlugins(metaAccess, plugins); - registerUnsafePlugins(metaAccess, arch, plugins); + registerObjectPlugins(plugins); + registerClassPlugins(plugins); + registerMathPlugins(arch, plugins); + registerUnsignedMathPlugins(plugins); + registerCharacterPlugins(plugins); + registerShortPlugins(plugins); + registerIntegerLongPlugins(plugins, Kind.Int); + registerIntegerLongPlugins(plugins, Kind.Long); + registerFloatPlugins(plugins); + registerDoublePlugins(plugins); + registerUnsafePlugins(arch, plugins); registerEdgesPlugins(metaAccess, plugins); - registerGraalDirectivesPlugins(metaAccess, plugins); + registerGraalDirectivesPlugins(plugins); if (useBoxingPlugins) { - registerBoxingPlugins(metaAccess, plugins); + registerBoxingPlugins(plugins); } if (Options.UseBlackholeSubstitution.getValue()) { - registerJMHBlackholePlugins(metaAccess, plugins); + registerJMHBlackholePlugins(plugins); } } - private static void registerUnsafePlugins(MetaAccessProvider metaAccess, Architecture arch, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, Unsafe.class); + private static void registerUnsafePlugins(Architecture arch, InvocationPlugins plugins) { + Registration r = new Registration(plugins, Unsafe.class); for (Kind kind : Kind.values()) { if ((kind.isPrimitive() && kind != Kind.Void) || kind == Kind.Object) { Class javaClass = kind == Kind.Object ? Object.class : kind.toJavaClass(); @@ -147,10 +145,10 @@ return arch.getName().equals("AMD64"); } - private static void registerIntegerLongPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins, Kind kind) { + private static void registerIntegerLongPlugins(InvocationPlugins plugins, Kind kind) { Class declaringClass = kind.toBoxedJavaClass(); Class type = kind.toJavaClass(); - Registration r = new Registration(plugins, metaAccess, declaringClass); + Registration r = new Registration(plugins, declaringClass); r.register1("reverseBytes", type, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { b.push(kind, b.append(new ReverseBytesNode(value).canonical(null, value))); @@ -177,8 +175,8 @@ }); } - private static void registerCharacterPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, Character.class); + private static void registerCharacterPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, Character.class); r.register1("reverseBytes", char.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { // return (char) (Integer.reverse(i) >> 16); @@ -191,8 +189,8 @@ }); } - private static void registerShortPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, Short.class); + private static void registerShortPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, Short.class); r.register1("reverseBytes", short.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { // return (short) (Integer.reverse(i) >> 16); @@ -205,8 +203,8 @@ }); } - private static void registerFloatPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, Float.class); + private static void registerFloatPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, Float.class); r.register1("floatToRawIntBits", float.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { b.push(Kind.Int, b.append(new ReinterpretNode(Kind.Int, value).canonical(null, value))); @@ -221,8 +219,8 @@ }); } - private static void registerDoublePlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, Double.class); + private static void registerDoublePlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, Double.class); r.register1("doubleToRawLongBits", double.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { b.push(Kind.Long, b.append(new ReinterpretNode(Kind.Long, value).canonical(null, value))); @@ -237,8 +235,8 @@ }); } - private static void registerMathPlugins(MetaAccessProvider metaAccess, Architecture arch, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, Math.class); + private static void registerMathPlugins(Architecture arch, InvocationPlugins plugins) { + Registration r = new Registration(plugins, Math.class); r.register1("abs", Float.TYPE, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { b.push(Kind.Float, b.append(new AbsNode(value).canonical(null, value))); @@ -303,8 +301,8 @@ } } - private static void registerUnsignedMathPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, UnsignedMath.class); + private static void registerUnsignedMathPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, UnsignedMath.class); r.register2("aboveThan", int.class, int.class, new UnsignedMathPlugin(Condition.AT)); r.register2("aboveThan", long.class, long.class, new UnsignedMathPlugin(Condition.AT)); r.register2("belowThan", int.class, int.class, new UnsignedMathPlugin(Condition.BT)); @@ -339,17 +337,17 @@ }); } - protected static void registerBoxingPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { + protected static void registerBoxingPlugins(InvocationPlugins plugins) { for (Kind kind : Kind.values()) { if (kind.isPrimitive() && kind != Kind.Void) { - new BoxPlugin(kind).register(metaAccess, plugins); - new UnboxPlugin(kind).register(metaAccess, plugins); + new BoxPlugin(kind).register(plugins); + new UnboxPlugin(kind).register(plugins); } } } - private static void registerObjectPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, Object.class); + private static void registerObjectPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, Object.class); r.register1("", Receiver.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode object) { if (RegisterFinalizerNode.mayHaveFinalizer(object, b.getAssumptions())) { @@ -362,8 +360,8 @@ }); } - private static void registerClassPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, Class.class); + private static void registerClassPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, Class.class); r.register2("isInstance", Receiver.class, Object.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode type, ValueNode object) { ValueNode nullCheckedType = nullCheckedValue(b, type); @@ -401,7 +399,7 @@ * project containing {@link Edges}. */ private static void registerEdgesPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, Edges.class); + Registration r = new Registration(plugins, Edges.class); for (Class c : new Class[]{Node.class, NodeList.class}) { r.register2("get" + c.getSimpleName() + "Unsafe", Node.class, long.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode node, ValueNode offset) { @@ -445,9 +443,8 @@ return true; } - void register(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - ResolvedJavaMethod method = Registration.resolve(metaAccess, kind.toBoxedJavaClass(), "valueOf", kind.toJavaClass()); - plugins.register(method, this); + void register(InvocationPlugins plugins) { + plugins.register(this, kind.toBoxedJavaClass(), "valueOf", kind.toJavaClass()); } } @@ -473,10 +470,9 @@ return true; } - void register(MetaAccessProvider metaAccess, InvocationPlugins plugins) { + void register(InvocationPlugins plugins) { String name = kind.toJavaClass().getSimpleName() + "Value"; - ResolvedJavaMethod method = Registration.resolve(metaAccess, kind.toBoxedJavaClass(), name); - plugins.register(method, this); + plugins.register(this, kind.toBoxedJavaClass(), name, Receiver.class); } } @@ -536,8 +532,8 @@ } } - private static void registerGraalDirectivesPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, GraalDirectives.class); + private static void registerGraalDirectivesPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, GraalDirectives.class); r.register0("deoptimize", new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod) { b.append(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.TransferToInterpreter)); @@ -596,7 +592,7 @@ } } - private static void registerJMHBlackholePlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { + private static void registerJMHBlackholePlugins(InvocationPlugins plugins) { InvocationPlugin blackholePlugin = new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode blackhole, ValueNode value) { b.append(new BlackholeNode(value)); @@ -608,7 +604,7 @@ Class blackholeClass; blackholeClass = ReplacementsImpl.resolveClass(name, true); if (blackholeClass != null) { - Registration r = new Registration(plugins, metaAccess, blackholeClass); + Registration r = new Registration(plugins, blackholeClass); for (Kind kind : Kind.values()) { if ((kind.isPrimitive() && kind != Kind.Void) || kind == Kind.Object) { Class javaClass = kind == Kind.Object ? Object.class : kind.toJavaClass(); diff -r 71f64b487b11 -r 1eea5182d102 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 Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java Tue Mar 17 13:57:33 2015 +0100 @@ -32,8 +32,7 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderPlugin.GenericInvocationPlugin; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.HeapAccess.BarrierType; import com.oracle.graal.nodes.calc.*; diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java --- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Tue Mar 17 13:57:33 2015 +0100 @@ -40,6 +40,8 @@ import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; @@ -185,14 +187,18 @@ } private static CompilationResult compileMethod(ResolvedJavaMethod javaMethod) { - Providers providers = getGraalProviders(); - MetaAccessProvider metaAccess = providers.getMetaAccess(); - SuitesProvider suitesProvider = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getSuites(); + HotSpotProviders providers = getGraalProviders(); + SuitesProvider suitesProvider = providers.getSuites(); Suites suites = suitesProvider.createSuites(); LIRSuites lirSuites = suitesProvider.createLIRSuites(); removeInliningPhase(suites); StructuredGraph graph = new StructuredGraph(javaMethod, AllowAssumptions.NO); - new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), providers.getConstantReflection(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL, null).apply(graph); + + MetaAccessProvider metaAccess = providers.getMetaAccess(); + Plugins plugins = new Plugins(new InvocationPlugins(metaAccess)); + GraphBuilderConfiguration config = GraphBuilderConfiguration.getEagerDefault(plugins); + new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), providers.getConstantReflection(), config, OptimisticOptimizations.ALL, null).apply(graph); + PhaseSuite graphBuilderSuite = getGraphBuilderSuite(suitesProvider); CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false); Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend(); @@ -201,9 +207,9 @@ suites, lirSuites, new CompilationResult(), factory); } - private static Providers getGraalProviders() { + private static HotSpotProviders getGraalProviders() { RuntimeProvider runtimeProvider = Graal.getRequiredCapability(RuntimeProvider.class); - return runtimeProvider.getHostBackend().getProviders(); + return (HotSpotProviders) runtimeProvider.getHostBackend().getProviders(); } private static PhaseSuite getGraphBuilderSuite(SuitesProvider suitesProvider) { diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ExactMathTest.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ExactMathTest.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ExactMathTest.java Tue Mar 17 13:57:33 2015 +0100 @@ -25,16 +25,16 @@ import org.junit.*; import com.oracle.graal.compiler.test.*; -import com.oracle.graal.java.*; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.truffle.substitutions.*; import com.oracle.truffle.api.*; public class ExactMathTest extends GraalCompilerTest { @Override - protected void editGraphBuilderPlugins(GraphBuilderConfiguration.Plugins plugins) { - TruffleGraphBuilderPlugins.registerExactMathPlugins(getMetaAccess(), plugins.getInvocationPlugins()); - super.editGraphBuilderPlugins(plugins); + protected GraphBuilderConfiguration editGraphBuilderConfiguration(GraphBuilderConfiguration conf) { + TruffleGraphBuilderPlugins.registerExactMathPlugins(conf.getPlugins().getInvocationPlugins()); + return super.editGraphBuilderConfiguration(conf); } @Test diff -r 71f64b487b11 -r 1eea5182d102 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 Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Tue Mar 17 13:57:33 2015 +0100 @@ -38,10 +38,9 @@ import com.oracle.graal.graph.Graph.Mark; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins; import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderConfiguration.Plugins; -import com.oracle.graal.java.GraphBuilderPlugin.LoadFieldPlugin; -import com.oracle.graal.java.GraphBuilderPlugin.ParameterPlugin; import com.oracle.graal.loop.*; import com.oracle.graal.nodes.CallTargetNode.InvokeKind; import com.oracle.graal.nodes.*; @@ -63,7 +62,6 @@ import com.oracle.graal.truffle.nodes.frame.*; import com.oracle.graal.truffle.nodes.frame.NewFrameNode.VirtualOnlyInstanceNode; import com.oracle.graal.truffle.phases.*; -import com.oracle.graal.truffle.substitutions.*; import com.oracle.graal.virtual.phases.ea.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -185,13 +183,13 @@ } } - private class InlineInvokePlugin implements GraphBuilderPlugin.InlineInvokePlugin { + private class PEInlineInvokePlugin implements InlineInvokePlugin { private Stack inlining; private OptimizedDirectCallNode lastDirectCallNode; private final Replacements replacements; - public InlineInvokePlugin(TruffleInlining inlining, Replacements replacements) { + public PEInlineInvokePlugin(TruffleInlining inlining, Replacements replacements) { this.inlining = new Stack<>(); this.inlining.push(inlining); this.replacements = replacements; @@ -235,7 +233,7 @@ } } - private class LoopExplosionPlugin implements GraphBuilderPlugin.LoopExplosionPlugin { + private class PELoopExplosionPlugin implements LoopExplosionPlugin { public boolean shouldExplodeLoops(ResolvedJavaMethod method) { return method.getAnnotation(ExplodeLoop.class) != null; @@ -259,10 +257,9 @@ plugins.setLoadFieldPlugin(new InterceptLoadFieldPlugin()); plugins.setParameterPlugin(new InterceptReceiverPlugin(callTarget)); callTarget.setInlining(new TruffleInlining(callTarget, new DefaultInliningPolicy())); - plugins.setInlineInvokePlugin(new InlineInvokePlugin(callTarget.getInlining(), providers.getReplacements())); - plugins.setLoopExplosionPlugin(new LoopExplosionPlugin()); - TruffleGraphBuilderPlugins.registerInvocationPlugins(providers.getMetaAccess(), newConfig.getPlugins().getInvocationPlugins()); - + plugins.setInlineInvokePlugin(new PEInlineInvokePlugin(callTarget.getInlining(), providers.getReplacements())); + plugins.setLoopExplosionPlugin(new PELoopExplosionPlugin()); + InvocationPlugins invocationPlugins = newConfig.getPlugins().getInvocationPlugins(); new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), this.snippetReflection, providers.getConstantReflection(), newConfig, TruffleCompilerImpl.Optimizations, null).apply(graph); Debug.dump(graph, "After FastPE"); diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Tue Mar 17 13:57:33 2015 +0100 @@ -32,6 +32,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Tue Mar 17 13:57:33 2015 +0100 @@ -27,15 +27,17 @@ import java.util.*; -import com.oracle.graal.api.meta.Assumptions.Assumption; import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.CallingConvention.Type; +import com.oracle.graal.api.meta.Assumptions.Assumption; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; import com.oracle.graal.java.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.phases.*; @@ -48,6 +50,7 @@ import com.oracle.graal.printer.*; import com.oracle.graal.runtime.*; import com.oracle.graal.truffle.nodes.*; +import com.oracle.graal.truffle.substitutions.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.nodes.*; @@ -97,14 +100,20 @@ this.lirSuites = backend.getSuites().getDefaultLIRSuites(); ResolvedJavaType[] skippedExceptionTypes = getSkippedExceptionTypes(providers.getMetaAccess()); - GraphBuilderConfiguration eagerConfig = GraphBuilderConfiguration.getEagerDefault().withSkippedExceptionTypes(skippedExceptionTypes); - this.config = GraphBuilderConfiguration.getDefault().withSkippedExceptionTypes(skippedExceptionTypes); + Plugins plugins; if (TruffleCompilerOptions.FastPE.getValue()) { GraphBuilderPhase phase = (GraphBuilderPhase) backend.getSuites().getDefaultGraphBuilderSuite().findPhase(GraphBuilderPhase.class).previous(); - this.config.getPlugins().getInvocationPlugins().setDefaults(phase.getGraphBuilderConfig().getPlugins().getInvocationPlugins()); + InvocationPlugins invocationPlugins = new InvocationPlugins(phase.getGraphBuilderConfig().getPlugins().getInvocationPlugins()); + plugins = new Plugins(invocationPlugins); + TruffleGraphBuilderPlugins.registerInvocationPlugins(providers.getMetaAccess(), invocationPlugins); + } else { + plugins = new Plugins(new InvocationPlugins(backendProviders.getMetaAccess())); } + this.config = GraphBuilderConfiguration.getDefault(plugins).withSkippedExceptionTypes(skippedExceptionTypes); + + GraphBuilderConfiguration eagerConfig = GraphBuilderConfiguration.getEagerDefault(plugins).withSkippedExceptionTypes(skippedExceptionTypes); this.truffleCache = new TruffleCacheImpl(providers, eagerConfig, TruffleCompilerImpl.Optimizations); this.partialEvaluator = new PartialEvaluator(providers, config, truffleCache, Graal.getRequiredCapability(SnippetReflectionProvider.class)); diff -r 71f64b487b11 -r 1eea5182d102 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java Tue Mar 17 13:27:50 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java Tue Mar 17 13:57:33 2015 +0100 @@ -31,10 +31,8 @@ import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; -import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderPlugin.InvocationPlugin; -import com.oracle.graal.java.InvocationPlugins.Registration; -import com.oracle.graal.java.InvocationPlugins.Registration.Receiver; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.InvocationPlugins.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; @@ -53,22 +51,22 @@ public class TruffleGraphBuilderPlugins { public static void registerInvocationPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - registerOptimizedAssumptionPlugins(metaAccess, plugins); - registerExactMathPlugins(metaAccess, plugins); - registerCompilerDirectivesPlugins(metaAccess, plugins); + registerOptimizedAssumptionPlugins(plugins); + registerExactMathPlugins(plugins); + registerCompilerDirectivesPlugins(plugins); registerOptimizedCallTargetPlugins(metaAccess, plugins); - registerUnsafeAccessImplPlugins(metaAccess, plugins); + registerUnsafeAccessImplPlugins(plugins); if (TruffleCompilerOptions.TruffleUseFrameWithoutBoxing.getValue()) { - registerFrameWithoutBoxingPlugins(metaAccess, plugins); + registerFrameWithoutBoxingPlugins(plugins); } else { - registerFrameWithBoxingPlugins(metaAccess, plugins); + registerFrameWithBoxingPlugins(plugins); } } - public static void registerOptimizedAssumptionPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, OptimizedAssumption.class); + public static void registerOptimizedAssumptionPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, OptimizedAssumption.class); r.register1("isValid", Receiver.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode arg) { if (arg.isConstant()) { @@ -86,8 +84,8 @@ }); } - public static void registerExactMathPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, ExactMath.class); + public static void registerExactMathPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, ExactMath.class); for (Kind kind : new Kind[]{Kind.Int, Kind.Long}) { Class type = kind.toJavaClass(); r.register2("addExact", type, type, new InvocationPlugin() { @@ -123,8 +121,8 @@ } } - public static void registerCompilerDirectivesPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, CompilerDirectives.class); + public static void registerCompilerDirectivesPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, CompilerDirectives.class); r.register0("inInterpreter", new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod) { b.push(Kind.Boolean.getStackKind(), b.append(ConstantNode.forBoolean(false))); @@ -190,7 +188,7 @@ } }); - r = new Registration(plugins, metaAccess, CompilerAsserts.class); + r = new Registration(plugins, CompilerAsserts.class); r.register1("partialEvaluationConstant", Object.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { ValueNode curValue = value; @@ -229,7 +227,7 @@ } public static void registerOptimizedCallTargetPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, OptimizedCallTarget.class); + Registration r = new Registration(plugins, OptimizedCallTarget.class); r.register2("createFrame", FrameDescriptor.class, Object[].class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode descriptor, ValueNode args) { Class frameClass = TruffleCompilerOptions.TruffleUseFrameWithoutBoxing.getValue() ? FrameWithoutBoxing.class : FrameWithBoxing.class; @@ -245,21 +243,21 @@ }); } - public static void registerFrameWithoutBoxingPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, FrameWithoutBoxing.class); + public static void registerFrameWithoutBoxingPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, FrameWithoutBoxing.class); registerMaterialize(r); registerUnsafeCast(r); registerUnsafeLoadStorePlugins(r, Kind.Int, Kind.Long, Kind.Float, Kind.Double, Kind.Object); } - public static void registerFrameWithBoxingPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, FrameWithBoxing.class); + public static void registerFrameWithBoxingPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, FrameWithBoxing.class); registerMaterialize(r); registerUnsafeCast(r); } - public static void registerUnsafeAccessImplPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, UnsafeAccessImpl.class); + public static void registerUnsafeAccessImplPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, UnsafeAccessImpl.class); registerUnsafeCast(r); registerUnsafeLoadStorePlugins(r, Kind.Boolean, Kind.Byte, Kind.Int, Kind.Short, Kind.Long, Kind.Float, Kind.Double, Kind.Object); } diff -r 71f64b487b11 -r 1eea5182d102 mx/suite.py --- a/mx/suite.py Tue Mar 17 13:27:50 2015 +0100 +++ b/mx/suite.py Tue Mar 17 13:57:33 2015 +0100 @@ -803,6 +803,7 @@ "sourceDirs" : ["src"], "dependencies" : [ "com.oracle.graal.phases", + "com.oracle.graal.graphbuilderconf" ], "checkstyle" : "com.oracle.graal.graph", "annotationProcessors" : ["com.oracle.graal.service.processor"], @@ -810,6 +811,17 @@ "workingSets" : "Graal,Java", }, + "com.oracle.graal.graphbuilderconf" : { + "subDir" : "graal", + "sourceDirs" : ["src"], + "dependencies" : [ + "com.oracle.graal.nodes", + ], + "checkstyle" : "com.oracle.graal.graph", + "javaCompliance" : "1.8", + "workingSets" : "Graal,Java", + }, + "com.oracle.graal.compiler.common" : { "subDir" : "graal", "sourceDirs" : ["src"], diff -r 71f64b487b11 -r 1eea5182d102 src/cpu/x86/vm/sharedRuntime_x86_32.cpp --- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Tue Mar 17 13:27:50 2015 +0100 +++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Tue Mar 17 13:57:33 2015 +0100 @@ -715,7 +715,7 @@ int total_args_passed, int comp_args_on_stack, const BasicType *sig_bt, - const VMRegPair *regs + const VMRegPair *regs, int frame_extension_argument) { assert(frame_extension_argument == -1, "unsupported");