# HG changeset patch # User Tom Rodriguez # Date 1426616586 25200 # Node ID 815a87264cbb50a573fe48943cd26db634f384a5 # Parent ea280aa54d58ff2eeb68d0732a5d812b755091b7# Parent fc1e46a702a14b0bed70fb969c8bbfd1d10eed73 Merge diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java --- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Tue Mar 17 11:23:06 2015 -0700 @@ -1943,6 +1943,10 @@ ADD.rmOp.emit(this, QWORD, dst, src); } + public final void addq(AMD64Address dst, Register src) { + ADD.mrOp.emit(this, QWORD, dst, src); + } + public final void andq(Register dst, int imm32) { AND.getMIOpcode(QWORD, isByte(imm32)).emit(this, QWORD, dst, imm32); } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Tue Mar 17 11:23:06 2015 -0700 @@ -41,6 +41,8 @@ import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; import com.oracle.graal.java.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; @@ -68,7 +70,8 @@ MetaAccessProvider metaAccess = providers.getMetaAccess(); PhaseSuite graphBuilderSuite = new PhaseSuite<>(); - graphBuilderSuite.appendPhase(new GraphBuilderPhase(GraphBuilderConfiguration.getEagerDefault())); + GraphBuilderConfiguration config = GraphBuilderConfiguration.getEagerDefault(new Plugins(new InvocationPlugins(metaAccess))); + graphBuilderSuite.appendPhase(new GraphBuilderPhase(config)); HighTierContext context = new HighTierContext(providers, null, graphBuilderSuite, OptimisticOptimizations.NONE); Assume.assumeTrue(VerifyPhase.class.desiredAssertionStatus()); diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Tue Mar 17 11:23:06 2015 -0700 @@ -28,10 +28,11 @@ import org.junit.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.Assumptions.Assumption; import com.oracle.graal.api.meta.Assumptions.NoFinalizableSubclass; -import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; @@ -66,7 +67,7 @@ final ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(constructors[0]); StructuredGraph graph = new StructuredGraph(javaMethod, allowAssumptions); - GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault(); + GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault(getDefaultGraphBuilderPlugins()); new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), getProviders().getConstantReflection(), conf, OptimisticOptimizations.ALL, null).apply(graph); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); new InliningPhase(new CanonicalizerPhase()).apply(graph, context); diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Tue Mar 17 11:23:06 2015 -0700 @@ -48,6 +48,8 @@ import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; import com.oracle.graal.java.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.phases.*; @@ -61,7 +63,7 @@ import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.schedule.*; -import com.oracle.graal.phases.schedule.SchedulePhase.*; +import com.oracle.graal.phases.schedule.SchedulePhase.SchedulingStrategy; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.printer.*; @@ -773,7 +775,7 @@ } /** - * Parses a Java method in {@linkplain GraphBuilderConfiguration#getDefault() default} mode to + * Parses a Java method in {@linkplain GraphBuilderConfiguration#getDefault default} mode to * produce a graph. * * @param methodName the name of the method in {@code this.getClass()} to be parsed @@ -783,7 +785,7 @@ } /** - * Parses a Java method in {@linkplain GraphBuilderConfiguration#getDefault() default} mode to + * Parses a Java method in {@linkplain GraphBuilderConfiguration#getDefault default} mode to * produce a graph. */ protected StructuredGraph parseProfiled(ResolvedJavaMethod m, AllowAssumptions allowAssumptions) { @@ -791,8 +793,8 @@ } /** - * Parses a Java method in {@linkplain GraphBuilderConfiguration#getEagerDefault() eager} mode - * to produce a graph. + * Parses a Java method in {@linkplain GraphBuilderConfiguration#getEagerDefault eager} mode to + * produce a graph. * * @param methodName the name of the method in {@code this.getClass()} to be parsed */ @@ -801,19 +803,19 @@ } /** - * Parses a Java method in {@linkplain GraphBuilderConfiguration#getEagerDefault() eager} mode - * to produce a graph. + * Parses a Java method in {@linkplain GraphBuilderConfiguration#getEagerDefault eager} mode to + * produce a graph. */ protected StructuredGraph parseEager(ResolvedJavaMethod m, AllowAssumptions allowAssumptions) { - return parse1(m, getCustomGraphBuilderSuite(GraphBuilderConfiguration.getEagerDefault()), allowAssumptions); + return parse1(m, getCustomGraphBuilderSuite(GraphBuilderConfiguration.getEagerDefault(getDefaultGraphBuilderPlugins())), allowAssumptions); } /** - * Parses a Java method in {@linkplain GraphBuilderConfiguration#getFullDebugDefault() full - * debug} mode to produce a graph. + * Parses a Java method in {@linkplain GraphBuilderConfiguration#getFullDebugDefault full debug} + * mode to produce a graph. */ protected StructuredGraph parseDebug(ResolvedJavaMethod m, AllowAssumptions allowAssumptions) { - return parse1(m, getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault()), allowAssumptions); + return parse1(m, getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault(getDefaultGraphBuilderPlugins())), allowAssumptions); } private StructuredGraph parse1(ResolvedJavaMethod javaMethod, PhaseSuite graphBuilderSuite, AllowAssumptions allowAssumptions) { @@ -827,32 +829,31 @@ } } + protected Plugins getDefaultGraphBuilderPlugins() { + PhaseSuite suite = backend.getSuites().getDefaultGraphBuilderSuite(); + Plugins defaultPlugins = ((GraphBuilderPhase) suite.findPhase(GraphBuilderPhase.class).previous()).getGraphBuilderConfig().getPlugins(); + // defensive copying + return new Plugins(defaultPlugins); + } + protected PhaseSuite getDefaultGraphBuilderSuite() { // defensive copying return backend.getSuites().getDefaultGraphBuilderSuite().copy(); } protected PhaseSuite getCustomGraphBuilderSuite(GraphBuilderConfiguration gbConf) { - PhaseSuite suite = getDefaultGraphBuilderSuite().copy(); + PhaseSuite suite = getDefaultGraphBuilderSuite(); ListIterator> iterator = suite.findPhase(GraphBuilderPhase.class); - GraphBuilderPhase graphBuilderPhase = (GraphBuilderPhase) iterator.previous(); - GraphBuilderConfiguration gbConfCopy = editGraphBuilderConfiguration(gbConf.copy().copyPluginsFrom(graphBuilderPhase.getGraphBuilderConfig())); + GraphBuilderConfiguration gbConfCopy = editGraphBuilderConfiguration(gbConf.copy()); iterator.remove(); iterator.add(new GraphBuilderPhase(gbConfCopy)); return suite; } protected GraphBuilderConfiguration editGraphBuilderConfiguration(GraphBuilderConfiguration conf) { - editGraphBuilderPlugins(conf.getPlugins()); return conf; } - /** - * @param plugins - */ - protected void editGraphBuilderPlugins(GraphBuilderConfiguration.Plugins plugins) { - } - protected Replacements getReplacements() { return getProviders().getReplacements(); } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java Tue Mar 17 11:23:06 2015 -0700 @@ -34,7 +34,7 @@ import com.oracle.graal.api.code.CompilationResult.Call; import com.oracle.graal.api.code.CompilationResult.Infopoint; import com.oracle.graal.api.meta.*; -import com.oracle.graal.java.*; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; @@ -84,7 +84,7 @@ } assertTrue(graphLineSPs > 0); CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false); - PhaseSuite graphBuilderSuite = getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault()); + PhaseSuite graphBuilderSuite = getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault(getDefaultGraphBuilderPlugins())); final CompilationResult cr = compileGraph(graph, cc, graph.method(), getProviders(), getBackend(), getCodeCache().getTarget(), null, graphBuilderSuite, OptimisticOptimizations.ALL, getProfilingInfo(graph), getSpeculationLog(), getSuites(), getLIRSuites(), new CompilationResult(), CompilationResultBuilderFactory.Default); int lineSPs = 0; diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Tue Mar 17 11:23:06 2015 -0700 @@ -282,9 +282,42 @@ } /** + * Here the read should not float out of the loop. + */ + public static int testLoop7Snippet(int a, int b, MemoryScheduleTest obj) { + int ret = 0; + int bb = b; + for (int i = 0; i < a; i++) { + ret = obj.hash; + if (a > 10) { + bb++; + } else { + bb--; + for (int k = 0; k < a; ++k) { + if (k % 2 == 1) { + for (int j = 0; j < b; ++j) { + obj.hash = 3; + } + } + } + } + ret = ret / 10; + } + return ret + bb; + } + + @Test + public void testLoop7() { + SchedulePhase schedule = getFinalSchedule("testLoop7Snippet", TestMode.WITHOUT_FRAMESTATES); + assertDeepEquals(18, schedule.getCFG().getBlocks().size()); + assertReadWithinStartBlock(schedule, false); + assertReadWithinAllReturnBlocks(schedule, false); + } + + /** * Here the read should not float to the end. */ - public static int testLoop7Snippet(int a, int b) { + public static int testLoop8Snippet(int a, int b) { int result = container.a; for (int i = 0; i < a; i++) { if (b < 0) { @@ -301,8 +334,8 @@ } @Test - public void testLoop7() { - SchedulePhase schedule = getFinalSchedule("testLoop7Snippet", TestMode.WITHOUT_FRAMESTATES); + public void testLoop8() { + SchedulePhase schedule = getFinalSchedule("testLoop8Snippet", TestMode.WITHOUT_FRAMESTATES); assertDeepEquals(10, schedule.getCFG().getBlocks().size()); assertReadWithinStartBlock(schedule, true); assertReadWithinAllReturnBlocks(schedule, false); diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SchedulingTest2.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SchedulingTest2.java Tue Mar 17 11:23:06 2015 -0700 @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2015, 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.compiler.test; + +import java.util.*; + +import org.junit.*; + +import com.oracle.graal.compiler.common.cfg.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.DeoptimizingNode.DeoptDuring; +import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.cfg.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.*; +import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.schedule.*; +import com.oracle.graal.phases.schedule.SchedulePhase.SchedulingStrategy; +import com.oracle.graal.phases.tiers.*; + +public class SchedulingTest2 extends GraphScheduleTest { + + public static int testSnippet() { + return test() + 2; + } + + public static int test() { + return 40; + } + + @Test + public void testValueProxyInputs() { + StructuredGraph graph = parseEager("testSnippet", AllowAssumptions.YES); + ReturnNode returnNode = graph.getNodes(ReturnNode.TYPE).first(); + BeginNode beginNode = graph.add(new BeginNode()); + returnNode.replaceAtPredecessor(beginNode); + beginNode.setNext(returnNode); + Debug.dump(graph, "Graph"); + SchedulePhase schedule = new SchedulePhase(SchedulingStrategy.EARLIEST); + schedule.apply(graph); + BlockMap> blockToNodesMap = schedule.getBlockToNodesMap(); + NodeMap nodeToBlock = schedule.getNodeToBlockMap(); + assertDeepEquals(2, schedule.getCFG().getBlocks().size()); + for (BinaryArithmeticNode node : graph.getNodes().filter(BinaryArithmeticNode.class)) { + if (node instanceof AddNode) { + assertTrue(node.toString() + " expected: " + nodeToBlock.get(beginNode) + " but was: " + nodeToBlock.get(node), nodeToBlock.get(node) == nodeToBlock.get(beginNode)); + } + } + + for (FrameState fs : graph.getNodes(FrameState.TYPE)) { + Block block = nodeToBlock.get(fs); + assertTrue(fs.toString(), block == schedule.getCFG().getStartBlock()); + for (Node usage : fs.usages()) { + if (usage instanceof StateSplit && ((StateSplit) usage).stateAfter() == fs) { + assertTrue(usage.toString(), nodeToBlock.get(usage) == block); + if (usage != block.getBeginNode()) { + List map = blockToNodesMap.get(block); + assertTrue(map.indexOf(fs) + " < " + map.indexOf(usage), map.indexOf(fs) < map.indexOf(usage)); + } + } + } + } + + PhaseContext context = new PhaseContext(getProviders()); + new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); + new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, context); + MidTierContext midContext = new MidTierContext(getProviders(), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo(), null); + + new GuardLoweringPhase().apply(graph, midContext); + FrameStateAssignmentPhase phase = new FrameStateAssignmentPhase(); + phase.apply(graph); + + schedule = new SchedulePhase(SchedulingStrategy.EARLIEST); + schedule.apply(graph); + blockToNodesMap = schedule.getBlockToNodesMap(); + nodeToBlock = schedule.getNodeToBlockMap(); + for (FrameState fs : graph.getNodes(FrameState.TYPE)) { + Block block = nodeToBlock.get(fs); + assertTrue(fs.toString(), block == schedule.getCFG().getStartBlock()); + for (Node usage : fs.usages()) { + if ((usage instanceof StateSplit && ((StateSplit) usage).stateAfter() == fs) || (usage instanceof DeoptDuring && ((DeoptDuring) usage).stateDuring() == fs)) { + assertTrue(usage.toString(), nodeToBlock.get(usage) == block); + if (usage != block.getBeginNode()) { + List map = blockToNodesMap.get(block); + assertTrue(map.indexOf(fs) + " < " + map.indexOf(usage), map.indexOf(fs) < map.indexOf(usage)); + } + } + } + } + } +} diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java Tue Mar 17 11:23:06 2015 -0700 @@ -30,7 +30,7 @@ import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; -import com.oracle.graal.java.*; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.phases.*; @@ -231,7 +231,8 @@ try (Scope s = Debug.scope("InliningTest", new DebugDumpScope(snippet))) { ResolvedJavaMethod method = getResolvedJavaMethod(snippet); StructuredGraph graph = eagerInfopointMode ? parseDebug(method, AllowAssumptions.YES) : parseEager(method, AllowAssumptions.YES); - PhaseSuite graphBuilderSuite = eagerInfopointMode ? getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault()) : getDefaultGraphBuilderSuite(); + PhaseSuite graphBuilderSuite = eagerInfopointMode ? getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault(getDefaultGraphBuilderPlugins())) + : getDefaultGraphBuilderSuite(); HighTierContext context = new HighTierContext(getProviders(), null, graphBuilderSuite, OptimisticOptimizations.ALL); Debug.dump(graph, "Graph"); new CanonicalizerPhase().apply(graph, context); diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysis.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysis.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysis.java Tue Mar 17 11:23:06 2015 -0700 @@ -29,6 +29,8 @@ import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.CallTargetNode.InvokeKind; import com.oracle.graal.nodes.*; @@ -222,7 +224,7 @@ * the code before static analysis, the classes would otherwise be not loaded * yet and the bytecode parser would only create a graph. */ - GraphBuilderConfiguration graphBuilderConfig = GraphBuilderConfiguration.getEagerDefault(); + GraphBuilderConfiguration graphBuilderConfig = GraphBuilderConfiguration.getEagerDefault(new Plugins(new InvocationPlugins(metaAccess))); /* * For simplicity, we ignore all exception handling during the static analysis. * This is a constraint of this example code, a real static analysis needs to diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Tue Mar 17 11:23:06 2015 -0700 @@ -346,7 +346,7 @@ AllocationContext allocContext = new AllocationContext(lirGen.getSpillMoveFactory()); lirSuites.getAllocationStage().apply(target, lirGenRes, codeEmittingOrder, linearScanOrder, allocContext); - PostAllocationOptimizationContext postAllocOptContext = new PostAllocationOptimizationContext(); + PostAllocationOptimizationContext postAllocOptContext = new PostAllocationOptimizationContext(lirGen); lirSuites.getPostAllocationOptimizationStage().apply(target, lirGenRes, codeEmittingOrder, linearScanOrder, postAllocOptContext); return lirGenRes; diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GenericInvocationPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GenericInvocationPlugin.java Tue Mar 17 11:23:06 2015 -0700 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.graphbuilderconf; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; + +/** + * Plugin for handling an invocation based on some property of the method being invoked such as any + * annotations it may have. + */ +public interface GenericInvocationPlugin extends GraphBuilderPlugin { + /** + * Executes this plugin for an invocation of a given method with a given set of arguments. + * + * @return {@code true} if this plugin handled the invocation, {@code false} if not + */ + boolean apply(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args); +} diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderConfiguration.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderConfiguration.java Tue Mar 17 11:23:06 2015 -0700 @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.graphbuilderconf; + +import java.util.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.nodes.*; + +public class GraphBuilderConfiguration { + + public static class Plugins { + private final InvocationPlugins invocationPlugins; + private LoadFieldPlugin loadFieldPlugin; + private LoadIndexedPlugin loadIndexedPlugin; + private ParameterPlugin parameterPlugin; + private InlineInvokePlugin inlineInvokePlugin; + private GenericInvocationPlugin genericInvocationPlugin; + private LoopExplosionPlugin loopExplosionPlugin; + + /** + * Creates a copy of a given set of plugins. The {@link InvocationPlugins} in + * {@code copyFrom} become the {@linkplain InvocationPlugins#getParent() default} + * {@linkplain #getInvocationPlugins() invocation plugins} in this object. + */ + public Plugins(Plugins copyFrom) { + this.invocationPlugins = new InvocationPlugins(copyFrom.invocationPlugins); + this.parameterPlugin = copyFrom.parameterPlugin; + this.loadFieldPlugin = copyFrom.loadFieldPlugin; + this.loadIndexedPlugin = copyFrom.loadIndexedPlugin; + this.inlineInvokePlugin = copyFrom.inlineInvokePlugin; + this.loopExplosionPlugin = copyFrom.loopExplosionPlugin; + this.genericInvocationPlugin = copyFrom.genericInvocationPlugin; + } + + /** + * Creates a new set of plugins. + * + * @param invocationPlugins the {@linkplain #getInvocationPlugins() invocation plugins} in + * this object + */ + public Plugins(InvocationPlugins invocationPlugins) { + this.invocationPlugins = invocationPlugins; + } + + public InvocationPlugins getInvocationPlugins() { + return invocationPlugins; + } + + public GenericInvocationPlugin getGenericInvocationPlugin() { + return genericInvocationPlugin; + } + + public void setGenericInvocationPlugin(GenericInvocationPlugin plugin) { + this.genericInvocationPlugin = plugin; + } + + public LoadFieldPlugin getLoadFieldPlugin() { + return loadFieldPlugin; + } + + public void setLoadFieldPlugin(LoadFieldPlugin plugin) { + this.loadFieldPlugin = plugin; + } + + public LoadIndexedPlugin getLoadIndexedPlugin() { + return loadIndexedPlugin; + } + + public void setLoadIndexedPlugin(LoadIndexedPlugin plugin) { + this.loadIndexedPlugin = plugin; + } + + public ParameterPlugin getParameterPlugin() { + return parameterPlugin; + } + + public void setParameterPlugin(ParameterPlugin plugin) { + this.parameterPlugin = plugin; + } + + public InlineInvokePlugin getInlineInvokePlugin() { + return inlineInvokePlugin; + } + + public void setInlineInvokePlugin(InlineInvokePlugin plugin) { + this.inlineInvokePlugin = plugin; + } + + public LoopExplosionPlugin getLoopExplosionPlugin() { + return loopExplosionPlugin; + } + + public void setLoopExplosionPlugin(LoopExplosionPlugin plugin) { + this.loopExplosionPlugin = plugin; + } + } + + private static final ResolvedJavaType[] EMPTY = new ResolvedJavaType[]{}; + + private final boolean eagerResolving; + private final boolean omitAllExceptionEdges; + private final ResolvedJavaType[] skippedExceptionTypes; + private final DebugInfoMode debugInfoMode; + private final boolean doLivenessAnalysis; + private boolean useProfiling; + private final Plugins plugins; + + public static enum DebugInfoMode { + SafePointsOnly, + /** + * This mode inserts {@link SimpleInfopointNode}s in places where no safepoints would be + * inserted: inlining boundaries, and line number switches. + *

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

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

