# HG changeset patch # User Thomas Wuerthinger # Date 1363040914 -3600 # Node ID dce9cefed5710543080e9a192983eb80c49fec4e # Parent 169ec449974af55c81dd3a9df2c3c860cf756154 Draft speculation log. diff -r 169ec449974a -r dce9cefed571 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DebugInfo.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DebugInfo.java Mon Mar 11 20:55:31 2013 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DebugInfo.java Mon Mar 11 23:28:34 2013 +0100 @@ -25,6 +25,8 @@ import java.io.*; import java.util.*; +import com.oracle.graal.api.meta.*; + /** * Represents the debugging information for a particular place in the code, which includes the code * position, a reference map, and deoptimization information. @@ -36,6 +38,7 @@ private final BytecodePosition bytecodePosition; private final BitSet registerRefMap; private final BitSet frameRefMap; + private final short deoptimizationReason; /** * Creates a new {@link DebugInfo} from the given values. @@ -45,10 +48,11 @@ * @param registerRefMap the register map * @param frameRefMap the reference map for {@code frame}, which may be {@code null} */ - public DebugInfo(BytecodePosition codePos, BitSet registerRefMap, BitSet frameRefMap) { + public DebugInfo(BytecodePosition codePos, BitSet registerRefMap, BitSet frameRefMap, short deoptimizationReason) { this.bytecodePosition = codePos; this.registerRefMap = registerRefMap; this.frameRefMap = frameRefMap; + this.deoptimizationReason = deoptimizationReason; } /** @@ -114,4 +118,13 @@ public BitSet getFrameRefMap() { return frameRefMap; } + + /** + * Identifies the reason in case a deoptimization happens at this program counter. + * + * @return the reason of the deoptimization + */ + public short getDeoptimizationReason() { + return deoptimizationReason; + } } diff -r 169ec449974a -r dce9cefed571 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/SpeculationLog.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/SpeculationLog.java Mon Mar 11 23:28:34 2013 +0100 @@ -0,0 +1,74 @@ +/* + * 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.api.code; + +import java.util.*; + +import com.oracle.graal.api.meta.*; + +/** + * Manages a list of unique deoptimization reasons and returns a unique index for each reason. This + * class is not thread safe and assumes that at every point in time there is only a single Graal + * compilation accessing this object. + * + */ +public final class SpeculationLog { + + public static final int MAX_CACHE_SIZE = 1 << 15; + + private List speculations = new ArrayList<>(); + private boolean[] map = new boolean[10]; + private Set snapshot = new HashSet<>(); + + public short addSpeculation(DeoptimizationReason reason) { + short index = (short) speculations.indexOf(reason); + if (index != -1) { + // Nothing to add, reason already registered. + return index; + } + if (speculations.size() >= MAX_CACHE_SIZE) { + throw new BailoutException("Too many deoptimization reasons recorded"); + } + speculations.add(reason); + if (map.length < speculations.size()) { + map = Arrays.copyOf(map, map.length * 2); + } + return (short) (speculations.size() - 1); + } + + public boolean[] getRawMap() { + return map; + } + + public void snapshot() { + for (int i = 0; i < speculations.size(); ++i) { + if (map[i]) { + snapshot.add(speculations.get(i)); + } + } + } + + public boolean maySpeculate(DeoptimizationReason reason) { + return !snapshot.contains(reason); + } +} diff -r 169ec449974a -r dce9cefed571 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Mon Mar 11 20:55:31 2013 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Mon Mar 11 23:28:34 2013 +0100 @@ -175,5 +175,4 @@ * Returns the localvariable table of this method. */ LocalVariableTable getLocalVariableTable(); - } diff -r 169ec449974a -r dce9cefed571 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Mon Mar 11 20:55:31 2013 +0100 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Mon Mar 11 23:28:34 2013 +0100 @@ -774,7 +774,7 @@ @Override public void emitDeoptimizeOnOverflow(DeoptimizationAction action, DeoptimizationReason reason) { - LIRFrameState info = state(); + LIRFrameState info = state(reason); LabelRef stubEntry = createDeoptStub(action, reason, info); append(new BranchOp(ConditionFlag.Overflow, stubEntry, info)); } diff -r 169ec449974a -r dce9cefed571 graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/BasicPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/BasicPTXTest.java Mon Mar 11 20:55:31 2013 +0100 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/BasicPTXTest.java Mon Mar 11 23:28:34 2013 +0100 @@ -71,7 +71,7 @@ phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); phasePlan.addPhase(PhasePosition.AFTER_PARSING, new PTXPhase()); new PTXPhase().apply(graph); - CompilationResult result = GraalCompiler.compileMethod(runtime, ptxBackend, target, graph.method(), graph, null, phasePlan, OptimisticOptimizations.NONE); + CompilationResult result = GraalCompiler.compileMethod(runtime, ptxBackend, target, graph.method(), graph, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog()); System.out.println("result=" + result); } diff -r 169ec449974a -r dce9cefed571 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 Mon Mar 11 20:55:31 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Mon Mar 11 23:28:34 2013 +0100 @@ -360,7 +360,8 @@ GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); editPhasePlan(method, graph, phasePlan); - CompilationResult compResult = GraalCompiler.compileMethod(runtime(), backend, runtime().getTarget(), method, graph, null, phasePlan, OptimisticOptimizations.ALL); + CompilationResult compResult = GraalCompiler.compileMethod(runtime(), backend, runtime().getTarget(), method, graph, null, phasePlan, OptimisticOptimizations.ALL, + new SpeculationLog()); if (printCompilation) { TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, compResult.getTargetCodeSize())); } diff -r 169ec449974a -r dce9cefed571 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Mon Mar 11 20:55:31 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Mon Mar 11 23:28:34 2013 +0100 @@ -115,7 +115,7 @@ @Override public LIR call() { - return GraalCompiler.emitHIR(runtime, backend.target, graph, assumptions, null, phasePlan, OptimisticOptimizations.NONE); + return GraalCompiler.emitHIR(runtime, backend.target, graph, assumptions, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog()); } }); diff -r 169ec449974a -r dce9cefed571 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 Mon Mar 11 20:55:31 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Mon Mar 11 23:28:34 2013 +0100 @@ -48,7 +48,7 @@ public class GraalCompiler { public static CompilationResult compileMethod(final GraalCodeCacheProvider runtime, final Backend backend, final TargetDescription target, final ResolvedJavaMethod method, - final StructuredGraph graph, final GraphCache cache, final PhasePlan plan, final OptimisticOptimizations optimisticOpts) { + final StructuredGraph graph, final GraphCache cache, final PhasePlan plan, final OptimisticOptimizations optimisticOpts, final SpeculationLog speculationLog) { assert (method.getModifiers() & Modifier.NATIVE) == 0 : "compiling native methods is not supported"; return Debug.scope("GraalCompiler", new Object[]{graph, method, runtime}, new Callable() { @@ -58,7 +58,7 @@ final LIR lir = Debug.scope("FrontEnd", new Callable() { public LIR call() { - return emitHIR(runtime, target, graph, assumptions, cache, plan, optimisticOpts); + return emitHIR(runtime, target, graph, assumptions, cache, plan, optimisticOpts, speculationLog); } }); final FrameMap frameMap = Debug.scope("BackEnd", lir, new Callable() { @@ -96,7 +96,11 @@ * @param target */ public static LIR emitHIR(GraalCodeCacheProvider runtime, TargetDescription target, StructuredGraph graph, Assumptions assumptions, GraphCache cache, PhasePlan plan, - OptimisticOptimizations optimisticOpts) { + OptimisticOptimizations optimisticOpts, final SpeculationLog speculationLog) { + + if (speculationLog != null) { + speculationLog.snapshot(); + } if (graph.start().next() == null) { plan.runPhases(PhasePosition.AFTER_PARSING, graph); @@ -216,7 +220,7 @@ List codeEmittingOrder = ComputeBlockOrder.computeCodeEmittingOrder(blocks.length, startBlock); List linearScanOrder = ComputeBlockOrder.computeLinearScanOrder(blocks.length, startBlock); - LIR lir = new LIR(schedule.getCFG(), schedule.getBlockToNodesMap(), linearScanOrder, codeEmittingOrder); + LIR lir = new LIR(schedule.getCFG(), schedule.getBlockToNodesMap(), linearScanOrder, codeEmittingOrder, speculationLog); Debug.dump(lir, "After linear scan order"); return lir; diff -r 169ec449974a -r dce9cefed571 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Mon Mar 11 20:55:31 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Mon Mar 11 23:28:34 2013 +0100 @@ -45,7 +45,7 @@ private HashMap virtualObjects = new HashMap<>(); private IdentityHashMap objectStates = new IdentityHashMap<>(); - public LIRFrameState build(FrameState topState, List lockData, LabelRef exceptionEdge) { + public LIRFrameState build(FrameState topState, List lockData, short reason, LabelRef exceptionEdge) { assert virtualObjects.size() == 0; assert objectStates.size() == 0; @@ -103,7 +103,7 @@ } objectStates.clear(); - return new LIRFrameState(frame, virtualObjectsArray, exceptionEdge); + return new LIRFrameState(frame, virtualObjectsArray, exceptionEdge, reason); } private BytecodeFrame computeFrameForState(FrameState state, List lockDataSlots) { diff -r 169ec449974a -r dce9cefed571 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 Mon Mar 11 20:55:31 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Mon Mar 11 23:28:34 2013 +0100 @@ -231,19 +231,23 @@ } public LIRFrameState state() { + return state(null); + } + + public LIRFrameState state(DeoptimizationReason reason) { assert lastState != null || needOnlyOopMaps() : "must have state before instruction"; - return stateFor(lastState); + return stateFor(lastState, reason); } - public LIRFrameState stateFor(FrameState state) { - return stateFor(state, null); + public LIRFrameState stateFor(FrameState state, DeoptimizationReason reason) { + return stateForWithExceptionEdge(state, reason, null); } - public LIRFrameState stateFor(FrameState state, LabelRef exceptionEdge) { + public LIRFrameState stateForWithExceptionEdge(FrameState state, DeoptimizationReason reason, LabelRef exceptionEdge) { if (needOnlyOopMaps()) { - return new LIRFrameState(null, null, null); + return new LIRFrameState(null, null, null, (short) -1); } - return debugInfoBuilder.build(state, lockDataSlots.subList(0, currentLockCount), exceptionEdge); + return debugInfoBuilder.build(state, lockDataSlots.subList(0, currentLockCount), lir.getDeoptimizationReasons().addSpeculation(reason), exceptionEdge); } /** @@ -595,7 +599,7 @@ // False constants are handled within emitBranch. } else { // Fall back to a normal branch. - LIRFrameState info = state(); + LIRFrameState info = state(deoptReason); LabelRef stubEntry = createDeoptStub(action, deoptReason, info); if (negated) { emitBranch(comp, stubEntry, null, info); @@ -716,7 +720,7 @@ LIRFrameState callState = null; if (x.stateAfter() != null) { - callState = stateFor(x.stateDuring(), x instanceof InvokeWithExceptionNode ? getLIRBlock(((InvokeWithExceptionNode) x).exceptionEdge()) : null); + callState = stateForWithExceptionEdge(x.stateDuring(), null, x instanceof InvokeWithExceptionNode ? getLIRBlock(((InvokeWithExceptionNode) x).exceptionEdge()) : null); } Value result = cc.getReturn(); @@ -818,7 +822,7 @@ if ((stateAfter.stackSize() > 0 && stateAfter.stackAt(stateAfter.stackSize() - 1) == x) || (stateAfter.stackSize() > 1 && stateAfter.stackAt(stateAfter.stackSize() - 2) == x)) { stateBeforeReturn = stateAfter.duplicateModified(stateAfter.bci, stateAfter.rethrowException(), x.kind()); } - info = stateFor(stateBeforeReturn); + info = stateFor(stateBeforeReturn, null); } else { info = state(); } diff -r 169ec449974a -r dce9cefed571 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 Mon Mar 11 20:55:31 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Mon Mar 11 23:28:34 2013 +0100 @@ -185,7 +185,7 @@ @Override public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason) { - append(new AMD64DeoptimizeOp(action, reason, state())); + append(new AMD64DeoptimizeOp(action, reason, state(reason))); } } diff -r 169ec449974a -r dce9cefed571 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 Mon Mar 11 20:55:31 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Mon Mar 11 23:28:34 2013 +0100 @@ -146,7 +146,8 @@ graph = graph.copy(); } InlinedBytecodes.add(method.getCodeSize()); - return GraalCompiler.compileMethod(graalRuntime.getRuntime(), graalRuntime.getBackend(), graalRuntime.getTarget(), method, graph, graalRuntime.getCache(), plan, optimisticOpts); + return GraalCompiler.compileMethod(graalRuntime.getRuntime(), graalRuntime.getBackend(), graalRuntime.getTarget(), method, graph, graalRuntime.getCache(), plan, + optimisticOpts, method.getSpeculationLog()); } }); } finally { diff -r 169ec449974a -r dce9cefed571 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Mon Mar 11 20:55:31 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Mon Mar 11 23:28:34 2013 +0100 @@ -25,6 +25,7 @@ import java.lang.reflect.*; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; @@ -152,7 +153,7 @@ * not null * @return the outcome of the installation as a {@link CodeInstallResult}. */ - CodeInstallResult installCode(HotSpotCompilationResult compResult, HotSpotInstalledCode code, HotSpotCodeInfo info, boolean[] triggeredDeoptimizations); + CodeInstallResult installCode(HotSpotCompilationResult compResult, HotSpotInstalledCode code, HotSpotCodeInfo info, SpeculationLog cache); void initializeConfiguration(HotSpotVMConfig config); diff -r 169ec449974a -r dce9cefed571 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Mon Mar 11 20:55:31 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Mon Mar 11 23:28:34 2013 +0100 @@ -25,6 +25,7 @@ import java.lang.reflect.*; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; @@ -37,8 +38,8 @@ private native int installCode0(HotSpotCompilationResult comp, HotSpotInstalledCode code, HotSpotCodeInfo info, boolean[] triggeredDeoptimizations); @Override - public CodeInstallResult installCode(HotSpotCompilationResult comp, HotSpotInstalledCode code, HotSpotCodeInfo info, boolean[] triggeredDeoptimizations) { - return CodeInstallResult.values()[installCode0(comp, code, info, triggeredDeoptimizations)]; + public CodeInstallResult installCode(HotSpotCompilationResult comp, HotSpotInstalledCode code, HotSpotCodeInfo info, SpeculationLog speculationLog) { + return CodeInstallResult.values()[installCode0(comp, code, info, (speculationLog == null) ? null : speculationLog.getRawMap())]; } @Override diff -r 169ec449974a -r dce9cefed571 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Mon Mar 11 20:55:31 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Mon Mar 11 23:28:34 2013 +0100 @@ -30,6 +30,7 @@ import java.util.*; import java.util.concurrent.*; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.ProfilingInfo.ExceptionSeen; import com.oracle.graal.bytecode.*; @@ -58,8 +59,8 @@ private HotSpotMethodData methodData; private byte[] code; private int compilationComplexity; - private CompilationTask currentTask; + private SpeculationLog speculationLog; HotSpotResolvedJavaMethod(HotSpotResolvedObjectType holder, long metaspaceMethod) { this.metaspaceMethod = metaspaceMethod; @@ -345,4 +346,10 @@ return currentTask; } + public SpeculationLog getSpeculationLog() { + if (speculationLog == null) { + speculationLog = new SpeculationLog(); + } + return speculationLog; + } } diff -r 169ec449974a -r dce9cefed571 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Mon Mar 11 20:55:31 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Mon Mar 11 23:28:34 2013 +0100 @@ -818,7 +818,7 @@ public void installMethod(HotSpotResolvedJavaMethod method, int entryBCI, CompilationResult compResult, CodeInfo[] info) { HotSpotCodeInfo hsInfo = makeInfo(method, compResult, info); HotSpotInstalledCode code = new HotSpotInstalledCode(method, true); - graalRuntime.getCompilerToVM().installCode(new HotSpotCompilationResult(method, entryBCI, compResult), code, hsInfo, null); + graalRuntime.getCompilerToVM().installCode(new HotSpotCompilationResult(method, entryBCI, compResult), code, hsInfo, method.getSpeculationLog()); } @Override diff -r 169ec449974a -r dce9cefed571 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 Mon Mar 11 20:55:31 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Mon Mar 11 23:28:34 2013 +0100 @@ -118,7 +118,8 @@ PhasePlan phasePlan = new PhasePlan(); GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); - final CompilationResult compResult = GraalCompiler.compileMethod(runtime(), backend, runtime().getTarget(), stubMethod, graph, null, phasePlan, OptimisticOptimizations.ALL); + final CompilationResult compResult = GraalCompiler.compileMethod(runtime(), backend, runtime().getTarget(), stubMethod, graph, null, phasePlan, OptimisticOptimizations.ALL, + new SpeculationLog()); final CodeInfo[] info = new CodeInfo[1]; stubCode = Debug.scope("CodeInstall", new Object[]{runtime(), stubMethod}, new Callable() { diff -r 169ec449974a -r dce9cefed571 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java Mon Mar 11 20:55:31 2013 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java Mon Mar 11 23:28:34 2013 +0100 @@ -24,6 +24,7 @@ import java.util.*; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; @@ -74,6 +75,8 @@ private boolean hasArgInCallerFrame; + private final SpeculationLog speculationLog; + /** * An opaque chunk of machine code. */ @@ -90,7 +93,7 @@ /** * Creates a new LIR instance for the specified compilation. */ - public LIR(ControlFlowGraph cfg, BlockMap> blockToNodesMap, List linearScanOrder, List codeEmittingOrder) { + public LIR(ControlFlowGraph cfg, BlockMap> blockToNodesMap, List linearScanOrder, List codeEmittingOrder, SpeculationLog speculationLog) { this.cfg = cfg; this.blockToNodesMap = blockToNodesMap; this.codeEmittingOrder = codeEmittingOrder; @@ -98,6 +101,11 @@ this.lirInstructions = new BlockMap<>(cfg); stubs = new ArrayList<>(); + this.speculationLog = speculationLog; + } + + public SpeculationLog getDeoptimizationReasons() { + return speculationLog; } /** diff -r 169ec449974a -r dce9cefed571 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java Mon Mar 11 20:55:31 2013 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java Mon Mar 11 23:28:34 2013 +0100 @@ -42,11 +42,13 @@ private final VirtualObject[] virtualObjects; public final LabelRef exceptionEdge; private DebugInfo debugInfo; + private final short deoptimizationReason; - public LIRFrameState(BytecodeFrame topFrame, VirtualObject[] virtualObjects, LabelRef exceptionEdge) { + public LIRFrameState(BytecodeFrame topFrame, VirtualObject[] virtualObjects, LabelRef exceptionEdge, short deoptimizationReason) { this.topFrame = topFrame; this.virtualObjects = virtualObjects; this.exceptionEdge = exceptionEdge; + this.deoptimizationReason = deoptimizationReason; } public boolean hasDebugInfo() { @@ -111,7 +113,7 @@ } public void finish(BitSet registerRefMap, BitSet frameRefMap) { - debugInfo = new DebugInfo(topFrame, registerRefMap, frameRefMap); + debugInfo = new DebugInfo(topFrame, registerRefMap, frameRefMap, deoptimizationReason); } @Override