# HG changeset patch # User Lukas Stadler # Date 1352294075 -3600 # Node ID 090868cbcda667abab4f7b5a53255fbc58cf10f9 # Parent 6eb83c6eb1770ad93723febb61487a5beeb75d4e Graal infrastructure for OnStackReplacement diff -r 6eb83c6eb177 -r 090868cbcda6 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 Wed Nov 07 14:08:03 2012 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Wed Nov 07 14:14:35 2012 +0100 @@ -298,7 +298,7 @@ GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); editPhasePlan(method, graph, phasePlan); - CompilationResult compResult = graalCompiler.compileMethod(method, graph, -1, null, phasePlan, OptimisticOptimizations.ALL); + CompilationResult compResult = graalCompiler.compileMethod(method, graph, null, phasePlan, OptimisticOptimizations.ALL); return addMethod(method, compResult); } }); diff -r 6eb83c6eb177 -r 090868cbcda6 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 Wed Nov 07 14:08:03 2012 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Wed Nov 07 14:14:35 2012 +0100 @@ -68,12 +68,9 @@ this.backend = backend; } - public CompilationResult compileMethod(final ResolvedJavaMethod method, final StructuredGraph graph, int osrBCI, final GraphCache cache, final PhasePlan plan, + public CompilationResult compileMethod(final ResolvedJavaMethod method, final StructuredGraph graph, final GraphCache cache, final PhasePlan plan, final OptimisticOptimizations optimisticOpts) { assert (method.getModifiers() & Modifier.NATIVE) == 0 : "compiling native methods is not supported"; - if (osrBCI != -1) { - throw new BailoutException("No OSR supported"); - } return Debug.scope("GraalCompiler", new Object[]{graph, method, this}, new Callable() { diff -r 6eb83c6eb177 -r 090868cbcda6 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Wed Nov 07 14:08:03 2012 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Wed Nov 07 14:14:35 2012 +0100 @@ -448,8 +448,12 @@ return !(location instanceof IndexedLocationNode) && location.displacement() < 4096; } + protected CallingConvention createCallingConvention() { + return frameMap.registerConfig.getCallingConvention(JavaCallee, method.getSignature().getReturnKind(), MetaUtil.signatureToKinds(method), target, false); + } + protected void emitPrologue() { - CallingConvention incomingArguments = frameMap.registerConfig.getCallingConvention(JavaCallee, method.getSignature().getReturnKind(), MetaUtil.signatureToKinds(method), target, false); + CallingConvention incomingArguments = createCallingConvention(); Value[] params = new Value[incomingArguments.getArgumentCount()]; for (int i = 0; i < params.length; i++) { diff -r 6eb83c6eb177 -r 090868cbcda6 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Wed Nov 07 14:08:03 2012 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Wed Nov 07 14:14:35 2012 +0100 @@ -73,6 +73,15 @@ } @Override + protected CallingConvention createCallingConvention() { + if (graph.getEntryBCI() == StructuredGraph.INVOCATION_ENTRY_BCI) { + return super.createCallingConvention(); + } else { + return frameMap.registerConfig.getCallingConvention(JavaCallee, method.getSignature().getReturnKind(), new Kind[]{Kind.Long}, target, false); + } + } + + @Override public void visitSafepointNode(SafepointNode i) { LIRFrameState info = state(); append(new AMD64SafepointOp(info, runtime().config)); @@ -245,7 +254,6 @@ Label unverifiedStub = new Label(); // Emit the prefix - tasm.recordMark(Marks.MARK_OSR_ENTRY); boolean isStatic = Modifier.isStatic(method.getModifiers()); if (!isStatic) { @@ -260,6 +268,7 @@ } asm.align(config.codeEntryAlignment); + tasm.recordMark(Marks.MARK_OSR_ENTRY); tasm.recordMark(Marks.MARK_VERIFIED_ENTRY); // Emit code for the LIR diff -r 6eb83c6eb177 -r 090868cbcda6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Wed Nov 07 14:08:03 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Wed Nov 07 14:14:35 2012 +0100 @@ -114,8 +114,8 @@ @Override public CompilationResult call() throws Exception { graalRuntime.evictDeoptedGraphs(); - StructuredGraph graph = new StructuredGraph(method); - return graalRuntime.getCompiler().compileMethod(method, graph, -1, graalRuntime.getCache(), plan, optimisticOpts); + StructuredGraph graph = new StructuredGraph(method, -1); + return graalRuntime.getCompiler().compileMethod(method, graph, graalRuntime.getCache(), plan, optimisticOpts); } }); } finally { diff -r 6eb83c6eb177 -r 090868cbcda6 graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java Wed Nov 07 14:08:03 2012 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java Wed Nov 07 14:14:35 2012 +0100 @@ -229,7 +229,7 @@ } } - public void insertProxies(LoopExitNode loopExit, FrameStateBuilder loopEntryState) { + public void insertLoopProxies(LoopExitNode loopExit, FrameStateBuilder loopEntryState) { for (int i = 0; i < localsSize(); i++) { ValueNode value = localAt(i); if (value != null && (!loopEntryState.contains(value) || loopExit.loopBegin().isPhiAtMerge(value))) { @@ -253,6 +253,30 @@ } } + public void insertProxies(BeginNode begin) { + for (int i = 0; i < localsSize(); i++) { + ValueNode value = localAt(i); + if (value != null) { + Debug.log(" inserting proxy for %s", value); + storeLocal(i, graph.unique(new ValueProxyNode(value, begin, PhiType.Value))); + } + } + for (int i = 0; i < stackSize(); i++) { + ValueNode value = stackAt(i); + if (value != null) { + Debug.log(" inserting proxy for %s", value); + storeStack(i, graph.unique(new ValueProxyNode(value, begin, PhiType.Value))); + } + } + for (int i = 0; i < locks.length; i++) { + ValueNode value = locks[i]; + if (value != null) { + Debug.log(" inserting proxy for %s", value); + locks[i] = graph.unique(new ValueProxyNode(value, begin, PhiType.Value)); + } + } + } + private PhiNode createLoopPhi(MergeNode block, ValueNode value) { if (value == null) { return null; diff -r 6eb83c6eb177 -r 090868cbcda6 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 Wed Nov 07 14:08:03 2012 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Nov 07 14:14:35 2012 +0100 @@ -75,6 +75,7 @@ private final MetaAccessProvider runtime; private ConstantPool constantPool; private ResolvedJavaMethod method; + private int entryBCI; private ProfilingInfo profilingInfo; private BytecodeStream stream; // the bytecode stream @@ -119,6 +120,7 @@ @Override protected void run(StructuredGraph graph) { method = graph.method(); + entryBCI = graph.getEntryBCI(); graphId = graph.graphId(); profilingInfo = method.getProfilingInfo(); assert method.getCode() != null : "method must contain bytecodes: " + method; @@ -1186,7 +1188,7 @@ } lastLoopExit = loopExit; Debug.log("Target %s (%s) Exits %s, scanning framestates...", targetBlock, target, loop); - newState.insertProxies(loopExit, loop.entryState); + newState.insertLoopProxies(loopExit, loop.entryState); loopExit.setStateAfter(newState.create(bci)); } @@ -1199,7 +1201,7 @@ private FixedNode createTarget(double probability, Block block, FrameStateBuilder stateAfter) { assert probability >= 0 && probability <= 1.01 : probability; - if (probability == 0 && optimisticOpts.removeNeverExecutedCode()) { + if (probability == 0 && optimisticOpts.removeNeverExecutedCode() && entryBCI == StructuredGraph.INVOCATION_ENTRY_BCI) { return currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.UnreachedCode, graphId)); } else { return createTarget(block, stateAfter); @@ -1486,6 +1488,12 @@ int opcode = stream.currentBC(); traceState(); traceInstruction(bci, opcode, bci == block.startBci); + if (bci == entryBCI) { + EntryMarkerNode x = currentGraph.add(new EntryMarkerNode()); + append(x); + frameState.insertProxies(x); + x.setStateAfter(frameState.create(bci)); + } processBytecode(bci, opcode); if (lastInstr == null || isBlockEnd(lastInstr) || lastInstr.next() != null) { diff -r 6eb83c6eb177 -r 090868cbcda6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java Wed Nov 07 14:14:35 2012 +0100 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012, 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.nodes; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.spi.*; + +/** + * This node will be inserted at point specified by {@link StructuredGraph#getEntryBCI()}, usually by the graph builder. + */ +public class EntryMarkerNode extends BeginNode implements Node.IterableNodeType, Simplifiable, LIRLowerable { + + @Override + public void simplify(SimplifierTool tool) { + // this node should not be removed, this overrides BeginNode.simplify + } + + @Override + public void generate(LIRGeneratorTool gen) { + throw new GraalInternalError("OnStackReplacementNode should not survive"); + } +} diff -r 6eb83c6eb177 -r 090868cbcda6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Wed Nov 07 14:08:03 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Wed Nov 07 14:14:35 2012 +0100 @@ -38,11 +38,14 @@ */ public class StructuredGraph extends Graph { + public static final int INVOCATION_ENTRY_BCI = -1; public static final long INVALID_GRAPH_ID = -1; + private static final AtomicLong uniqueGraphIds = new AtomicLong(); private final StartNode start; private final ResolvedJavaMethod method; private final long graphId; + private final int entryBCI; /** * Creates a new Graph containing a single {@link BeginNode} as the {@link #start() start} node. @@ -67,10 +70,18 @@ this.start = add(new StartNode()); this.method = method; this.graphId = graphId; + this.entryBCI = INVOCATION_ENTRY_BCI; } public StructuredGraph(ResolvedJavaMethod method) { - this(null, method); + this(method, INVOCATION_ENTRY_BCI); + } + + public StructuredGraph(ResolvedJavaMethod method, int entryBCI) { + this.start = add(new StartNode()); + this.method = method; + this.graphId = uniqueGraphIds.incrementAndGet(); + this.entryBCI = entryBCI; } @Override @@ -102,6 +113,10 @@ return method; } + public int getEntryBCI() { + return entryBCI; + } + public long graphId() { return graphId; }