+ * This is relevant when code is to be generated for native, machine-code level debugging + * but can have a limit the amount of optimization applied to the code. + */ + Full, + } + + protected GraphBuilderConfiguration(boolean eagerResolving, boolean omitAllExceptionEdges, DebugInfoMode debugInfoMode, ResolvedJavaType[] skippedExceptionTypes, boolean doLivenessAnalysis, + Plugins plugins) { + this.eagerResolving = eagerResolving; + this.omitAllExceptionEdges = omitAllExceptionEdges; + this.debugInfoMode = debugInfoMode; + this.skippedExceptionTypes = skippedExceptionTypes; + this.doLivenessAnalysis = doLivenessAnalysis; + this.useProfiling = true; + this.plugins = plugins; + } + + /** + * Creates a copy of this configuration with all its plugins. The {@link InvocationPlugins} in + * this configuration become the {@linkplain InvocationPlugins#getParent() parent} of the + * {@link InvocationPlugins} in the copy. + */ + public GraphBuilderConfiguration copy() { + Plugins newPlugins = new Plugins(new InvocationPlugins(plugins.getInvocationPlugins())); + GraphBuilderConfiguration result = new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, doLivenessAnalysis, newPlugins); + result.useProfiling = useProfiling; + return result; + } + + public boolean getUseProfiling() { + return useProfiling; + } + + public void setUseProfiling(boolean b) { + this.useProfiling = b; + } + + public GraphBuilderConfiguration withSkippedExceptionTypes(ResolvedJavaType[] newSkippedExceptionTypes) { + return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, newSkippedExceptionTypes, doLivenessAnalysis, plugins); + } + + public GraphBuilderConfiguration withOmitAllExceptionEdges(boolean newOmitAllExceptionEdges) { + return new GraphBuilderConfiguration(eagerResolving, newOmitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, doLivenessAnalysis, plugins); + } + + public GraphBuilderConfiguration withDebugInfoMode(DebugInfoMode newDebugInfoMode) { + ResolvedJavaType[] newSkippedExceptionTypes = skippedExceptionTypes == EMPTY ? EMPTY : Arrays.copyOf(skippedExceptionTypes, skippedExceptionTypes.length); + return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, newDebugInfoMode, newSkippedExceptionTypes, doLivenessAnalysis, plugins); + } + + public GraphBuilderConfiguration withDoLivenessAnalysis(boolean newLivenessAnalysis) { + return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, newLivenessAnalysis, plugins); + } + + public ResolvedJavaType[] getSkippedExceptionTypes() { + return skippedExceptionTypes; + } + + public boolean eagerResolving() { + return eagerResolving; + } + + public boolean omitAllExceptionEdges() { + return omitAllExceptionEdges; + } + + public boolean insertNonSafepointDebugInfo() { + return debugInfoMode.ordinal() >= DebugInfoMode.Simple.ordinal(); + } + + public boolean insertFullDebugInfo() { + return debugInfoMode.ordinal() >= DebugInfoMode.Full.ordinal(); + } + + public boolean doLivenessAnalysis() { + return doLivenessAnalysis; + } + + public static GraphBuilderConfiguration getDefault(Plugins plugins) { + return new GraphBuilderConfiguration(false, false, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptLivenessAnalysis.getValue(), plugins); + } + + public static GraphBuilderConfiguration getEagerDefault(Plugins plugins) { + return new GraphBuilderConfiguration(true, false, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptLivenessAnalysis.getValue(), plugins); + } + + public static GraphBuilderConfiguration getSnippetDefault(Plugins plugins) { + return new GraphBuilderConfiguration(true, true, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptLivenessAnalysis.getValue(), plugins); + } + + public static GraphBuilderConfiguration getFullDebugDefault(Plugins plugins) { + return new GraphBuilderConfiguration(true, false, DebugInfoMode.Full, EMPTY, GraalOptions.OptLivenessAnalysis.getValue(), plugins); + } + + /** + * Returns {@code true} if it is an error for a class/field/method resolution to fail. The + * default is the same result as returned by {@link #eagerResolving()}. However, it may be + * overridden to allow failure even when {@link #eagerResolving} is {@code true}. + */ + public boolean unresolvedIsError() { + return eagerResolving; + } + + public Plugins getPlugins() { + return plugins; + } +} diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderContext.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderContext.java Tue Mar 17 11:23:06 2015 -0700 @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.graphbuilderconf; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; + +/** + * Used by a {@link GraphBuilderPlugin} to interface with a graph builder object. + */ +public interface GraphBuilderContext { + + /** + * Information about a snippet or method substitution currently being processed by the graph + * builder. When in the scope of a replacement, the graph builder does not check the value kinds + * flowing through the JVM state since replacements can employ non-Java kinds to represent + * values such as raw machine words and pointers. + */ + public interface Replacement { + + /** + * Gets the method being replaced. + */ + ResolvedJavaMethod getOriginalMethod(); + + /** + * Gets the replacement method. + */ + ResolvedJavaMethod getReplacementMethod(); + + /** + * Determines if this replacement is being inlined as a compiler intrinsic. A compiler + * intrinsic is atomic with respect to deoptimization. Deoptimization within a compiler + * intrinsic will restart the interpreter at the intrinsified call. + */ + boolean isIntrinsic(); + } + + T append(T fixed); + + T append(T fixed); + + T append(T fixed); + + T append(T value); + + T append(T value); + + StampProvider getStampProvider(); + + MetaAccessProvider getMetaAccess(); + + Assumptions getAssumptions(); + + ConstantReflectionProvider getConstantReflection(); + + SnippetReflectionProvider getSnippetReflection(); + + void push(Kind kind, ValueNode value); + + StructuredGraph getGraph(); + + FrameState createStateAfter(); + + /** + * Gets the parsing context for the method that inlines the method being parsed by this context. + */ + GraphBuilderContext getParent(); + + /** + * Gets the root method for the graph building process. + */ + ResolvedJavaMethod getRootMethod(); + + /** + * Gets the method currently being parsed. + */ + ResolvedJavaMethod getMethod(); + + /** + * Gets the index of the bytecode instruction currently being parsed. + */ + int bci(); + + /** + * Gets the inline depth of this context. 0 implies this is the context for the + * {@linkplain #getRootMethod() root method}. + */ + int getDepth(); + + /** + * Determines if the current parsing context is a snippet or method substitution. + */ + default boolean parsingReplacement() { + return getReplacement() == null; + } + + /** + * Gets the replacement of the current parsing context or {@code null} if not + * {@link #parsingReplacement() parsing a replacement}. + */ + Replacement getReplacement(); + + /** + * @see GuardingPiNode#nullCheckedValue(ValueNode) + */ + static ValueNode nullCheckedValue(GraphBuilderContext builder, ValueNode value) { + ValueNode nonNullValue = GuardingPiNode.nullCheckedValue(value); + if (nonNullValue != value) { + builder.append((FixedWithNextNode) nonNullValue); + } + return nonNullValue; + } + + boolean eagerResolving(); + + BailoutException bailout(String string); +} diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderPlugin.java Tue Mar 17 11:23:06 2015 -0700 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.graphbuilderconf; + +/** + * Marker interface for graph builder plugins. + */ +public interface GraphBuilderPlugin { +} diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InlineInvokePlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InlineInvokePlugin.java Tue Mar 17 11:23:06 2015 -0700 @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.graphbuilderconf; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; + +/** + * Plugin for specifying what is inlined during graph parsing or for post-processing non-inlined + * invocations that result in {@link Invoke} nodes. + */ +public interface InlineInvokePlugin extends GraphBuilderPlugin { + + public static class InlineInfo { + + /** + * The method to be inlined. + */ + public final ResolvedJavaMethod methodToInline; + + /** + * Specifies if {@link #methodToInline} is to be considered a + * {@linkplain GraphBuilderContext.Replacement replacement} for the {@code method} passed to + * {@link InlineInvokePlugin#getInlineInfo}. + */ + public final boolean isReplacement; + + /** + * Specifies if {@link #methodToInline} is an intrinsic for the original method. If so, any + * {@link StateSplit} node created in the (recursive) inlining scope will be given a frame + * state that restarts the interpreter just before the intrinsified invocation. + */ + public final boolean isIntrinsic; + + public InlineInfo(ResolvedJavaMethod methodToInline, boolean isReplacement, boolean isIntrinsic) { + this.methodToInline = methodToInline; + this.isIntrinsic = isIntrinsic; + this.isReplacement = isReplacement; + assert !isIntrinsic || isReplacement : "cannot be an intrinsic without also being a replacement"; + } + } + + /** + * Determines whether a call to a given method is to be inlined. + * + * @param method the target method of an invoke + * @param args the arguments to the invoke + * @param returnType the return type derived from {@code method}'s signature + */ + default InlineInvokePlugin.InlineInfo getInlineInfo(@SuppressWarnings("unused") GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType) { + return null; + } + + /** + * @param inlinedTargetMethod + */ + default void postInline(ResolvedJavaMethod inlinedTargetMethod) { + } + + /** + * Notifies this plugin of the {@link Invoke} node created for a method that was not inlined per + * {@link #getInlineInfo}. + * + * @param method the method that was not inlined + * @param invoke the invoke node created for the call to {@code method} + */ + default void notifyOfNoninlinedInvoke(@SuppressWarnings("unused") GraphBuilderContext b, ResolvedJavaMethod method, Invoke invoke) { + } +} diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugin.java Tue Mar 17 11:23:06 2015 -0700 @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.graphbuilderconf; + +import java.lang.reflect.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.nodes.*; + +/** + * Plugin for handling a specific method invocation. + */ +public interface InvocationPlugin extends GraphBuilderPlugin { + + /** + * @see #execute + */ + default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod) { + throw invalidHandler(b, targetMethod); + } + + /** + * @see #execute + */ + default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode arg) { + throw invalidHandler(b, targetMethod, arg); + } + + /** + * @see #execute + */ + default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode arg1, ValueNode arg2) { + throw invalidHandler(b, targetMethod, arg1, arg2); + } + + /** + * @see #execute + */ + default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode arg1, ValueNode arg2, ValueNode arg3) { + throw invalidHandler(b, targetMethod, arg1, arg2, arg3); + } + + /** + * @see #execute + */ + default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode arg1, ValueNode arg2, ValueNode arg3, ValueNode arg4) { + throw invalidHandler(b, targetMethod, arg1, arg2, arg3, arg4); + } + + /** + * @see #execute + */ + default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode arg1, ValueNode arg2, ValueNode arg3, ValueNode arg4, ValueNode arg5) { + throw invalidHandler(b, targetMethod, arg1, arg2, arg3, arg4, arg5); + } + + default ResolvedJavaMethod getSubstitute() { + return null; + } + + /** + * Executes a given plugin against a set of invocation arguments by dispatching to the + * {@code apply(...)} method that matches the number of arguments. + * + * @param targetMethod the method for which plugin is being applied + * @return {@code true} if the plugin handled the invocation of {@code targetMethod} + * {@code false} if the graph builder should process the invoke further (e.g., by + * inlining it or creating an {@link Invoke} node). A plugin that does not handle an + * invocation must not modify the graph being constructed. + */ + static boolean execute(GraphBuilderContext b, ResolvedJavaMethod targetMethod, InvocationPlugin plugin, ValueNode[] args) { + if (args.length == 0) { + return plugin.apply(b, targetMethod); + } else if (args.length == 1) { + return plugin.apply(b, targetMethod, args[0]); + } else if (args.length == 2) { + return plugin.apply(b, targetMethod, args[0], args[1]); + } else if (args.length == 3) { + return plugin.apply(b, targetMethod, args[0], args[1], args[2]); + } else if (args.length == 4) { + return plugin.apply(b, targetMethod, args[0], args[1], args[2], args[3]); + } else if (args.length == 5) { + return plugin.apply(b, targetMethod, args[0], args[1], args[2], args[3], args[4]); + } else { + throw plugin.invalidHandler(b, targetMethod, args); + } + } + + default Error invalidHandler(@SuppressWarnings("unused") GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode... args) { + return new GraalInternalError("Invocation plugin for %s does not handle invocations with %d arguments", targetMethod.format("%H.%n(%p)"), args.length); + } + + default StackTraceElement getApplySourceLocation(MetaAccessProvider metaAccess) { + Class c = getClass(); + for (Method m : c.getDeclaredMethods()) { + if (m.getName().equals("apply")) { + return metaAccess.lookupJavaMethod(m).asStackTraceElement(0); + } + } + throw new GraalInternalError("could not find method named \"apply\" in " + c.getName()); + } +} diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPluginIdHolder.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPluginIdHolder.java Tue Mar 17 11:23:06 2015 -0700 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.graphbuilderconf; + +import com.oracle.graal.api.meta.*; + +/** + * {@link ResolvedJavaMethod}s that can assign themselves an identifier for use in a side table + * mapping methods to {@link InvocationPlugin}s. + */ +public interface InvocationPluginIdHolder extends ResolvedJavaMethod { + /** + * Sets the unique, positive, non-zero identifier for this method. + */ + void setInvocationPluginId(int id); + + /** + * Gets the identifier set by {@link #setInvocationPluginId(int)} or 0 if no + * {@link InvocationPlugin} identifier was assigned to this method. + */ + int getInvocationPluginId(); +} diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java Tue Mar 17 11:23:06 2015 -0700 @@ -0,0 +1,388 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.graphbuilderconf; + +import static java.lang.String.*; + +import java.lang.reflect.*; +import java.util.*; +import java.util.stream.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.nodes.*; + +/** + * Manages a set of {@link InvocationPlugin}s. + */ +public class InvocationPlugins { + + /** + * Sentinel class for use with + * {@link InvocationPlugins#register(InvocationPlugin, Class, String, Class...)} to denote the + * receiver argument for a non-static method. + */ + public static final class Receiver { + private Receiver() { + throw GraalInternalError.shouldNotReachHere(); + } + } + + /** + * Utility for + * {@linkplain InvocationPlugins#register(InvocationPlugin, Class, String, Class...) + * registration} of invocation plugins. + */ + public static class Registration { + + private final InvocationPlugins plugins; + private final Class declaringClass; + + /** + * Creates an object for registering {@link InvocationPlugin}s for methods declared by a + * given class. + * + * @param plugins where to register the plugins + * @param declaringClass the class declaring the methods for which plugins will be + * registered via this object + */ + public Registration(InvocationPlugins plugins, Class declaringClass) { + this.plugins = plugins; + this.declaringClass = declaringClass; + } + + /** + * Registers a plugin for a method with no arguments. + * + * @param name the name of the method + * @param plugin the plugin to be registered + */ + public void register0(String name, InvocationPlugin plugin) { + plugins.register(plugin, declaringClass, name); + } + + /** + * Registers a plugin for a method with 1 argument. + * + * @param name the name of the method + * @param plugin the plugin to be registered + */ + public void register1(String name, Class arg, InvocationPlugin plugin) { + plugins.register(plugin, declaringClass, name, arg); + } + + /** + * Registers a plugin for a method with 2 arguments. + * + * @param name the name of the method + * @param plugin the plugin to be registered + */ + public void register2(String name, Class arg1, Class arg2, InvocationPlugin plugin) { + plugins.register(plugin, declaringClass, name, arg1, arg2); + } + + /** + * Registers a plugin for a method with 3 arguments. + * + * @param name the name of the method + * @param plugin the plugin to be registered + */ + public void register3(String name, Class arg1, Class arg2, Class arg3, InvocationPlugin plugin) { + plugins.register(plugin, declaringClass, name, arg1, arg2, arg3); + } + + /** + * Registers a plugin for a method with 4 arguments. + * + * @param name the name of the method + * @param plugin the plugin to be registered + */ + public void register4(String name, Class arg1, Class arg2, Class arg3, Class arg4, InvocationPlugin plugin) { + plugins.register(plugin, declaringClass, name, arg1, arg2, arg3, arg4); + } + + /** + * Registers a plugin for a method with 5 arguments. + * + * @param name the name of the method + * @param plugin the plugin to be registered + */ + public void register5(String name, Class arg1, Class arg2, Class arg3, Class arg4, Class arg5, InvocationPlugin plugin) { + plugins.register(plugin, declaringClass, name, arg1, arg2, arg3, arg4, arg5); + } + } + + static final class MethodInfo { + final boolean isStatic; + final Class declaringClass; + final String name; + final Class[] argumentTypes; + final InvocationPlugin plugin; + + int id; + + MethodInfo(InvocationPlugin plugin, Class declaringClass, String name, Class... argumentTypes) { + this.plugin = plugin; + this.isStatic = argumentTypes.length == 0 || argumentTypes[0] != Receiver.class; + this.declaringClass = declaringClass; + this.name = name; + this.argumentTypes = argumentTypes; + if (!isStatic) { + argumentTypes[0] = declaringClass; + } + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof MethodInfo) { + MethodInfo that = (MethodInfo) obj; + boolean res = this.name.equals(that.name) && this.declaringClass.equals(that.declaringClass) && Arrays.equals(this.argumentTypes, that.argumentTypes); + assert !res || this.isStatic == that.isStatic; + return res; + } + return false; + } + + @Override + public int hashCode() { + // Replay compilation mandates use of stable hash codes + return declaringClass.getName().hashCode() ^ name.hashCode(); + } + + ResolvedJavaMethod resolve(MetaAccessProvider metaAccess) { + try { + ResolvedJavaMethod method; + Class[] parameterTypes = isStatic ? argumentTypes : Arrays.copyOfRange(argumentTypes, 1, argumentTypes.length); + if (name.equals("")) { + method = metaAccess.lookupJavaMethod(declaringClass.getDeclaredConstructor(parameterTypes)); + } else { + method = metaAccess.lookupJavaMethod(declaringClass.getDeclaredMethod(name, parameterTypes)); + } + assert method.isStatic() == isStatic; + return method; + } catch (NoSuchMethodException | SecurityException e) { + throw new GraalInternalError(e); + } + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(declaringClass.getName()).append('.').append(name).append('('); + for (Class p : argumentTypes) { + if (sb.charAt(sb.length() - 1) != '(') { + sb.append(", "); + } + sb.append(p.getSimpleName()); + } + return sb.append(')').toString(); + } + } + + protected final MetaAccessProvider metaAccess; + private final List registrations; + private final Thread registrationThread; + + /** + * The minimum {@linkplain InvocationPluginIdHolder#getInvocationPluginId() id} for a method + * associated with a plugin in {@link #plugins}. + */ + private int minId = Integer.MAX_VALUE; + + /** + * Resolved methods to plugins map. The keys (i.e., indexes) are derived from + * {@link InvocationPluginIdHolder#getInvocationPluginId()}. + */ + private volatile InvocationPlugin[] plugins; + + /** + * The plugins {@linkplain #lookupInvocation(ResolvedJavaMethod) searched} before searching in + * this object. + */ + private InvocationPlugins parent; + + private InvocationPlugins(InvocationPlugins parent, MetaAccessProvider metaAccess, int estimatePluginCount) { + this.registrationThread = Thread.currentThread(); + this.metaAccess = metaAccess; + this.registrations = new ArrayList<>(estimatePluginCount); + InvocationPlugins p = parent; + // Only adopt a non-empty parent + while (p != null && p.size() == 0) { + p = p.parent; + } + this.parent = p; + } + + private static final int DEFAULT_ESTIMATE_PLUGIN_COUNT = 16; + + /** + * Creates a set of invocation plugins with a non-null {@linkplain #getParent() parent}. + */ + public InvocationPlugins(InvocationPlugins parent) { + this(parent, parent.metaAccess, DEFAULT_ESTIMATE_PLUGIN_COUNT); + } + + public InvocationPlugins(MetaAccessProvider metaAccess) { + this(metaAccess, DEFAULT_ESTIMATE_PLUGIN_COUNT); + } + + public InvocationPlugins(MetaAccessProvider metaAccess, int estimatePluginCount) { + this(null, metaAccess, estimatePluginCount); + } + + /** + * Registers an invocation plugin for a given method. There must be no plugin currently + * registered for {@code method}. + */ + public void register(InvocationPlugin plugin, Class declaringClass, String name, Class... argumentTypes) { + assert Thread.currentThread() == registrationThread : "invocation plugin registration must be single threaded"; + MethodInfo methodInfo = new MethodInfo(plugin, declaringClass, name, argumentTypes); + assert Checker.check(this, methodInfo, plugin); + assert plugins == null : "invocation plugin registration is closed"; + registrations.add(methodInfo); + } + + private static int nextInvocationPluginId = 1; + + /** + * Gets the plugin for a given method. + * + * @param method the method to lookup + * @return the plugin associated with {@code method} or {@code null} if none exists + */ + public InvocationPlugin lookupInvocation(ResolvedJavaMethod method) { + assert method instanceof InvocationPluginIdHolder; + if (parent != null) { + InvocationPlugin plugin = parent.lookupInvocation(method); + if (plugin != null) { + return plugin; + } + } + InvocationPluginIdHolder pluggable = (InvocationPluginIdHolder) method; + if (plugins == null) { + // Must synchronize across all InvocationPlugins objects to ensure thread safe + // allocation of InvocationPlugin identifiers + synchronized (InvocationPlugins.class) { + if (plugins == null) { + if (registrations.isEmpty()) { + plugins = new InvocationPlugin[0]; + } else { + int max = Integer.MIN_VALUE; + for (MethodInfo methodInfo : registrations) { + InvocationPluginIdHolder p = (InvocationPluginIdHolder) methodInfo.resolve(metaAccess); + int id = p.getInvocationPluginId(); + if (id == 0) { + id = nextInvocationPluginId++; + p.setInvocationPluginId(id); + } + if (id < minId) { + minId = id; + } + if (id > max) { + max = id; + + } + methodInfo.id = id; + } + + int length = (max - minId) + 1; + plugins = new InvocationPlugin[length]; + for (MethodInfo m : registrations) { + int index = m.id - minId; + plugins[index] = m.plugin; + } + } + } + } + } + + int id = pluggable.getInvocationPluginId(); + int index = id - minId; + return index >= 0 && index < plugins.length ? plugins[index] : null; + } + + /** + * Gets the invocation plugins {@linkplain #lookupInvocation(ResolvedJavaMethod) searched} + * before searching in this object. + */ + public InvocationPlugins getParent() { + return parent; + } + + @Override + public String toString() { + return registrations.stream().map(MethodInfo::toString).collect(Collectors.joining(", ")) + " / parent: " + this.parent; + } + + private static class Checker { + private static final int MAX_ARITY = 5; + /** + * The set of all {@link InvocationPlugin#apply} method signatures. + */ + static final Class[][] SIGS; + static { + ArrayList[]> sigs = new ArrayList<>(MAX_ARITY); + for (Method method : InvocationPlugin.class.getDeclaredMethods()) { + if (!Modifier.isStatic(method.getModifiers()) && method.getName().equals("apply")) { + Class[] sig = method.getParameterTypes(); + assert sig[0] == GraphBuilderContext.class; + assert sig[1] == ResolvedJavaMethod.class; + assert Arrays.asList(Arrays.copyOfRange(sig, 2, sig.length)).stream().allMatch(c -> c == ValueNode.class); + while (sigs.size() < sig.length - 1) { + sigs.add(null); + } + sigs.set(sig.length - 2, sig); + } + } + assert sigs.indexOf(null) == -1 : format("need to add an apply() method to %s that takes %d %s arguments ", InvocationPlugin.class.getName(), sigs.indexOf(null), + ValueNode.class.getSimpleName()); + SIGS = sigs.toArray(new Class[sigs.size()][]); + } + + public static boolean check(InvocationPlugins plugins, MethodInfo method, InvocationPlugin plugin) { + InvocationPlugins p = plugins; + while (p != null) { + assert !p.registrations.contains(method) : "a plugin is already registered for " + method; + p = p.parent; + } + int arguments = method.argumentTypes.length; + assert arguments < SIGS.length : format("need to extend %s to support method with %d arguments: %s", InvocationPlugin.class.getSimpleName(), arguments, method); + for (Method m : plugin.getClass().getDeclaredMethods()) { + if (m.getName().equals("apply")) { + Class[] parameterTypes = m.getParameterTypes(); + if (Arrays.equals(SIGS[arguments], parameterTypes)) { + return true; + } + } + } + throw new AssertionError(format("graph builder plugin for %s not found", method)); + } + } + + public MetaAccessProvider getMetaAccess() { + return metaAccess; + } + + public int size() { + return registrations.size(); + } +} diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/LoadFieldPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/LoadFieldPlugin.java Tue Mar 17 11:23:06 2015 -0700 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.graphbuilderconf; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; + +public interface LoadFieldPlugin extends GraphBuilderPlugin { + @SuppressWarnings("unused") + default boolean apply(GraphBuilderContext b, ValueNode receiver, ResolvedJavaField field) { + return false; + } + + @SuppressWarnings("unused") + default boolean apply(GraphBuilderContext graphBuilderContext, ResolvedJavaField staticField) { + return false; + } + + default boolean tryConstantFold(GraphBuilderContext b, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ResolvedJavaField field, JavaConstant receiver) { + JavaConstant result = constantReflection.readConstantFieldValue(field, receiver); + if (result != null) { + ConstantNode constantNode = b.append(ConstantNode.forConstant(result, metaAccess)); + b.push(constantNode.getKind().getStackKind(), constantNode); + return true; + } + return false; + } +} diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/LoadIndexedPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/LoadIndexedPlugin.java Tue Mar 17 11:23:06 2015 -0700 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.graphbuilderconf; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; + +public interface LoadIndexedPlugin extends GraphBuilderPlugin { + @SuppressWarnings("unused") + default boolean apply(GraphBuilderContext b, ValueNode array, ValueNode index, Kind elementKind) { + return false; + } +} diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/LoopExplosionPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/LoopExplosionPlugin.java Tue Mar 17 11:23:06 2015 -0700 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.graphbuilderconf; + +import com.oracle.graal.api.meta.*; + +public interface LoopExplosionPlugin extends GraphBuilderPlugin { + boolean shouldExplodeLoops(ResolvedJavaMethod method); + + boolean shouldMergeExplosions(ResolvedJavaMethod method); +} diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/ParameterPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/ParameterPlugin.java Tue Mar 17 11:23:06 2015 -0700 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.graphbuilderconf; + +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.nodes.calc.*; + +public interface ParameterPlugin extends GraphBuilderPlugin { + FloatingNode interceptParameter(GraphBuilderContext b, int index, Stamp stamp); +} diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Tue Mar 17 11:23:06 2015 -0700 @@ -31,9 +31,10 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.api.runtime.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.hotspot.word.*; import com.oracle.graal.phases.util.*; @ServiceProvider(HotSpotBackendFactory.class) @@ -124,9 +125,11 @@ HotSpotMetaAccessProvider metaAccess; HotSpotLoweringProvider lowerer; HotSpotSnippetReflectionProvider snippetReflection; - Replacements replacements; + HotSpotReplacementsImpl replacements; HotSpotDisassemblerProvider disassembler; HotSpotSuitesProvider suites; + HotSpotWordTypes wordTypes; + Plugins plugins; try (InitTimer t = timer("create providers")) { try (InitTimer rt = timer("create HotSpotRegisters provider")) { registers = createRegisters(); @@ -152,7 +155,8 @@ try (InitTimer rt = timer("create Lowerer provider")) { lowerer = createLowerer(runtime, metaAccess, foreignCalls, registers, target); } - Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null, new HotSpotStampProvider()); + HotSpotStampProvider stampProvider = new HotSpotStampProvider(); + Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null, stampProvider); try (InitTimer rt = timer("create SnippetReflection provider")) { snippetReflection = createSnippetReflection(runtime); @@ -163,10 +167,17 @@ try (InitTimer rt = timer("create Disassembler provider")) { disassembler = createDisassembler(runtime); } + try (InitTimer rt = timer("create WordTypes")) { + wordTypes = new HotSpotWordTypes(metaAccess, target.wordKind); + } + try (InitTimer rt = timer("create GraphBuilderPhase plugins")) { + plugins = HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch); + replacements.setGraphBuilderPlugins(plugins); + } try (InitTimer rt = timer("create Suites provider")) { - suites = createSuites(runtime); + suites = createSuites(runtime, plugins); } - providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, snippetReflection); + providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, snippetReflection, wordTypes, plugins); } try (InitTimer rt = timer("instantiate backend")) { return createBackend(runtime, providers); @@ -185,7 +196,7 @@ return new HotSpotDisassemblerProvider(runtime); } - protected Replacements createReplacements(HotSpotGraalRuntimeProvider runtime, Providers p, SnippetReflectionProvider snippetReflection) { + protected HotSpotReplacementsImpl createReplacements(HotSpotGraalRuntimeProvider runtime, Providers p, SnippetReflectionProvider snippetReflection) { return new HotSpotReplacementsImpl(p, snippetReflection, runtime.getConfig(), p.getCodeCache().getTarget()); } @@ -210,8 +221,8 @@ return new HotSpotMetaAccessProvider(runtime); } - protected HotSpotSuitesProvider createSuites(HotSpotGraalRuntimeProvider runtime) { - return new HotSpotSuitesProvider(runtime); + protected HotSpotSuitesProvider createSuites(HotSpotGraalRuntimeProvider runtime, Plugins plugins) { + return new HotSpotSuitesProvider(runtime, plugins); } protected HotSpotSnippetReflectionProvider createSnippetReflection(HotSpotGraalRuntimeProvider runtime) { @@ -249,15 +260,15 @@ } else { /* * System V Application Binary Interface, AMD64 Architecture Processor Supplement - * + * * Draft Version 0.96 - * + * * http://www.uclibc.org/docs/psABI-x86_64.pdf - * + * * 3.2.1 - * + * * ... - * + * * This subsection discusses usage of each register. Registers %rbp, %rbx and %r12 * through %r15 "belong" to the calling function and the called function is required to * preserve their values. In other words, a called function must preserve these diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCounterOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCounterOp.java Tue Mar 17 11:23:06 2015 -0700 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2015, 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.amd64; + +import static com.oracle.graal.amd64.AMD64.*; +import static com.oracle.graal.api.code.ValueUtil.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.*; + +@Opcode("BenchMarkCounter") +public class AMD64HotSpotCounterOp extends HotSpotCounterOp { + public static final LIRInstructionClass TYPE = LIRInstructionClass.create(AMD64HotSpotCounterOp.class); + + @Alive({OperandFlag.STACK, OperandFlag.UNINITIALIZED}) private StackSlotValue backupSlot; + + public AMD64HotSpotCounterOp(String name, String group, Value increment, HotSpotRegistersProvider registers, HotSpotVMConfig config, StackSlotValue backupSlot) { + super(TYPE, name, group, increment, registers, config); + this.backupSlot = backupSlot; + } + + public AMD64HotSpotCounterOp(String[] names, String[] groups, Value[] increments, HotSpotRegistersProvider registers, HotSpotVMConfig config, StackSlotValue backupSlot) { + super(TYPE, names, groups, increments, registers, config); + this.backupSlot = backupSlot; + } + + @Override + public void emitCode(CompilationResultBuilder crb) { + AMD64MacroAssembler masm = (AMD64MacroAssembler) crb.asm; + TargetDescription target = crb.target; + + Register scratch = rax; + + // address for counters array + AMD64Address countersArrayAddr = new AMD64Address(thread, config.graalCountersThreadOffset); + Register countersArrayReg = scratch; + + // backup scratch register + masm.movq((AMD64Address) crb.asAddress(backupSlot), scratch); + + // load counters array + masm.movptr(countersArrayReg, countersArrayAddr); + + forEachCounter((name, group, increment) -> emitIncrement(masm, target, countersArrayReg, name, group, increment)); + + // restore scratch register + masm.movq(scratch, (AMD64Address) crb.asAddress(backupSlot)); + } + + private void emitIncrement(AMD64MacroAssembler masm, TargetDescription target, Register countersArrayReg, String name, String group, Value increment) { + // address for counter value + AMD64Address counterAddr = new AMD64Address(countersArrayReg, getDisplacementForLongIndex(target, getIndex(name, group, increment))); + // increment counter (in memory) + if (isConstant(increment)) { + masm.incrementl(counterAddr, asInt(asConstant(increment))); + } else { + masm.addq(counterAddr, asRegister(increment)); + } + } +} diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Tue Mar 17 11:23:06 2015 -0700 @@ -39,9 +39,11 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.spi.*; +import com.oracle.graal.debug.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; import com.oracle.graal.hotspot.amd64.AMD64HotSpotMove.HotSpotStoreConstantOp; +import com.oracle.graal.hotspot.debug.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.lir.*; @@ -54,6 +56,8 @@ import com.oracle.graal.lir.amd64.AMD64Move.LoadOp; import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp; import com.oracle.graal.lir.amd64.AMD64Move.StoreOp; +import com.oracle.graal.lir.asm.*; +import com.oracle.graal.lir.framemap.*; import com.oracle.graal.lir.gen.*; /** @@ -118,6 +122,41 @@ SaveRbp saveRbp; + private static final class RescueSlotDummyOp extends LIRInstruction { + public static final LIRInstructionClass TYPE = LIRInstructionClass.create(RescueSlotDummyOp.class); + + @Alive({OperandFlag.STACK, OperandFlag.UNINITIALIZED}) private StackSlotValue slot; + + public RescueSlotDummyOp(FrameMapBuilder frameMapBuilder, LIRKind kind) { + super(TYPE); + slot = frameMapBuilder.allocateSpillSlot(kind); + } + + public StackSlotValue getSlot() { + return slot; + } + + @Override + public void emitCode(CompilationResultBuilder crb) { + } + } + + private RescueSlotDummyOp rescueSlotOp; + + private StackSlotValue getOrInitRescueSlot() { + if (rescueSlotOp == null) { + // create dummy instruction to keep the rescue slot alive + rescueSlotOp = new RescueSlotDummyOp(getResult().getFrameMapBuilder(), getLIRKindTool().getWordKind()); + // insert dummy instruction into the start block + LIR lir = getResult().getLIR(); + List instructions = lir.getLIRforBlock(lir.getControlFlowGraph().getStartBlock()); + // Note: we do not insert at position 1 to avoid interference with the save rpb op + instructions.add(instructions.size() - 1, rescueSlotOp); + Debug.dump(lir, "created rescue dummy op"); + } + return rescueSlotOp.getSlot(); + } + /** * List of epilogue operations that need to restore RBP. */ @@ -440,6 +479,10 @@ for (AMD64HotSpotEpilogueOp op : epilogueOps) { op.savedRbp = savedRbp; } + if (BenchmarkCounters.enabled) { + // ensure that the rescue slot is available + getOrInitRescueSlot(); + } } private static LIRKind toStackKind(LIRKind kind) { @@ -626,4 +669,20 @@ return super.canInlineConstant(c); } } + + @Override + public LIRInstruction createBenchmarkCounter(String name, String group, Value increment) { + if (BenchmarkCounters.enabled) { + return new AMD64HotSpotCounterOp(name, group, increment, getProviders().getRegisters(), config, getOrInitRescueSlot()); + } + return null; + } + + @Override + public LIRInstruction createMultiBenchmarkCounter(String[] names, String[] groups, Value[] increments) { + if (BenchmarkCounters.enabled) { + return new AMD64HotSpotCounterOp(names, groups, increments, getProviders().getRegisters(), config, getOrInitRescueSlot()); + } + return null; + } } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Tue Mar 17 11:23:06 2015 -0700 @@ -27,8 +27,10 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.word.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.sparc.*; @@ -60,18 +62,23 @@ Value[] nativeABICallerSaveRegisters = createNativeABICallerSaveRegisters(runtime.getConfig(), codeCache.getRegisterConfig()); HotSpotForeignCallsProvider foreignCalls = new SPARCHotSpotForeignCallsProvider(runtime, metaAccess, codeCache, nativeABICallerSaveRegisters); LoweringProvider lowerer = createLowerer(runtime, metaAccess, foreignCalls, registers, target); - Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null, new HotSpotStampProvider()); + HotSpotStampProvider stampProvider = new HotSpotStampProvider(); + Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null, stampProvider); HotSpotSnippetReflectionProvider snippetReflection = new HotSpotSnippetReflectionProvider(runtime); HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, snippetReflection, runtime.getConfig(), target); HotSpotDisassemblerProvider disassembler = new HotSpotDisassemblerProvider(runtime); - HotSpotSuitesProvider suites = createSuites(runtime); - HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, snippetReflection); + HotSpotWordTypes wordTypes = new HotSpotWordTypes(metaAccess, target.wordKind); + Plugins plugins = HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch); + replacements.setGraphBuilderPlugins(plugins); + HotSpotSuitesProvider suites = createSuites(runtime, plugins); + HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, snippetReflection, + wordTypes, plugins); return createBackend(runtime, providers); } - protected HotSpotSuitesProvider createSuites(HotSpotGraalRuntimeProvider runtime) { - return new HotSpotSuitesProvider(runtime); + protected HotSpotSuitesProvider createSuites(HotSpotGraalRuntimeProvider runtime, Plugins plugins) { + return new HotSpotSuitesProvider(runtime, plugins); } protected HotSpotCodeCacheProvider createCodeCache(HotSpotGraalRuntimeProvider runtime, TargetDescription target, RegisterConfig regConfig) { diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCounterOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCounterOp.java Tue Mar 17 11:23:06 2015 -0700 @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2015, 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.sparc; + +import static com.oracle.graal.api.code.ValueUtil.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.*; + +@Opcode("BenchMarkCounter") +public class SPARCHotSpotCounterOp extends HotSpotCounterOp { + public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCHotSpotCounterOp.class); + + @Temp({OperandFlag.REG}) private AllocatableValue scratch0; + @Temp({OperandFlag.REG}) private AllocatableValue scratch1; + + public SPARCHotSpotCounterOp(String name, String group, Value increment, HotSpotRegistersProvider registers, HotSpotVMConfig config, AllocatableValue scratch0, AllocatableValue scratch1) { + super(TYPE, name, group, increment, registers, config); + this.scratch0 = scratch0; + this.scratch1 = scratch1; + } + + public SPARCHotSpotCounterOp(String[] names, String[] groups, Value[] increments, HotSpotRegistersProvider registers, HotSpotVMConfig config, AllocatableValue scratch0, AllocatableValue scratch1) { + super(TYPE, names, groups, increments, registers, config); + this.scratch0 = scratch0; + this.scratch1 = scratch1; + } + + @Override + public void emitCode(CompilationResultBuilder crb) { + SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm; + TargetDescription target = crb.target; + + // address for counters array + SPARCAddress countersArrayAddr = new SPARCAddress(thread, config.graalCountersThreadOffset); + Register countersArrayReg = asRegister(scratch0); + + // load counters array + masm.ldx(countersArrayAddr, countersArrayReg); + + forEachCounter((name, group, increment) -> emitIncrement(masm, target, countersArrayReg, name, group, increment)); + } + + private void emitIncrement(SPARCMacroAssembler masm, TargetDescription target, Register countersArrayReg, String name, String group, Value increment) { + // address for counter + SPARCAddress counterAddr = new SPARCAddress(countersArrayReg, getDisplacementForLongIndex(target, getIndex(name, group, increment))); + Register counterReg = asRegister(scratch1); + // load counter value + masm.ldx(counterAddr, counterReg); + // increment counter + if (isConstant(increment)) { + masm.add(counterReg, asInt(asConstant(increment)), counterReg); + } else { + masm.add(counterReg, asRegister(increment), counterReg); + } + // store counter value + masm.stx(counterReg, counterAddr); + } +} diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Tue Mar 17 11:23:06 2015 -0700 @@ -37,6 +37,7 @@ import com.oracle.graal.compiler.sparc.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; +import com.oracle.graal.hotspot.debug.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.lir.*; @@ -48,6 +49,7 @@ import com.oracle.graal.lir.sparc.SPARCMove.NullCheckOp; import com.oracle.graal.lir.sparc.SPARCMove.StoreConstantOp; import com.oracle.graal.lir.sparc.SPARCMove.StoreOp; +import com.oracle.graal.sparc.*; public class SPARCHotSpotLIRGenerator extends SPARCLIRGenerator implements HotSpotLIRGenerator { @@ -362,4 +364,32 @@ assert kind == Kind.Object || kind == Kind.Long : address + " - " + kind + " not an object!"; append(new NullCheckOp(load(address), state)); } + + @Override + public LIRInstruction createBenchmarkCounter(String name, String group, Value increment) { + if (BenchmarkCounters.enabled) { + try (SPARCScratchRegister sc0 = SPARCScratchRegister.get()) { + RegisterValue scratch0 = sc0.getRegister().asValue(getLIRKindTool().getWordKind()); + try (SPARCScratchRegister sc1 = SPARCScratchRegister.get()) { + RegisterValue scratch1 = sc1.getRegister().asValue(getLIRKindTool().getWordKind()); + return new SPARCHotSpotCounterOp(name, group, increment, getProviders().getRegisters(), config, scratch0, scratch1); + } + } + } + return null; + } + + @Override + public LIRInstruction createMultiBenchmarkCounter(String[] names, String[] groups, Value[] increments) { + if (BenchmarkCounters.enabled) { + try (SPARCScratchRegister sc0 = SPARCScratchRegister.get()) { + RegisterValue scratch0 = sc0.getRegister().asValue(getLIRKindTool().getWordKind()); + try (SPARCScratchRegister sc1 = SPARCScratchRegister.get()) { + RegisterValue scratch1 = sc1.getRegister().asValue(getLIRKindTool().getWordKind()); + return new SPARCHotSpotCounterOp(names, groups, increments, getProviders().getRegisters(), config, scratch0, scratch1); + } + } + } + return null; + } } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Tue Mar 17 11:23:06 2015 -0700 @@ -251,7 +251,7 @@ StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO); HighTierContext highContext = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); MidTierContext midContext = new MidTierContext(getProviders(), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo(), null); - new NodeIntrinsificationPhase(getProviders(), getSnippetReflection()).apply(graph); + new NodeIntrinsificationPhase(getMetaAccess(), getConstantReflection(), getSnippetReflection(), getProviders().getForeignCalls(), getProviders().getStampProvider()).apply(graph); new InliningPhase(new InlineEverythingPolicy(), new CanonicalizerPhase()).apply(graph, highContext); new CanonicalizerPhase().apply(graph, highContext); new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highContext); diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCounterOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCounterOp.java Tue Mar 17 11:23:06 2015 -0700 @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2015, 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; + +import static com.oracle.graal.api.code.ValueUtil.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.hotspot.debug.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.lir.*; + +public abstract class HotSpotCounterOp extends LIRInstruction { + public static final LIRInstructionClass TYPE = LIRInstructionClass.create(HotSpotCounterOp.class); + + private final String[] names; + private final String[] groups; + protected final Register thread; + protected final HotSpotVMConfig config; + @Alive({OperandFlag.CONST, OperandFlag.REG}) protected Value[] increments; + + public HotSpotCounterOp(LIRInstructionClass c, String name, String group, Value increment, HotSpotRegistersProvider registers, HotSpotVMConfig config) { + this(c, new String[]{name}, new String[]{group}, new Value[]{increment}, registers, config); + } + + public HotSpotCounterOp(LIRInstructionClass c, String[] names, String[] groups, Value[] increments, HotSpotRegistersProvider registers, HotSpotVMConfig config) { + super(c); + + assert names.length == groups.length; + assert groups.length == increments.length; + + this.names = names; + this.groups = groups; + this.increments = increments; + this.thread = registers.getThreadRegister(); + this.config = config; + } + + protected static int getDisplacementForLongIndex(TargetDescription target, long index) { + long finalDisp = index * target.getSizeInBytes(Kind.Long); + if (!NumUtil.isInt(finalDisp)) { + throw GraalInternalError.unimplemented("cannot deal with indices that big: " + index); + } + return (int) finalDisp; + } + + protected interface CounterProcedure { + void apply(String name, String group, Value increment); + } + + protected void forEachCounter(CounterProcedure proc) { + for (int i = 0; i < names.length; i++) { + proc.apply(names[i], groups[i], increments[i]); + } + } + + protected int getIndex(String name, String group, Value increment) { + if (isConstant(increment)) { + // get index for the counter + return BenchmarkCounters.getIndexConstantIncrement(name, group, config, asLong(asConstant(increment))); + } + assert isRegister(increment) : "Unexpected Value: " + increment; + // get index for the counter + return BenchmarkCounters.getIndex(name, group, config); + } + + private static long asLong(JavaConstant value) { + Kind kind = value.getKind(); + switch (kind) { + case Byte: + case Short: + case Char: + case Int: + return value.asInt(); + case Long: + return value.asLong(); + default: + throw new IllegalArgumentException("not an integer kind: " + kind); + } + } + + protected static int asInt(JavaConstant value) { + long l = asLong(value); + if (!NumUtil.isInt(l)) { + throw GraalInternalError.shouldNotReachHere("value does not fit into int: " + l); + } + return (int) l; + } + +} diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java Tue Mar 17 11:23:06 2015 -0700 @@ -31,8 +31,6 @@ import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.stubs.*; -import com.oracle.graal.java.GraphBuilderConfiguration.Plugins; -import com.oracle.graal.java.*; import com.oracle.graal.nodes.spi.*; /** @@ -72,14 +70,6 @@ final HotSpotLoweringProvider lowerer = (HotSpotLoweringProvider) providers.getLowerer(); HotSpotReplacementsImpl replacements = (HotSpotReplacementsImpl) providers.getReplacements(); - try (InitTimer st = timer("graphBuilderPlugins.initialize")) { - Plugins plugins = HotSpotGraphBuilderPlugins.create(config, providers); - providers.setGraphBuilderPlugins(plugins); - GraphBuilderPhase phase = (GraphBuilderPhase) providers.getSuites().getDefaultGraphBuilderSuite().findPhase(GraphBuilderPhase.class).previous(); - phase.getGraphBuilderConfig().setPlugins(plugins); - replacements.completeInitialization(plugins); - } - try (InitTimer st = timer("foreignCalls.initialize")) { foreignCalls.initialize(providers, config); } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Tue Mar 17 11:23:06 2015 -0700 @@ -27,26 +27,13 @@ import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import sun.misc.*; - -import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; -import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; -import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.bridge.*; -import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; -import com.oracle.graal.nodeinfo.*; -import com.oracle.graal.nodes.HeapAccess.BarrierType; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.debug.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.options.*; -import com.oracle.graal.replacements.nodes.*; import edu.umd.cs.findbugs.annotations.*; @@ -105,59 +92,62 @@ public static boolean enabled = false; - public static final ConcurrentHashMap indexes = new ConcurrentHashMap<>(); - public static final ArrayList groups = new ArrayList<>(); + private static class Counter { + public final int index; + public final String group; + public final AtomicLong staticCounters; + + public Counter(int index, String group, AtomicLong staticCounters) { + this.index = index; + this.group = group; + this.staticCounters = staticCounters; + } + } + + public static final ConcurrentHashMap counterMap = new ConcurrentHashMap<>(); public static long[] delta; - public static final ArrayList staticCounters = new ArrayList<>(); + + public static int getIndexConstantIncrement(String name, String group, HotSpotVMConfig config, long increment) { + Counter counter = getCounter(name, group, config); + counter.staticCounters.addAndGet(increment); + return counter.index; + } + + public static int getIndex(String name, String group, HotSpotVMConfig config) { + Counter counter = getCounter(name, group, config); + return counter.index; + } @SuppressFBWarnings(value = "AT_OPERATION_SEQUENCE_ON_CONCURRENT_ABSTRACTION", justification = "concurrent abstraction calls are in synchronized block") - private static int getIndex(DynamicCounterNode counter, StructuredGraph currentGraph) { + private static Counter getCounter(String name, String group, HotSpotVMConfig config) throws GraalInternalError { if (!enabled) { - throw new GraalInternalError("counter nodes shouldn't exist when counters are not enabled: " + counter.getGroup() + ", " + counter.getName()); + throw new GraalInternalError("cannot access count index when counters are not enabled: " + group + ", " + name); } - String name; - String group = counter.getGroup(); - if (counter.isWithContext()) { - name = counter.getName() + " @ "; - if (currentGraph.method() != null) { - StackTraceElement stackTraceElement = currentGraph.method().asStackTraceElement(0); - if (stackTraceElement != null) { - name += " " + stackTraceElement.toString(); - } else { - name += currentGraph.method().format("%h.%n"); - } - } - if (currentGraph.name != null) { - name += " (" + currentGraph.name + ")"; - } - name += "#" + group; - - } else { - name = counter.getName() + "#" + group; - } - Integer index = indexes.get(name); - if (index == null) { + String nameGroup = name + "#" + group; + Counter counter = counterMap.get(nameGroup); + if (counter == null) { synchronized (BenchmarkCounters.class) { - index = indexes.get(name); - if (index == null) { - index = indexes.size(); - indexes.put(name, index); - groups.add(group); - staticCounters.add(new AtomicLong()); + counter = counterMap.get(nameGroup); + if (counter == null) { + counter = new Counter(counterMap.size(), group, new AtomicLong()); + counterMap.put(nameGroup, counter); } } } - assert groups.get(index).equals(group) : "mismatching groups: " + groups.get(index) + " vs. " + group; - if (counter.getIncrement().isConstant()) { - staticCounters.get(index).addAndGet(counter.getIncrement().asJavaConstant().asLong()); + assert counter.group.equals(group) : "mismatching groups: " + counter.group + " vs. " + group; + int countersSize = config.graalCountersSize; + if (counter.index >= countersSize) { + throw new GraalInternalError("too many counters, reduce number of counters or increase -XX:GraalCounterSize=... (current value: " + countersSize + ")"); } - return index; + return counter; } private static synchronized void dump(PrintStream out, double seconds, long[] counters, int maxRows) { - if (!groups.isEmpty()) { - out.println("====== dynamic counters (" + staticCounters.size() + " in total) ======"); - for (String group : new TreeSet<>(groups)) { + if (!counterMap.isEmpty()) { + out.println("====== dynamic counters (" + counterMap.size() + " in total) ======"); + TreeSet set = new TreeSet<>(); + counterMap.forEach((nameGroup, counter) -> set.add(counter.group)); + for (String group : set) { if (group != null) { if (DUMP_STATIC) { dumpCounters(out, seconds, counters, true, group, maxRows); @@ -181,9 +171,9 @@ // collect the numbers long[] array; if (staticCounter) { - array = new long[indexes.size()]; - for (int i = 0; i < array.length; i++) { - array[i] = staticCounters.get(i).get(); + array = new long[counterMap.size()]; + for (Counter counter : counterMap.values()) { + array[counter.index] = counter.staticCounters.get(); } } else { array = counters.clone(); @@ -193,9 +183,10 @@ } // sort the counters by putting them into a sorted map long sum = 0; - for (Map.Entry entry : indexes.entrySet()) { - int index = entry.getValue(); - if (groups.get(index).equals(group)) { + for (Map.Entry entry : counterMap.entrySet()) { + Counter counter = entry.getValue(); + int index = counter.index; + if (counter.group.equals(group)) { sum += array[index]; sorted.put(array[index] * array.length + index, entry.getKey().substring(0, entry.getKey().length() - group.length() - 1)); } @@ -383,51 +374,4 @@ dump(TTY.cachedOut, (System.nanoTime() - compilerStartTime) / 1000000000d, compilerToVM.collectCounters(), 100); } } - - private static final LocationIdentity COUNTER_ARRAY_LOCATION = NamedLocationIdentity.mutable("COUNTER_ARRAY_LOCATION"); - private static final LocationIdentity COUNTER_LOCATION = NamedLocationIdentity.mutable("COUNTER_LOCATION"); - - @NodeInfo(nameTemplate = "CounterIndex") - private static final class CounterIndexNode extends FloatingNode implements LIRLowerable { - - public static final NodeClass TYPE = NodeClass.create(CounterIndexNode.class); - protected final Object counter; - protected final int countersSize; - - protected CounterIndexNode(Stamp stamp, DynamicCounterNode counter, int countersSize) { - super(TYPE, stamp); - this.countersSize = countersSize; - this.counter = counter; - } - - @Override - public void generate(NodeLIRBuilderTool generator) { - int index = BenchmarkCounters.getIndex((DynamicCounterNode) counter, graph()); - if (index >= countersSize) { - throw new GraalInternalError("too many counters, reduce number of counters or increase -XX:GraalCounterSize=... (current value: " + countersSize + ")"); - } - - generator.setResult(this, JavaConstant.forIntegerKind(getKind(), index)); - } - } - - public static void lower(DynamicCounterNode counter, HotSpotRegistersProvider registers, HotSpotVMConfig config, Kind wordKind) { - StructuredGraph graph = counter.graph(); - - ReadRegisterNode thread = graph.add(new ReadRegisterNode(registers.getThreadRegister(), wordKind, true, false)); - - CounterIndexNode index = graph.unique(new CounterIndexNode(StampFactory.forKind(wordKind), counter, config.graalCountersSize)); - ConstantLocationNode arrayLocation = graph.unique(new ConstantLocationNode(COUNTER_ARRAY_LOCATION, config.graalCountersThreadOffset)); - ReadNode readArray = graph.add(new ReadNode(thread, arrayLocation, StampFactory.forKind(wordKind), BarrierType.NONE)); - IndexedLocationNode location = graph.unique(new IndexedLocationNode(COUNTER_LOCATION, 0, index, Unsafe.ARRAY_LONG_INDEX_SCALE)); - ReadNode read = graph.add(new ReadNode(readArray, location, StampFactory.forKind(Kind.Long), BarrierType.NONE)); - AddNode add = graph.unique(new AddNode(read, counter.getIncrement())); - WriteNode write = graph.add(new WriteNode(readArray, add, location, BarrierType.NONE)); - - graph.addBeforeFixed(counter, thread); - graph.addBeforeFixed(counter, readArray); - graph.addBeforeFixed(counter, read); - graph.addBeforeFixed(counter, write); - graph.removeFixed(counter); - } } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Tue Mar 17 11:23:06 2015 -0700 @@ -36,7 +36,6 @@ import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.debug.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.hotspot.replacements.*; @@ -105,8 +104,6 @@ lowerStoreHubNode((StoreHubNode) n, graph); } else if (n instanceof OSRStartNode) { lowerOSRStartNode((OSRStartNode) n); - } else if (n instanceof DynamicCounterNode) { - lowerDynamicCounterNode((DynamicCounterNode) n); } else if (n instanceof BytecodeExceptionNode) { lowerBytecodeExceptionNode((BytecodeExceptionNode) n); } else if (n instanceof CheckCastDynamicNode) { @@ -369,13 +366,6 @@ } } - private void lowerDynamicCounterNode(DynamicCounterNode n) { - StructuredGraph graph = n.graph(); - if (graph.getGuardsStage().areFrameStatesAtDeopts()) { - BenchmarkCounters.lower(n, registers, runtime.getConfig(), runtime.getTarget().wordKind); - } - } - static final class Exceptions { protected static final ArrayIndexOutOfBoundsException cachedArrayIndexOutOfBoundsException; protected static final NullPointerException cachedNullPointerException; diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Tue Mar 17 11:23:06 2015 -0700 @@ -22,21 +22,20 @@ */ package com.oracle.graal.hotspot.meta; +import static com.oracle.graal.graphbuilderconf.GraphBuilderContext.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; -import static com.oracle.graal.java.GraphBuilderContext.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; +import com.oracle.graal.graphbuilderconf.InvocationPlugins.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.hotspot.word.*; -import com.oracle.graal.java.GraphBuilderConfiguration.Plugins; -import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderPlugin.InvocationPlugin; -import com.oracle.graal.java.InvocationPlugins.Registration; -import com.oracle.graal.java.InvocationPlugins.Registration.Receiver; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.HeapAccess.BarrierType; import com.oracle.graal.nodes.extended.*; @@ -50,36 +49,45 @@ */ public class HotSpotGraphBuilderPlugins { + private static final int PLUGIN_COUNT_ESTIMATE = 160; + /** * Creates a {@link Plugins} object that should be used when running on HotSpot. + * + * @param constantReflection + * @param snippetReflection + * @param foreignCalls + * @param stampProvider */ - public static Plugins create(HotSpotVMConfig config, HotSpotProviders providers) { + public static Plugins create(HotSpotVMConfig config, HotSpotWordTypes wordTypes, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, + SnippetReflectionProvider snippetReflection, ForeignCallsProvider foreignCalls, StampProvider stampProvider, ReplacementsImpl replacements, Architecture arch) { - MetaAccessProvider metaAccess = providers.getMetaAccess(); - HotSpotWordTypes wordTypes = providers.getWordTypes(); - InvocationPlugins invocationPlugins = new HotSpotInvocationPlugins(config, metaAccess); + InvocationPlugins invocationPlugins = new HotSpotInvocationPlugins(config, metaAccess, PLUGIN_COUNT_ESTIMATE); Plugins plugins = new Plugins(invocationPlugins); - NodeIntrinsificationPhase nodeIntrinsification = new NodeIntrinsificationPhase(providers, providers.getSnippetReflection()); - ConstantReflectionProvider constantReflection = providers.getConstantReflection(); - HotSpotWordOperationPlugin wordOperationPlugin = new HotSpotWordOperationPlugin(providers.getSnippetReflection(), wordTypes); + NodeIntrinsificationPhase nodeIntrinsification = new NodeIntrinsificationPhase(metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider); + HotSpotWordOperationPlugin wordOperationPlugin = new HotSpotWordOperationPlugin(snippetReflection, wordTypes); plugins.setParameterPlugin(new HotSpotParameterPlugin(wordTypes)); plugins.setLoadFieldPlugin(new HotSpotLoadFieldPlugin(metaAccess, constantReflection)); plugins.setLoadIndexedPlugin(new HotSpotLoadIndexedPlugin(wordTypes)); - plugins.setInlineInvokePlugin(new HotSpotInlineInvokePlugin(nodeIntrinsification, (ReplacementsImpl) providers.getReplacements())); + plugins.setInlineInvokePlugin(new HotSpotInlineInvokePlugin(nodeIntrinsification, replacements)); plugins.setGenericInvocationPlugin(new DefaultGenericInvocationPlugin(nodeIntrinsification, wordOperationPlugin)); - registerObjectPlugins(invocationPlugins, metaAccess); - registerSystemPlugins(invocationPlugins, metaAccess, providers.getForeignCalls()); + registerObjectPlugins(invocationPlugins); + registerSystemPlugins(invocationPlugins, foreignCalls); registerThreadPlugins(invocationPlugins, metaAccess, wordTypes, config); - registerStableOptionPlugins(invocationPlugins, metaAccess); - StandardGraphBuilderPlugins.registerInvocationPlugins(providers.getMetaAccess(), providers.getCodeCache().target.arch, invocationPlugins, !config.useHeapProfiler); + registerStableOptionPlugins(invocationPlugins); + StandardGraphBuilderPlugins.registerInvocationPlugins(metaAccess, arch, invocationPlugins, !config.useHeapProfiler); + + int size = invocationPlugins.size(); + assert PLUGIN_COUNT_ESTIMATE >= size : String.format("adjust %s.PLUGIN_COUNT_ESTIMATE to be above or equal to %d", HotSpotGraphBuilderPlugins.class.getSimpleName(), size); + assert PLUGIN_COUNT_ESTIMATE - size < 20 : String.format("adjust %s.PLUGIN_COUNT_ESTIMATE to be closer to %d", HotSpotGraphBuilderPlugins.class.getSimpleName(), size); return plugins; } - private static void registerObjectPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess) { - Registration r = new Registration(plugins, metaAccess, Object.class); + private static void registerObjectPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, Object.class); r.register1("getClass", Receiver.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode rcvr) { ObjectStamp objectStamp = (ObjectStamp) rcvr.stamp(); @@ -97,8 +105,8 @@ }); } - private static void registerSystemPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls) { - Registration r = new Registration(plugins, metaAccess, System.class); + private static void registerSystemPlugins(InvocationPlugins plugins, ForeignCallsProvider foreignCalls) { + Registration r = new Registration(plugins, System.class); r.register0("currentTimeMillis", new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod) { ForeignCallNode foreignCall = new ForeignCallNode(foreignCalls, SystemSubstitutions.JAVA_TIME_MILLIS, StampFactory.forKind(Kind.Long)); @@ -118,7 +126,7 @@ } private static void registerThreadPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess, WordTypes wordTypes, HotSpotVMConfig config) { - Registration r = new Registration(plugins, metaAccess, Thread.class); + Registration r = new Registration(plugins, Thread.class); r.register0("currentThread", new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod) { CurrentJavaThreadNode thread = b.append(new CurrentJavaThreadNode(wordTypes.getWordKind())); @@ -133,8 +141,8 @@ }); } - private static void registerStableOptionPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess) { - Registration r = new Registration(plugins, metaAccess, StableOptionValue.class); + private static void registerStableOptionPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, StableOptionValue.class); r.register1("getValue", Receiver.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode rcvr) { if (rcvr.isConstant() && !rcvr.isNullConstant()) { diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInlineInvokePlugin.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInlineInvokePlugin.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInlineInvokePlugin.java Tue Mar 17 11:23:06 2015 -0700 @@ -28,10 +28,9 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.Node.NodeIntrinsic; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderContext.Replacement; import com.oracle.graal.hotspot.word.*; -import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderContext.Replacement; -import com.oracle.graal.java.GraphBuilderPlugin.InlineInvokePlugin; import com.oracle.graal.nodes.*; import com.oracle.graal.replacements.*; import com.oracle.graal.word.*; diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInvocationPlugins.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInvocationPlugins.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInvocationPlugins.java Tue Mar 17 11:23:06 2015 -0700 @@ -23,40 +23,38 @@ package com.oracle.graal.hotspot.meta; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderPlugin.*; -import com.oracle.graal.replacements.StandardGraphBuilderPlugins.*; +import com.oracle.graal.replacements.StandardGraphBuilderPlugins.BoxPlugin; /** * Extension of {@link InvocationPlugins} that disables plugins based on runtime configuration. */ final class HotSpotInvocationPlugins extends InvocationPlugins { final HotSpotVMConfig config; - final MetaAccessProvider metaAccess; - public HotSpotInvocationPlugins(HotSpotVMConfig config, MetaAccessProvider metaAccess) { + public HotSpotInvocationPlugins(HotSpotVMConfig config, MetaAccessProvider metaAccess, int estimatePluginCount) { + super(metaAccess, estimatePluginCount); this.config = config; - this.metaAccess = metaAccess; } @Override - public void register(ResolvedJavaMethod method, InvocationPlugin plugin) { + public void register(InvocationPlugin plugin, Class declaringClass, String name, Class... argumentTypes) { if (!config.usePopCountInstruction) { - if (method.getName().equals("bitCount")) { - assert method.getDeclaringClass().equals(metaAccess.lookupJavaType(Integer.class)) || method.getDeclaringClass().equals(metaAccess.lookupJavaType(Long.class)); + if (name.equals("bitCount")) { + assert declaringClass.equals(Integer.class) || declaringClass.equals(Long.class); return; } } if (!config.useCountLeadingZerosInstruction) { - if (method.getName().equals("numberOfLeadingZeros")) { - assert method.getDeclaringClass().equals(metaAccess.lookupJavaType(Integer.class)) || method.getDeclaringClass().equals(metaAccess.lookupJavaType(Long.class)); + if (name.equals("numberOfLeadingZeros")) { + assert declaringClass.equals(Integer.class) || declaringClass.equals(Long.class); return; } } if (!config.useCountTrailingZerosInstruction) { - if (method.getName().equals("numberOfTrailingZeros")) { - assert method.getDeclaringClass().equals(metaAccess.lookupJavaType(Integer.class)); + if (name.equals("numberOfTrailingZeros")) { + assert declaringClass.equals(Integer.class); return; } } @@ -67,6 +65,6 @@ return; } } - super.register(method, plugin); + super.register(plugin, declaringClass, name, argumentTypes); } } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadFieldPlugin.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadFieldPlugin.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadFieldPlugin.java Tue Mar 17 11:23:06 2015 -0700 @@ -27,8 +27,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; -import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderPlugin.LoadFieldPlugin; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.nodes.*; public final class HotSpotLoadFieldPlugin implements LoadFieldPlugin { diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadIndexedPlugin.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadIndexedPlugin.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadIndexedPlugin.java Tue Mar 17 11:23:06 2015 -0700 @@ -24,11 +24,10 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.hotspot.word.*; -import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderPlugin.LoadIndexedPlugin; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.type.*; diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotParameterPlugin.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotParameterPlugin.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotParameterPlugin.java Tue Mar 17 11:23:06 2015 -0700 @@ -24,8 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderPlugin.ParameterPlugin; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.type.*; diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProviders.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProviders.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProviders.java Tue Mar 17 11:23:06 2015 -0700 @@ -24,8 +24,8 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; import com.oracle.graal.hotspot.word.*; -import com.oracle.graal.java.GraphBuilderConfiguration.Plugins; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; @@ -41,17 +41,18 @@ private final HotSpotRegistersProvider registers; private final SnippetReflectionProvider snippetReflection; private final HotSpotWordTypes wordTypes; - private Plugins graphBuilderPlugins; + private final Plugins graphBuilderPlugins; public HotSpotProviders(MetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, HotSpotForeignCallsProvider foreignCalls, LoweringProvider lowerer, Replacements replacements, HotSpotDisassemblerProvider disassembler, SuitesProvider suites, HotSpotRegistersProvider registers, - SnippetReflectionProvider snippetReflection) { + SnippetReflectionProvider snippetReflection, HotSpotWordTypes wordTypes, Plugins graphBuilderPlugins) { super(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, new HotSpotStampProvider()); this.disassembler = disassembler; this.suites = suites; this.registers = registers; this.snippetReflection = snippetReflection; - this.wordTypes = new HotSpotWordTypes(metaAccess, codeCache.getTarget().wordKind); + this.wordTypes = wordTypes; + this.graphBuilderPlugins = graphBuilderPlugins; } @Override @@ -80,12 +81,7 @@ return snippetReflection; } - public void setGraphBuilderPlugins(Plugins plugins) { - graphBuilderPlugins = plugins; - } - public Plugins getGraphBuilderPlugins() { - assert graphBuilderPlugins != null; return graphBuilderPlugins; } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java Tue Mar 17 11:23:06 2015 -0700 @@ -34,6 +34,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.debug.*; import com.oracle.graal.nodes.*; @@ -41,7 +42,7 @@ /** * Implementation of {@link JavaMethod} for resolved HotSpot methods. */ -public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, HotSpotProxified { +public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, HotSpotProxified, InvocationPluginIdHolder { private static final long serialVersionUID = -5486975070147586588L; @@ -740,4 +741,15 @@ } return runtime().getCompilerToVM().hasCompiledCodeForOSR(metaspaceMethod, entryBCI, level); } + + private int invocationPluginId; + + public void setInvocationPluginId(int id) { + assert invocationPluginId == 0; + invocationPluginId = id; + } + + public int getInvocationPluginId() { + return invocationPluginId; + } } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java Tue Mar 17 11:23:06 2015 -0700 @@ -24,11 +24,12 @@ import static com.oracle.graal.compiler.common.GraalOptions.*; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.phases.*; import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderConfiguration.DebugInfoMode; import com.oracle.graal.lir.phases.*; import com.oracle.graal.options.*; import com.oracle.graal.options.DerivedOptionValue.OptionSupplier; @@ -65,9 +66,9 @@ } - public HotSpotSuitesProvider(HotSpotGraalRuntimeProvider runtime) { + public HotSpotSuitesProvider(HotSpotGraalRuntimeProvider runtime, Plugins plugins) { this.runtime = runtime; - this.defaultGraphBuilderSuite = createGraphBuilderSuite(); + this.defaultGraphBuilderSuite = createGraphBuilderSuite(plugins); this.defaultSuites = new DerivedOptionValue<>(new SuitesSupplier()); this.defaultLIRSuites = new DerivedOptionValue<>(new LIRSuitesSupplier()); } @@ -99,9 +100,9 @@ return ret; } - protected PhaseSuite createGraphBuilderSuite() { + protected PhaseSuite createGraphBuilderSuite(Plugins plugins) { PhaseSuite suite = new PhaseSuite<>(); - GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(); + GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(plugins); suite.appendPhase(new GraphBuilderPhase(config)); return suite; } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotWordOperationPlugin.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotWordOperationPlugin.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotWordOperationPlugin.java Tue Mar 17 11:23:06 2015 -0700 @@ -30,10 +30,10 @@ import com.oracle.graal.api.replacements.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.hotspot.word.*; import com.oracle.graal.hotspot.word.HotSpotOperation.HotspotOpcode; -import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.HeapAccess.BarrierType; import com.oracle.graal.nodes.calc.*; diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java Tue Mar 17 11:23:06 2015 -0700 @@ -24,7 +24,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; @@ -57,14 +56,6 @@ gen.setResult(this, rawThread.asValue(wordKind)); } - private static int eetopOffset() { - try { - return (int) UnsafeAccess.unsafe.objectFieldOffset(Thread.class.getDeclaredField("eetop")); - } catch (Exception e) { - throw new GraalInternalError(e); - } - } - @NodeIntrinsic public static native Word get(); } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java Tue Mar 17 11:23:06 2015 -0700 @@ -180,24 +180,26 @@ maybeCastArgument(receiverSkip + index, parameterType); } + if (target.canBeStaticallyBound()) { + return createTargetInvokeNode(target, intrinsicMethod); + } + // Try to get the most accurate receiver type if (intrinsicMethod == IntrinsicMethod.LINK_TO_VIRTUAL || intrinsicMethod == IntrinsicMethod.LINK_TO_INTERFACE) { ResolvedJavaType receiverType = StampTool.typeOrNull(getReceiver().stamp()); if (receiverType != null) { AssumptionResult concreteMethod = receiverType.findUniqueConcreteMethod(target); if (concreteMethod != null) { + graph().getAssumptions().record(concreteMethod); return createTargetInvokeNode(concreteMethod.getResult(), intrinsicMethod); } } - } - - if (target.canBeStaticallyBound()) { - return createTargetInvokeNode(target, intrinsicMethod); - } - - AssumptionResult concreteMethod = target.getDeclaringClass().findUniqueConcreteMethod(target); - if (concreteMethod != null) { - return createTargetInvokeNode(concreteMethod.getResult(), intrinsicMethod); + } else { + AssumptionResult concreteMethod = target.getDeclaringClass().findUniqueConcreteMethod(target); + if (concreteMethod != null) { + graph().getAssumptions().record(concreteMethod); + return createTargetInvokeNode(concreteMethod.getResult(), intrinsicMethod); + } } return null; diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Tue Mar 17 11:23:06 2015 -0700 @@ -157,7 +157,8 @@ public static native Object newInstance(@ConstantNodeParameter ForeignCallDescriptor descriptor, KlassPointer hub); @Snippet - public static Object allocateInstanceDynamic(Class type, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister, @ConstantParameter String typeContext) { + public static Object allocateInstanceDynamic(Class type, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister, + @SuppressWarnings("unused") @ConstantParameter String typeContext) { KlassPointer hub = ClassGetHubNode.readClass(type); if (probability(FAST_PATH_PROBABILITY, !hub.isNull())) { if (probability(FAST_PATH_PROBABILITY, isInstanceKlassFullyInitialized(hub))) { @@ -170,7 +171,11 @@ */ if (probability(FAST_PATH_PROBABILITY, (layoutHelper & 1) == 0)) { Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION); - return allocateInstance(layoutHelper, hub, prototypeMarkWord, fillContents, threadRegister, false, typeContext); + /* + * FIXME(je,ds): we should actually pass typeContext instead of "" but late + * binding of parameters is not yet supported by the GraphBuilderPlugin system. + */ + return allocateInstance(layoutHelper, hub, prototypeMarkWord, fillContents, threadRegister, false, ""); } } } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java Tue Mar 17 11:23:06 2015 -0700 @@ -28,10 +28,11 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderConfiguration.Plugins; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.nodes.StructuredGraph.GuardsStage; @@ -79,11 +80,11 @@ @Override protected StructuredGraph getGraph() { - GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(); Plugins defaultPlugins = providers.getGraphBuilderPlugins(); - Plugins plugins = config.getPlugins().updateFrom(defaultPlugins, false); - plugins.getInvocationPlugins().setDefaults(defaultPlugins.getInvocationPlugins()); - plugins.setParameterPlugin(new ConstantBindingParameterPlugin(makeConstArgs(), plugins.getParameterPlugin(), providers.getMetaAccess(), providers.getSnippetReflection())); + MetaAccessProvider metaAccess = providers.getMetaAccess(); + Plugins plugins = new Plugins(defaultPlugins); + plugins.setParameterPlugin(new ConstantBindingParameterPlugin(makeConstArgs(), plugins.getParameterPlugin(), metaAccess, providers.getSnippetReflection())); + GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(plugins); // Stubs cannot have optimistic assumptions since they have // to be valid for the entire run of the VM. Nor can they be @@ -93,7 +94,7 @@ assert SnippetGraphUnderConstruction.get() == null; SnippetGraphUnderConstruction.set(graph); - new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), providers.getConstantReflection(), config, OptimisticOptimizations.NONE, method).apply(graph); + new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), providers.getConstantReflection(), config, OptimisticOptimizations.NONE, method).apply(graph); SnippetGraphUnderConstruction.set(null); graph.setGuardsStage(GuardsStage.FLOATING_GUARDS); diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Tue Mar 17 11:23:06 2015 -0700 @@ -40,6 +40,8 @@ import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.phases.*; +import com.oracle.graal.lir.phases.PostAllocationOptimizationPhase.PostAllocationOptimizationContext; +import com.oracle.graal.lir.profiling.*; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.schedule.*; @@ -180,7 +182,7 @@ Suites suites = new Suites(new PhaseSuite<>(), defaultSuites.getMidTier(), defaultSuites.getLowTier()); SchedulePhase schedule = emitFrontEnd(providers, target, graph, null, providers.getSuites().getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, getProfilingInfo(graph), null, suites); - LIRSuites lirSuites = providers.getSuites().getDefaultLIRSuites(); + LIRSuites lirSuites = createLIRSuites(); emitBackEnd(graph, Stub.this, incomingCc, getInstalledCodeOwner(), backend, target, compResult, CompilationResultBuilderFactory.Default, schedule, getRegisterConfig(), lirSuites); } catch (Throwable e) { throw Debug.handle(e); @@ -210,6 +212,15 @@ return code; } + private LIRSuites createLIRSuites() { + LIRSuites lirSuites = new LIRSuites(providers.getSuites().getDefaultLIRSuites()); + ListIterator> moveProfiling = lirSuites.getPostAllocationOptimizationStage().findPhase(MoveProfiling.class); + if (moveProfiling != null) { + moveProfiling.remove(); + } + return lirSuites; + } + /** * Gets the compilation result for this stub, compiling it first if necessary, and installing it * in code. diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Tue Mar 17 11:23:06 2015 -0700 @@ -37,11 +37,10 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.debug.*; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderContext.*; import com.oracle.graal.java.BciBlockMapping.BciBlock; -import com.oracle.graal.java.GraphBuilderContext.Replacement; import com.oracle.graal.java.GraphBuilderPhase.Instance.BytecodeParser; -import com.oracle.graal.java.GraphBuilderPlugin.LoadFieldPlugin; -import com.oracle.graal.java.GraphBuilderPlugin.LoadIndexedPlugin; import com.oracle.graal.nodes.*; import com.oracle.graal.options.*; import com.oracle.graal.phases.*; diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.java/src/com/oracle/graal/java/DefaultSuitesProvider.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/DefaultSuitesProvider.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/DefaultSuitesProvider.java Tue Mar 17 11:23:06 2015 -0700 @@ -22,6 +22,8 @@ */ package com.oracle.graal.java; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; import com.oracle.graal.lir.phases.*; import com.oracle.graal.options.*; import com.oracle.graal.options.DerivedOptionValue.OptionSupplier; @@ -54,8 +56,8 @@ } - public DefaultSuitesProvider() { - this.defaultGraphBuilderSuite = createGraphBuilderSuite(); + public DefaultSuitesProvider(Plugins plugins) { + this.defaultGraphBuilderSuite = createGraphBuilderSuite(plugins); this.defaultSuites = new DerivedOptionValue<>(new SuitesSupplier()); this.defaultLIRSuites = new DerivedOptionValue<>(new LIRSuitesSupplier()); } @@ -72,9 +74,9 @@ return defaultGraphBuilderSuite; } - protected PhaseSuite createGraphBuilderSuite() { + protected PhaseSuite createGraphBuilderSuite(Plugins plugins) { PhaseSuite suite = new PhaseSuite<>(); - suite.appendPhase(new GraphBuilderPhase(GraphBuilderConfiguration.getDefault())); + suite.appendPhase(new GraphBuilderPhase(GraphBuilderConfiguration.getDefault(plugins))); return suite; } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java Tue Mar 17 11:22:56 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,258 +0,0 @@ -/* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.java; - -import java.util.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.*; -import com.oracle.graal.java.GraphBuilderPlugin.GenericInvocationPlugin; -import com.oracle.graal.java.GraphBuilderPlugin.InlineInvokePlugin; -import com.oracle.graal.java.GraphBuilderPlugin.LoadFieldPlugin; -import com.oracle.graal.java.GraphBuilderPlugin.LoadIndexedPlugin; -import com.oracle.graal.java.GraphBuilderPlugin.LoopExplosionPlugin; -import com.oracle.graal.java.GraphBuilderPlugin.ParameterPlugin; -import com.oracle.graal.nodes.*; - -public class GraphBuilderConfiguration { - - public static class Plugins { - private InvocationPlugins invocationPlugins; - private LoadFieldPlugin loadFieldPlugin; - private LoadIndexedPlugin loadIndexedPlugin; - private ParameterPlugin parameterPlugin; - private InlineInvokePlugin inlineInvokePlugin; - private GenericInvocationPlugin genericInvocationPlugin; - private LoopExplosionPlugin loopExplosionPlugin; - - public Plugins() { - invocationPlugins = new InvocationPlugins(); - } - - public Plugins(InvocationPlugins invocationPlugins) { - this.invocationPlugins = invocationPlugins; - } - - public InvocationPlugins getInvocationPlugins() { - return invocationPlugins; - } - - public GenericInvocationPlugin getGenericInvocationPlugin() { - return genericInvocationPlugin; - } - - public void setGenericInvocationPlugin(GenericInvocationPlugin plugin) { - this.genericInvocationPlugin = plugin; - } - - public LoadFieldPlugin getLoadFieldPlugin() { - return loadFieldPlugin; - } - - public void setLoadFieldPlugin(LoadFieldPlugin plugin) { - this.loadFieldPlugin = plugin; - } - - public LoadIndexedPlugin getLoadIndexedPlugin() { - return loadIndexedPlugin; - } - - public void setLoadIndexedPlugin(LoadIndexedPlugin plugin) { - this.loadIndexedPlugin = plugin; - } - - public ParameterPlugin getParameterPlugin() { - return parameterPlugin; - } - - public void setParameterPlugin(ParameterPlugin plugin) { - this.parameterPlugin = plugin; - } - - public InlineInvokePlugin getInlineInvokePlugin() { - return inlineInvokePlugin; - } - - public void setInlineInvokePlugin(InlineInvokePlugin plugin) { - this.inlineInvokePlugin = plugin; - } - - public LoopExplosionPlugin getLoopExplosionPlugin() { - return loopExplosionPlugin; - } - - public void setLoopExplosionPlugin(LoopExplosionPlugin plugin) { - this.loopExplosionPlugin = plugin; - } - - public Plugins updateFrom(Plugins other, boolean includeInvocationPlugins) { - if (includeInvocationPlugins) { - this.invocationPlugins.updateFrom(other.getInvocationPlugins()); - } - this.parameterPlugin = other.parameterPlugin; - this.loadFieldPlugin = other.loadFieldPlugin; - this.loadIndexedPlugin = other.loadIndexedPlugin; - this.inlineInvokePlugin = other.inlineInvokePlugin; - this.loopExplosionPlugin = other.loopExplosionPlugin; - this.genericInvocationPlugin = other.genericInvocationPlugin; - return this; - } - } - - private static final ResolvedJavaType[] EMPTY = new ResolvedJavaType[]{}; - - private final boolean eagerResolving; - private final boolean omitAllExceptionEdges; - private final ResolvedJavaType[] skippedExceptionTypes; - private final DebugInfoMode debugInfoMode; - private final boolean doLivenessAnalysis; - private boolean useProfiling; - private Plugins plugins = new Plugins(); - - public static enum DebugInfoMode { - SafePointsOnly, - /** - * This mode inserts {@link SimpleInfopointNode}s in places where no safepoints would be - * inserted: inlining boundaries, and line number switches. - *

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

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

- * This is relevant when code is to be generated for native, machine-code level debugging - * but can have a limit the amount of optimization applied to the code. - */ - Full, - } - - protected GraphBuilderConfiguration(boolean eagerResolving, boolean omitAllExceptionEdges, DebugInfoMode debugInfoMode, ResolvedJavaType[] skippedExceptionTypes, boolean doLivenessAnalysis) { - this.eagerResolving = eagerResolving; - this.omitAllExceptionEdges = omitAllExceptionEdges; - this.debugInfoMode = debugInfoMode; - this.skippedExceptionTypes = skippedExceptionTypes; - this.doLivenessAnalysis = doLivenessAnalysis; - this.useProfiling = true; - } - - public GraphBuilderConfiguration copy() { - GraphBuilderConfiguration result = new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, doLivenessAnalysis); - result.useProfiling = useProfiling; - result.copyPluginsFrom(this); - return result; - } - - public boolean getUseProfiling() { - return useProfiling; - } - - public void setUseProfiling(boolean b) { - this.useProfiling = b; - } - - public GraphBuilderConfiguration withSkippedExceptionTypes(ResolvedJavaType[] newSkippedExceptionTypes) { - return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, newSkippedExceptionTypes, doLivenessAnalysis); - } - - public GraphBuilderConfiguration withOmitAllExceptionEdges(boolean newOmitAllExceptionEdges) { - return new GraphBuilderConfiguration(eagerResolving, newOmitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, doLivenessAnalysis); - } - - public GraphBuilderConfiguration withDebugInfoMode(DebugInfoMode newDebugInfoMode) { - ResolvedJavaType[] newSkippedExceptionTypes = skippedExceptionTypes == EMPTY ? EMPTY : Arrays.copyOf(skippedExceptionTypes, skippedExceptionTypes.length); - return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, newDebugInfoMode, newSkippedExceptionTypes, doLivenessAnalysis); - } - - public GraphBuilderConfiguration withDoLivenessAnalysis(boolean newLivenessAnalysis) { - return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, newLivenessAnalysis); - } - - public ResolvedJavaType[] getSkippedExceptionTypes() { - return skippedExceptionTypes; - } - - public boolean eagerResolving() { - return eagerResolving; - } - - public boolean omitAllExceptionEdges() { - return omitAllExceptionEdges; - } - - public boolean insertNonSafepointDebugInfo() { - return debugInfoMode.ordinal() >= DebugInfoMode.Simple.ordinal(); - } - - public boolean insertFullDebugInfo() { - return debugInfoMode.ordinal() >= DebugInfoMode.Full.ordinal(); - } - - public boolean doLivenessAnalysis() { - return doLivenessAnalysis; - } - - public static GraphBuilderConfiguration getDefault() { - return new GraphBuilderConfiguration(false, false, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptLivenessAnalysis.getValue()); - } - - public static GraphBuilderConfiguration getEagerDefault() { - return new GraphBuilderConfiguration(true, false, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptLivenessAnalysis.getValue()); - } - - public static GraphBuilderConfiguration getSnippetDefault() { - return new GraphBuilderConfiguration(true, true, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptLivenessAnalysis.getValue()); - } - - public static GraphBuilderConfiguration getFullDebugDefault() { - return new GraphBuilderConfiguration(true, false, DebugInfoMode.Full, EMPTY, GraalOptions.OptLivenessAnalysis.getValue()); - } - - /** - * Returns {@code true} if it is an error for a class/field/method resolution to fail. The - * default is the same result as returned by {@link #eagerResolving()}. However, it may be - * overridden to allow failure even when {@link #eagerResolving} is {@code true}. - */ - public boolean unresolvedIsError() { - return eagerResolving; - } - - public Plugins getPlugins() { - return plugins; - } - - public void setPlugins(Plugins plugins) { - this.plugins = plugins; - } - - public GraphBuilderConfiguration copyPluginsFrom(GraphBuilderConfiguration other) { - this.plugins.updateFrom(other.plugins, true); - return this; - } -} diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderContext.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderContext.java Tue Mar 17 11:22:56 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.java; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.replacements.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; - -/** - * Used by a {@link GraphBuilderPlugin} to interface with a graph builder object. - */ -public interface GraphBuilderContext { - - /** - * Information about a snippet or method substitution currently being processed by the graph - * builder. When in the scope of a replacement, the graph builder does not check the value kinds - * flowing through the JVM state since replacements can employ non-Java kinds to represent - * values such as raw machine words and pointers. - */ - public interface Replacement { - - /** - * Gets the method being replaced. - */ - ResolvedJavaMethod getOriginalMethod(); - - /** - * Gets the replacement method. - */ - ResolvedJavaMethod getReplacementMethod(); - - /** - * Determines if this replacement is being inlined as a compiler intrinsic. A compiler - * intrinsic is atomic with respect to deoptimization. Deoptimization within a compiler - * intrinsic will restart the interpreter at the intrinsified call. - */ - boolean isIntrinsic(); - } - - T append(T fixed); - - T append(T fixed); - - T append(T fixed); - - T append(T value); - - T append(T value); - - StampProvider getStampProvider(); - - MetaAccessProvider getMetaAccess(); - - Assumptions getAssumptions(); - - ConstantReflectionProvider getConstantReflection(); - - SnippetReflectionProvider getSnippetReflection(); - - void push(Kind kind, ValueNode value); - - StructuredGraph getGraph(); - - FrameState createStateAfter(); - - /** - * Gets the parsing context for the method that inlines the method being parsed by this context. - */ - GraphBuilderContext getParent(); - - /** - * Gets the root method for the graph building process. - */ - ResolvedJavaMethod getRootMethod(); - - /** - * Gets the method currently being parsed. - */ - ResolvedJavaMethod getMethod(); - - /** - * Gets the index of the bytecode instruction currently being parsed. - */ - int bci(); - - /** - * Gets the inline depth of this context. 0 implies this is the context for the - * {@linkplain #getRootMethod() root method}. - */ - int getDepth(); - - /** - * Determines if the current parsing context is a snippet or method substitution. - */ - default boolean parsingReplacement() { - return getReplacement() == null; - } - - /** - * Gets the replacement of the current parsing context or {@code null} if not - * {@link #parsingReplacement() parsing a replacement}. - */ - Replacement getReplacement(); - - /** - * @see GuardingPiNode#nullCheckedValue(ValueNode) - */ - static ValueNode nullCheckedValue(GraphBuilderContext builder, ValueNode value) { - ValueNode nonNullValue = GuardingPiNode.nullCheckedValue(value); - if (nonNullValue != value) { - builder.append((FixedWithNextNode) nonNullValue); - } - return nonNullValue; - } - - boolean eagerResolving(); - - BailoutException bailout(String string); -} diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Mar 17 11:23:06 2015 -0700 @@ -46,14 +46,11 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.ValueNumberable; import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.InlineInvokePlugin.InlineInfo; import com.oracle.graal.java.AbstractBytecodeParser.ReplacementContext; import com.oracle.graal.java.BciBlockMapping.BciBlock; import com.oracle.graal.java.BciBlockMapping.ExceptionDispatchBlock; -import com.oracle.graal.java.GraphBuilderPlugin.GenericInvocationPlugin; -import com.oracle.graal.java.GraphBuilderPlugin.InlineInvokePlugin; -import com.oracle.graal.java.GraphBuilderPlugin.InlineInvokePlugin.InlineInfo; -import com.oracle.graal.java.GraphBuilderPlugin.InvocationPlugin; -import com.oracle.graal.java.GraphBuilderPlugin.LoopExplosionPlugin; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.CallTargetNode.InvokeKind; diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugin.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugin.java Tue Mar 17 11:22:56 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,255 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.java; - -import java.lang.reflect.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.*; -import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.java.GraphBuilderPhase.Instance.BytecodeParser; -import com.oracle.graal.java.GraphBuilderPlugin.InlineInvokePlugin.InlineInfo; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; - -/** - * Marker interface for graph builder plugins. - */ -public interface GraphBuilderPlugin { - - public interface LoadFieldPlugin extends GraphBuilderPlugin { - @SuppressWarnings("unused") - default boolean apply(GraphBuilderContext b, ValueNode receiver, ResolvedJavaField field) { - return false; - } - - @SuppressWarnings("unused") - default boolean apply(GraphBuilderContext graphBuilderContext, ResolvedJavaField staticField) { - return false; - } - - default boolean tryConstantFold(GraphBuilderContext b, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ResolvedJavaField field, JavaConstant receiver) { - JavaConstant result = constantReflection.readConstantFieldValue(field, receiver); - if (result != null) { - ConstantNode constantNode = b.append(ConstantNode.forConstant(result, metaAccess)); - b.push(constantNode.getKind().getStackKind(), constantNode); - return true; - } - return false; - } - } - - public interface LoadIndexedPlugin extends GraphBuilderPlugin { - @SuppressWarnings("unused") - default boolean apply(GraphBuilderContext b, ValueNode array, ValueNode index, Kind elementKind) { - return false; - } - } - - /** - * Plugin for specifying what is inlined during graph parsing or for post-processing non-inlined - * invocations that result in {@link Invoke} nodes. - */ - public interface InlineInvokePlugin extends GraphBuilderPlugin { - - public static class InlineInfo { - - /** - * The method to be inlined. - */ - public final ResolvedJavaMethod methodToInline; - - /** - * Specifies if {@link #methodToInline} is to be considered a - * {@linkplain GraphBuilderContext.Replacement replacement} for the {@code method} - * passed to {@link InlineInvokePlugin#getInlineInfo}. - */ - public final boolean isReplacement; - - /** - * Specifies if {@link #methodToInline} is an intrinsic for the original method. If so, - * any {@link StateSplit} node created in the (recursive) inlining scope will be given a - * frame state that restarts the interpreter just before the intrinsified invocation. - */ - public final boolean isIntrinsic; - - public InlineInfo(ResolvedJavaMethod methodToInline, boolean isReplacement, boolean isIntrinsic) { - this.methodToInline = methodToInline; - this.isIntrinsic = isIntrinsic; - this.isReplacement = isReplacement; - assert !isIntrinsic || isReplacement : "cannot be an intrinsic without also being a replacement"; - } - } - - /** - * Determines whether a call to a given method is to be inlined. - * - * @param method the target method of an invoke - * @param args the arguments to the invoke - * @param returnType the return type derived from {@code method}'s signature - */ - default InlineInfo getInlineInfo(@SuppressWarnings("unused") GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType) { - return null; - } - - /** - * @param inlinedTargetMethod - */ - default void postInline(ResolvedJavaMethod inlinedTargetMethod) { - } - - /** - * Notifies this plugin of the {@link Invoke} node created for a method that was not inlined - * per {@link #getInlineInfo}. - * - * @param method the method that was not inlined - * @param invoke the invoke node created for the call to {@code method} - */ - default void notifyOfNoninlinedInvoke(@SuppressWarnings("unused") GraphBuilderContext b, ResolvedJavaMethod method, Invoke invoke) { - } - } - - public interface LoopExplosionPlugin extends GraphBuilderPlugin { - boolean shouldExplodeLoops(ResolvedJavaMethod method); - - boolean shouldMergeExplosions(ResolvedJavaMethod method); - } - - public interface ParameterPlugin extends GraphBuilderPlugin { - FloatingNode interceptParameter(GraphBuilderContext b, int index, Stamp stamp); - } - - /** - * Plugin for handling an invocation based on some property of the method being invoked such as - * any annotations it may have. - */ - public interface GenericInvocationPlugin extends GraphBuilderPlugin { - /** - * Executes this plugin for an invocation of a given method with a given set of arguments. - * - * @return {@code true} if this plugin handled the invocation, {@code false} if not - */ - boolean apply(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args); - } - - /** - * Plugin for handling a specific method invocation. - */ - public interface InvocationPlugin extends GraphBuilderPlugin { - /** - * @see #execute - */ - default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod) { - throw invalidHandler(b, targetMethod); - } - - /** - * @see #execute - */ - default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode arg) { - throw invalidHandler(b, targetMethod, arg); - } - - /** - * @see #execute - */ - default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode arg1, ValueNode arg2) { - throw invalidHandler(b, targetMethod, arg1, arg2); - } - - /** - * @see #execute - */ - default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode arg1, ValueNode arg2, ValueNode arg3) { - throw invalidHandler(b, targetMethod, arg1, arg2, arg3); - } - - /** - * @see #execute - */ - default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode arg1, ValueNode arg2, ValueNode arg3, ValueNode arg4) { - throw invalidHandler(b, targetMethod, arg1, arg2, arg3, arg4); - } - - /** - * @see #execute - */ - default boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode arg1, ValueNode arg2, ValueNode arg3, ValueNode arg4, ValueNode arg5) { - throw invalidHandler(b, targetMethod, arg1, arg2, arg3, arg4, arg5); - } - - default ResolvedJavaMethod getSubstitute() { - return null; - } - - boolean ALLOW_INVOCATION_PLUGIN_TO_DO_INLINING = false; - - /** - * Executes a given plugin against a set of invocation arguments by dispatching to the - * {@code apply(...)} method that matches the number of arguments. - * - * @param targetMethod the method for which plugin is being applied - * @return {@code true} if the plugin handled the invocation of {@code targetMethod} - * {@code false} if the graph builder should process the invoke further (e.g., by - * inlining it or creating an {@link Invoke} node). A plugin that does not handle an - * invocation must not modify the graph being constructed. - */ - static boolean execute(GraphBuilderContext b, ResolvedJavaMethod targetMethod, InvocationPlugin plugin, ValueNode[] args) { - if (ALLOW_INVOCATION_PLUGIN_TO_DO_INLINING) { - ResolvedJavaMethod subst = plugin.getSubstitute(); - if (subst != null) { - return ((BytecodeParser) b).inline(null, targetMethod, new InlineInfo(subst, true, false), args); - } - } - if (args.length == 0) { - return plugin.apply(b, targetMethod); - } else if (args.length == 1) { - return plugin.apply(b, targetMethod, args[0]); - } else if (args.length == 2) { - return plugin.apply(b, targetMethod, args[0], args[1]); - } else if (args.length == 3) { - return plugin.apply(b, targetMethod, args[0], args[1], args[2]); - } else if (args.length == 4) { - return plugin.apply(b, targetMethod, args[0], args[1], args[2], args[3]); - } else if (args.length == 5) { - return plugin.apply(b, targetMethod, args[0], args[1], args[2], args[3], args[4]); - } else { - throw plugin.invalidHandler(b, targetMethod, args); - } - } - - default Error invalidHandler(@SuppressWarnings("unused") GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode... args) { - return new GraalInternalError("Invocation plugin for %s does not handle invocations with %d arguments", targetMethod.format("%H.%n(%p)"), args.length); - } - - default StackTraceElement getApplySourceLocation(MetaAccessProvider metaAccess) { - Class c = getClass(); - for (Method m : c.getDeclaredMethods()) { - if (m.getName().equals("apply")) { - return metaAccess.lookupJavaMethod(m).asStackTraceElement(0); - } - } - throw new GraalInternalError("could not find method named \"apply\" in " + c.getName()); - } - } -} diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java Tue Mar 17 11:23:06 2015 -0700 @@ -31,10 +31,10 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.java.AbstractBytecodeParser.IntrinsicContext; import com.oracle.graal.java.BciBlockMapping.BciBlock; import com.oracle.graal.java.GraphBuilderPhase.Instance.BytecodeParser; -import com.oracle.graal.java.GraphBuilderPlugin.ParameterPlugin; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.java/src/com/oracle/graal/java/InvocationPlugins.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/InvocationPlugins.java Tue Mar 17 11:22:56 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,245 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.java; - -import static java.lang.String.*; - -import java.lang.reflect.*; -import java.util.*; -import java.util.stream.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.*; -import com.oracle.graal.java.GraphBuilderPlugin.InvocationPlugin; -import com.oracle.graal.nodes.*; - -/** - * Manages a set of {@link InvocationPlugin}s. - */ -public class InvocationPlugins { - /** - * Utility for {@linkplain InvocationPlugins#register(ResolvedJavaMethod, InvocationPlugin) - * registration} of invocation plugins. - */ - public static class Registration { - - /** - * Sentinel class for use with {@link Registration#register1}, - * {@link Registration#register2} or {@link Registration#register3} to denote the receiver - * argument for a non-static method. - */ - public static final class Receiver { - private Receiver() { - throw GraalInternalError.shouldNotReachHere(); - } - } - - private final InvocationPlugins plugins; - private final MetaAccessProvider metaAccess; - private final Class declaringClass; - - /** - * Creates an object for registering {@link InvocationPlugin}s for methods declared by a - * given class. - * - * @param plugins where to register the plugins - * @param metaAccess used to resolve classes and methods - * @param declaringClass the class declaring the methods for which plugins will be - * registered via this object - */ - public Registration(InvocationPlugins plugins, MetaAccessProvider metaAccess, Class declaringClass) { - this.plugins = plugins; - this.metaAccess = metaAccess; - this.declaringClass = declaringClass; - } - - /** - * Registers a plugin for a method with no arguments. - * - * @param name the name of the method - * @param plugin the plugin to be registered - */ - public void register0(String name, InvocationPlugin plugin) { - plugins.register(resolve(metaAccess, declaringClass, name), plugin); - } - - /** - * Registers a plugin for a method with 1 argument. - * - * @param name the name of the method - * @param plugin the plugin to be registered - */ - public void register1(String name, Class arg, InvocationPlugin plugin) { - plugins.register(arg == Receiver.class ? resolve(metaAccess, declaringClass, name) : resolve(metaAccess, declaringClass, name, arg), plugin); - } - - /** - * Registers a plugin for a method with 2 arguments. - * - * @param name the name of the method - * @param plugin the plugin to be registered - */ - public void register2(String name, Class arg1, Class arg2, InvocationPlugin plugin) { - plugins.register(arg1 == Receiver.class ? resolve(metaAccess, declaringClass, name, arg2) : resolve(metaAccess, declaringClass, name, arg1, arg2), plugin); - } - - /** - * Registers a plugin for a method with 3 arguments. - * - * @param name the name of the method - * @param plugin the plugin to be registered - */ - public void register3(String name, Class arg1, Class arg2, Class arg3, InvocationPlugin plugin) { - plugins.register(arg1 == Receiver.class ? resolve(metaAccess, declaringClass, name, arg2, arg3) : resolve(metaAccess, declaringClass, name, arg1, arg2, arg3), plugin); - } - - /** - * Registers a plugin for a method with 4 arguments. - * - * @param name the name of the method - * @param plugin the plugin to be registered - */ - public void register4(String name, Class arg1, Class arg2, Class arg3, Class arg4, InvocationPlugin plugin) { - plugins.register(arg1 == Receiver.class ? resolve(metaAccess, declaringClass, name, arg2, arg3, arg4) : resolve(metaAccess, declaringClass, name, arg1, arg2, arg3, arg4), plugin); - } - - /** - * Registers a plugin for a method with 5 arguments. - * - * @param name the name of the method - * @param plugin the plugin to be registered - */ - public void register5(String name, Class arg1, Class arg2, Class arg3, Class arg4, Class arg5, InvocationPlugin plugin) { - plugins.register(arg1 == Receiver.class ? resolve(metaAccess, declaringClass, name, arg2, arg3, arg4, arg5) : resolve(metaAccess, declaringClass, name, arg1, arg2, arg3, arg4, arg5), - plugin); - } - - /** - * Resolves a method given a declaring class, name and parameter types. - */ - public static ResolvedJavaMethod resolve(MetaAccessProvider metaAccess, Class declaringClass, String name, Class... parameterTypes) { - try { - return metaAccess.lookupJavaMethod(name.equals("") ? declaringClass.getDeclaredConstructor(parameterTypes) : declaringClass.getDeclaredMethod(name, parameterTypes)); - } catch (NoSuchMethodException | SecurityException e) { - throw new GraalInternalError(e); - } - } - } - - private final Map plugins = new HashMap<>(); - - /** - * The invocation plugins deferred to if a plugin is not found in this object. - */ - private InvocationPlugins defaults; - - /** - * Registers an invocation plugin for a given method. There must be no plugin currently - * registered for {@code method}. - */ - public void register(ResolvedJavaMethod method, InvocationPlugin plugin) { - assert Checker.check(method, plugin); - GraphBuilderPlugin oldValue = plugins.put(method, plugin); - // System.out.println("registered: " + plugin); - assert oldValue == null; - } - - /** - * Gets the plugin for a given method. - * - * @param method the method to lookup - * @return the plugin associated with {@code method} or {@code null} if none exists - */ - public InvocationPlugin lookupInvocation(ResolvedJavaMethod method) { - InvocationPlugin res = plugins.get(method); - if (res == null && defaults != null) { - return defaults.lookupInvocation(method); - } - return res; - } - - /** - * Sets the invocation plugins {@linkplain #lookupInvocation(ResolvedJavaMethod) searched} if a - * plugin is not found in this object. - */ - public InvocationPlugins setDefaults(InvocationPlugins defaults) { - InvocationPlugins old = this.defaults; - this.defaults = defaults; - return old; - } - - /** - * Adds all the plugins from {@code other} to this object. - */ - public void updateFrom(InvocationPlugins other) { - this.plugins.putAll(other.plugins); - if (other.defaults != null) { - updateFrom(other.defaults); - } - } - - @Override - public String toString() { - return plugins.keySet().stream().map(m -> m.format("%H.%n(%p)")).collect(Collectors.joining(", ")) + " / defaults: " + this.defaults; - } - - private static class Checker { - private static final int MAX_ARITY = 5; - /** - * The set of all {@link InvocationPlugin#apply} method signatures. - */ - static final Class[][] SIGS; - static { - ArrayList[]> sigs = new ArrayList<>(MAX_ARITY); - for (Method method : InvocationPlugin.class.getDeclaredMethods()) { - if (!Modifier.isStatic(method.getModifiers()) && method.getName().equals("apply")) { - Class[] sig = method.getParameterTypes(); - assert sig[0] == GraphBuilderContext.class; - assert sig[1] == ResolvedJavaMethod.class; - assert Arrays.asList(Arrays.copyOfRange(sig, 2, sig.length)).stream().allMatch(c -> c == ValueNode.class); - while (sigs.size() < sig.length - 1) { - sigs.add(null); - } - sigs.set(sig.length - 2, sig); - } - } - assert sigs.indexOf(null) == -1 : format("need to add an apply() method to %s that takes %d %s arguments ", InvocationPlugin.class.getName(), sigs.indexOf(null), - ValueNode.class.getSimpleName()); - SIGS = sigs.toArray(new Class[sigs.size()][]); - } - - public static boolean check(ResolvedJavaMethod method, InvocationPlugin plugin) { - int arguments = method.getSignature().getParameterCount(!method.isStatic()); - assert arguments < SIGS.length : format("need to extend %s to support method with %d arguments: %s", InvocationPlugin.class.getSimpleName(), arguments, method.format("%H.%n(%p)")); - for (Method m : plugin.getClass().getDeclaredMethods()) { - if (m.getName().equals("apply")) { - Class[] parameterTypes = m.getParameterTypes(); - if (Arrays.equals(SIGS[arguments], parameterTypes)) { - return true; - } - } - } - throw new AssertionError(format("graph builder plugin for %s not found", method.format("%H.%n(%p)"))); - } - } -} diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ControlFlowOptimizer.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ControlFlowOptimizer.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ControlFlowOptimizer.java Tue Mar 17 11:23:06 2015 -0700 @@ -41,7 +41,8 @@ * Performs control flow optimizations on the given LIR graph. */ @Override - protected > void run(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, List linearScanOrder) { + protected > void run(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, List linearScanOrder, + BenchmarkCounterFactory counterFactory) { LIR lir = lirGenRes.getLIR(); new Optimizer(lir).deleteEmptyBlocks(codeEmittingOrder); } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.lir/src/com/oracle/graal/lir/EdgeMoveOptimizer.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/EdgeMoveOptimizer.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/EdgeMoveOptimizer.java Tue Mar 17 11:23:06 2015 -0700 @@ -51,7 +51,8 @@ public final class EdgeMoveOptimizer extends PostAllocationOptimizationPhase { @Override - protected > void run(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, List linearScanOrder) { + protected > void run(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, List linearScanOrder, + BenchmarkCounterFactory counterFactory) { LIR ir = lirGenRes.getLIR(); Optimizer optimizer = new Optimizer(ir); diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.lir/src/com/oracle/graal/lir/NullCheckOptimizer.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/NullCheckOptimizer.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/NullCheckOptimizer.java Tue Mar 17 11:23:06 2015 -0700 @@ -34,7 +34,8 @@ public final class NullCheckOptimizer extends PostAllocationOptimizationPhase { @Override - protected > void run(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, List linearScanOrder) { + protected > void run(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, List linearScanOrder, + BenchmarkCounterFactory counterFactory) { LIR ir = lirGenRes.getLIR(); List> blocks = ir.codeEmittingOrder(); NullCheckOptimizer.foldNullChecks(ir, blocks, target.implicitNullCheckLimit); diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.lir/src/com/oracle/graal/lir/RedundantMoveElimination.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/RedundantMoveElimination.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/RedundantMoveElimination.java Tue Mar 17 11:23:06 2015 -0700 @@ -44,7 +44,8 @@ public final class RedundantMoveElimination extends PostAllocationOptimizationPhase { @Override - protected > void run(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, List linearScanOrder) { + protected > void run(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, List linearScanOrder, + BenchmarkCounterFactory counterFactory) { Optimization redundantMoveElimination = new Optimization(); redundantMoveElimination.doOptimize(lirGenRes.getLIR(), lirGenRes.getFrameMap()); } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/BenchmarkCounterFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/BenchmarkCounterFactory.java Tue Mar 17 11:23:06 2015 -0700 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2015, 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.lir.gen; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.lir.*; + +public interface BenchmarkCounterFactory { + LIRInstruction createBenchmarkCounter(String name, String group, Value increment); + + LIRInstruction createMultiBenchmarkCounter(String[] names, String[] groups, Value[] increments); +} diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java Tue Mar 17 11:23:06 2015 -0700 @@ -391,4 +391,12 @@ public void emitBlackhole(Value operand) { append(new StandardOp.BlackholeOp(operand)); } + + public LIRInstruction createBenchmarkCounter(String name, String group, Value increment) { + throw GraalInternalError.unimplemented(); + } + + public LIRInstruction createMultiBenchmarkCounter(String[] names, String[] groups, Value[] increments) { + throw GraalInternalError.unimplemented(); + } } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java Tue Mar 17 11:23:06 2015 -0700 @@ -30,7 +30,7 @@ import com.oracle.graal.compiler.common.spi.*; import com.oracle.graal.lir.*; -public interface LIRGeneratorTool extends ArithmeticLIRGenerator { +public interface LIRGeneratorTool extends ArithmeticLIRGenerator, BenchmarkCounterFactory { public interface SpillMoveFactory { diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/LIRPhaseSuite.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/LIRPhaseSuite.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/LIRPhaseSuite.java Tue Mar 17 11:23:06 2015 -0700 @@ -28,7 +28,7 @@ import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.lir.gen.*; -public abstract class LIRPhaseSuite extends LIRPhase { +public class LIRPhaseSuite extends LIRPhase { private final List> phases; public LIRPhaseSuite() { @@ -75,4 +75,9 @@ } } + public LIRPhaseSuite copy() { + LIRPhaseSuite suite = new LIRPhaseSuite<>(); + suite.phases.addAll(phases); + return suite; + } } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/LIRSuites.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/LIRSuites.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/LIRSuites.java Tue Mar 17 11:23:06 2015 -0700 @@ -41,6 +41,10 @@ this.postAllocStage = postAllocStage; } + public LIRSuites(LIRSuites other) { + this(other.getPreAllocationOptimizationStage().copy(), other.getAllocationStage().copy(), other.getPostAllocationOptimizationStage().copy()); + } + /** * {@link PreAllocationOptimizationPhase}s are executed between {@link LIR} generation and * register allocation. diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/PostAllocationOptimizationPhase.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/PostAllocationOptimizationPhase.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/PostAllocationOptimizationPhase.java Tue Mar 17 11:23:06 2015 -0700 @@ -31,14 +31,20 @@ public abstract class PostAllocationOptimizationPhase extends LIRPhase { public static final class PostAllocationOptimizationContext { + private final BenchmarkCounterFactory counterFactory; + + public PostAllocationOptimizationContext(BenchmarkCounterFactory counterFactory) { + this.counterFactory = counterFactory; + } } @Override protected final > void run(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, List linearScanOrder, PostAllocationOptimizationContext context) { - run(target, lirGenRes, codeEmittingOrder, linearScanOrder); + run(target, lirGenRes, codeEmittingOrder, linearScanOrder, context.counterFactory); } - protected abstract > void run(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, List linearScanOrder); + protected abstract > void run(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, List linearScanOrder, + BenchmarkCounterFactory counterFactory); } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/PostAllocationOptimizationStage.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/PostAllocationOptimizationStage.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/PostAllocationOptimizationStage.java Tue Mar 17 11:23:06 2015 -0700 @@ -25,7 +25,8 @@ import static com.oracle.graal.lir.phases.LIRPhase.Options.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.phases.PostAllocationOptimizationPhase.*; +import com.oracle.graal.lir.phases.PostAllocationOptimizationPhase.PostAllocationOptimizationContext; +import com.oracle.graal.lir.profiling.*; import com.oracle.graal.options.*; public class PostAllocationOptimizationStage extends LIRPhaseSuite { @@ -39,6 +40,8 @@ public static final NestedBooleanOptionValue LIROptRedundantMoveElimination = new NestedBooleanOptionValue(LIROptimization, true); @Option(help = "", type = OptionType.Debug) public static final NestedBooleanOptionValue LIROptNullCheckOptimizer = new NestedBooleanOptionValue(LIROptimization, true); + @Option(help = "", type = OptionType.Debug) + public static final OptionValue LIROptMoveProfiling = new OptionValue<>(false); // @formatter:on } @@ -55,5 +58,8 @@ if (Options.LIROptNullCheckOptimizer.getValue()) { appendPhase(new NullCheckOptimizer()); } + if (Options.LIROptMoveProfiling.getValue()) { + appendPhase(new MoveProfiling()); + } } } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.lir/src/com/oracle/graal/lir/profiling/MoveProfiling.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/profiling/MoveProfiling.java Tue Mar 17 11:23:06 2015 -0700 @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2015, 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.lir.profiling; + +import static com.oracle.graal.api.code.ValueUtil.*; + +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.compiler.common.cfg.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.StandardOp.BlockEndOp; +import com.oracle.graal.lir.StandardOp.LabelOp; +import com.oracle.graal.lir.StandardOp.MoveOp; +import com.oracle.graal.lir.gen.*; +import com.oracle.graal.lir.phases.*; + +public class MoveProfiling extends PostAllocationOptimizationPhase { + + @Override + protected > void run(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, List linearScanOrder, + BenchmarkCounterFactory counterFactory) { + new Analyzer(lirGenRes.getLIR(), counterFactory).run(); + } + + private static enum MoveType { + REG2REG("Reg", "Reg"), + STACK2REG("Reg", "Stack"), + CONST2REG("Reg", "Const"), + REG2STACK("Stack", "Reg"), + CONST2STACK("Stack", "Const"); + + private final String name; + + MoveType(String dst, String src) { + this.name = String.format("%5s <- %s", dst, src); + } + + @Override + public String toString() { + return name; + } + + public static MoveType get(MoveOp move) { + AllocatableValue dst = move.getResult(); + Value src = move.getInput(); + if (isRegister(dst)) { + if (isRegister(src)) { + return REG2REG; + } + if (isStackSlot(src)) { + return STACK2REG; + } + if (isConstant(src)) { + return CONST2REG; + } + } else if (isStackSlot(dst)) { + if (isRegister(src)) { + return REG2STACK; + } + if (isConstant(src)) { + return CONST2STACK; + } + } + throw GraalInternalError.shouldNotReachHere(String.format("Unrecognized Move: %s dst=%s, src=%s", move, dst, src)); + } + } + + private static class Analyzer { + private final LIR lir; + private final BenchmarkCounterFactory counterFactory; + private final LIRInsertionBuffer buffer; + private final int[] cnt; + + public Analyzer(LIR lir, BenchmarkCounterFactory counterFactory) { + this.lir = lir; + this.counterFactory = counterFactory; + this.buffer = new LIRInsertionBuffer(); + cnt = new int[MoveType.values().length]; + } + + public void run() { + for (AbstractBlockBase block : lir.getControlFlowGraph().getBlocks()) { + doBlock(block); + } + } + + public void doBlock(AbstractBlockBase block) { + List instructions = lir.getLIRforBlock(block); + assert instructions.size() >= 2 : "Malformed block: " + block + ", " + instructions; + assert instructions.get(instructions.size() - 1) instanceof BlockEndOp : "Not a BlockEndOp: " + instructions.get(instructions.size() - 1); + assert !(instructions.get(instructions.size() - 2) instanceof BlockEndOp) : "Is a BlockEndOp: " + instructions.get(instructions.size() - 2); + assert instructions.get(0) instanceof LabelOp : "Not a LabelOp: " + instructions.get(0); + assert !(instructions.get(1) instanceof LabelOp) : "Is a LabelOp: " + instructions.get(1); + + // reset counters + Arrays.fill(cnt, 0); + // analysis phase + for (LIRInstruction inst : instructions) { + if (inst instanceof MoveOp) { + cnt[MoveType.get((MoveOp) inst).ordinal()]++; + } + } + + // counter insertion phase + List names = new ArrayList<>(); + List increments = new ArrayList<>(); + for (MoveType type : MoveType.values()) { + int i = cnt[type.ordinal()]; + if (i > 0) { + names.add(type.toString()); + increments.add(JavaConstant.forInt(i)); + } + } + String[] groups = new String[names.size()]; + Arrays.fill(groups, "Move Operations"); + + LIRInstruction inst = counterFactory.createMultiBenchmarkCounter(names.toArray(new String[0]), groups, increments.toArray(new Value[0])); + assert inst != null; + buffer.init(instructions); + buffer.append(1, inst); + buffer.finish(); + } + } + +} diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java Tue Mar 17 11:23:06 2015 -0700 @@ -237,15 +237,21 @@ if (this.killLocationsBetweenThisAndDominator == null) { LocationSet dominatorResult = new LocationSet(); Block stopBlock = getDominator(); - for (Block b : this.getPredecessors()) { - if (b != stopBlock && (!this.isLoopHeader() || b.getLoopDepth() < this.getLoopDepth())) { - dominatorResult.addAll(b.getKillLocations()); - if (dominatorResult.isAny()) { - break; - } - b.calcKillLocationsBetweenThisAndTarget(dominatorResult, stopBlock); - if (dominatorResult.isAny()) { - break; + if (this.isLoopHeader()) { + assert stopBlock.getLoopDepth() < this.getLoopDepth(); + dominatorResult.addAll(((HIRLoop) this.getLoop()).getKillLocations()); + } else { + for (Block b : this.getPredecessors()) { + assert !this.isLoopHeader(); + if (b != stopBlock) { + dominatorResult.addAll(b.getKillLocations()); + if (dominatorResult.isAny()) { + break; + } + b.calcKillLocationsBetweenThisAndTarget(dominatorResult, stopBlock); + if (dominatorResult.isAny()) { + break; + } } } } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/HIRLoop.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/HIRLoop.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/HIRLoop.java Tue Mar 17 11:23:06 2015 -0700 @@ -39,7 +39,7 @@ return ((LoopBeginNode) getHeader().getBeginNode()).loopEnds().count(); } - private LocationSet getKillLocations() { + public LocationSet getKillLocations() { if (killLocations == null) { killLocations = new LocationSet(); for (Block b : this.getBlocks()) { diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java Tue Mar 17 11:23:06 2015 -0700 @@ -22,8 +22,11 @@ */ package com.oracle.graal.nodes.debug; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -37,7 +40,7 @@ * value of withContext, the name of the root method is added to the counter's name. */ @NodeInfo -public class DynamicCounterNode extends FixedWithNextNode implements Lowerable { +public class DynamicCounterNode extends FixedWithNextNode implements LIRLowerable { public static final NodeClass TYPE = NodeClass.create(DynamicCounterNode.class); @Input ValueNode increment; @@ -74,11 +77,6 @@ return withContext; } - @Override - public void lower(LoweringTool tool) { - tool.getLowerer().lower(this, tool); - } - public static void addCounterBefore(String group, String name, long increment, boolean withContext, FixedNode position) { StructuredGraph graph = position.graph(); graph.addBeforeFixed(position, position.graph().add(new DynamicCounterNode(name, group, ConstantNode.forLong(increment, position.graph()), withContext))); @@ -87,4 +85,32 @@ @NodeIntrinsic public static native void counter(@ConstantNodeParameter String name, @ConstantNodeParameter String group, long increment, @ConstantNodeParameter boolean addContext); + public void generate(NodeLIRBuilderTool generator) { + LIRGeneratorTool lirGen = generator.getLIRGeneratorTool(); + String nameWithContext; + if (isWithContext()) { + nameWithContext = getName() + " @ "; + if (graph().method() != null) { + StackTraceElement stackTraceElement = graph().method().asStackTraceElement(0); + if (stackTraceElement != null) { + nameWithContext += " " + stackTraceElement.toString(); + } else { + nameWithContext += graph().method().format("%h.%n"); + } + } + if (graph().name != null) { + nameWithContext += " (" + graph().name + ")"; + } + + } else { + nameWithContext = getName(); + } + LIRInstruction counterOp = lirGen.createBenchmarkCounter(nameWithContext, getGroup(), generator.operand(increment)); + if (counterOp != null) { + lirGen.append(counterOp); + } else { + throw GraalInternalError.unimplemented("Benchmark counters not enabled or not implemented by the back end."); + } + } + } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Tue Mar 17 11:23:06 2015 -0700 @@ -79,7 +79,6 @@ public void virtualize(VirtualizerTool tool) { State state = tool.getObjectState(object()); // the monitor exit for a synchronized method should never be virtualized - assert stateAfter().bci != BytecodeFrame.AFTER_BCI || state == null; if (state != null && state.getState() == EscapeState.Virtual && state.getVirtualObject().hasIdentity()) { MonitorIdNode removedLock = state.removeLock(); assert removedLock == getMonitorId() : "mismatch at " + this + ": " + removedLock + " vs. " + getMonitorId(); diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/MemoryScheduleVerification.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/MemoryScheduleVerification.java Tue Mar 17 11:23:06 2015 -0700 @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2015, 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.phases.schedule; + +import java.util.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.cfg.*; +import com.oracle.graal.graph.Node; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.cfg.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.phases.graph.*; +import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure; + +public final class MemoryScheduleVerification extends BlockIteratorClosure> { + + private final BlockMap> blockToNodesMap; + + public static boolean check(Block startBlock, BlockMap> blockToNodesMap) { + ReentrantBlockIterator.apply(new MemoryScheduleVerification(blockToNodesMap), startBlock); + return true; + } + + private MemoryScheduleVerification(BlockMap> blockToNodesMap) { + this.blockToNodesMap = blockToNodesMap; + } + + @Override + protected Set getInitialState() { + return CollectionsFactory.newSet(); + } + + @Override + protected Set processBlock(Block block, Set currentState) { + for (Node n : blockToNodesMap.get(block)) { + if (n instanceof AbstractMergeNode) { + AbstractMergeNode abstractMergeNode = (AbstractMergeNode) n; + for (PhiNode phi : abstractMergeNode.phis()) { + if (phi instanceof MemoryPhiNode) { + MemoryPhiNode memoryPhiNode = (MemoryPhiNode) phi; + addFloatingReadUsages(currentState, memoryPhiNode); + } + } + + } + + if (n instanceof MemoryCheckpoint) { + if (n instanceof MemoryCheckpoint.Single) { + MemoryCheckpoint.Single single = (MemoryCheckpoint.Single) n; + processLocation(n, single.getLocationIdentity(), currentState); + } else if (n instanceof MemoryCheckpoint.Multi) { + MemoryCheckpoint.Multi multi = (MemoryCheckpoint.Multi) n; + for (LocationIdentity location : multi.getLocationIdentities()) { + processLocation(n, location, currentState); + } + } + + addFloatingReadUsages(currentState, n); + } else if (n instanceof FloatingReadNode) { + FloatingReadNode floatingReadNode = (FloatingReadNode) n; + if (floatingReadNode.getLastLocationAccess() != null && floatingReadNode.getLocationIdentity().isMutable()) { + if (currentState.contains(floatingReadNode)) { + // Floating read was found in the state. + currentState.remove(floatingReadNode); + } else { + throw new RuntimeException("Floating read node " + n + " was not found in the state, i.e., it was killed by a memory check point before its place in the schedule"); + } + } + + } + } + return currentState; + } + + private static void addFloatingReadUsages(Set currentState, Node n) { + for (FloatingReadNode read : n.usages().filter(FloatingReadNode.class)) { + if (read.getLastLocationAccess() == n && read.getLocationIdentity().isMutable()) { + currentState.add(read); + } + } + } + + private void processLocation(Node n, LocationIdentity location, Set currentState) { + assert n != null; + if (location.isImmutable()) { + return; + } + + for (FloatingReadNode r : cloneState(currentState)) { + if (r.getLocationIdentity().overlaps(location)) { + // This read is killed by this location. + currentState.remove(r); + } + } + } + + @Override + protected Set merge(Block merge, List> states) { + Set result = states.get(0); + for (int i = 1; i < states.size(); ++i) { + result.retainAll(states.get(i)); + } + return result; + } + + @Override + protected Set cloneState(Set oldState) { + Set result = CollectionsFactory.newSet(); + result.addAll(oldState); + return result; + } + + @Override + protected List> processLoop(Loop loop, Set initialState) { + HIRLoop l = (HIRLoop) loop; + for (MemoryPhiNode memoryPhi : ((LoopBeginNode) l.getHeader().getBeginNode()).phis().filter(MemoryPhiNode.class)) { + for (FloatingReadNode r : cloneState(initialState)) { + if (r.getLocationIdentity().overlaps(memoryPhi.getLocationIdentity())) { + initialState.remove(r); + } + } + } + return ReentrantBlockIterator.processLoop(this, loop, initialState).exitStates; + } +} diff -r ea280aa54d58 -r 815a87264cbb 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 Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Tue Mar 17 11:23:06 2015 -0700 @@ -94,6 +94,7 @@ cfg = ControlFlowGraph.compute(graph, true, true, true, false); if (selectedStrategy == SchedulingStrategy.EARLIEST) { + // Assign early so we are getting a context in case of an exception. this.nodeToBlockMap = graph.createNodeMap(); this.blockToNodesMap = new BlockMap<>(cfg); NodeBitMap visited = graph.createNodeBitMap(); @@ -105,6 +106,11 @@ NodeMap currentNodeMap = graph.createNodeMap(); BlockMap> earliestBlockToNodesMap = new BlockMap<>(cfg); NodeBitMap visited = graph.createNodeBitMap(); + + // Assign early so we are getting a context in case of an exception. + this.blockToNodesMap = earliestBlockToNodesMap; + this.nodeToBlockMap = currentNodeMap; + scheduleEarliestIterative(cfg, earliestBlockToNodesMap, currentNodeMap, visited, graph); BlockMap> latestBlockToNodesMap = new BlockMap<>(cfg); @@ -115,10 +121,12 @@ BlockMap> watchListMap = calcLatestBlocks(isOutOfLoops, currentNodeMap, earliestBlockToNodesMap, visited, latestBlockToNodesMap); sortNodesLatestWithinBlock(cfg, earliestBlockToNodesMap, latestBlockToNodesMap, currentNodeMap, watchListMap, visited); + assert verifySchedule(cfg, latestBlockToNodesMap, currentNodeMap); + assert MemoryScheduleVerification.check(cfg.getStartBlock(), latestBlockToNodesMap); + this.blockToNodesMap = latestBlockToNodesMap; this.nodeToBlockMap = currentNodeMap; - assert verifySchedule(cfg, latestBlockToNodesMap, currentNodeMap); cfg.setNodeToBlock(currentNodeMap); } } @@ -165,7 +173,7 @@ // We are not constraint within currentBlock. Check if // we are contraint while walking down the dominator // line. - Block newLatestBlock = adjustLatestForRead(currentBlock, latestBlock, location); + Block newLatestBlock = adjustLatestForRead(floatingReadNode, currentBlock, latestBlock, location); assert dominates(newLatestBlock, latestBlock); assert dominates(currentBlock, newLatestBlock); latestBlock = newLatestBlock; @@ -203,7 +211,7 @@ return true; } - private static Block adjustLatestForRead(Block earliestBlock, Block latestBlock, LocationIdentity location) { + private static Block adjustLatestForRead(FloatingReadNode floatingReadNode, Block earliestBlock, Block latestBlock, LocationIdentity location) { assert strictlyDominates(earliestBlock, latestBlock); Block current = latestBlock.getDominator(); @@ -218,6 +226,7 @@ } dominatorChain.add(current); current = current.getDominator(); + assert current != null : floatingReadNode; } // The first element of dominatorChain now contains the latest possible block. @@ -291,7 +300,7 @@ for (ProxyNode proxy : loopExitNode.proxies()) { unprocessed.clear(proxy); ValueNode value = proxy.value(); - if (nodeMap.get(value) == b) { + if (value != null && nodeMap.get(value) == b) { sortIntoList(value, b, result, nodeMap, unprocessed, null); } } @@ -537,6 +546,8 @@ } } } + + assert MemoryScheduleVerification.check(cfg.getStartBlock(), blockToNodes); } private static void resortEarliestWithinBlock(Block b, BlockMap> blockToNodes, NodeMap nodeToBlock, NodeBitMap unprocessed) { @@ -550,7 +561,7 @@ MemoryNode lastLocationAccess = floatingReadNode.getLastLocationAccess(); if (locationIdentity.isMutable() && lastLocationAccess != null) { ValueNode lastAccessLocation = lastLocationAccess.asNode(); - if (nodeToBlock.get(lastAccessLocation) == b && lastAccessLocation != beginNode) { + if (nodeToBlock.get(lastAccessLocation) == b && lastAccessLocation != beginNode && !(lastAccessLocation instanceof MemoryPhiNode)) { // This node's last access location is within this block. Add to watch list // when processing the last access location. } else { @@ -650,16 +661,22 @@ assert current.predecessor() == null && !(current instanceof FixedNode) : "The assignment of blocks to fixed nodes is already done when constructing the cfg."; Block earliest = startBlock; for (Node input : current.inputs()) { - Block inputEarliest; - if (input instanceof ControlSplitNode) { - inputEarliest = nodeToBlock.get(((ControlSplitNode) input).getPrimarySuccessor()); - } else { - inputEarliest = nodeToBlock.get(input); - } + Block inputEarliest = nodeToBlock.get(input); if (inputEarliest == null) { assert current instanceof FrameState && input instanceof StateSplit && ((StateSplit) input).stateAfter() == current; } else { assert inputEarliest != null; + if (inputEarliest.getEndNode() == input) { + // This is the last node of the block. + if (current instanceof FrameState && input instanceof StateSplit && ((StateSplit) input).stateAfter() == current) { + // Keep regular inputEarliest. + } else if (input instanceof ControlSplitNode) { + inputEarliest = nodeToBlock.get(((ControlSplitNode) input).getPrimarySuccessor()); + } else { + assert inputEarliest.getSuccessorCount() == 1; + inputEarliest = inputEarliest.getSuccessors().get(0); + } + } if (earliest.getDominatorDepth() < inputEarliest.getDominatorDepth()) { earliest = inputEarliest; } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ConstantBindingParameterPlugin.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ConstantBindingParameterPlugin.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ConstantBindingParameterPlugin.java Tue Mar 17 11:23:06 2015 -0700 @@ -25,8 +25,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderPlugin.ParameterPlugin; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultGenericInvocationPlugin.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultGenericInvocationPlugin.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultGenericInvocationPlugin.java Tue Mar 17 11:23:06 2015 -0700 @@ -31,8 +31,7 @@ import com.oracle.graal.api.replacements.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.Node.NodeIntrinsic; -import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderPlugin.GenericInvocationPlugin; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.word.*; diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Tue Mar 17 11:23:06 2015 -0700 @@ -45,7 +45,6 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.*; -import com.oracle.graal.phases.util.*; /** * Replaces calls to {@link NodeIntrinsic}s with nodes and calls to methods annotated with @@ -53,12 +52,19 @@ */ public class NodeIntrinsificationPhase extends Phase { - private final Providers providers; + private final MetaAccessProvider metaAccess; + private final ConstantReflectionProvider constantReflection; private final SnippetReflectionProvider snippetReflection; + private final ForeignCallsProvider foreignCalls; + private final StampProvider stampProvider; - public NodeIntrinsificationPhase(Providers providers, SnippetReflectionProvider snippetReflection) { - this.providers = providers; + public NodeIntrinsificationPhase(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, SnippetReflectionProvider snippetReflection, ForeignCallsProvider foreignCalls, + StampProvider stampProvider) { + this.metaAccess = metaAccess; + this.constantReflection = constantReflection; this.snippetReflection = snippetReflection; + this.foreignCalls = foreignCalls; + this.stampProvider = stampProvider; } @Override @@ -101,7 +107,7 @@ if (constant != null) { // Replace the invoke with the result of the call - ConstantNode node = ConstantNode.forConstant(constant, providers.getMetaAccess(), methodCallTargetNode.graph()); + ConstantNode node = ConstantNode.forConstant(constant, metaAccess, methodCallTargetNode.graph()); methodCallTargetNode.invoke().intrinsify(node); // Clean up checkcast instructions inserted by javac if the return type is generic. @@ -165,7 +171,7 @@ if (intrinsic.foldable() && areAllConstant(arguments)) { JavaConstant res = tryFold(arguments, parameterTypes, method); if (!res.equals(COULD_NOT_FOLD)) { - return ConstantNode.forConstant(res, providers.getMetaAccess()); + return ConstantNode.forConstant(res, metaAccess); } } @@ -220,12 +226,12 @@ * For intrinsification (but not for folding) if we have a Class object we want * the corresponding ResolvedJavaType. */ - ResolvedJavaType type = folding ? null : providers.getConstantReflection().asJavaType(constant); + ResolvedJavaType type = folding ? null : constantReflection.asJavaType(constant); Object arg; if (type != null) { /* If we found such a type then it's our arg */ arg = type; - parameterTypes[i] = providers.getMetaAccess().lookupJavaType(ResolvedJavaType.class); + parameterTypes[i] = metaAccess.lookupJavaType(ResolvedJavaType.class); } else { JavaConstant javaConstant = (JavaConstant) constant; if (folding) { @@ -253,7 +259,7 @@ reflectionCallArguments[i] = arg; } else { reflectionCallArguments[i] = argument; - parameterTypes[i] = providers.getMetaAccess().lookupJavaType(ValueNode.class); + parameterTypes[i] = metaAccess.lookupJavaType(ValueNode.class); } } return reflectionCallArguments; @@ -264,10 +270,10 @@ if (intrinsic.value() == NodeIntrinsic.class) { result = target.getDeclaringClass(); } else { - result = providers.getMetaAccess().lookupJavaType(intrinsic.value()); + result = metaAccess.lookupJavaType(intrinsic.value()); } - assert providers.getMetaAccess().lookupJavaType(ValueNode.class).isAssignableFrom(result) : "Node intrinsic class " + result.toJavaName(false) + " derived from @" + - NodeIntrinsic.class.getSimpleName() + " annotation on " + target.format("%H.%n(%p)") + " is not a subclass of " + ValueNode.class; + assert metaAccess.lookupJavaType(ValueNode.class).isAssignableFrom(result) : "Node intrinsic class " + result.toJavaName(false) + " derived from @" + NodeIntrinsic.class.getSimpleName() + + " annotation on " + target.format("%H.%n(%p)") + " is not a subclass of " + ValueNode.class; return result; } @@ -339,7 +345,6 @@ Object[] injected = null; ResolvedJavaType[] signature = resolveJavaTypes(c.getSignature().toParameterTypes(null), c.getDeclaringClass()); - MetaAccessProvider metaAccess = providers.getMetaAccess(); for (int i = 0; i < signature.length; i++) { if (c.getParameterAnnotation(InjectedNodeParameter.class, i) != null) { injected = injected == null ? new Object[1] : Arrays.copyOf(injected, injected.length + 1); @@ -351,13 +356,13 @@ } else if (signature[i].equals(metaAccess.lookupJavaType(StructuredGraph.class))) { injected[injected.length - 1] = graph; } else if (signature[i].equals(metaAccess.lookupJavaType(ForeignCallsProvider.class))) { - injected[injected.length - 1] = providers.getForeignCalls(); + injected[injected.length - 1] = foreignCalls; } else if (signature[i].equals(metaAccess.lookupJavaType(SnippetReflectionProvider.class))) { injected[injected.length - 1] = snippetReflection; } else if (signature[i].isAssignableFrom(metaAccess.lookupJavaType(Stamp.class))) { injected[injected.length - 1] = invokeStamp; } else if (signature[i].isAssignableFrom(metaAccess.lookupJavaType(StampProvider.class))) { - injected[injected.length - 1] = providers.getStampProvider(); + injected[injected.length - 1] = stampProvider; } else { throw new GraalInternalError("Cannot handle injected argument of type %s in %s", signature[i].toJavaName(), c.format("%H.%n(%p)")); } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Tue Mar 17 11:23:06 2015 -0700 @@ -42,9 +42,10 @@ import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.Graph.Mark; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; import com.oracle.graal.graph.*; import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderConfiguration.Plugins; import com.oracle.graal.java.GraphBuilderPhase.Instance; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; @@ -71,7 +72,8 @@ */ protected final ConcurrentMap graphs; - public void completeInitialization(GraphBuilderConfiguration.Plugins plugins) { + public void setGraphBuilderPlugins(GraphBuilderConfiguration.Plugins plugins) { + assert this.graphBuilderPlugins == null; this.graphBuilderPlugins = plugins; } @@ -299,7 +301,7 @@ } protected NodeIntrinsificationPhase createNodeIntrinsificationPhase() { - return new NodeIntrinsificationPhase(providers, snippetReflection); + return new NodeIntrinsificationPhase(providers.getMetaAccess(), providers.getConstantReflection(), snippetReflection, providers.getForeignCalls(), providers.getStampProvider()); } @Override @@ -640,9 +642,8 @@ if (MethodsElidedInSnippets != null && methodToParse.getSignature().getReturnKind() == Kind.Void && MethodFilter.matches(MethodsElidedInSnippets, methodToParse)) { graph.addAfterFixed(graph.start(), graph.add(new ReturnNode(null))); } else { - GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(); - Plugins plugins = config.getPlugins().updateFrom(replacements.graphBuilderPlugins, false); - plugins.getInvocationPlugins().setDefaults(replacements.graphBuilderPlugins.getInvocationPlugins()); + Plugins plugins = new Plugins(replacements.graphBuilderPlugins); + GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(plugins); if (args != null) { plugins.setParameterPlugin(new ConstantBindingParameterPlugin(args, plugins.getParameterPlugin(), metaAccess, replacements.snippetReflection)); } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java Tue Mar 17 11:23:06 2015 -0700 @@ -23,7 +23,7 @@ package com.oracle.graal.replacements; import static com.oracle.graal.api.code.MemoryBarriers.*; -import static com.oracle.graal.java.GraphBuilderContext.*; +import static com.oracle.graal.graphbuilderconf.GraphBuilderContext.*; import static com.oracle.graal.replacements.nodes.MathIntrinsicNode.Operation.*; import sun.misc.*; @@ -32,10 +32,8 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.graph.*; -import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderPlugin.InvocationPlugin; -import com.oracle.graal.java.InvocationPlugins.Registration; -import com.oracle.graal.java.InvocationPlugins.Registration.Receiver; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.InvocationPlugins.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.debug.*; @@ -57,29 +55,29 @@ // @formatter:on public static void registerInvocationPlugins(MetaAccessProvider metaAccess, Architecture arch, InvocationPlugins plugins, boolean useBoxingPlugins) { - registerObjectPlugins(metaAccess, plugins); - registerClassPlugins(metaAccess, plugins); - registerMathPlugins(metaAccess, arch, plugins); - registerUnsignedMathPlugins(metaAccess, plugins); - registerCharacterPlugins(metaAccess, plugins); - registerShortPlugins(metaAccess, plugins); - registerIntegerLongPlugins(metaAccess, plugins, Kind.Int); - registerIntegerLongPlugins(metaAccess, plugins, Kind.Long); - registerFloatPlugins(metaAccess, plugins); - registerDoublePlugins(metaAccess, plugins); - registerUnsafePlugins(metaAccess, arch, plugins); + registerObjectPlugins(plugins); + registerClassPlugins(plugins); + registerMathPlugins(arch, plugins); + registerUnsignedMathPlugins(plugins); + registerCharacterPlugins(plugins); + registerShortPlugins(plugins); + registerIntegerLongPlugins(plugins, Kind.Int); + registerIntegerLongPlugins(plugins, Kind.Long); + registerFloatPlugins(plugins); + registerDoublePlugins(plugins); + registerUnsafePlugins(arch, plugins); registerEdgesPlugins(metaAccess, plugins); - registerGraalDirectivesPlugins(metaAccess, plugins); + registerGraalDirectivesPlugins(plugins); if (useBoxingPlugins) { - registerBoxingPlugins(metaAccess, plugins); + registerBoxingPlugins(plugins); } if (Options.UseBlackholeSubstitution.getValue()) { - registerJMHBlackholePlugins(metaAccess, plugins); + registerJMHBlackholePlugins(plugins); } } - private static void registerUnsafePlugins(MetaAccessProvider metaAccess, Architecture arch, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, Unsafe.class); + private static void registerUnsafePlugins(Architecture arch, InvocationPlugins plugins) { + Registration r = new Registration(plugins, Unsafe.class); for (Kind kind : Kind.values()) { if ((kind.isPrimitive() && kind != Kind.Void) || kind == Kind.Object) { Class javaClass = kind == Kind.Object ? Object.class : kind.toJavaClass(); @@ -147,10 +145,10 @@ return arch.getName().equals("AMD64"); } - private static void registerIntegerLongPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins, Kind kind) { + private static void registerIntegerLongPlugins(InvocationPlugins plugins, Kind kind) { Class declaringClass = kind.toBoxedJavaClass(); Class type = kind.toJavaClass(); - Registration r = new Registration(plugins, metaAccess, declaringClass); + Registration r = new Registration(plugins, declaringClass); r.register1("reverseBytes", type, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { b.push(kind, b.append(new ReverseBytesNode(value).canonical(null, value))); @@ -177,8 +175,8 @@ }); } - private static void registerCharacterPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, Character.class); + private static void registerCharacterPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, Character.class); r.register1("reverseBytes", char.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { // return (char) (Integer.reverse(i) >> 16); @@ -191,8 +189,8 @@ }); } - private static void registerShortPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, Short.class); + private static void registerShortPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, Short.class); r.register1("reverseBytes", short.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { // return (short) (Integer.reverse(i) >> 16); @@ -205,8 +203,8 @@ }); } - private static void registerFloatPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, Float.class); + private static void registerFloatPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, Float.class); r.register1("floatToRawIntBits", float.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { b.push(Kind.Int, b.append(new ReinterpretNode(Kind.Int, value).canonical(null, value))); @@ -221,8 +219,8 @@ }); } - private static void registerDoublePlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, Double.class); + private static void registerDoublePlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, Double.class); r.register1("doubleToRawLongBits", double.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { b.push(Kind.Long, b.append(new ReinterpretNode(Kind.Long, value).canonical(null, value))); @@ -237,8 +235,8 @@ }); } - private static void registerMathPlugins(MetaAccessProvider metaAccess, Architecture arch, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, Math.class); + private static void registerMathPlugins(Architecture arch, InvocationPlugins plugins) { + Registration r = new Registration(plugins, Math.class); r.register1("abs", Float.TYPE, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { b.push(Kind.Float, b.append(new AbsNode(value).canonical(null, value))); @@ -303,8 +301,8 @@ } } - private static void registerUnsignedMathPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, UnsignedMath.class); + private static void registerUnsignedMathPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, UnsignedMath.class); r.register2("aboveThan", int.class, int.class, new UnsignedMathPlugin(Condition.AT)); r.register2("aboveThan", long.class, long.class, new UnsignedMathPlugin(Condition.AT)); r.register2("belowThan", int.class, int.class, new UnsignedMathPlugin(Condition.BT)); @@ -339,17 +337,17 @@ }); } - protected static void registerBoxingPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { + protected static void registerBoxingPlugins(InvocationPlugins plugins) { for (Kind kind : Kind.values()) { if (kind.isPrimitive() && kind != Kind.Void) { - new BoxPlugin(kind).register(metaAccess, plugins); - new UnboxPlugin(kind).register(metaAccess, plugins); + new BoxPlugin(kind).register(plugins); + new UnboxPlugin(kind).register(plugins); } } } - private static void registerObjectPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, Object.class); + private static void registerObjectPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, Object.class); r.register1("", Receiver.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode object) { if (RegisterFinalizerNode.mayHaveFinalizer(object, b.getAssumptions())) { @@ -362,8 +360,8 @@ }); } - private static void registerClassPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, Class.class); + private static void registerClassPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, Class.class); r.register2("isInstance", Receiver.class, Object.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode type, ValueNode object) { ValueNode nullCheckedType = nullCheckedValue(b, type); @@ -401,7 +399,7 @@ * project containing {@link Edges}. */ private static void registerEdgesPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, Edges.class); + Registration r = new Registration(plugins, Edges.class); for (Class c : new Class[]{Node.class, NodeList.class}) { r.register2("get" + c.getSimpleName() + "Unsafe", Node.class, long.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode node, ValueNode offset) { @@ -445,9 +443,8 @@ return true; } - void register(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - ResolvedJavaMethod method = Registration.resolve(metaAccess, kind.toBoxedJavaClass(), "valueOf", kind.toJavaClass()); - plugins.register(method, this); + void register(InvocationPlugins plugins) { + plugins.register(this, kind.toBoxedJavaClass(), "valueOf", kind.toJavaClass()); } } @@ -473,10 +470,9 @@ return true; } - void register(MetaAccessProvider metaAccess, InvocationPlugins plugins) { + void register(InvocationPlugins plugins) { String name = kind.toJavaClass().getSimpleName() + "Value"; - ResolvedJavaMethod method = Registration.resolve(metaAccess, kind.toBoxedJavaClass(), name); - plugins.register(method, this); + plugins.register(this, kind.toBoxedJavaClass(), name, Receiver.class); } } @@ -536,8 +532,8 @@ } } - private static void registerGraalDirectivesPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, GraalDirectives.class); + private static void registerGraalDirectivesPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, GraalDirectives.class); r.register0("deoptimize", new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod) { b.append(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.TransferToInterpreter)); @@ -596,7 +592,7 @@ } } - private static void registerJMHBlackholePlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { + private static void registerJMHBlackholePlugins(InvocationPlugins plugins) { InvocationPlugin blackholePlugin = new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode blackhole, ValueNode value) { b.append(new BlackholeNode(value)); @@ -608,7 +604,7 @@ Class blackholeClass; blackholeClass = ReplacementsImpl.resolveClass(name, true); if (blackholeClass != null) { - Registration r = new Registration(plugins, metaAccess, blackholeClass); + Registration r = new Registration(plugins, blackholeClass); for (Kind kind : Kind.values()) { if ((kind.isPrimitive() && kind != Kind.Void) || kind == Kind.Object) { Class javaClass = kind == Kind.Object ? Object.class : kind.toJavaClass(); diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java Tue Mar 17 11:23:06 2015 -0700 @@ -32,8 +32,7 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderPlugin.GenericInvocationPlugin; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.HeapAccess.BarrierType; import com.oracle.graal.nodes.calc.*; diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java --- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Tue Mar 17 11:23:06 2015 -0700 @@ -37,12 +37,14 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.java.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.phases.*; @@ -56,7 +58,6 @@ import com.oracle.graal.printer.*; import com.oracle.graal.runtime.*; import com.oracle.graal.truffle.*; -import com.oracle.graal.word.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.nodes.*; @@ -78,6 +79,7 @@ private final ThreadPoolExecutor compileQueue; private final Map callTargets = Collections.synchronizedMap(new WeakHashMap()); + private static final long THREAD_EETOP_OFFSET = eetopOffset(); private HotSpotTruffleRuntime() { installOptimizedCallTargetCallMethod(); @@ -185,14 +187,18 @@ } private static CompilationResult compileMethod(ResolvedJavaMethod javaMethod) { - Providers providers = getGraalProviders(); - MetaAccessProvider metaAccess = providers.getMetaAccess(); - SuitesProvider suitesProvider = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getSuites(); + HotSpotProviders providers = getGraalProviders(); + SuitesProvider suitesProvider = providers.getSuites(); Suites suites = suitesProvider.createSuites(); LIRSuites lirSuites = suitesProvider.createLIRSuites(); removeInliningPhase(suites); StructuredGraph graph = new StructuredGraph(javaMethod, AllowAssumptions.NO); - new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), providers.getConstantReflection(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL, null).apply(graph); + + MetaAccessProvider metaAccess = providers.getMetaAccess(); + Plugins plugins = new Plugins(new InvocationPlugins(metaAccess)); + GraphBuilderConfiguration config = GraphBuilderConfiguration.getEagerDefault(plugins); + new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), providers.getConstantReflection(), config, OptimisticOptimizations.ALL, null).apply(graph); + PhaseSuite graphBuilderSuite = getGraphBuilderSuite(suitesProvider); CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false); Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend(); @@ -201,9 +207,9 @@ suites, lirSuites, new CompilationResult(), factory); } - private static Providers getGraalProviders() { + private static HotSpotProviders getGraalProviders() { RuntimeProvider runtimeProvider = Graal.getRequiredCapability(RuntimeProvider.class); - return runtimeProvider.getHostBackend().getProviders(); + return (HotSpotProviders) runtimeProvider.getHostBackend().getProviders(); } private static PhaseSuite getGraphBuilderSuite(SuitesProvider suitesProvider) { @@ -242,7 +248,7 @@ try { future.get(); } catch (ExecutionException e) { - if (TruffleCompilationExceptionsAreThrown.getValue() && !(e.getCause() instanceof BailoutException) && !((BailoutException) e.getCause()).isPermanent()) { + if (TruffleCompilationExceptionsAreThrown.getValue() && !(e.getCause() instanceof BailoutException && !((BailoutException) e.getCause()).isPermanent())) { throw new RuntimeException(e.getCause()); } else { // silently ignored @@ -315,10 +321,11 @@ public void notifyTransferToInterpreter() { CompilerAsserts.neverPartOfCompilation(); if (TraceTruffleTransferToInterpreter.getValue()) { - Word thread = CurrentJavaThreadNode.get(); - boolean deoptimized = thread.readByte(HotSpotGraalRuntime.runtime().getConfig().pendingTransferToInterpreterOffset) != 0; + long thread = UnsafeAccess.unsafe.getLong(Thread.currentThread(), THREAD_EETOP_OFFSET); + long pendingTransferToInterpreterAddress = thread + HotSpotGraalRuntime.runtime().getConfig().pendingTransferToInterpreterOffset; + boolean deoptimized = UnsafeAccess.unsafe.getByte(pendingTransferToInterpreterAddress) != 0; if (deoptimized) { - thread.writeByte(HotSpotGraalRuntime.runtime().getConfig().pendingTransferToInterpreterOffset, (byte) 0); + UnsafeAccess.unsafe.putByte(pendingTransferToInterpreterAddress, (byte) 0); logTransferToInterpreter(); } @@ -332,4 +339,12 @@ String suffix = stackTrace.length > skip + limit ? "\n ..." : ""; TTY.out().out().println(Arrays.stream(stackTrace).skip(skip).limit(limit).map(StackTraceElement::toString).collect(Collectors.joining("\n ", "", suffix))); } + + private static long eetopOffset() { + try { + return UnsafeAccess.unsafe.objectFieldOffset(Thread.class.getDeclaredField("eetop")); + } catch (Exception e) { + throw new GraalInternalError(e); + } + } } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ExactMathTest.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ExactMathTest.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ExactMathTest.java Tue Mar 17 11:23:06 2015 -0700 @@ -25,16 +25,16 @@ import org.junit.*; import com.oracle.graal.compiler.test.*; -import com.oracle.graal.java.*; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.truffle.substitutions.*; import com.oracle.truffle.api.*; public class ExactMathTest extends GraalCompilerTest { @Override - protected void editGraphBuilderPlugins(GraphBuilderConfiguration.Plugins plugins) { - TruffleGraphBuilderPlugins.registerExactMathPlugins(getMetaAccess(), plugins.getInvocationPlugins()); - super.editGraphBuilderPlugins(plugins); + protected GraphBuilderConfiguration editGraphBuilderConfiguration(GraphBuilderConfiguration conf) { + TruffleGraphBuilderPlugins.registerExactMathPlugins(conf.getPlugins().getInvocationPlugins()); + return super.editGraphBuilderConfiguration(conf); } @Test diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/SimplePartialEvaluationTest.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/SimplePartialEvaluationTest.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/SimplePartialEvaluationTest.java Tue Mar 17 11:23:06 2015 -0700 @@ -136,4 +136,11 @@ assertPartialEvalNoInvokes(rootNode); assertPartialEvalEquals("constant42", rootNode); } + + @Test + public void lambda() { + FrameDescriptor fd = new FrameDescriptor(); + AbstractTestNode result = new LambdaTestNode(); + assertPartialEvalEquals("constant42", new RootTestNode(fd, "constantValue", result)); + } } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/LambdaTestNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/LambdaTestNode.java Tue Mar 17 11:23:06 2015 -0700 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2015, 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.truffle.test.nodes; + +import java.util.function.*; + +import com.oracle.truffle.api.frame.*; + +public class LambdaTestNode extends AbstractTestNode { + @Override + public int execute(VirtualFrame frame) { + return lambda(() -> 42); + } + + private static int lambda(Supplier supplier) { + return supplier.get(); + } +} diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Tue Mar 17 11:23:06 2015 -0700 @@ -28,7 +28,9 @@ import java.util.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.Assumptions.AssumptionResult; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.meta.MethodHandleAccessProvider.IntrinsicMethod; import com.oracle.graal.api.replacements.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; @@ -38,10 +40,9 @@ import com.oracle.graal.graph.Graph.Mark; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins; import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderConfiguration.Plugins; -import com.oracle.graal.java.GraphBuilderPlugin.LoadFieldPlugin; -import com.oracle.graal.java.GraphBuilderPlugin.ParameterPlugin; import com.oracle.graal.loop.*; import com.oracle.graal.nodes.CallTargetNode.InvokeKind; import com.oracle.graal.nodes.*; @@ -49,6 +50,7 @@ import com.oracle.graal.nodes.calc.*; 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.nodes.virtual.*; import com.oracle.graal.phases.*; @@ -63,7 +65,6 @@ import com.oracle.graal.truffle.nodes.frame.*; import com.oracle.graal.truffle.nodes.frame.NewFrameNode.VirtualOnlyInstanceNode; import com.oracle.graal.truffle.phases.*; -import com.oracle.graal.truffle.substitutions.*; import com.oracle.graal.virtual.phases.ea.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -185,14 +186,14 @@ } } - private class InlineInvokePlugin implements GraphBuilderPlugin.InlineInvokePlugin { + private class PEInlineInvokePlugin implements InlineInvokePlugin { - private Stack inlining; + private Deque inlining; private OptimizedDirectCallNode lastDirectCallNode; private final Replacements replacements; - public InlineInvokePlugin(TruffleInlining inlining, Replacements replacements) { - this.inlining = new Stack<>(); + public PEInlineInvokePlugin(TruffleInlining inlining, Replacements replacements) { + this.inlining = new ArrayDeque<>(); this.inlining.push(inlining); this.replacements = replacements; } @@ -201,28 +202,37 @@ if (original.getAnnotation(TruffleBoundary.class) != null) { return null; } + IntrinsicMethod intrinsicMethod = builder.getConstantReflection().getMethodHandleAccess().lookupMethodHandleIntrinsic(original); + if (intrinsicMethod != null) { + InlineInfo inlineInfo = getMethodHandleIntrinsicInlineInfo(builder, arguments, intrinsicMethod); + if (inlineInfo != null) { + return inlineInfo; + } + } if (replacements != null && (replacements.getMethodSubstitutionMethod(original) != null || replacements.getMacroSubstitution(original) != null)) { return null; } assert !builder.parsingReplacement(); - if (original.equals(callSiteProxyMethod)) { - ValueNode arg1 = arguments[0]; - if (!arg1.isConstant()) { - GraalInternalError.shouldNotReachHere("The direct call node does not resolve to a constant!"); - } + if (TruffleCompilerOptions.TruffleFunctionInlining.getValue()) { + if (original.equals(callSiteProxyMethod)) { + ValueNode arg1 = arguments[0]; + if (!arg1.isConstant()) { + GraalInternalError.shouldNotReachHere("The direct call node does not resolve to a constant!"); + } - Object callNode = builder.getSnippetReflection().asObject(Object.class, (JavaConstant) arg1.asConstant()); - if (callNode instanceof OptimizedDirectCallNode) { - OptimizedDirectCallNode directCallNode = (OptimizedDirectCallNode) callNode; - lastDirectCallNode = directCallNode; - } - } else if (original.equals(callDirectMethod)) { - TruffleInliningDecision decision = getDecision(inlining.peek(), lastDirectCallNode); - lastDirectCallNode = null; - if (decision != null && decision.isInline()) { - inlining.push(decision); - builder.getAssumptions().record(new AssumptionValidAssumption((OptimizedAssumption) decision.getTarget().getNodeRewritingAssumption())); - return new InlineInfo(callInlinedMethod, false, false); + Object callNode = builder.getSnippetReflection().asObject(Object.class, (JavaConstant) arg1.asConstant()); + if (callNode instanceof OptimizedDirectCallNode) { + OptimizedDirectCallNode directCallNode = (OptimizedDirectCallNode) callNode; + lastDirectCallNode = directCallNode; + } + } else if (original.equals(callDirectMethod)) { + TruffleInliningDecision decision = getDecision(inlining.peek(), lastDirectCallNode); + lastDirectCallNode = null; + if (decision != null && decision.isInline()) { + inlining.push(decision); + builder.getAssumptions().record(new AssumptionValidAssumption((OptimizedAssumption) decision.getTarget().getNodeRewritingAssumption())); + return new InlineInfo(callInlinedMethod, false, false); + } } } return new InlineInfo(original, false, false); @@ -233,9 +243,59 @@ inlining.pop(); } } + + private InlineInfo getMethodHandleIntrinsicInlineInfo(GraphBuilderContext builder, ValueNode[] arguments, IntrinsicMethod intrinsicMethod) { + ResolvedJavaMethod targetMethod = null; + switch (intrinsicMethod) { + case INVOKE_BASIC: + ValueNode methodHandleNode = arguments[0]; + if (methodHandleNode.isConstant()) { + targetMethod = builder.getConstantReflection().getMethodHandleAccess().resolveInvokeBasicTarget(methodHandleNode.asJavaConstant(), true); + } + break; + case LINK_TO_STATIC: + case LINK_TO_SPECIAL: + case LINK_TO_VIRTUAL: + case LINK_TO_INTERFACE: + ValueNode memberNameNode = arguments[arguments.length - 1]; + if (memberNameNode.isConstant()) { + targetMethod = builder.getConstantReflection().getMethodHandleAccess().resolveLinkToTarget(memberNameNode.asJavaConstant()); + } + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + if (targetMethod != null) { + // TODO maybe cast arguments + + if (targetMethod.canBeStaticallyBound()) { + return new InlineInfo(targetMethod, false, false); + } + + // Try to get the most accurate receiver type + if (intrinsicMethod == IntrinsicMethod.LINK_TO_VIRTUAL || intrinsicMethod == IntrinsicMethod.LINK_TO_INTERFACE) { + ResolvedJavaType receiverType = StampTool.typeOrNull(arguments[0].stamp()); + if (receiverType != null) { + AssumptionResult concreteMethod = receiverType.findUniqueConcreteMethod(targetMethod); + if (concreteMethod != null) { + builder.getAssumptions().record(concreteMethod); + return new InlineInfo(concreteMethod.getResult(), false, false); + } + } + } else { + AssumptionResult concreteMethod = targetMethod.getDeclaringClass().findUniqueConcreteMethod(targetMethod); + if (concreteMethod != null) { + builder.getAssumptions().record(concreteMethod); + return new InlineInfo(concreteMethod.getResult(), false, false); + } + } + } + + return null; + } } - private class LoopExplosionPlugin implements GraphBuilderPlugin.LoopExplosionPlugin { + private class PELoopExplosionPlugin implements LoopExplosionPlugin { public boolean shouldExplodeLoops(ResolvedJavaMethod method) { return method.getAnnotation(ExplodeLoop.class) != null; @@ -259,10 +319,9 @@ plugins.setLoadFieldPlugin(new InterceptLoadFieldPlugin()); plugins.setParameterPlugin(new InterceptReceiverPlugin(callTarget)); callTarget.setInlining(new TruffleInlining(callTarget, new DefaultInliningPolicy())); - plugins.setInlineInvokePlugin(new InlineInvokePlugin(callTarget.getInlining(), providers.getReplacements())); - plugins.setLoopExplosionPlugin(new LoopExplosionPlugin()); - TruffleGraphBuilderPlugins.registerInvocationPlugins(providers.getMetaAccess(), newConfig.getPlugins().getInvocationPlugins()); - + plugins.setInlineInvokePlugin(new PEInlineInvokePlugin(callTarget.getInlining(), providers.getReplacements())); + plugins.setLoopExplosionPlugin(new PELoopExplosionPlugin()); + InvocationPlugins invocationPlugins = newConfig.getPlugins().getInvocationPlugins(); new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), this.snippetReflection, providers.getConstantReflection(), newConfig, TruffleCompilerImpl.Optimizations, null).apply(graph); Debug.dump(graph, "After FastPE"); diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Tue Mar 17 11:23:06 2015 -0700 @@ -32,6 +32,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Tue Mar 17 11:23:06 2015 -0700 @@ -27,15 +27,17 @@ import java.util.*; -import com.oracle.graal.api.meta.Assumptions.Assumption; import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.CallingConvention.Type; +import com.oracle.graal.api.meta.Assumptions.Assumption; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; import com.oracle.graal.java.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.phases.*; @@ -48,6 +50,7 @@ import com.oracle.graal.printer.*; import com.oracle.graal.runtime.*; import com.oracle.graal.truffle.nodes.*; +import com.oracle.graal.truffle.substitutions.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.nodes.*; @@ -97,14 +100,20 @@ this.lirSuites = backend.getSuites().getDefaultLIRSuites(); ResolvedJavaType[] skippedExceptionTypes = getSkippedExceptionTypes(providers.getMetaAccess()); - GraphBuilderConfiguration eagerConfig = GraphBuilderConfiguration.getEagerDefault().withSkippedExceptionTypes(skippedExceptionTypes); - this.config = GraphBuilderConfiguration.getDefault().withSkippedExceptionTypes(skippedExceptionTypes); + Plugins plugins; if (TruffleCompilerOptions.FastPE.getValue()) { GraphBuilderPhase phase = (GraphBuilderPhase) backend.getSuites().getDefaultGraphBuilderSuite().findPhase(GraphBuilderPhase.class).previous(); - this.config.getPlugins().getInvocationPlugins().setDefaults(phase.getGraphBuilderConfig().getPlugins().getInvocationPlugins()); + InvocationPlugins invocationPlugins = new InvocationPlugins(phase.getGraphBuilderConfig().getPlugins().getInvocationPlugins()); + plugins = new Plugins(invocationPlugins); + TruffleGraphBuilderPlugins.registerInvocationPlugins(providers.getMetaAccess(), invocationPlugins); + } else { + plugins = new Plugins(new InvocationPlugins(backendProviders.getMetaAccess())); } + this.config = GraphBuilderConfiguration.getDefault(plugins).withSkippedExceptionTypes(skippedExceptionTypes); + + GraphBuilderConfiguration eagerConfig = GraphBuilderConfiguration.getEagerDefault(plugins).withSkippedExceptionTypes(skippedExceptionTypes); this.truffleCache = new TruffleCacheImpl(providers, eagerConfig, TruffleCompilerImpl.Optimizations); this.partialEvaluator = new PartialEvaluator(providers, config, truffleCache, Graal.getRequiredCapability(SnippetReflectionProvider.class)); diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java Tue Mar 17 11:23:06 2015 -0700 @@ -31,10 +31,8 @@ import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; -import com.oracle.graal.java.*; -import com.oracle.graal.java.GraphBuilderPlugin.InvocationPlugin; -import com.oracle.graal.java.InvocationPlugins.Registration; -import com.oracle.graal.java.InvocationPlugins.Registration.Receiver; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.InvocationPlugins.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; @@ -53,22 +51,22 @@ public class TruffleGraphBuilderPlugins { public static void registerInvocationPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - registerOptimizedAssumptionPlugins(metaAccess, plugins); - registerExactMathPlugins(metaAccess, plugins); - registerCompilerDirectivesPlugins(metaAccess, plugins); + registerOptimizedAssumptionPlugins(plugins); + registerExactMathPlugins(plugins); + registerCompilerDirectivesPlugins(plugins); registerOptimizedCallTargetPlugins(metaAccess, plugins); - registerUnsafeAccessImplPlugins(metaAccess, plugins); + registerUnsafeAccessImplPlugins(plugins); if (TruffleCompilerOptions.TruffleUseFrameWithoutBoxing.getValue()) { - registerFrameWithoutBoxingPlugins(metaAccess, plugins); + registerFrameWithoutBoxingPlugins(plugins); } else { - registerFrameWithBoxingPlugins(metaAccess, plugins); + registerFrameWithBoxingPlugins(plugins); } } - public static void registerOptimizedAssumptionPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, OptimizedAssumption.class); + public static void registerOptimizedAssumptionPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, OptimizedAssumption.class); r.register1("isValid", Receiver.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode arg) { if (arg.isConstant()) { @@ -86,8 +84,8 @@ }); } - public static void registerExactMathPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, ExactMath.class); + public static void registerExactMathPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, ExactMath.class); for (Kind kind : new Kind[]{Kind.Int, Kind.Long}) { Class type = kind.toJavaClass(); r.register2("addExact", type, type, new InvocationPlugin() { @@ -123,8 +121,8 @@ } } - public static void registerCompilerDirectivesPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, CompilerDirectives.class); + public static void registerCompilerDirectivesPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, CompilerDirectives.class); r.register0("inInterpreter", new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod) { b.push(Kind.Boolean.getStackKind(), b.append(ConstantNode.forBoolean(false))); @@ -190,7 +188,7 @@ } }); - r = new Registration(plugins, metaAccess, CompilerAsserts.class); + r = new Registration(plugins, CompilerAsserts.class); r.register1("partialEvaluationConstant", Object.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { ValueNode curValue = value; @@ -229,7 +227,7 @@ } public static void registerOptimizedCallTargetPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, OptimizedCallTarget.class); + Registration r = new Registration(plugins, OptimizedCallTarget.class); r.register2("createFrame", FrameDescriptor.class, Object[].class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode descriptor, ValueNode args) { Class frameClass = TruffleCompilerOptions.TruffleUseFrameWithoutBoxing.getValue() ? FrameWithoutBoxing.class : FrameWithBoxing.class; @@ -245,21 +243,21 @@ }); } - public static void registerFrameWithoutBoxingPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, FrameWithoutBoxing.class); + public static void registerFrameWithoutBoxingPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, FrameWithoutBoxing.class); registerMaterialize(r); registerUnsafeCast(r); registerUnsafeLoadStorePlugins(r, Kind.Int, Kind.Long, Kind.Float, Kind.Double, Kind.Object); } - public static void registerFrameWithBoxingPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, FrameWithBoxing.class); + public static void registerFrameWithBoxingPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, FrameWithBoxing.class); registerMaterialize(r); registerUnsafeCast(r); } - public static void registerUnsafeAccessImplPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { - Registration r = new Registration(plugins, metaAccess, UnsafeAccessImpl.class); + public static void registerUnsafeAccessImplPlugins(InvocationPlugins plugins) { + Registration r = new Registration(plugins, UnsafeAccessImpl.class); registerUnsafeCast(r); registerUnsafeLoadStorePlugins(r, Kind.Boolean, Kind.Byte, Kind.Int, Kind.Short, Kind.Long, Kind.Float, Kind.Double, Kind.Object); } @@ -267,7 +265,7 @@ private static void registerMaterialize(Registration r) { r.register1("materialize", Receiver.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode frame) { - b.push(Kind.Object, b.append(new MaterializeFrameNode(frame))); + b.push(Kind.Object, b.append(new MaterializeFrameNode(GraphBuilderContext.nullCheckedValue(b, frame)))); return true; } }); diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTest.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTest.java Tue Mar 17 11:23:06 2015 -0700 @@ -380,11 +380,7 @@ @Override public Probe getProbe() { - try { - return probeNode.getProbe(); - } catch (IllegalStateException e) { - throw new IllegalStateException("Cannot call getProbe() on a wrapper that has no probe"); - } + return probeNode.getProbe(); } @Override diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/tools/TestNodes.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/tools/TestNodes.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/tools/TestNodes.java Tue Mar 17 11:23:06 2015 -0700 @@ -119,11 +119,7 @@ @Override public Probe getProbe() { - try { - return probeNode.getProbe(); - } catch (IllegalStateException e) { - throw new IllegalStateException("Cannot call getProbe() on a wrapper that has no probe"); - } + return probeNode.getProbe(); } @Override diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeFailure.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeFailure.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeFailure.java Tue Mar 17 11:23:06 2015 -0700 @@ -58,12 +58,7 @@ /** * Wrapper not assignable to the parent's child field. */ - WRAPPER_TYPE("Wrapper not assignable to parent's child field"), - - /** - * Attempt to \"probe lite\" an already probed node. - */ - LITE_VIOLATION("Attempt to \"probe lite\" an already probed node"); + WRAPPER_TYPE("Wrapper not assignable to parent's child field"); final String message; diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeNode.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeNode.java Tue Mar 17 11:23:06 2015 -0700 @@ -33,9 +33,20 @@ import com.oracle.truffle.api.source.*; /** - * Implementation interfaces and classes for attaching {@link Probe}s to {@link WrapperNode}s. + * Implementation class & interface for enabling the attachment of {@linkplain Probe Probes} to + * Truffle ASTs. + *

+ * A {@link ProbeNode} is the head of a chain of nodes acting on behalf of {@linkplain Instrument + * instruments}. It is attached to an AST as a child of a guest-language-specific + * {@link WrapperNode} node. + *

+ * When Truffle clones an AST, the chain, including all attached {@linkplain Instrument instruments} + * will be cloned along with the {@link WrapperNode} to which it is attached. An instance of + * {@link Probe} represents abstractly the instrumentation at a particular location in a GL AST, + * tracks the clones of the chain, and keeps the instrumentation attached to the clones consistent. */ -public abstract class ProbeNode extends Node implements TruffleEvents, InstrumentationNode { +@NodeInfo(cost = NodeCost.NONE) +public final class ProbeNode extends Node implements TruffleEvents, InstrumentationNode { /** * A node that can be inserted into a Truffle AST, and which enables {@linkplain Instrument @@ -91,8 +102,7 @@ Node getChild(); /** - * Gets the {@link Probe} responsible for installing this wrapper; none if the wrapper - * installed via {@linkplain Node#probeLite(ASTInstrumentListener) "lite-Probing"}. + * Gets the {@link Probe} responsible for installing this wrapper. */ Probe getProbe(); @@ -100,7 +110,6 @@ * Implementation support for completing a newly created wrapper node. */ void insertProbe(ProbeNode probeNode); - } /** @@ -109,202 +118,99 @@ */ public static Probe insertProbe(WrapperNode wrapper) { final SourceSection sourceSection = wrapper.getChild().getSourceSection(); - final ProbeFullNode probeFullNode = new ProbeFullNode(); // private constructor - final Probe probe = new Probe(probeFullNode, sourceSection); // package private access - probeFullNode.setProbe(probe); - wrapper.insertProbe(probeFullNode); - return probe; + final ProbeNode probeNode = new ProbeNode(); // private constructor + probeNode.probe = new Probe(probeNode, sourceSection); // package private access + wrapper.insertProbe(probeNode); + return probeNode.probe; } + // Never changed once set. + @CompilationFinal Probe probe = null; /** - * Creates a new {@link ProbeLiteNode} associated with, and attached to, a Guest Language - * specific instance of {@link WrapperNode}. + * First {@link AbstractInstrumentNode} node in chain; {@code null} of no instruments in chain. */ - public static void insertProbeLite(WrapperNode wrapper, ASTInstrumentListener instrumentListener) { - final ProbeLiteNode probeLiteNode = new ProbeLiteNode(instrumentListener); - wrapper.insertProbe(probeLiteNode); - } + @Child protected AbstractInstrumentNode firstInstrument; @Override public boolean isInstrumentable() { return false; } + @Override + public Node copy() { + Node node = super.copy(); + probe.registerProbeNodeClone((ProbeNode) node); + return node; + } + /** * @return the {@link Probe} permanently associated with this {@link ProbeNode}. - * - * @throws IllegalStateException if this location was "lite-Probed" */ - public abstract Probe getProbe() throws IllegalStateException; + public Probe getProbe() { + return probe; + } + + public void enter(Node node, VirtualFrame vFrame) { + this.probe.checkProbeUnchanged(); + final SyntaxTagTrap trap = probe.getTrap(); + if (trap != null) { + trap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize()); + } + if (firstInstrument != null) { + firstInstrument.enter(node, vFrame); + } + } + + public void returnVoid(Node node, VirtualFrame vFrame) { + this.probe.checkProbeUnchanged(); + if (firstInstrument != null) { + firstInstrument.returnVoid(node, vFrame); + } + } + + public void returnValue(Node node, VirtualFrame vFrame, Object result) { + this.probe.checkProbeUnchanged(); + if (firstInstrument != null) { + firstInstrument.returnValue(node, vFrame, result); + } + } + + public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) { + this.probe.checkProbeUnchanged(); + if (firstInstrument != null) { + firstInstrument.returnExceptional(node, vFrame, exception); + } + } + + public String instrumentationInfo() { + return "Standard probe"; + } /** * Adds an {@link AbstractInstrumentNode} to this chain. - * - * @throws IllegalStateException if at a "lite-Probed" location. */ - abstract void addInstrument(Instrument instrument); + @TruffleBoundary + void addInstrument(Instrument instrument) { + assert instrument.getProbe() == probe; + // The existing chain of nodes may be empty + // Attach the modified chain. + firstInstrument = insert(instrument.addToChain(firstInstrument)); + } /** * Removes an instrument from this chain of instruments. * - * @throws IllegalStateException if at a "lite-Probed" location. * @throws RuntimeException if no matching instrument is found, */ - abstract void removeInstrument(Instrument instrument); - - /** - * Implementation class & interfaces for enabling the attachment of {@linkplain Probe Probes} to - * Truffle ASTs. - *

- * Head of a chain of nodes acting on behalf of {@linkplain Instrument instruments}, attached to - * a Guest Language (GL) AST as a child of a GL-specific {@link WrapperNode} node. - *

- * When Truffle clones an AST, the chain, including all attached {@linkplain Instrument - * instruments} will be cloned along with the {@link WrapperNode} to which it is attached. An - * instance of {@link Probe} represents abstractly the instrumentation at a particular location - * in a GL AST, tracks the clones of the chain, and keeps the instrumentation attached to the - * clones consistent. - */ - @NodeInfo(cost = NodeCost.NONE) - private static final class ProbeFullNode extends ProbeNode { - - /** - * First {@link AbstractInstrumentNode} node in chain; {@code null} of no instruments in - * chain. - */ - @Child protected AbstractInstrumentNode firstInstrument; - - // Never changed once set. - @CompilationFinal private Probe probe = null; - - private ProbeFullNode() { - this.firstInstrument = null; - } - - @Override - public Probe getProbe() throws IllegalStateException { - return probe; - } - - @Override - public Node copy() { - Node node = super.copy(); - probe.registerProbeNodeClone((ProbeNode) node); - return node; - } - - private void setProbe(Probe probe) { - this.probe = probe; - } - - @Override - @TruffleBoundary - void addInstrument(Instrument instrument) { - assert instrument.getProbe() == probe; - // The existing chain of nodes may be empty - // Attach the modified chain. - firstInstrument = insert(instrument.addToChain(firstInstrument)); - } - - @Override - @TruffleBoundary - void removeInstrument(Instrument instrument) { - assert instrument.getProbe() == probe; - final AbstractInstrumentNode modifiedChain = instrument.removeFromChain(firstInstrument); - if (modifiedChain == null) { - firstInstrument = null; - } else { - firstInstrument = insert(modifiedChain); - } - } - - public void enter(Node node, VirtualFrame vFrame) { - this.probe.checkProbeUnchanged(); - final SyntaxTagTrap trap = probe.getTrap(); - if (trap != null) { - trap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize()); - } - if (firstInstrument != null) { - firstInstrument.enter(node, vFrame); - } - } - - public void returnVoid(Node node, VirtualFrame vFrame) { - this.probe.checkProbeUnchanged(); - if (firstInstrument != null) { - firstInstrument.returnVoid(node, vFrame); - } - } - - public void returnValue(Node node, VirtualFrame vFrame, Object result) { - this.probe.checkProbeUnchanged(); - if (firstInstrument != null) { - firstInstrument.returnValue(node, vFrame, result); - } - } - - public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) { - this.probe.checkProbeUnchanged(); - if (firstInstrument != null) { - firstInstrument.returnExceptional(node, vFrame, exception); - } - } - - public String instrumentationInfo() { - return "Standard probe"; + @TruffleBoundary + void removeInstrument(Instrument instrument) { + assert instrument.getProbe() == probe; + final AbstractInstrumentNode modifiedChain = instrument.removeFromChain(firstInstrument); + if (modifiedChain == null) { + firstInstrument = null; + } else { + firstInstrument = insert(modifiedChain); } } - /** - * Implementation of a probe that only ever has a single "instrument" associated with it. No - * {@link Instrument} is ever created; instead this method simply delegates the various enter - * and return events to a {@link TruffleEvents} passed in during construction. - */ - @NodeInfo(cost = NodeCost.NONE) - private static final class ProbeLiteNode extends ProbeNode { - - private final ASTInstrumentListener instrumentListener; - - private ProbeLiteNode(ASTInstrumentListener eventListener) { - this.instrumentListener = eventListener; - } - - @Override - public Probe getProbe() throws IllegalStateException { - throw new IllegalStateException("\"lite-Probed\" nodes have no explicit Probe"); - } - - @Override - @TruffleBoundary - void addInstrument(Instrument instrument) { - throw new IllegalStateException("Instruments may not be added at a \"lite-probed\" location"); - } - - @Override - @TruffleBoundary - void removeInstrument(Instrument instrument) { - throw new IllegalStateException("Instruments may not be removed at a \"lite-probed\" location"); - } - - public void enter(Node node, VirtualFrame vFrame) { - instrumentListener.enter(getProbe(), node, vFrame); - } - - public void returnVoid(Node node, VirtualFrame vFrame) { - instrumentListener.returnVoid(getProbe(), node, vFrame); - } - - public void returnValue(Node node, VirtualFrame vFrame, Object result) { - instrumentListener.returnValue(getProbe(), node, vFrame, result); - } - - public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) { - instrumentListener.returnExceptional(getProbe(), node, vFrame, exception); - } - - public String instrumentationInfo() { - return "\"Lite\" probe"; - } - - } } diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Tue Mar 17 11:23:06 2015 -0700 @@ -497,61 +497,6 @@ } /** - * Enables "one-shot", unmodifiable {@linkplain Instrument instrumentation} of a node, where the - * node is presumed to be part of a well-formed Truffle AST that is not being executed. - *

- * Modifies the AST by inserting a {@linkplain WrapperNode wrapper node} between the node and - * its parent; the wrapper node must be provided by implementations of - * {@link #createWrapperNode()}. - *

- * Unlike {@link #probe()}, once {@link #probeLite(ASTInstrumentListener)} is called at a node, - * no additional probing can be added and no additional instrumentation can be attached. - *

- * This restricted form of instrumentation is intended for special cases where only one kind of - * instrumentation is desired, and for which performance is a concern - * - * @param instrumentListener - * @throws ProbeException (unchecked) when a probe cannot be created, leaving the AST unchanged - */ - public final void probeLite(ASTInstrumentListener instrumentListener) { - - if (this instanceof WrapperNode) { - throw new ProbeException(ProbeFailure.Reason.WRAPPER_NODE, null, this, null); - } - - if (parent == null) { - throw new ProbeException(ProbeFailure.Reason.NO_PARENT, null, this, null); - } - - if (parent instanceof WrapperNode) { - throw new ProbeException(ProbeFailure.Reason.LITE_VIOLATION, null, this, null); - } - - if (!isInstrumentable()) { - throw new ProbeException(ProbeFailure.Reason.NOT_INSTRUMENTABLE, parent, this, null); - } - - // Create a new wrapper/probe with this node as its child. - final WrapperNode wrapper = createWrapperNode(); - - if (wrapper == null || !(wrapper instanceof Node)) { - throw new ProbeException(ProbeFailure.Reason.NO_WRAPPER, parent, this, wrapper); - } - - final Node wrapperNode = (Node) wrapper; - - if (!this.isSafelyReplaceableBy(wrapperNode)) { - throw new ProbeException(ProbeFailure.Reason.WRAPPER_TYPE, parent, this, wrapper); - } - - // Connect it to a Probe - ProbeNode.insertProbeLite(wrapper, instrumentListener); - - // Replace this node in the AST with the wrapper - this.replace(wrapperNode); - } - - /** * Converts this node to a textual representation useful for debugging. */ @Override diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLExpressionWrapperNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLExpressionWrapperNode.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLExpressionWrapperNode.java Tue Mar 17 11:23:06 2015 -0700 @@ -72,11 +72,7 @@ } public Probe getProbe() { - try { - return probeNode.getProbe(); - } catch (IllegalStateException e) { - throw new IllegalStateException("A lite-Probed wrapper has no explicit Probe"); - } + return probeNode.getProbe(); } public Node getChild() { diff -r ea280aa54d58 -r 815a87264cbb graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLStatementWrapperNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLStatementWrapperNode.java Tue Mar 17 11:22:56 2015 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLStatementWrapperNode.java Tue Mar 17 11:23:06 2015 -0700 @@ -65,11 +65,7 @@ } public Probe getProbe() { - try { - return probeNode.getProbe(); - } catch (IllegalStateException e) { - throw new IllegalStateException("A lite-Probed wrapper has no explicit Probe"); - } + return probeNode.getProbe(); } @Override diff -r ea280aa54d58 -r 815a87264cbb mx/suite.py --- a/mx/suite.py Tue Mar 17 11:22:56 2015 -0700 +++ b/mx/suite.py Tue Mar 17 11:23:06 2015 -0700 @@ -803,6 +803,7 @@ "sourceDirs" : ["src"], "dependencies" : [ "com.oracle.graal.phases", + "com.oracle.graal.graphbuilderconf" ], "checkstyle" : "com.oracle.graal.graph", "annotationProcessors" : ["com.oracle.graal.service.processor"], @@ -810,6 +811,17 @@ "workingSets" : "Graal,Java", }, + "com.oracle.graal.graphbuilderconf" : { + "subDir" : "graal", + "sourceDirs" : ["src"], + "dependencies" : [ + "com.oracle.graal.nodes", + ], + "checkstyle" : "com.oracle.graal.graph", + "javaCompliance" : "1.8", + "workingSets" : "Graal,Java", + }, + "com.oracle.graal.compiler.common" : { "subDir" : "graal", "sourceDirs" : ["src"], diff -r ea280aa54d58 -r 815a87264cbb src/cpu/x86/vm/sharedRuntime_x86_32.cpp --- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Tue Mar 17 11:22:56 2015 -0700 +++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Tue Mar 17 11:23:06 2015 -0700 @@ -715,7 +715,7 @@ int total_args_passed, int comp_args_on_stack, const BasicType *sig_bt, - const VMRegPair *regs + const VMRegPair *regs, int frame_extension_argument) { assert(frame_extension_argument == -1, "unsupported"); diff -r ea280aa54d58 -r 815a87264cbb src/os/solaris/vm/os_solaris.cpp --- a/src/os/solaris/vm/os_solaris.cpp Tue Mar 17 11:22:56 2015 -0700 +++ b/src/os/solaris/vm/os_solaris.cpp Tue Mar 17 11:23:06 2015 -0700 @@ -2674,8 +2674,6 @@ if (!recoverable_mmap_error(err)) { warn_fail_commit_memory(addr, bytes, exec, err); - // Introduced temporarily to debug the memory allocation issues on Solaris - tty->print_cr("GRAAL_DEBUG: unrecoverable error during mmap got errno %d", err); vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, "committing reserved memory."); } diff -r ea280aa54d58 -r 815a87264cbb src/share/vm/compiler/compileBroker.cpp --- a/src/share/vm/compiler/compileBroker.cpp Tue Mar 17 11:22:56 2015 -0700 +++ b/src/share/vm/compiler/compileBroker.cpp Tue Mar 17 11:23:06 2015 -0700 @@ -801,12 +801,6 @@ GraalCompiler* graal = new GraalCompiler(); #endif -#ifdef COMPILER1 - if (c1_count > 0) { - _compilers[0] = new Compiler(); - } -#endif // COMPILER1 - #if defined(COMPILERGRAAL) _compilers[1] = graal; if (FLAG_IS_DEFAULT(GraalThreads)) { @@ -817,8 +811,18 @@ } else { c2_count = GraalThreads; } + if (FLAG_IS_DEFAULT(GraalHostThreads)) { + } else { + c1_count = GraalHostThreads; + } #endif // COMPILERGRAAL +#ifdef COMPILER1 + if (c1_count > 0) { + _compilers[0] = new Compiler(); + } +#endif // COMPILER1 + #ifdef COMPILER2 if (c2_count > 0) { _compilers[1] = new C2Compiler(); diff -r ea280aa54d58 -r 815a87264cbb src/share/vm/graal/graalGlobals.hpp --- a/src/share/vm/graal/graalGlobals.hpp Tue Mar 17 11:22:56 2015 -0700 +++ b/src/share/vm/graal/graalGlobals.hpp Tue Mar 17 11:23:06 2015 -0700 @@ -61,6 +61,9 @@ COMPILERGRAAL_PRESENT(product(intx, GraalThreads, 1, \ "Force number of Graal compiler threads to use")) \ \ + COMPILERGRAAL_PRESENT(product(intx, GraalHostThreads, 1, \ + "Force number of compiler threads for Graal host compiler")) \ + \ GRAAL_ONLY(product(bool, CodeInstallSafepointChecks, true, \ "Perform explicit safepoint checks while installing code")) \ \ diff -r ea280aa54d58 -r 815a87264cbb test/blacklist_sparc.txt --- a/test/blacklist_sparc.txt Tue Mar 17 11:22:56 2015 -0700 +++ b/test/blacklist_sparc.txt Tue Mar 17 11:23:06 2015 -0700 @@ -1,2 +1,3 @@ com.oracle.graal.replacements.test.StandardMethodSubstitutionsTest com.oracle.graal.hotspot.amd64.test.CompressedNullCheckTest +com.oracle.nfi.test.NativeFunctionInterfaceTest