# HG changeset patch # User Doug Simon # Date 1422660600 -3600 # Node ID 75da87c96605f46bf8f7b38acc5154af1143708f # Parent c198e397bb594db2edd6673aeb1e982241a7ead1 initial commit of GraphBuilderPhase plugins diff -r c198e397bb59 -r 75da87c96605 graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineCompiler.java --- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineCompiler.java Sat Jan 31 00:19:34 2015 +0100 +++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineCompiler.java Sat Jan 31 00:30:00 2015 +0100 @@ -32,6 +32,7 @@ import com.oracle.graal.debug.*; import com.oracle.graal.java.*; import com.oracle.graal.lir.asm.*; +import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; /** @@ -50,7 +51,7 @@ private final GraphBuilderConfiguration graphBuilderConfig; public CompilationResult generate(ResolvedJavaMethod method, int entryBCI, Backend backend, CompilationResult compilationResult, ResolvedJavaMethod installedCodeOwner, - CompilationResultBuilderFactory factory, OptimisticOptimizations optimisticOpts) { + CompilationResultBuilderFactory factory, OptimisticOptimizations optimisticOpts, Replacements replacements) { assert method.getCode() != null : "method must contain bytecodes: " + method; TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method); diff -r c198e397bb59 -r 75da87c96605 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 Sat Jan 31 00:19:34 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Sat Jan 31 00:30:00 2015 +0100 @@ -67,7 +67,7 @@ StructuredGraph graph = new StructuredGraph(javaMethod); GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault(); - new GraphBuilderPhase.Instance(getMetaAccess(), conf, OptimisticOptimizations.ALL).apply(graph); + new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), assumptions, conf, OptimisticOptimizations.ALL).apply(graph); HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); new CanonicalizerPhase(true).apply(graph, context); diff -r c198e397bb59 -r 75da87c96605 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 Sat Jan 31 00:19:34 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Sat Jan 31 00:30:00 2015 +0100 @@ -525,7 +525,7 @@ try (Scope bds = Debug.scope("CompileBaseline", javaMethod, providers.getCodeCache())) { BaselineCompiler baselineCompiler = new BaselineCompiler(GraphBuilderConfiguration.getDefault(), providers.getMetaAccess()); OptimisticOptimizations optimisticOpts = OptimisticOptimizations.ALL; - return baselineCompiler.generate(javaMethod, -1, getBackend(), new CompilationResult(), javaMethod, CompilationResultBuilderFactory.Default, optimisticOpts); + return baselineCompiler.generate(javaMethod, -1, getBackend(), new CompilationResult(), javaMethod, CompilationResultBuilderFactory.Default, optimisticOpts, getReplacements()); } catch (Throwable e) { throw Debug.handle(e); } diff -r c198e397bb59 -r 75da87c96605 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java Sat Jan 31 00:19:34 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java Sat Jan 31 00:30:00 2015 +0100 @@ -151,8 +151,8 @@ ResolvedJavaMethod method = getResolvedJavaMethod(snippet); graph = new StructuredGraph(method); try (Scope s = Debug.scope(getClass(), graph, method, getCodeCache())) { - new GraphBuilderPhase.Instance(getMetaAccess(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); Assumptions assumptions = new Assumptions(false); + new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), assumptions, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); new DeadCodeEliminationPhase().apply(graph); diff -r c198e397bb59 -r 75da87c96605 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 Sat Jan 31 00:19:34 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysis.java Sat Jan 31 00:30:00 2015 +0100 @@ -24,6 +24,7 @@ import java.util.*; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; @@ -33,6 +34,7 @@ import com.oracle.graal.nodes.CallTargetNode.InvokeKind; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.graph.*; @@ -57,13 +59,16 @@ public class StaticAnalysis { /** Access to type, method, and fields using the Graal API. */ private final MetaAccessProvider metaAccess; + /** Access to platform dependent stamps. */ + private final StampProvider stampProvider; /** The results of the static analysis. */ private final Results results; /** Worklist for fixpoint iteration. */ private final Deque worklist; - public StaticAnalysis(MetaAccessProvider metaAccess) { + public StaticAnalysis(MetaAccessProvider metaAccess, StampProvider stampProvider) { this.metaAccess = metaAccess; + this.stampProvider = stampProvider; this.results = new Results(); this.worklist = new ArrayDeque<>(); } @@ -231,8 +236,9 @@ * wrong. */ OptimisticOptimizations optimisticOpts = OptimisticOptimizations.NONE; + Assumptions assumptions = new Assumptions(false); - GraphBuilderPhase.Instance graphBuilder = new GraphBuilderPhase.Instance(metaAccess, graphBuilderConfig, optimisticOpts); + GraphBuilderPhase.Instance graphBuilder = new GraphBuilderPhase.Instance(metaAccess, stampProvider, assumptions, graphBuilderConfig, optimisticOpts); graphBuilder.apply(graph); } catch (Throwable ex) { Debug.handle(ex); diff -r c198e397bb59 -r 75da87c96605 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysisTests.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysisTests.java Sat Jan 31 00:19:34 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysisTests.java Sat Jan 31 00:30:00 2015 +0100 @@ -32,6 +32,7 @@ import com.oracle.graal.compiler.target.*; import com.oracle.graal.compiler.test.tutorial.StaticAnalysis.MethodState; import com.oracle.graal.compiler.test.tutorial.StaticAnalysis.TypeFlow; +import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.runtime.*; @@ -58,12 +59,14 @@ Object f; } - private MetaAccessProvider metaAccess; + private final MetaAccessProvider metaAccess; + private final StampProvider stampProvider; public StaticAnalysisTests() { Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend(); Providers providers = backend.getProviders(); this.metaAccess = providers.getMetaAccess(); + this.stampProvider = providers.getStampProvider(); } static void test01Entry() { @@ -73,7 +76,7 @@ @Test public void test01() { - StaticAnalysis sa = new StaticAnalysis(metaAccess); + StaticAnalysis sa = new StaticAnalysis(metaAccess, stampProvider); sa.addMethod(findMethod(StaticAnalysisTests.class, "test01Entry")); sa.finish(); @@ -94,7 +97,7 @@ @Test public void test02() { - StaticAnalysis sa = new StaticAnalysis(metaAccess); + StaticAnalysis sa = new StaticAnalysis(metaAccess, stampProvider); sa.addMethod(findMethod(StaticAnalysisTests.class, "test02Entry")); sa.finish(); @@ -121,7 +124,7 @@ @Test public void test03() { - StaticAnalysis sa = new StaticAnalysis(metaAccess); + StaticAnalysis sa = new StaticAnalysis(metaAccess, stampProvider); sa.addMethod(findMethod(StaticAnalysisTests.class, "test03Entry")); sa.finish(); @@ -151,7 +154,7 @@ @Test public void test04() { - StaticAnalysis sa = new StaticAnalysis(metaAccess); + StaticAnalysis sa = new StaticAnalysis(metaAccess, stampProvider); sa.addMethod(findMethod(StaticAnalysisTests.class, "test04Entry")); sa.finish(); diff -r c198e397bb59 -r 75da87c96605 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Sat Jan 31 00:19:34 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Sat Jan 31 00:30:00 2015 +0100 @@ -197,7 +197,7 @@ HotSpotProviders providers = backend.getProviders(); BaselineCompiler baselineCompiler = new BaselineCompiler(GraphBuilderConfiguration.getDefault(), providers.getMetaAccess()); OptimisticOptimizations optimisticOpts = OptimisticOptimizations.ALL; - result = baselineCompiler.generate(method, -1, backend, new CompilationResult(), method, CompilationResultBuilderFactory.Default, optimisticOpts); + result = baselineCompiler.generate(method, -1, backend, new CompilationResult(), method, CompilationResultBuilderFactory.Default, optimisticOpts, providers.getReplacements()); } else { Map graphCache = null; if (GraalOptions.CacheGraphs.getValue()) { diff -r c198e397bb59 -r 75da87c96605 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 Sat Jan 31 00:19:34 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java Sat Jan 31 00:30:00 2015 +0100 @@ -31,6 +31,7 @@ import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.stubs.*; +import com.oracle.graal.java.*; import com.oracle.graal.nodes.spi.*; /** @@ -65,6 +66,15 @@ HotSpotHostForeignCallsProvider foreignCalls = (HotSpotHostForeignCallsProvider) providers.getForeignCalls(); final HotSpotLoweringProvider lowerer = (HotSpotLoweringProvider) providers.getLowerer(); + try (InitTimer st = timer("graphBuilderPlugins.initialize")) { + GraphBuilderPhase phase = (GraphBuilderPhase) providers.getSuites().getDefaultGraphBuilderSuite().findPhase(GraphBuilderPhase.class).previous(); + GraphBuilderPlugins plugins = phase.getGraphBuilderPlugins(); + Iterable sl = Services.load(GraphBuilderPluginsProvider.class); + for (GraphBuilderPluginsProvider p : sl) { + p.registerPlugins(providers.getMetaAccess(), plugins); + } + } + try (InitTimer st = timer("foreignCalls.initialize")) { foreignCalls.initialize(providers, config); } @@ -92,6 +102,5 @@ throw Debug.handle(e); } } - } } diff -r c198e397bb59 -r 75da87c96605 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 Sat Jan 31 00:19:34 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java Sat Jan 31 00:30:00 2015 +0100 @@ -30,7 +30,7 @@ import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.phases.*; import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderConfiguration.*; +import com.oracle.graal.java.GraphBuilderConfiguration.DebugInfoMode; import com.oracle.graal.options.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.tiers.*; diff -r c198e397bb59 -r 75da87c96605 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotGraphBuilderPluginsProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotGraphBuilderPluginsProvider.java Sat Jan 31 00:30:00 2015 +0100 @@ -0,0 +1,61 @@ +/* + * 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.hotspot.replacements; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.runtime.*; +import com.oracle.graal.java.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; + +@ServiceProvider(GraphBuilderPluginsProvider.class) +public class HotSpotGraphBuilderPluginsProvider implements GraphBuilderPluginsProvider { + public void registerPlugins(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins) { + plugins.register(metaAccess, ObjectPlugin.class); + } + + enum ObjectPlugin implements GraphBuilderPlugin { + getClass() { + public boolean handleInvocation(GraphBuilderContext builder, ValueNode[] args) { + assert args.length == 1; + ValueNode rcvr = args[0]; + GuardingPiNode pi = builder.append(new GuardingPiNode(rcvr)); + StampProvider stampProvider = builder.getStampProvider(); + LoadHubNode hub = builder.append(new LoadHubNode(stampProvider, pi)); + HubGetClassNode mirror = builder.append(new HubGetClassNode(builder.getMetaAccess(), hub)); + builder.push(Kind.Object, mirror); + return true; + } + }; + + public ResolvedJavaMethod getInvocationTarget(MetaAccessProvider metaAccess) { + return GraphBuilderPlugin.resolveTarget(metaAccess, Object.class, name()); + } + + @Override + public String toString() { + return Object.class.getName() + "." + name() + "()"; + } + } +} diff -r c198e397bb59 -r 75da87c96605 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 Sat Jan 31 00:19:34 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Sat Jan 31 00:30:00 2015 +0100 @@ -1153,5 +1153,4 @@ } Debug.log("%s", sb); } - } diff -r c198e397bb59 -r 75da87c96605 graal/com.oracle.graal.java/src/com/oracle/graal/java/DefaultGraphBuilderPluginsProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/DefaultGraphBuilderPluginsProvider.java Sat Jan 31 00:30:00 2015 +0100 @@ -0,0 +1,74 @@ +/* + * 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.runtime.*; +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; + +@ServiceProvider(GraphBuilderPluginsProvider.class) +public class DefaultGraphBuilderPluginsProvider implements GraphBuilderPluginsProvider { + public void registerPlugins(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins) { + plugins.register(metaAccess, ObjectPlugin.class); + } + + enum ObjectPlugin implements GraphBuilderPlugin { + init() { + public boolean handleInvocation(GraphBuilderContext builder, ValueNode[] args) { + assert args.length == 1; + ValueNode rcvr = args[0]; + ObjectStamp objectStamp = (ObjectStamp) rcvr.stamp(); + + boolean needsCheck = true; + if (objectStamp.isExactType()) { + needsCheck = objectStamp.type().hasFinalizer(); + } else if (objectStamp.type() != null && !objectStamp.type().hasFinalizableSubclass()) { + // if either the declared type of receiver or the holder + // can be assumed to have no finalizers + Assumptions assumptions = builder.getAssumptions(); + if (assumptions.useOptimisticAssumptions()) { + assumptions.recordNoFinalizableSubclassAssumption(objectStamp.type()); + needsCheck = false; + } + } + + if (needsCheck) { + builder.append(new RegisterFinalizerNode(rcvr)); + } + return true; + } + + public ResolvedJavaMethod getInvocationTarget(MetaAccessProvider metaAccess) { + return GraphBuilderPlugin.resolveTarget(metaAccess, Object.class, ""); + } + }; + + @Override + public String toString() { + return Object.class.getName() + "." + name() + "()"; + } + } +} diff -r c198e397bb59 -r 75da87c96605 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderContext.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderContext.java Sat Jan 31 00:30:00 2015 +0100 @@ -0,0 +1,51 @@ +/* + * 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.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 { + + T append(T fixed); + + T append(T fixed); + + T append(T fixed); + + T append(T v); + + StampProvider getStampProvider(); + + MetaAccessProvider getMetaAccess(); + + Assumptions getAssumptions(); + + void push(Kind kind, ValueNode value); +} diff -r c198e397bb59 -r 75da87c96605 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 Sat Jan 31 00:19:34 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Sat Jan 31 00:30:00 2015 +0100 @@ -47,6 +47,7 @@ import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.*; @@ -58,20 +59,26 @@ public class GraphBuilderPhase extends BasePhase { private final GraphBuilderConfiguration graphBuilderConfig; + private final GraphBuilderPlugins graphBuilderPlugins; - public GraphBuilderPhase(GraphBuilderConfiguration graphBuilderConfig) { - this.graphBuilderConfig = graphBuilderConfig; + public GraphBuilderPhase(GraphBuilderConfiguration config) { + this.graphBuilderConfig = config; + this.graphBuilderPlugins = new GraphBuilderPlugins(); } @Override protected void run(StructuredGraph graph, HighTierContext context) { - new Instance(context.getMetaAccess(), graphBuilderConfig, context.getOptimisticOptimizations()).run(graph); + new Instance(context.getMetaAccess(), context.getStampProvider(), context.getAssumptions(), graphBuilderConfig, graphBuilderPlugins, context.getOptimisticOptimizations()).run(graph); } public GraphBuilderConfiguration getGraphBuilderConfig() { return graphBuilderConfig; } + public GraphBuilderPlugins getGraphBuilderPlugins() { + return graphBuilderPlugins; + } + public static class Instance extends Phase { protected StructuredGraph currentGraph; @@ -81,7 +88,10 @@ private ResolvedJavaMethod rootMethod; private final GraphBuilderConfiguration graphBuilderConfig; + private final GraphBuilderPlugins graphBuilderPlugins; private final OptimisticOptimizations optimisticOpts; + private final StampProvider stampProvider; + private final Assumptions assumptions; /** * Gets the graph being processed by this builder. @@ -90,13 +100,21 @@ return currentGraph; } - public Instance(MetaAccessProvider metaAccess, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) { + public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, Assumptions assumptions, GraphBuilderConfiguration graphBuilderConfig, GraphBuilderPlugins graphBuilderPlugins, + OptimisticOptimizations optimisticOpts) { this.graphBuilderConfig = graphBuilderConfig; this.optimisticOpts = optimisticOpts; this.metaAccess = metaAccess; + this.stampProvider = stampProvider; + this.assumptions = assumptions; + this.graphBuilderPlugins = graphBuilderPlugins; assert metaAccess != null; } + public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, Assumptions assumptions, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) { + this(metaAccess, stampProvider, assumptions, graphBuilderConfig, null, optimisticOpts); + } + @Override protected void run(StructuredGraph graph) { ResolvedJavaMethod method = graph.method(); @@ -143,7 +161,7 @@ } } - public class BytecodeParser extends AbstractBytecodeParser { + public class BytecodeParser extends AbstractBytecodeParser implements GraphBuilderContext { private BciBlock[] loopHeaders; private LocalLiveness liveness; @@ -752,38 +770,49 @@ args[0] = TypeProfileProxyNode.proxify(args[0], profile); } } + if (GraalOptions.InlineDuringParsing.getValue() && invokeKind.isDirect()) { - if (GraalOptions.InlineDuringParsing.getValue() && invokeKind.isDirect() && targetMethod.canBeInlined() && targetMethod.hasBytecodes()) { - if (targetMethod.getCode().length <= GraalOptions.TrivialInliningSize.getValue() && currentDepth < GraalOptions.InlineDuringParsingMaxDepth.getValue() && - graphBuilderConfig.shouldInlineTrivial()) { - BytecodeParser parser = new BytecodeParser(metaAccess, targetMethod, graphBuilderConfig, optimisticOpts, StructuredGraph.INVOCATION_ENTRY_BCI); - final FrameState[] lazyFrameState = new FrameState[1]; - HIRFrameStateBuilder startFrameState = new HIRFrameStateBuilder(targetMethod, currentGraph, () -> { - if (lazyFrameState[0] == null) { - lazyFrameState[0] = frameState.create(bci()); - } - return lazyFrameState[0]; - }); - startFrameState.initializeFromArgumentsArray(args); - parser.build(currentDepth + 1, this.lastInstr, startFrameState); - - FixedWithNextNode calleeBeforeReturnNode = parser.getBeforeReturnNode(); - this.lastInstr = calleeBeforeReturnNode; - if (calleeBeforeReturnNode != null) { - ValueNode calleeReturnValue = parser.getReturnValue(); - if (calleeReturnValue != null) { - frameState.push(calleeReturnValue.getKind().getStackKind(), calleeReturnValue); + if (graphBuilderPlugins != null) { + GraphBuilderPlugin plugin = graphBuilderPlugins.getPlugin(targetMethod); + if (plugin != null) { + if (plugin.handleInvocation(this, args)) { + return; } } + } - FixedWithNextNode calleeBeforeUnwindNode = parser.getBeforeUnwindNode(); - if (calleeBeforeUnwindNode != null) { - ValueNode calleeUnwindValue = parser.getUnwindValue(); - assert calleeUnwindValue != null; - calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci())); + if (targetMethod.canBeInlined() && targetMethod.hasBytecodes()) { + if (targetMethod.getCode().length <= GraalOptions.TrivialInliningSize.getValue() && currentDepth < GraalOptions.InlineDuringParsingMaxDepth.getValue() && + graphBuilderConfig.shouldInlineTrivial()) { + BytecodeParser parser = new BytecodeParser(metaAccess, targetMethod, graphBuilderConfig, optimisticOpts, StructuredGraph.INVOCATION_ENTRY_BCI); + final FrameState[] lazyFrameState = new FrameState[1]; + HIRFrameStateBuilder startFrameState = new HIRFrameStateBuilder(targetMethod, currentGraph, () -> { + if (lazyFrameState[0] == null) { + lazyFrameState[0] = frameState.create(bci()); + } + return lazyFrameState[0]; + }); + startFrameState.initializeFromArgumentsArray(args); + parser.build(currentDepth + 1, this.lastInstr, startFrameState); + + FixedWithNextNode calleeBeforeReturnNode = parser.getBeforeReturnNode(); + this.lastInstr = calleeBeforeReturnNode; + if (calleeBeforeReturnNode != null) { + ValueNode calleeReturnValue = parser.getReturnValue(); + if (calleeReturnValue != null) { + frameState.push(calleeReturnValue.getKind().getStackKind(), calleeReturnValue); + } + } + + FixedWithNextNode calleeBeforeUnwindNode = parser.getBeforeUnwindNode(); + if (calleeBeforeUnwindNode != null) { + ValueNode calleeUnwindValue = parser.getUnwindValue(); + assert calleeUnwindValue != null; + calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci())); + } + + return; } - - return; } } @@ -937,7 +966,7 @@ throw GraalInternalError.shouldNotReachHere("Can not append Node of type: " + v.getClass().getName()); } - private T append(T fixed) { + public T append(T fixed) { assert !fixed.isAlive() && !fixed.isDeleted() : "instruction should not have been appended yet"; assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")"; T added = currentGraph.add(fixed); @@ -946,7 +975,7 @@ return added; } - private T append(T fixed) { + public T append(T fixed) { assert !fixed.isAlive() && !fixed.isDeleted() : "instruction should not have been appended yet"; assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")"; T added = currentGraph.add(fixed); @@ -955,7 +984,7 @@ return added; } - protected T append(T fixed) { + public T append(T fixed) { assert !fixed.isAlive() && !fixed.isDeleted() : "instruction should not have been appended yet"; assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")"; T added = currentGraph.add(fixed); @@ -964,7 +993,7 @@ return added; } - private T append(T v) { + public T append(T v) { assert !(v instanceof ConstantNode); T added = currentGraph.unique(v); return added; @@ -1456,6 +1485,22 @@ append(ifNode); } + public StampProvider getStampProvider() { + return stampProvider; + } + + public MetaAccessProvider getMetaAccess() { + return metaAccess; + } + + public Assumptions getAssumptions() { + return assumptions; + } + + public void push(Kind kind, ValueNode value) { + frameState.push(kind, value); + } + } } } diff -r c198e397bb59 -r 75da87c96605 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugin.java Sat Jan 31 00:30:00 2015 +0100 @@ -0,0 +1,57 @@ +/* + * 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.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.nodes.*; + +/** + * Extensions for handling certain bytecode instructions while building a + * {@linkplain StructuredGraph graph} from a bytecode stream. + */ +public interface GraphBuilderPlugin { + + /** + * Processes an invocation parsed in a bytecode stream and add nodes to a graph being + * constructed that implement the semantics of the invocation. + * + * @param builder object being used to build a graph + * @param args the arguments to the invocation + */ + boolean handleInvocation(GraphBuilderContext builder, ValueNode[] args); + + /** + * Gets the target method handled by {@link #handleInvocation(GraphBuilderContext, ValueNode[])} + * . + */ + ResolvedJavaMethod getInvocationTarget(MetaAccessProvider metaAccess); + + static ResolvedJavaMethod resolveTarget(MetaAccessProvider metaAccess, Class clazz, String methodName, Class... parameterTypes) { + try { + return metaAccess.lookupJavaMethod(methodName.equals("") ? clazz.getDeclaredConstructor(parameterTypes) : clazz.getDeclaredMethod(methodName, parameterTypes)); + } catch (NoSuchMethodException | SecurityException e) { + throw new GraalInternalError(e); + } + } +} diff -r c198e397bb59 -r 75da87c96605 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugins.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugins.java Sat Jan 31 00:30:00 2015 +0100 @@ -0,0 +1,65 @@ +/* + * 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.util.*; +import java.util.stream.*; + +import com.oracle.graal.api.meta.*; + +/** + * A repository of {@link GraphBuilderPlugin}s. + */ +public class GraphBuilderPlugins { + + private final Map map = new HashMap<>(); + + /** + * Registers all the constants of an enum that implements {@link GraphBuilderPlugin}. + */ + public & GraphBuilderPlugin> void register(MetaAccessProvider metaAccess, Class enumClass) { + assert Enum.class.isAssignableFrom(enumClass); + Object[] enumConstants = enumClass.getEnumConstants(); + for (Object o : enumConstants) { + GraphBuilderPlugin gbp = (GraphBuilderPlugin) o; + ResolvedJavaMethod target = gbp.getInvocationTarget(metaAccess); + GraphBuilderPlugin oldValue = map.put(target, gbp); + assert oldValue == null; + } + } + + /** + * Gets the plugin for a given method registered in the object. + * + * @param method the method to lookup + * @return the plugin associated with {@code method} or {@code null} if none exists + */ + public GraphBuilderPlugin getPlugin(ResolvedJavaMethod method) { + return map.get(method); + } + + @Override + public String toString() { + return map.keySet().stream().map(m -> m.format("%H.%n(%p)")).collect(Collectors.joining(", ")); + } +} diff -r c198e397bb59 -r 75da87c96605 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPluginsProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPluginsProvider.java Sat Jan 31 00:30:00 2015 +0100 @@ -0,0 +1,38 @@ +/* + * 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.meta.*; +import com.oracle.graal.api.runtime.*; + +/** + * Interface for providers of {@link GraphBuilderPlugin}s. + */ +public interface GraphBuilderPluginsProvider extends Service { + /** + * Registers the plugins provided by this object with a plugins registry. + * + * @param plugins registry of plugins + */ + void registerPlugins(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins); +} diff -r c198e397bb59 -r 75da87c96605 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 Sat Jan 31 00:19:34 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Sat Jan 31 00:30:00 2015 +0100 @@ -605,7 +605,8 @@ if (MethodsElidedInSnippets != null && methodToParse.getSignature().getReturnKind() == Kind.Void && MethodFilter.matches(MethodsElidedInSnippets, methodToParse)) { graph.addAfterFixed(graph.start(), graph.add(new ReturnNode(null))); } else { - createGraphBuilder(metaAccess, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph); + createGraphBuilder(metaAccess, replacements.providers.getStampProvider(), replacements.assumptions, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply( + graph); } afterParsing(graph); @@ -618,8 +619,9 @@ return graph; } - protected Instance createGraphBuilder(MetaAccessProvider metaAccess, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) { - return new GraphBuilderPhase.Instance(metaAccess, graphBuilderConfig, optimisticOpts); + protected Instance createGraphBuilder(MetaAccessProvider metaAccess, StampProvider stampProvider, Assumptions assumptions, GraphBuilderConfiguration graphBuilderConfig, + OptimisticOptimizations optimisticOpts) { + return new GraphBuilderPhase.Instance(metaAccess, stampProvider, assumptions, graphBuilderConfig, optimisticOpts); } protected void afterParsing(StructuredGraph graph) { diff -r c198e397bb59 -r 75da87c96605 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 Sat Jan 31 00:19:34 2015 +0100 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Sat Jan 31 00:30:00 2015 +0100 @@ -177,7 +177,7 @@ Suites suites = suitesProvider.createSuites(); removeInliningPhase(suites); StructuredGraph graph = new StructuredGraph(javaMethod); - new GraphBuilderPhase.Instance(metaAccess, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); + new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), new Assumptions(false), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); PhaseSuite graphBuilderSuite = getGraphBuilderSuite(suitesProvider); CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false); Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend(); diff -r c198e397bb59 -r 75da87c96605 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 Sat Jan 31 00:19:34 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Sat Jan 31 00:30:00 2015 +0100 @@ -94,13 +94,13 @@ public StructuredGraph createInlineGraph(String name) { StructuredGraph graph = new StructuredGraph(name, callInlinedMethod); - new GraphBuilderPhase.Instance(providers.getMetaAccess(), config, TruffleCompilerImpl.Optimizations).apply(graph); + new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), new Assumptions(false), config, TruffleCompilerImpl.Optimizations).apply(graph); return graph; } public StructuredGraph createRootGraph(String name) { StructuredGraph graph = new StructuredGraph(name, callRootMethod); - new GraphBuilderPhase.Instance(providers.getMetaAccess(), configForRoot, TruffleCompilerImpl.Optimizations).apply(graph); + new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), new Assumptions(false), configForRoot, TruffleCompilerImpl.Optimizations).apply(graph); return graph; } @@ -294,7 +294,7 @@ protected StructuredGraph parseGraph(final ResolvedJavaMethod method, final PhaseContext phaseContext) { final StructuredGraph graph = new StructuredGraph(method); - new GraphBuilderPhase.Instance(phaseContext.getMetaAccess(), config, optimisticOptimizations).apply(graph); + new GraphBuilderPhase.Instance(phaseContext.getMetaAccess(), phaseContext.getStampProvider(), phaseContext.getAssumptions(), config, optimisticOptimizations).apply(graph); return graph; } diff -r c198e397bb59 -r 75da87c96605 mx/suite.py --- a/mx/suite.py Sat Jan 31 00:19:34 2015 +0100 +++ b/mx/suite.py Sat Jan 31 00:30:00 2015 +0100 @@ -818,6 +818,7 @@ "com.oracle.graal.phases", ], "checkstyle" : "com.oracle.graal.graph", + "annotationProcessors" : ["com.oracle.graal.service.processor"], "javaCompliance" : "1.8", "workingSets" : "Graal,Java", },