# HG changeset patch # User Tom Rodriguez # Date 1422853076 28800 # Node ID a8bcda325946d54c3bfb14da56e0b4d9b5aff524 # Parent c370e6f3957528e89454dc4db63b455cbef8d3f7# Parent 9544b5f6762615ef1c262a0af247da501d9bdd7f Merge diff -r c370e6f39575 -r a8bcda325946 graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Services.java --- a/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Services.java Fri Jan 30 11:56:24 2015 -0800 +++ b/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Services.java Sun Feb 01 20:57:56 2015 -0800 @@ -38,7 +38,9 @@ protected List computeValue(Class type) { Service[] names = getServiceImpls(type); if (names == null || names.length == 0) { - throw new InternalError(format("No implementations for %s found (ensure %s extends %s)", type.getSimpleName(), type.getSimpleName(), Service.class)); + throw new InternalError( + format("No implementations for %s found (ensure %s extends %s and that in suite.py the \"annotationProcessors\" attribute for the project enclosing %s includes \"com.oracle.graal.service.processor\")", + type.getSimpleName(), type.getSimpleName(), Service.class, type.getSimpleName())); } return Arrays.asList(names); } diff -r c370e6f39575 -r a8bcda325946 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 Fri Jan 30 11:56:24 2015 -0800 +++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineCompiler.java Sun Feb 01 20:57:56 2015 -0800 @@ -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 c370e6f39575 -r a8bcda325946 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticStamp.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticStamp.java Fri Jan 30 11:56:24 2015 -0800 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticStamp.java Sun Feb 01 20:57:56 2015 -0800 @@ -23,6 +23,7 @@ package com.oracle.graal.compiler.common.type; import java.nio.*; +import java.util.*; import com.oracle.graal.api.meta.*; @@ -59,7 +60,7 @@ if (!(obj instanceof ArithmeticStamp)) { return false; } - assert this.ops.toString().equals(((ArithmeticStamp) obj).ops.toString()); + assert Objects.equals(ops, ((ArithmeticStamp) obj).ops); return true; } } diff -r c370e6f39575 -r a8bcda325946 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java Fri Jan 30 11:56:24 2015 -0800 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java Sun Feb 01 20:57:56 2015 -0800 @@ -256,9 +256,6 @@ if (!(otherStamp instanceof IntegerStamp)) { return StampFactory.illegal(Kind.Illegal); } - if (equals(otherStamp)) { - return this; - } IntegerStamp other = (IntegerStamp) otherStamp; return createStamp(other, Math.max(upperBound, other.upperBound), Math.min(lowerBound, other.lowerBound), downMask & other.downMask, upMask | other.upMask); } diff -r c370e6f39575 -r a8bcda325946 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 Fri Jan 30 11:56:24 2015 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Sun Feb 01 20:57:56 2015 -0800 @@ -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 c370e6f39575 -r a8bcda325946 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 Fri Jan 30 11:56:24 2015 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Sun Feb 01 20:57:56 2015 -0800 @@ -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 c370e6f39575 -r a8bcda325946 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 Fri Jan 30 11:56:24 2015 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java Sun Feb 01 20:57:56 2015 -0800 @@ -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 c370e6f39575 -r a8bcda325946 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 Fri Jan 30 11:56:24 2015 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysis.java Sun Feb 01 20:57:56 2015 -0800 @@ -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 c370e6f39575 -r a8bcda325946 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 Fri Jan 30 11:56:24 2015 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysisTests.java Sun Feb 01 20:57:56 2015 -0800 @@ -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 c370e6f39575 -r a8bcda325946 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Edges.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Edges.java Fri Jan 30 11:56:24 2015 -0800 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Edges.java Sun Feb 01 20:57:56 2015 -0800 @@ -331,7 +331,13 @@ } else { subIndex++; } - while (index < edges.getCount()) { + if (index < edges.getCount()) { + forwardNodeList(); + } + } + + private void forwardNodeList() { + do { if (subIndex == 0) { list = edges.getNodeList(node, index); } @@ -346,7 +352,7 @@ } subIndex = 0; index++; - } + } while (index < edges.getCount()); } private Node nextElement() { diff -r c370e6f39575 -r a8bcda325946 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 Fri Jan 30 11:56:24 2015 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Sun Feb 01 20:57:56 2015 -0800 @@ -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 c370e6f39575 -r a8bcda325946 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 Fri Jan 30 11:56:24 2015 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java Sun Feb 01 20:57:56 2015 -0800 @@ -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 c370e6f39575 -r a8bcda325946 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 Fri Jan 30 11:56:24 2015 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java Sun Feb 01 20:57:56 2015 -0800 @@ -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 c370e6f39575 -r a8bcda325946 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 Sun Feb 01 20:57:56 2015 -0800 @@ -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 c370e6f39575 -r a8bcda325946 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 Fri Jan 30 11:56:24 2015 -0800 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Sun Feb 01 20:57:56 2015 -0800 @@ -1153,5 +1153,4 @@ } Debug.log("%s", sb); } - } diff -r c370e6f39575 -r a8bcda325946 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 Sun Feb 01 20:57:56 2015 -0800 @@ -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 c370e6f39575 -r a8bcda325946 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 Sun Feb 01 20:57:56 2015 -0800 @@ -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 c370e6f39575 -r a8bcda325946 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri Jan 30 11:56:24 2015 -0800 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Sun Feb 01 20:57:56 2015 -0800 @@ -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 c370e6f39575 -r a8bcda325946 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 Sun Feb 01 20:57:56 2015 -0800 @@ -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 c370e6f39575 -r a8bcda325946 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 Sun Feb 01 20:57:56 2015 -0800 @@ -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 c370e6f39575 -r a8bcda325946 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 Sun Feb 01 20:57:56 2015 -0800 @@ -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 c370e6f39575 -r a8bcda325946 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInsertionBuffer.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInsertionBuffer.java Fri Jan 30 11:56:24 2015 -0800 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInsertionBuffer.java Sun Feb 01 20:57:56 2015 -0800 @@ -48,7 +48,8 @@ * index into lir list where "count" ops should be inserted indexAndCount[i * 2 + 1]: the number * of ops to be inserted at index */ - private final List indexAndCount; + private int[] indexAndCount; + private int indexAndCountSize; /** * The LIROps to be inserted. @@ -56,8 +57,8 @@ private final List ops; public LIRInsertionBuffer() { - indexAndCount = new ArrayList<>(8); - ops = new ArrayList<>(8); + indexAndCount = new int[8]; + ops = new ArrayList<>(4); } /** @@ -65,7 +66,7 @@ */ public void init(List newLir) { assert !initialized() : "already initialized"; - assert indexAndCount.size() == 0 && ops.size() == 0; + assert indexAndCountSize == 0 && ops.size() == 0; this.lir = newLir; } @@ -126,32 +127,38 @@ } ipIndex--; } - indexAndCount.clear(); + indexAndCountSize = 0; ops.clear(); } lir = null; } private void appendNew(int index, int count) { - indexAndCount.add(index); - indexAndCount.add(count); + int oldSize = indexAndCountSize; + int newSize = oldSize + 2; + if (newSize > this.indexAndCount.length) { + indexAndCount = Arrays.copyOf(indexAndCount, newSize * 2); + } + indexAndCount[oldSize] = index; + indexAndCount[oldSize + 1] = count; + this.indexAndCountSize = newSize; } private void setCountAt(int i, int value) { - indexAndCount.set((i << 1) + 1, value); + indexAndCount[(i << 1) + 1] = value; } private int numberOfInsertionPoints() { - assert indexAndCount.size() % 2 == 0 : "must have a count for each index"; - return indexAndCount.size() >> 1; + assert indexAndCount.length % 2 == 0 : "must have a count for each index"; + return indexAndCountSize >> 1; } private int indexAt(int i) { - return indexAndCount.get((i << 1)); + return indexAndCount[(i << 1)]; } private int countAt(int i) { - return indexAndCount.get((i << 1) + 1); + return indexAndCount[(i << 1) + 1]; } private boolean verify() { diff -r c370e6f39575 -r a8bcda325946 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Fri Jan 30 11:56:24 2015 -0800 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Sun Feb 01 20:57:56 2015 -0800 @@ -641,177 +641,210 @@ @Override protected void node(FixedNode node) { if (node instanceof AbstractBeginNode) { - AbstractBeginNode begin = (AbstractBeginNode) node; - Node pred = node.predecessor(); + processAbstractBegin((AbstractBeginNode) node); + } else if (node instanceof FixedGuardNode) { + processFixedGuard((FixedGuardNode) node); + } else if (node instanceof CheckCastNode) { + processCheckCast((CheckCastNode) node); + } else if (node instanceof ConditionAnchorNode) { + processConditionAnchor((ConditionAnchorNode) node); + } else if (node instanceof IfNode) { + processIf((IfNode) node); + } else if (node instanceof AbstractEndNode) { + processAbstractEnd((AbstractEndNode) node); + } else if (node instanceof Invoke) { + processInvoke((Invoke) node); + } + } - if (pred != null) { - registerControlSplitInfo(pred, begin); - } - - // First eliminate any guards which can be trivially removed and register any - // type constraints the guards produce. - for (GuardNode guard : begin.guards().snapshot()) { - eliminateTrivialGuardOrRegisterStamp(guard); - } + private void processIf(IfNode ifNode) { + LogicNode compare = ifNode.condition(); - // Collect the guards which have produced conditional stamps. - // XXX (gd) IdentityHashMap.values().contains performs a linear search - // so we prefer to build a set - Set provers = Node.newSet(); - for (GuardedStamp e : state.valueConstraints.values()) { - provers.add(e.getGuard()); - } - - // Process the remaining guards. Guards which produced some type constraint should - // just be registered since they aren't trivially deleteable. Test the other guards - // to see if they can be deleted using type constraints. - for (GuardNode guard : begin.guards().snapshot()) { - if (provers.contains(guard) || !(tryReplaceWithExistingGuard(guard) || testImpliedGuard(guard))) { - registerCondition(!guard.isNegated(), guard.condition(), guard); + LogicNode replacement = null; + GuardingNode replacementAnchor = null; + AbstractBeginNode survivingSuccessor = null; + if (state.trueConditions.containsKey(compare)) { + replacement = trueConstant; + replacementAnchor = state.trueConditions.get(compare); + survivingSuccessor = ifNode.trueSuccessor(); + } else if (state.falseConditions.containsKey(compare)) { + replacement = falseConstant; + replacementAnchor = state.falseConditions.get(compare); + survivingSuccessor = ifNode.falseSuccessor(); + } else { + replacement = evaluateCondition(compare, trueConstant, falseConstant); + if (replacement != null) { + if (replacement == trueConstant) { + survivingSuccessor = ifNode.trueSuccessor(); + } else { + assert replacement == falseConstant; + survivingSuccessor = ifNode.falseSuccessor(); } } - for (GuardNode guard : provers) { - assert !testImpliedGuard(guard) : "provers shouldn't be trivially eliminatable"; - } - } else if (node instanceof FixedGuardNode) { - FixedGuardNode guard = (FixedGuardNode) node; - GuardingNode existingGuard = guard.isNegated() ? state.falseConditions.get(guard.condition()) : state.trueConditions.get(guard.condition()); - if (existingGuard != null && existingGuard instanceof FixedGuardNode) { - guard.replaceAtUsages(existingGuard.asNode()); - guard.graph().removeFixed(guard); - } else { - registerCondition(!guard.isNegated(), guard.condition(), guard); - } - } else if (node instanceof CheckCastNode) { - CheckCastNode checkCast = (CheckCastNode) node; - ValueNode object = checkCast.object(); - boolean isNull = state.isNull(object); - ResolvedJavaType type = state.getNodeType(object); - if (isNull || (type != null && checkCast.type().isAssignableFrom(type))) { - boolean nonNull = state.isNonNull(object); - GuardingNode replacementAnchor = null; - if (nonNull) { - replacementAnchor = searchAnchor(GraphUtil.unproxify(object), type); - } - if (replacementAnchor == null) { - replacementAnchor = AbstractBeginNode.prevBegin(checkCast); - } - PiNode piNode; - if (isNull) { - ConstantNode nullObject = ConstantNode.defaultForKind(Kind.Object, graph); - piNode = graph.unique(new PiNode(nullObject, nullObject.stamp(), replacementAnchor.asNode())); - } else { - piNode = graph.unique(new PiNode(object, StampFactory.declaredTrusted(type, nonNull), replacementAnchor.asNode())); - } - checkCast.replaceAtUsages(piNode); - graph.removeFixed(checkCast); - metricCheckCastRemoved.increment(); - } - } else if (node instanceof ConditionAnchorNode) { - ConditionAnchorNode conditionAnchorNode = (ConditionAnchorNode) node; - LogicNode condition = conditionAnchorNode.condition(); - GuardingNode replacementAnchor = null; - if (conditionAnchorNode.isNegated()) { - if (state.falseConditions.containsKey(condition)) { - replacementAnchor = state.falseConditions.get(condition); - } - } else { - if (state.trueConditions.containsKey(condition)) { - replacementAnchor = state.trueConditions.get(condition); - } - } - if (replacementAnchor != null) { - conditionAnchorNode.replaceAtUsages(replacementAnchor.asNode()); - conditionAnchorNode.graph().removeFixed(conditionAnchorNode); - } - } else if (node instanceof IfNode) { - IfNode ifNode = (IfNode) node; - LogicNode compare = ifNode.condition(); + } + + if (replacement != null) { + trySimplify(ifNode, compare, replacement, replacementAnchor, survivingSuccessor); + } + } - LogicNode replacement = null; - GuardingNode replacementAnchor = null; - AbstractBeginNode survivingSuccessor = null; - if (state.trueConditions.containsKey(compare)) { - replacement = trueConstant; - replacementAnchor = state.trueConditions.get(compare); - survivingSuccessor = ifNode.trueSuccessor(); - } else if (state.falseConditions.containsKey(compare)) { - replacement = falseConstant; - replacementAnchor = state.falseConditions.get(compare); - survivingSuccessor = ifNode.falseSuccessor(); + private void trySimplify(IfNode ifNode, LogicNode compare, LogicNode replacement, GuardingNode replacementAnchor, AbstractBeginNode survivingSuccessor) { + if (replacementAnchor != null && !(replacementAnchor instanceof AbstractBeginNode)) { + ValueAnchorNode anchor = graph.add(new ValueAnchorNode(replacementAnchor.asNode())); + graph.addBeforeFixed(ifNode, anchor); + } + boolean canSimplify = true; + for (Node n : survivingSuccessor.usages().snapshot()) { + if (n instanceof GuardNode || n instanceof ProxyNode) { + // Keep wired to the begin node. } else { - replacement = evaluateCondition(compare, trueConstant, falseConstant); - if (replacement != null) { - if (replacement == trueConstant) { - survivingSuccessor = ifNode.trueSuccessor(); - } else { - assert replacement == falseConstant; - survivingSuccessor = ifNode.falseSuccessor(); - } - } - } - - if (replacement != null) { - if (replacementAnchor != null && !(replacementAnchor instanceof AbstractBeginNode)) { - ValueAnchorNode anchor = graph.add(new ValueAnchorNode(replacementAnchor.asNode())); - graph.addBeforeFixed(ifNode, anchor); + if (replacementAnchor == null) { + // Cannot simplify this IfNode as there is no anchor. + canSimplify = false; + break; } - for (Node n : survivingSuccessor.usages().snapshot()) { - if (n instanceof GuardNode || n instanceof ProxyNode) { - // Keep wired to the begin node. - } else { - if (replacementAnchor == null) { - // Cannot simplify this IfNode as there is no anchor. - return; - } - // Rewire to the replacement anchor. - n.replaceFirstInput(survivingSuccessor, replacementAnchor.asNode()); - } - } + // Rewire to the replacement anchor. + n.replaceFirstInput(survivingSuccessor, replacementAnchor.asNode()); + } + } + + if (canSimplify) { + ifNode.setCondition(replacement); + if (compare.hasNoUsages()) { + GraphUtil.killWithUnusedFloatingInputs(compare); + } + } + } - ifNode.setCondition(replacement); - if (compare.hasNoUsages()) { - GraphUtil.killWithUnusedFloatingInputs(compare); - } - } - } else if (node instanceof AbstractEndNode) { - AbstractEndNode endNode = (AbstractEndNode) node; - for (PhiNode phi : endNode.merge().phis()) { - int index = endNode.merge().phiPredecessorIndex(endNode); - ValueNode value = phi.valueAt(index); - if (value instanceof ConditionalNode) { - ConditionalNode materialize = (ConditionalNode) value; - LogicNode compare = materialize.condition(); - ValueNode replacement = evaluateCondition(compare, materialize.trueValue(), materialize.falseValue()); - - if (replacement != null) { - phi.setValueAt(index, replacement); - if (materialize.hasNoUsages()) { - GraphUtil.killWithUnusedFloatingInputs(materialize); + private void processInvoke(Invoke invoke) { + if (invoke.callTarget() instanceof MethodCallTargetNode) { + MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget(); + ValueNode receiver = callTarget.receiver(); + if (receiver != null && callTarget.invokeKind().isIndirect()) { + ResolvedJavaType type = state.getNodeType(receiver); + if (!Objects.equals(type, StampTool.typeOrNull(receiver))) { + ResolvedJavaMethod method = type.resolveConcreteMethod(callTarget.targetMethod(), invoke.getContextType()); + if (method != null) { + if (method.canBeStaticallyBound() || type.isFinal()) { + callTarget.setInvokeKind(InvokeKind.Special); + callTarget.setTargetMethod(method); } } } } - } else if (node instanceof Invoke) { - Invoke invoke = (Invoke) node; - if (invoke.callTarget() instanceof MethodCallTargetNode) { - MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget(); - ValueNode receiver = callTarget.receiver(); - if (receiver != null && callTarget.invokeKind().isIndirect()) { - ResolvedJavaType type = state.getNodeType(receiver); - if (!Objects.equals(type, StampTool.typeOrNull(receiver))) { - ResolvedJavaMethod method = type.resolveConcreteMethod(callTarget.targetMethod(), invoke.getContextType()); - if (method != null) { - if (method.canBeStaticallyBound() || type.isFinal()) { - callTarget.setInvokeKind(InvokeKind.Special); - callTarget.setTargetMethod(method); - } - } + } + } + + private void processAbstractEnd(AbstractEndNode endNode) { + for (PhiNode phi : endNode.merge().phis()) { + int index = endNode.merge().phiPredecessorIndex(endNode); + ValueNode value = phi.valueAt(index); + if (value instanceof ConditionalNode) { + ConditionalNode materialize = (ConditionalNode) value; + LogicNode compare = materialize.condition(); + ValueNode replacement = evaluateCondition(compare, materialize.trueValue(), materialize.falseValue()); + + if (replacement != null) { + phi.setValueAt(index, replacement); + if (materialize.hasNoUsages()) { + GraphUtil.killWithUnusedFloatingInputs(materialize); } } } + } + } + private void processConditionAnchor(ConditionAnchorNode conditionAnchorNode) { + LogicNode condition = conditionAnchorNode.condition(); + GuardingNode replacementAnchor = null; + if (conditionAnchorNode.isNegated()) { + if (state.falseConditions.containsKey(condition)) { + replacementAnchor = state.falseConditions.get(condition); + } + } else { + if (state.trueConditions.containsKey(condition)) { + replacementAnchor = state.trueConditions.get(condition); + } } + if (replacementAnchor != null) { + conditionAnchorNode.replaceAtUsages(replacementAnchor.asNode()); + conditionAnchorNode.graph().removeFixed(conditionAnchorNode); + } + } + + private void processCheckCast(CheckCastNode checkCast) { + ValueNode object = checkCast.object(); + boolean isNull = state.isNull(object); + ResolvedJavaType type = state.getNodeType(object); + if (isNull || (type != null && checkCast.type().isAssignableFrom(type))) { + boolean nonNull = state.isNonNull(object); + GuardingNode replacementAnchor = null; + if (nonNull) { + replacementAnchor = searchAnchor(GraphUtil.unproxify(object), type); + } + if (replacementAnchor == null) { + replacementAnchor = AbstractBeginNode.prevBegin(checkCast); + } + PiNode piNode; + if (isNull) { + ConstantNode nullObject = ConstantNode.defaultForKind(Kind.Object, graph); + piNode = graph.unique(new PiNode(nullObject, nullObject.stamp(), replacementAnchor.asNode())); + } else { + piNode = graph.unique(new PiNode(object, StampFactory.declaredTrusted(type, nonNull), replacementAnchor.asNode())); + } + checkCast.replaceAtUsages(piNode); + graph.removeFixed(checkCast); + metricCheckCastRemoved.increment(); + } + } + + private void processFixedGuard(FixedGuardNode guard) { + GuardingNode existingGuard = guard.isNegated() ? state.falseConditions.get(guard.condition()) : state.trueConditions.get(guard.condition()); + if (existingGuard != null && existingGuard instanceof FixedGuardNode) { + guard.replaceAtUsages(existingGuard.asNode()); + guard.graph().removeFixed(guard); + } else { + registerCondition(!guard.isNegated(), guard.condition(), guard); + } + } + + private void processAbstractBegin(AbstractBeginNode begin) { + Node pred = begin.predecessor(); + + if (pred != null) { + registerControlSplitInfo(pred, begin); + } + + // First eliminate any guards which can be trivially removed and register any + // type constraints the guards produce. + for (GuardNode guard : begin.guards().snapshot()) { + eliminateTrivialGuardOrRegisterStamp(guard); + } + + // Collect the guards which have produced conditional stamps. + // XXX (gd) IdentityHashMap.values().contains performs a linear search + // so we prefer to build a set + Set provers = Node.newSet(); + for (GuardedStamp e : state.valueConstraints.values()) { + provers.add(e.getGuard()); + } + + // Process the remaining guards. Guards which produced some type constraint should + // just be registered since they aren't trivially deleteable. Test the other guards + // to see if they can be deleted using type constraints. + for (GuardNode guard : begin.guards().snapshot()) { + if (provers.contains(guard) || !(tryReplaceWithExistingGuard(guard) || testImpliedGuard(guard))) { + registerCondition(!guard.isNegated(), guard.condition(), guard); + } + } + assert assertImpliedGuard(provers); + } + + private boolean assertImpliedGuard(Set provers) { + for (GuardNode guard : provers) { + assert !testImpliedGuard(guard) : "provers shouldn't be trivially eliminatable"; + } + return true; } private GuardingNode searchAnchor(ValueNode value, ResolvedJavaType type) { diff -r c370e6f39575 -r a8bcda325946 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Fri Jan 30 11:56:24 2015 -0800 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Sun Feb 01 20:57:56 2015 -0800 @@ -1068,7 +1068,13 @@ } private void addToLatestSorting(ValueNode i, SortState state) { - if (i == null || state.isVisited(i) || cfg.getNodeToBlock().get(i) != state.currentBlock() || i instanceof PhiNode || i instanceof ProxyNode) { + if (i == null || state.isVisited(i) || cfg.getNodeToBlock().get(i) != state.currentBlock() || i instanceof PhiNode) { + return; + } + + if (i instanceof ProxyNode) { + ProxyNode proxyNode = (ProxyNode) i; + addToLatestSorting(proxyNode.value(), state); return; } diff -r c370e6f39575 -r a8bcda325946 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Fri Jan 30 11:56:24 2015 -0800 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Sun Feb 01 20:57:56 2015 -0800 @@ -619,7 +619,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); @@ -632,8 +633,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 c370e6f39575 -r a8bcda325946 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 Fri Jan 30 11:56:24 2015 -0800 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Sun Feb 01 20:57:56 2015 -0800 @@ -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 c370e6f39575 -r a8bcda325946 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 Fri Jan 30 11:56:24 2015 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Sun Feb 01 20:57:56 2015 -0800 @@ -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 c370e6f39575 -r a8bcda325946 mx/suite.py --- a/mx/suite.py Fri Jan 30 11:56:24 2015 -0800 +++ b/mx/suite.py Sun Feb 01 20:57:56 2015 -0800 @@ -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", },