changeset 7660:0b646334c5f7

keep track of leafGraphIds only at the StructuredGraph level (see GRAAL-60)
author Lukas Stadler <lukas.stadler@jku.at>
date Fri, 01 Feb 2013 17:32:59 +0100
parents 01aeaf194641
children 1b3ca8791ced
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/MonitorSnippets.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeAccessNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeReadNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeWriteNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertUnreachedToGuardPhase.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/EliminatePartiallyRedundantGuardsPhase.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BranchProbabilityNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/MacroNode.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/CyclicMaterializeStoreNode.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/MaterializeObjectNode.java src/share/vm/code/debugInfoRec.cpp src/share/vm/code/debugInfoRec.hpp src/share/vm/code/nmethod.cpp src/share/vm/code/nmethod.hpp src/share/vm/code/pcDesc.cpp src/share/vm/code/pcDesc.hpp src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/graal/graalEnv.cpp src/share/vm/graal/graalEnv.hpp src/share/vm/graal/graalJavaAccess.hpp src/share/vm/runtime/deoptimization.cpp
diffstat 53 files changed, 267 insertions(+), 284 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java	Fri Feb 01 17:32:59 2013 +0100
@@ -82,14 +82,6 @@
      */
     public final int numLocks;
 
-    /**
-     * In case this frame state belongs to a deoptimization, the leafGraphId will contain the
-     * StructuredGraph.graphId() of the graph that originally introduced this deoptimization point.
-     * This id is later on used by the runtime system to evict graphs from the graph cache when
-     * deoptimizations originating from them have been hit.
-     */
-    public final long leafGraphId;
-
     public final boolean rethrowException;
 
     public final boolean duringCall;
@@ -107,8 +99,7 @@
      * @param numStack the depth of the stack
      * @param numLocks the number of locked objects
      */
-    public BytecodeFrame(BytecodeFrame caller, ResolvedJavaMethod method, int bci, boolean rethrowException, boolean duringCall, Value[] values, int numLocals, int numStack, int numLocks,
-                    long leafGraphId) {
+    public BytecodeFrame(BytecodeFrame caller, ResolvedJavaMethod method, int bci, boolean rethrowException, boolean duringCall, Value[] values, int numLocals, int numStack, int numLocks) {
         super(caller, method, bci);
         assert values != null;
         this.rethrowException = rethrowException;
@@ -117,7 +108,6 @@
         this.numLocals = numLocals;
         this.numStack = numStack;
         this.numLocks = numLocks;
-        this.leafGraphId = leafGraphId;
         assert !rethrowException || numStack == 1 : "must have exception on top of the stack";
     }
 
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Fri Feb 01 17:32:59 2013 +0100
@@ -365,6 +365,13 @@
 
     private Assumptions assumptions;
 
+    /**
+     * The leafGraphIds will contain the StructuredGraph.graphId()s of the graphs that were
+     * incorporated into this compilation. These ids are later on used by the runtime system to
+     * evict graphs from the graph cache when deoptimizations occur.
+     */
+    private long[] leafGraphIds;
+
     public void setAssumptions(Assumptions assumptions) {
         this.assumptions = assumptions;
     }
@@ -373,6 +380,14 @@
         return assumptions;
     }
 
+    public void setLeafGraphIds(long[] leafGraphIds) {
+        this.leafGraphIds = leafGraphIds;
+    }
+
+    public long[] getLeafGraphIds() {
+        return leafGraphIds;
+    }
+
     /**
      * Sets the frame size in bytes. Does not include the return address pushed onto the stack, if
      * any.
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Fri Feb 01 17:32:59 2013 +0100
@@ -711,8 +711,8 @@
     }
 
     @Override
-    public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason, Object deoptInfo, long leafGraphId) {
-        LIRFrameState info = state(leafGraphId);
+    public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason, Object deoptInfo) {
+        LIRFrameState info = state();
         LabelRef stubEntry = createDeoptStub(action, reason, info, deoptInfo);
         append(new JumpOp(stubEntry, info));
     }
@@ -845,9 +845,9 @@
     }
 
     @Override
-    protected void emitNullCheckGuard(ValueNode object, long leafGraphId) {
+    protected void emitNullCheckGuard(ValueNode object) {
         Variable value = load(operand(object));
-        LIRFrameState info = state(leafGraphId);
+        LIRFrameState info = state();
         append(new NullCheckOp(value, info));
     }
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java	Fri Feb 01 17:32:59 2013 +0100
@@ -43,7 +43,7 @@
         BeginNode falseBegin = graph.add(new BeginNode());
         falseBegin.setNext(falseEnd);
 
-        IfNode ifNode = graph.add(new IfNode(null, trueBegin, falseBegin, 0.5, graph.graphId()));
+        IfNode ifNode = graph.add(new IfNode(null, trueBegin, falseBegin, 0.5));
         graph.start().setNext(ifNode);
 
         MergeNode merge = graph.add(new MergeNode());
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Fri Feb 01 17:32:59 2013 +0100
@@ -90,13 +90,24 @@
                 return Debug.scope("CodeGen", frameMap, new Callable<CompilationResult>() {
 
                     public CompilationResult call() {
-                        return emitCode(assumptions, method, lir, frameMap);
+                        return emitCode(getLeafGraphIdArray(graph), assumptions, method, lir, frameMap);
                     }
+
                 });
             }
         });
     }
 
+    private static long[] getLeafGraphIdArray(StructuredGraph graph) {
+        long[] leafGraphIdArray = new long[graph.getLeafGraphIds().size() + 1];
+        int i = 0;
+        leafGraphIdArray[i++] = graph.graphId();
+        for (long id : graph.getLeafGraphIds()) {
+            leafGraphIdArray[i++] = id;
+        }
+        return leafGraphIdArray;
+    }
+
     /**
      * Builds the graph, optimizes it.
      */
@@ -264,15 +275,16 @@
         return frameMap;
     }
 
-    public CompilationResult emitCode(Assumptions assumptions, ResolvedJavaMethod method, LIR lir, FrameMap frameMap) {
+    public CompilationResult emitCode(long[] leafGraphIds, Assumptions assumptions, ResolvedJavaMethod method, LIR lir, FrameMap frameMap) {
         TargetMethodAssembler tasm = backend.newAssembler(frameMap, lir);
         backend.emitCode(tasm, method, lir);
-        CompilationResult targetMethod = tasm.finishTargetMethod(method, false);
+        CompilationResult result = tasm.finishTargetMethod(method, false);
         if (!assumptions.isEmpty()) {
-            targetMethod.setAssumptions(assumptions);
+            result.setAssumptions(assumptions);
         }
+        result.setLeafGraphIds(leafGraphIds);
 
-        Debug.dump(targetMethod, "After code generation");
-        return targetMethod;
+        Debug.dump(result, "After code generation");
+        return result;
     }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java	Fri Feb 01 17:32:59 2013 +0100
@@ -45,7 +45,7 @@
     private HashMap<VirtualObjectNode, VirtualObject> virtualObjects = new HashMap<>();
     private IdentityHashMap<VirtualObjectNode, EscapeObjectState> objectStates = new IdentityHashMap<>();
 
-    public LIRFrameState build(FrameState topState, List<StackSlot> lockData, LabelRef exceptionEdge, long leafGraphId) {
+    public LIRFrameState build(FrameState topState, List<StackSlot> lockData, LabelRef exceptionEdge) {
         assert virtualObjects.size() == 0;
         assert objectStates.size() == 0;
 
@@ -65,7 +65,7 @@
             current = current.outerFrameState();
         } while (current != null);
 
-        BytecodeFrame frame = computeFrameForState(topState, lockData, leafGraphId);
+        BytecodeFrame frame = computeFrameForState(topState, lockData);
 
         VirtualObject[] virtualObjectsArray = null;
         if (virtualObjects.size() != 0) {
@@ -106,7 +106,7 @@
         return new LIRFrameState(frame, virtualObjectsArray, exceptionEdge);
     }
 
-    private BytecodeFrame computeFrameForState(FrameState state, List<StackSlot> lockDataSlots, long leafGraphId) {
+    private BytecodeFrame computeFrameForState(FrameState state, List<StackSlot> lockDataSlots) {
         int numLocals = state.localsSize();
         int numStack = state.stackSize();
         int numLocks = state.locksSize();
@@ -129,14 +129,14 @@
         if (state.outerFrameState() != null) {
             // remove the locks that were used for this frame from the lockDataSlots list
             List<StackSlot> nextLockDataSlots = lockDataSlots.subList(0, lockDataSlots.size() - numLocks);
-            caller = computeFrameForState(state.outerFrameState(), nextLockDataSlots, -1);
+            caller = computeFrameForState(state.outerFrameState(), nextLockDataSlots);
         } else {
             if (lockDataSlots.size() != numLocks) {
                 throw new BailoutException("unbalanced monitors: found monitor for unknown frame (%d != %d) at %s", lockDataSlots.size(), numLocks, state);
             }
         }
         assert state.bci >= 0 || state.bci == FrameState.BEFORE_BCI;
-        return new BytecodeFrame(caller, state.method(), state.bci, state.rethrowException(), state.duringCall(), values, numLocals, numStack, numLocks, leafGraphId);
+        return new BytecodeFrame(caller, state.method(), state.bci, state.rethrowException(), state.duringCall(), values, numLocals, numStack, numLocks);
     }
 
     private Value toValue(ValueNode value) {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Fri Feb 01 17:32:59 2013 +0100
@@ -227,23 +227,18 @@
 
     public LIRFrameState state() {
         assert lastState != null || needOnlyOopMaps() : "must have state before instruction";
-        return stateFor(lastState, StructuredGraph.INVALID_GRAPH_ID);
+        return stateFor(lastState);
     }
 
-    public LIRFrameState state(long leafGraphId) {
-        assert lastState != null || needOnlyOopMaps() : "must have state before instruction";
-        return stateFor(lastState, leafGraphId);
+    public LIRFrameState stateFor(FrameState state) {
+        return stateFor(state, null);
     }
 
-    public LIRFrameState stateFor(FrameState state, long leafGraphId) {
-        return stateFor(state, null, leafGraphId);
-    }
-
-    public LIRFrameState stateFor(FrameState state, LabelRef exceptionEdge, long leafGraphId) {
+    public LIRFrameState stateFor(FrameState state, LabelRef exceptionEdge) {
         if (needOnlyOopMaps()) {
             return new LIRFrameState(null, null, null);
         }
-        return debugInfoBuilder.build(state, lockDataSlots.subList(0, currentLockCount), exceptionEdge, leafGraphId);
+        return debugInfoBuilder.build(state, lockDataSlots.subList(0, currentLockCount), exceptionEdge);
     }
 
     /**
@@ -590,15 +585,15 @@
     }
 
     @Override
-    public void emitGuardCheck(BooleanNode comp, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated, long leafGraphId) {
+    public void emitGuardCheck(BooleanNode comp, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) {
         if (comp instanceof IsNullNode && negated) {
-            emitNullCheckGuard(((IsNullNode) comp).object(), leafGraphId);
+            emitNullCheckGuard(((IsNullNode) comp).object());
         } else if (comp instanceof ConstantNode && (comp.asConstant().asBoolean() != negated)) {
             // True constant, nothing to emit.
             // False constants are handled within emitBranch.
         } else {
             // Fall back to a normal branch.
-            LIRFrameState info = state(leafGraphId);
+            LIRFrameState info = state();
             LabelRef stubEntry = createDeoptStub(action, deoptReason, info, comp);
             if (negated) {
                 emitBranch(comp, stubEntry, null, info);
@@ -608,7 +603,7 @@
         }
     }
 
-    protected abstract void emitNullCheckGuard(ValueNode object, long leafGraphId);
+    protected abstract void emitNullCheckGuard(ValueNode object);
 
     public void emitBranch(BooleanNode node, LabelRef trueSuccessor, LabelRef falseSuccessor, LIRFrameState info) {
         if (node instanceof IsNullNode) {
@@ -698,7 +693,7 @@
 
         LIRFrameState callState = null;
         if (x.stateAfter() != null) {
-            callState = stateFor(x.stateDuring(), x instanceof InvokeWithExceptionNode ? getLIRBlock(((InvokeWithExceptionNode) x).exceptionEdge()) : null, x.leafGraphId());
+            callState = stateFor(x.stateDuring(), x instanceof InvokeWithExceptionNode ? getLIRBlock(((InvokeWithExceptionNode) x).exceptionEdge()) : null);
         }
 
         Value result = cc.getReturn();
@@ -800,7 +795,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, -1);
+            info = stateFor(stateBeforeReturn);
         } else {
             info = state();
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Fri Feb 01 17:32:59 2013 +0100
@@ -531,7 +531,7 @@
         Kind wordKind = graalRuntime.getTarget().wordKind;
         if (n instanceof ArrayLengthNode) {
             ArrayLengthNode arrayLengthNode = (ArrayLengthNode) n;
-            SafeReadNode safeReadArrayLength = safeReadArrayLength(arrayLengthNode.array(), StructuredGraph.INVALID_GRAPH_ID);
+            SafeReadNode safeReadArrayLength = safeReadArrayLength(arrayLengthNode.array());
             graph.replaceFixedWithFixed(arrayLengthNode, safeReadArrayLength);
         } else if (n instanceof Invoke) {
             Invoke invoke = (Invoke) n;
@@ -540,7 +540,7 @@
                 NodeInputList<ValueNode> parameters = callTarget.arguments();
                 ValueNode receiver = parameters.size() <= 0 ? null : parameters.get(0);
                 if (!callTarget.isStatic() && receiver.kind() == Kind.Object && !receiver.objectStamp().nonNull()) {
-                    invoke.node().dependencies().add(tool.createNullCheckGuard(receiver, invoke.leafGraphId()));
+                    invoke.node().dependencies().add(tool.createNullCheckGuard(receiver));
                 }
                 JavaType[] signature = MetaUtil.signatureToTypes(callTarget.targetMethod().getSignature(), callTarget.isStatic() ? null : callTarget.targetMethod().getDeclaringClass());
 
@@ -582,7 +582,7 @@
             ValueNode object = loadField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), this, graph) : loadField.object();
             assert loadField.kind() != Kind.Illegal;
             ReadNode memoryRead = graph.add(new ReadNode(object, LocationNode.create(field, field.getKind(), field.offset(), graph), loadField.stamp()));
-            memoryRead.dependencies().add(tool.createNullCheckGuard(object, loadField.leafGraphId()));
+            memoryRead.dependencies().add(tool.createNullCheckGuard(object));
             graph.replaceFixedWithFixed(loadField, memoryRead);
             if (loadField.isVolatile()) {
                 MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_READ));
@@ -595,7 +595,7 @@
             HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) storeField.field();
             ValueNode object = storeField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), this, graph) : storeField.object();
             WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), LocationNode.create(field, field.getKind(), field.offset(), graph)));
-            memoryWrite.dependencies().add(tool.createNullCheckGuard(object, storeField.leafGraphId()));
+            memoryWrite.dependencies().add(tool.createNullCheckGuard(object));
             memoryWrite.setStateAfter(storeField.stateAfter());
             graph.replaceFixedWithFixed(storeField, memoryWrite);
             FixedWithNextNode last = memoryWrite;
@@ -705,13 +705,13 @@
             LocationNode location = LocationNode.create(LocationNode.FINAL_LOCATION, wordKind, config.hubOffset, graph);
             ValueNode object = loadHub.object();
             assert !object.isConstant();
-            ValueNode guard = tool.createNullCheckGuard(object, StructuredGraph.INVALID_GRAPH_ID);
+            ValueNode guard = tool.createNullCheckGuard(object);
             ReadNode hub = graph.add(new ReadNode(object, location, StampFactory.forKind(wordKind())));
             hub.dependencies().add(guard);
             graph.replaceFixed(loadHub, hub);
         } else if (n instanceof FixedGuardNode) {
             FixedGuardNode node = (FixedGuardNode) n;
-            ValueAnchorNode newAnchor = graph.add(new ValueAnchorNode(tool.createGuard(node.condition(), node.getReason(), node.getAction(), node.isNegated(), node.getLeafGraphId())));
+            ValueAnchorNode newAnchor = graph.add(new ValueAnchorNode(tool.createGuard(node.condition(), node.getReason(), node.getAction(), node.isNegated())));
             graph.replaceFixedWithFixed(node, newAnchor);
         } else if (n instanceof CheckCastNode) {
             checkcastSnippets.lower((CheckCastNode) n, tool);
@@ -750,21 +750,21 @@
         return IndexedLocationNode.create(LocationNode.getArrayLocation(elementKind), elementKind, getArrayBaseOffset(elementKind), index, graph, true);
     }
 
-    private SafeReadNode safeReadArrayLength(ValueNode array, long leafGraphId) {
-        return safeRead(array.graph(), Kind.Int, array, config.arrayLengthOffset, StampFactory.positiveInt(), leafGraphId);
+    private SafeReadNode safeReadArrayLength(ValueNode array) {
+        return safeRead(array.graph(), Kind.Int, array, config.arrayLengthOffset, StampFactory.positiveInt());
     }
 
     private static ValueNode createBoundsCheck(AccessIndexedNode n, LoweringTool tool) {
         StructuredGraph graph = (StructuredGraph) n.graph();
         ArrayLengthNode arrayLength = graph.add(new ArrayLengthNode(n.array()));
-        ValueNode guard = tool.createGuard(graph.unique(new IntegerBelowThanNode(n.index(), arrayLength)), BoundsCheckException, InvalidateReprofile, n.leafGraphId());
+        ValueNode guard = tool.createGuard(graph.unique(new IntegerBelowThanNode(n.index(), arrayLength)), BoundsCheckException, InvalidateReprofile);
 
         graph.addBeforeFixed(n, arrayLength);
         return guard;
     }
 
-    private static SafeReadNode safeRead(Graph graph, Kind kind, ValueNode value, int offset, Stamp stamp, long leafGraphId) {
-        return graph.add(new SafeReadNode(value, LocationNode.create(LocationNode.FINAL_LOCATION, kind, offset, graph), stamp, leafGraphId));
+    private static SafeReadNode safeRead(Graph graph, Kind kind, ValueNode value, int offset, Stamp stamp) {
+        return graph.add(new SafeReadNode(value, LocationNode.create(LocationNode.FINAL_LOCATION, kind, offset, graph), stamp));
     }
 
     public ResolvedJavaType lookupJavaType(Class<?> clazz) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/MonitorSnippets.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/MonitorSnippets.java	Fri Feb 01 17:32:59 2013 +0100
@@ -76,7 +76,10 @@
     public static final boolean CHECK_BALANCED_MONITORS = Boolean.getBoolean("graal.monitors.checkBalanced");
 
     @Snippet
-    public static void monitorenter(@Parameter("object") Object object, @ConstantParameter("checkNull") boolean checkNull, @ConstantParameter("trace") boolean trace) {
+    public static void monitorenter(@Parameter("object")
+    Object object, @ConstantParameter("checkNull")
+    boolean checkNull, @ConstantParameter("trace")
+    boolean trace) {
         verifyOop(object);
 
         if (checkNull && object == null) {
@@ -265,7 +268,10 @@
      * Calls straight out to the monitorenter stub.
      */
     @Snippet
-    public static void monitorenterStub(@Parameter("object") Object object, @ConstantParameter("checkNull") boolean checkNull, @ConstantParameter("trace") boolean trace) {
+    public static void monitorenterStub(@Parameter("object")
+    Object object, @ConstantParameter("checkNull")
+    boolean checkNull, @ConstantParameter("trace")
+    boolean trace) {
         verifyOop(object);
         incCounter();
         if (checkNull && object == null) {
@@ -279,7 +285,9 @@
     }
 
     @Snippet
-    public static void monitorexit(@Parameter("object") Object object, @ConstantParameter("trace") boolean trace) {
+    public static void monitorexit(@Parameter("object")
+    Object object, @ConstantParameter("trace")
+    boolean trace) {
         trace(trace, "           object: 0x%016lx\n", Word.fromObject(object));
         if (useBiasedLocking()) {
             // Check for biased locking unlock case, which is a no-op
@@ -331,7 +339,9 @@
      * Calls straight out to the monitorexit stub.
      */
     @Snippet
-    public static void monitorexitStub(@Parameter("object") Object object, @ConstantParameter("trace") boolean trace) {
+    public static void monitorexitStub(@Parameter("object")
+    Object object, @ConstantParameter("trace")
+    boolean trace) {
         verifyOop(object);
         traceObject(trace, "-lock{stub}", object);
         MonitorExitStubCall.call(object);
@@ -424,7 +434,8 @@
             this.useFastLocking = useFastLocking;
         }
 
-        public void lower(MonitorEnterNode monitorenterNode, @SuppressWarnings("unused") LoweringTool tool) {
+        public void lower(MonitorEnterNode monitorenterNode, @SuppressWarnings("unused")
+        LoweringTool tool) {
             StructuredGraph graph = (StructuredGraph) monitorenterNode.graph();
 
             checkBalancedMonitors(graph);
@@ -455,7 +466,8 @@
             }
         }
 
-        public void lower(MonitorExitNode monitorexitNode, @SuppressWarnings("unused") LoweringTool tool) {
+        public void lower(MonitorExitNode monitorexitNode, @SuppressWarnings("unused")
+        LoweringTool tool) {
             StructuredGraph graph = (StructuredGraph) monitorexitNode.graph();
             FrameState stateAfter = monitorexitNode.stateAfter();
             boolean eliminated = monitorexitNode.eliminated();
@@ -518,7 +530,7 @@
                     // Only insert the nodes if this is the first monitorenter being lowered.
                     JavaType returnType = initCounter.getSignature().getReturnType(initCounter.getDeclaringClass());
                     MethodCallTargetNode callTarget = graph.add(new MethodCallTargetNode(InvokeKind.Static, initCounter, new ValueNode[0], returnType));
-                    InvokeNode invoke = graph.add(new InvokeNode(callTarget, 0, -1));
+                    InvokeNode invoke = graph.add(new InvokeNode(callTarget, 0));
                     invoke.setStateAfter(graph.start().stateAfter());
                     graph.addAfterFixed(graph.start(), invoke);
                     StructuredGraph inlineeGraph = (StructuredGraph) initCounter.getCompilerStorage().get(Graph.class);
@@ -530,7 +542,7 @@
                         Object msg = ((HotSpotRuntime) runtime).registerGCRoot("unbalanced monitors in " + MetaUtil.format("%H.%n(%p)", graph.method()) + ", count = %d");
                         ConstantNode errMsg = ConstantNode.forObject(msg, runtime, graph);
                         callTarget = graph.add(new MethodCallTargetNode(InvokeKind.Static, checkCounter, new ValueNode[]{errMsg}, returnType));
-                        invoke = graph.add(new InvokeNode(callTarget, 0, -1));
+                        invoke = graph.add(new InvokeNode(callTarget, 0));
                         List<ValueNode> stack = Collections.emptyList();
                         FrameState stateAfter = new FrameState(graph.method(), FrameState.AFTER_BCI, new ValueNode[0], stack, new ValueNode[0], false, false);
                         invoke.setStateAfter(graph.add(stateAfter));
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri Feb 01 17:32:59 2013 +0100
@@ -94,8 +94,6 @@
     private final GraphBuilderConfiguration graphBuilderConfig;
     private final OptimisticOptimizations optimisticOpts;
 
-    private long graphId;
-
     /**
      * Meters the number of actual bytecodes parsed.
      */
@@ -127,7 +125,6 @@
     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;
         this.stream = new BytecodeStream(method.getCode());
@@ -309,7 +306,7 @@
             if (type instanceof ResolvedJavaType) {
                 frameState.push(Kind.Object, append(ConstantNode.forConstant(((ResolvedJavaType) type).getEncoding(Representation.JavaClass), runtime, currentGraph)));
             } else {
-                append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId)));
+                append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved)));
                 frameState.push(Kind.Object, append(ConstantNode.forObject(null, runtime, currentGraph)));
             }
         } else if (con instanceof Constant) {
@@ -325,7 +322,7 @@
 
         ValueNode index = frameState.ipop();
         ValueNode array = frameState.apop();
-        ValueNode v = append(currentGraph.add(new LoadIndexedNode(array, index, kind, graphId)));
+        ValueNode v = append(currentGraph.add(new LoadIndexedNode(array, index, kind)));
         frameState.push(kind.getStackKind(), v);
     }
 
@@ -335,7 +332,7 @@
         ValueNode value = frameState.pop(kind.getStackKind());
         ValueNode index = frameState.ipop();
         ValueNode array = frameState.apop();
-        StoreIndexedNode result = currentGraph.add(new StoreIndexedNode(array, index, kind, value, graphId));
+        StoreIndexedNode result = currentGraph.add(new StoreIndexedNode(array, index, kind, value));
         append(result);
     }
 
@@ -604,7 +601,7 @@
         BeginNode trueSuccessor = createBlockTarget(probability, trueBlock, frameState);
         BeginNode falseSuccessor = createBlockTarget(1 - probability, falseBlock, frameState);
 
-        IfNode ifNode = negate ? new IfNode(condition, falseSuccessor, trueSuccessor, 1 - probability, graphId) : new IfNode(condition, trueSuccessor, falseSuccessor, probability, graphId);
+        IfNode ifNode = negate ? new IfNode(condition, falseSuccessor, trueSuccessor, 1 - probability) : new IfNode(condition, trueSuccessor, falseSuccessor, probability);
         append(currentGraph.add(ifNode));
     }
 
@@ -630,7 +627,7 @@
     private void genThrow() {
         ValueNode exception = frameState.apop();
         FixedGuardNode node = currentGraph.add(new FixedGuardNode(currentGraph.unique(new IsNullNode(exception)), DeoptimizationReason.NullCheckException, DeoptimizationAction.InvalidateReprofile,
-                        true, graphId));
+                        true));
         append(node);
         append(handleException(exception, bci()));
     }
@@ -699,7 +696,7 @@
             frameState.apush(checkCast);
         } else {
             ValueNode object = frameState.apop();
-            append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new IsNullNode(object)), DeoptimizationReason.Unresolved, DeoptimizationAction.InvalidateRecompile, graphId)));
+            append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new IsNullNode(object)), DeoptimizationReason.Unresolved, DeoptimizationAction.InvalidateRecompile)));
             frameState.apush(appendConstant(Constant.NULL_OBJECT));
         }
     }
@@ -714,8 +711,8 @@
             frameState.ipush(append(MaterializeNode.create(currentGraph.unique(instanceOfNode))));
         } else {
             BlockPlaceholderNode successor = currentGraph.add(new BlockPlaceholderNode());
-            DeoptimizeNode deopt = currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId));
-            IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new IsNullNode(object)), successor, deopt, 1, graphId));
+            DeoptimizeNode deopt = currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved));
+            IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new IsNullNode(object)), successor, deopt, 1));
             append(ifNode);
             lastInstr = successor;
             frameState.ipush(appendConstant(Constant.INT_0));
@@ -728,7 +725,7 @@
             NewInstanceNode n = currentGraph.add(new NewInstanceNode((ResolvedJavaType) type, true, false));
             frameState.apush(append(n));
         } else {
-            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId)));
+            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved)));
             frameState.apush(appendConstant(Constant.NULL_OBJECT));
         }
     }
@@ -779,7 +776,7 @@
             NewArrayNode n = currentGraph.add(new NewObjectArrayNode((ResolvedJavaType) type, length, true, false));
             frameState.apush(append(n));
         } else {
-            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId)));
+            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved)));
             frameState.apush(appendConstant(Constant.NULL_OBJECT));
         }
 
@@ -796,7 +793,7 @@
             FixedWithNextNode n = currentGraph.add(new NewMultiArrayNode((ResolvedJavaType) type, dims));
             frameState.apush(append(n));
         } else {
-            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId)));
+            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved)));
             frameState.apush(appendConstant(Constant.NULL_OBJECT));
         }
     }
@@ -807,10 +804,10 @@
         Kind kind = field.getKind();
         ValueNode receiver = frameState.apop();
         if ((field instanceof ResolvedJavaField) && ((ResolvedJavaField) field).getDeclaringClass().isInitialized()) {
-            LoadFieldNode load = currentGraph.add(new LoadFieldNode(receiver, (ResolvedJavaField) field, graphId));
+            LoadFieldNode load = currentGraph.add(new LoadFieldNode(receiver, (ResolvedJavaField) field));
             appendOptimizedLoadField(kind, load);
         } else {
-            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId)));
+            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved)));
             frameState.push(kind.getStackKind(), append(ConstantNode.defaultForKind(kind, currentGraph)));
         }
     }
@@ -832,7 +829,7 @@
         }
         BlockPlaceholderNode trueSucc = currentGraph.add(new BlockPlaceholderNode());
         BlockPlaceholderNode falseSucc = currentGraph.add(new BlockPlaceholderNode());
-        IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new IsNullNode(receiver)), trueSucc, falseSucc, 0.5, graphId));
+        IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new IsNullNode(receiver)), trueSucc, falseSucc, 0.5));
 
         append(ifNode);
         lastInstr = falseSucc;
@@ -858,7 +855,7 @@
     private void emitBoundsCheck(ValueNode index, ValueNode length) {
         BlockPlaceholderNode trueSucc = currentGraph.add(new BlockPlaceholderNode());
         BlockPlaceholderNode falseSucc = currentGraph.add(new BlockPlaceholderNode());
-        IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new IntegerBelowThanNode(index, length)), trueSucc, falseSucc, 0.5, graphId));
+        IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new IntegerBelowThanNode(index, length)), trueSucc, falseSucc, 0.5));
 
         append(ifNode);
         lastInstr = trueSucc;
@@ -894,10 +891,10 @@
         ValueNode value = frameState.pop(field.getKind().getStackKind());
         ValueNode receiver = frameState.apop();
         if (field instanceof ResolvedJavaField && ((ResolvedJavaField) field).getDeclaringClass().isInitialized()) {
-            StoreFieldNode store = currentGraph.add(new StoreFieldNode(receiver, (ResolvedJavaField) field, value, graphId));
+            StoreFieldNode store = currentGraph.add(new StoreFieldNode(receiver, (ResolvedJavaField) field, value));
             appendOptimizedStoreField(store);
         } else {
-            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId)));
+            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved)));
         }
     }
 
@@ -908,11 +905,11 @@
             if (constantValue != null) {
                 frameState.push(constantValue.getKind().getStackKind(), appendConstant(constantValue));
             } else {
-                LoadFieldNode load = currentGraph.add(new LoadFieldNode(null, (ResolvedJavaField) field, graphId));
+                LoadFieldNode load = currentGraph.add(new LoadFieldNode(null, (ResolvedJavaField) field));
                 appendOptimizedLoadField(kind, load);
             }
         } else {
-            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId)));
+            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved)));
             frameState.push(kind.getStackKind(), append(ConstantNode.defaultForKind(kind, currentGraph)));
         }
     }
@@ -920,10 +917,10 @@
     private void genPutStatic(JavaField field) {
         ValueNode value = frameState.pop(field.getKind().getStackKind());
         if (field instanceof ResolvedJavaField && ((ResolvedJavaType) field.getDeclaringClass()).isInitialized()) {
-            StoreFieldNode store = currentGraph.add(new StoreFieldNode(null, (ResolvedJavaField) field, value, graphId));
+            StoreFieldNode store = currentGraph.add(new StoreFieldNode(null, (ResolvedJavaField) field, value));
             appendOptimizedStoreField(store);
         } else {
-            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId)));
+            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved)));
         }
     }
 
@@ -931,7 +928,7 @@
         if (initialized) {
             return appendConstant(((ResolvedJavaType) holder).getEncoding(representation));
         } else {
-            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId)));
+            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved)));
             return null;
         }
     }
@@ -992,7 +989,7 @@
     }
 
     private void genInvokeDeopt(JavaMethod unresolvedTarget, boolean withReceiver) {
-        append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId)));
+        append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved)));
         frameState.popArguments(unresolvedTarget.getSignature().getParameterSlots(withReceiver), unresolvedTarget.getSignature().getParameterCount(withReceiver));
         Kind kind = unresolvedTarget.getSignature().getReturnKind();
         if (kind != Kind.Void) {
@@ -1032,7 +1029,7 @@
     private void appendInvoke(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args) {
         Kind resultType = targetMethod.getSignature().getReturnKind();
         if (GraalOptions.DeoptALot) {
-            DeoptimizeNode deoptimize = currentGraph.add(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint, graphId));
+            DeoptimizeNode deoptimize = currentGraph.add(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint));
             deoptimize.setMessage(targetMethod.getName());
             append(deoptimize);
             frameState.pushReturn(resultType, ConstantNode.defaultForKind(resultType, currentGraph));
@@ -1047,12 +1044,12 @@
         // be conservative if information was not recorded (could result in endless recompiles
         // otherwise)
         if (optimisticOpts.useExceptionProbability() && profilingInfo.getExceptionSeen(bci()) == ExceptionSeen.FALSE) {
-            ValueNode result = appendWithBCI(currentGraph.add(new InvokeNode(callTarget, bci(), graphId)));
+            ValueNode result = appendWithBCI(currentGraph.add(new InvokeNode(callTarget, bci())));
             frameState.pushReturn(resultType, result);
 
         } else {
             DispatchBeginNode exceptionEdge = handleException(null, bci());
-            InvokeWithExceptionNode invoke = currentGraph.add(new InvokeWithExceptionNode(callTarget, exceptionEdge, bci(), graphId));
+            InvokeWithExceptionNode invoke = currentGraph.add(new InvokeWithExceptionNode(callTarget, exceptionEdge, bci()));
             ValueNode result = append(invoke);
             frameState.pushReturn(resultType, result);
             Block nextBlock = currentBlock.successors.get(0);
@@ -1115,7 +1112,7 @@
         JsrScope scope = currentBlock.jsrScope;
         int retAddress = scope.nextReturnAddress();
         append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new IntegerEqualsNode(local, ConstantNode.forJsr(retAddress, currentGraph))), DeoptimizationReason.JavaSubroutineMismatch,
-                        DeoptimizationAction.InvalidateReprofile, graphId)));
+                        DeoptimizationAction.InvalidateReprofile)));
         if (!successor.jsrScope.equals(scope.pop())) {
             throw new JsrNotSupportedBailout("unstructured control flow (ret leaves more than one scope)");
         }
@@ -1302,7 +1299,7 @@
     private FixedNode createTarget(double probability, Block block, FrameStateBuilder stateAfter) {
         assert probability >= 0 && probability <= 1.01 : probability;
         if (isNeverExecutedCode(probability)) {
-            return currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.UnreachedCode, graphId));
+            return currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.UnreachedCode));
         } else {
             assert block != null;
             return createTarget(block, stateAfter);
@@ -1534,7 +1531,7 @@
             frameState.push(Kind.Object, exception);
             FixedNode nextDispatch = createTarget(nextBlock, frameState);
             checkCast.setNext(catchSuccessor);
-            IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new InstanceOfNode((ResolvedJavaType) catchType, exception, null)), checkCast, nextDispatch, 0.5, graphId));
+            IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new InstanceOfNode((ResolvedJavaType) catchType, exception, null)), checkCast, nextDispatch, 0.5));
             append(ifNode);
         }
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java	Fri Feb 01 17:32:59 2013 +0100
@@ -34,17 +34,11 @@
     private String message;
     private final DeoptimizationAction action;
     private final DeoptimizationReason reason;
-    private final long leafGraphId;
 
     public DeoptimizeNode(DeoptimizationAction action, DeoptimizationReason reason) {
-        this(action, reason, -1);
-    }
-
-    public DeoptimizeNode(DeoptimizationAction action, DeoptimizationReason reason, long leafGraphId) {
         super(StampFactory.forVoid());
         this.action = action;
         this.reason = reason;
-        this.leafGraphId = leafGraphId;
     }
 
     public void setMessage(String message) {
@@ -63,13 +57,9 @@
         return reason;
     }
 
-    public long leafGraphId() {
-        return leafGraphId;
-    }
-
     @Override
     public void generate(LIRGeneratorTool gen) {
-        gen.emitDeoptimize(action, reason, message, leafGraphId);
+        gen.emitDeoptimize(action, reason, message);
     }
 
     @NodeIntrinsic
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Fri Feb 01 17:32:59 2013 +0100
@@ -35,7 +35,6 @@
     private final DeoptimizationReason reason;
     private final DeoptimizationAction action;
     private boolean negated;
-    private final long leafGraphId;
 
     public BooleanNode condition() {
         return condition;
@@ -46,15 +45,14 @@
         condition = x;
     }
 
-    public FixedGuardNode(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, long leafGraphId) {
-        this(condition, deoptReason, action, false, leafGraphId);
+    public FixedGuardNode(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action) {
+        this(condition, deoptReason, action, false);
     }
 
-    public FixedGuardNode(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated, long leafGraphId) {
+    public FixedGuardNode(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) {
         super(StampFactory.forVoid());
         this.action = action;
         this.negated = negated;
-        this.leafGraphId = leafGraphId;
         this.condition = condition;
         this.reason = deoptReason;
     }
@@ -71,10 +69,6 @@
         return negated;
     }
 
-    public long getLeafGraphId() {
-        return leafGraphId;
-    }
-
     @Override
     public String toString(Verbosity verbosity) {
         if (verbosity == Verbosity.Name && negated) {
@@ -86,7 +80,7 @@
 
     @Override
     public void generate(LIRGeneratorTool gen) {
-        gen.emitGuardCheck(condition, reason, action, negated, leafGraphId);
+        gen.emitGuardCheck(condition, reason, action, negated);
     }
 
     @Override
@@ -100,7 +94,7 @@
                 if (next != null) {
                     tool.deleteBranch(next);
                 }
-                setNext(graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, reason, leafGraphId)));
+                setNext(graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, reason)));
                 return;
             }
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java	Fri Feb 01 17:32:59 2013 +0100
@@ -48,15 +48,13 @@
     private final DeoptimizationReason reason;
     private final DeoptimizationAction action;
     private boolean negated;
-    private final long leafGraphId;
 
-    public GuardNode(BooleanNode condition, FixedNode anchor, DeoptimizationReason reason, DeoptimizationAction action, boolean negated, long leafGraphId) {
+    public GuardNode(BooleanNode condition, FixedNode anchor, DeoptimizationReason reason, DeoptimizationAction action, boolean negated) {
         super(StampFactory.dependency(), anchor);
         this.condition = condition;
         this.reason = reason;
         this.action = action;
         this.negated = negated;
-        this.leafGraphId = leafGraphId;
     }
 
     /**
@@ -83,10 +81,6 @@
         return action;
     }
 
-    public long getLeafGraphId() {
-        return leafGraphId;
-    }
-
     @Override
     public String toString(Verbosity verbosity) {
         if (verbosity == Verbosity.Name && negated) {
@@ -98,7 +92,7 @@
 
     @Override
     public void generate(LIRGeneratorTool gen) {
-        gen.emitGuardCheck(condition(), reason(), action(), negated(), leafGraphId);
+        gen.emitGuardCheck(condition(), reason(), action(), negated());
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Fri Feb 01 17:32:59 2013 +0100
@@ -39,11 +39,10 @@
  */
 public final class IfNode extends ControlSplitNode implements Simplifiable, LIRLowerable, Negatable {
 
-    private final long leafGraphId;
     @Successor private BeginNode trueSuccessor;
     @Successor private BeginNode falseSuccessor;
     @Input private BooleanNode condition;
-    private double takenProbability;
+    private double trueSuccessorProbability;
 
     public BooleanNode condition() {
         return condition;
@@ -54,24 +53,19 @@
         condition = x;
     }
 
-    public IfNode(BooleanNode condition, FixedNode trueSuccessor, FixedNode falseSuccessor, double takenProbability, long leafGraphId) {
-        this(condition, BeginNode.begin(trueSuccessor), BeginNode.begin(falseSuccessor), takenProbability, leafGraphId);
+    public IfNode(BooleanNode condition, FixedNode trueSuccessor, FixedNode falseSuccessor, double trueSuccessorProbability) {
+        this(condition, BeginNode.begin(trueSuccessor), BeginNode.begin(falseSuccessor), trueSuccessorProbability);
     }
 
-    public IfNode(BooleanNode condition, BeginNode trueSuccessor, BeginNode falseSuccessor, double takenProbability, long leafGraphId) {
+    public IfNode(BooleanNode condition, BeginNode trueSuccessor, BeginNode falseSuccessor, double trueSuccessorProbability) {
         super(StampFactory.forVoid());
         this.condition = condition;
         this.falseSuccessor = falseSuccessor;
-        this.takenProbability = takenProbability;
-        this.leafGraphId = leafGraphId;
+        this.trueSuccessorProbability = trueSuccessorProbability;
         this.trueSuccessor = trueSuccessor;
 
     }
 
-    public long leafGraphId() {
-        return leafGraphId;
-    }
-
     /**
      * Gets the true successor.
      * 
@@ -118,17 +112,17 @@
         setFalseSuccessor(null);
         setTrueSuccessor(falseSucc);
         setFalseSuccessor(trueSucc);
-        takenProbability = 1 - takenProbability;
+        trueSuccessorProbability = 1 - trueSuccessorProbability;
         return this;
     }
 
-    public void setTakenProbability(double prob) {
-        takenProbability = prob;
+    public void setTrueSuccessorProbability(double prob) {
+        trueSuccessorProbability = prob;
     }
 
     @Override
     public double probability(BeginNode successor) {
-        return successor == trueSuccessor ? takenProbability : 1 - takenProbability;
+        return successor == trueSuccessor ? trueSuccessorProbability : 1 - trueSuccessorProbability;
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java	Fri Feb 01 17:32:59 2013 +0100
@@ -71,6 +71,4 @@
     boolean isPolymorphic();
 
     void setPolymorphic(boolean value);
-
-    long leafGraphId();
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Fri Feb 01 17:32:59 2013 +0100
@@ -41,7 +41,6 @@
     private final int bci;
     private boolean polymorphic;
     private boolean useForInlining;
-    private final long leafGraphId;
     private double inliningRelevance;
 
     /**
@@ -50,11 +49,10 @@
      * @param bci the bytecode index of the original invoke (used for debug infos)
      * @param callTarget the target method being called
      */
-    public InvokeNode(CallTargetNode callTarget, int bci, long leafGraphId) {
+    public InvokeNode(CallTargetNode callTarget, int bci) {
         super(callTarget.returnStamp());
         this.callTarget = callTarget;
         this.bci = bci;
-        this.leafGraphId = leafGraphId;
         this.polymorphic = false;
         this.useForInlining = true;
         this.inliningRelevance = Double.NaN;
@@ -100,11 +98,6 @@
     }
 
     @Override
-    public long leafGraphId() {
-        return leafGraphId;
-    }
-
-    @Override
     public Map<Object, Object> getDebugProperties(Map<Object, Object> map) {
         Map<Object, Object> debugProperties = super.getDebugProperties(map);
         if (callTarget instanceof MethodCallTargetNode && methodCallTarget().targetMethod() != null) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Fri Feb 01 17:32:59 2013 +0100
@@ -41,15 +41,13 @@
     private final int bci;
     private boolean polymorphic;
     private boolean useForInlining;
-    private final long leafGraphId;
     private double inliningRelevance;
 
-    public InvokeWithExceptionNode(CallTargetNode callTarget, DispatchBeginNode exceptionEdge, int bci, long leafGraphId) {
+    public InvokeWithExceptionNode(CallTargetNode callTarget, DispatchBeginNode exceptionEdge, int bci) {
         super(callTarget.returnStamp());
         this.exceptionEdge = exceptionEdge;
         this.bci = bci;
         this.callTarget = callTarget;
-        this.leafGraphId = leafGraphId;
         this.polymorphic = false;
         this.useForInlining = true;
         this.inliningRelevance = Double.NaN;
@@ -112,11 +110,6 @@
     }
 
     @Override
-    public long leafGraphId() {
-        return leafGraphId;
-    }
-
-    @Override
     public String toString(Verbosity verbosity) {
         if (verbosity == Verbosity.Long) {
             return super.toString(Verbosity.Short) + "(bci=" + bci() + ")";
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Fri Feb 01 17:32:59 2013 +0100
@@ -41,6 +41,9 @@
     public static final long INVALID_GRAPH_ID = -1;
 
     private static final AtomicLong uniqueGraphIds = new AtomicLong();
+
+    private final Set<Long> leafGraphIds = new HashSet<>(4);
+
     private final StartNode start;
     private final ResolvedJavaMethod method;
     private final long graphId;
@@ -113,6 +116,14 @@
         return graphId;
     }
 
+    /**
+     * @return the {@link Set} that contains the {@link #graphId()} of all graphs that were
+     *         incorporated into this one (e.g. by inlining).
+     */
+    public Set<Long> getLeafGraphIds() {
+        return leafGraphIds;
+    }
+
     @Override
     public StructuredGraph copy() {
         return copy(name);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java	Fri Feb 01 17:32:59 2013 +0100
@@ -56,7 +56,7 @@
         ResolvedJavaMethod boxingMethod = pool.getBoxingMethod(sourceKind);
         MethodCallTargetNode callTarget = graph().add(
                         new MethodCallTargetNode(InvokeKind.Static, boxingMethod, new ValueNode[]{source}, boxingMethod.getSignature().getReturnType(boxingMethod.getDeclaringClass())));
-        InvokeNode invokeNode = graph().add(new InvokeNode(callTarget, bci, -1));
+        InvokeNode invokeNode = graph().add(new InvokeNode(callTarget, bci));
         invokeNode.setProbability(this.probability());
         invokeNode.setStateAfter(stateAfter());
         ((StructuredGraph) graph()).replaceFixedWithFixed(this, invokeNode);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeAccessNode.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeAccessNode.java	Fri Feb 01 17:32:59 2013 +0100
@@ -33,13 +33,11 @@
 
     @Input private ValueNode object;
     @Input private LocationNode location;
-    private final long leafGraphId;
 
-    public SafeAccessNode(ValueNode object, LocationNode location, Stamp stamp, long leafGraphId) {
+    public SafeAccessNode(ValueNode object, LocationNode location, Stamp stamp) {
         super(stamp);
         this.object = object;
         this.location = location;
-        this.leafGraphId = leafGraphId;
     }
 
     public ValueNode object() {
@@ -49,8 +47,4 @@
     public LocationNode location() {
         return location;
     }
-
-    public long leafGraphId() {
-        return leafGraphId;
-    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeReadNode.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeReadNode.java	Fri Feb 01 17:32:59 2013 +0100
@@ -32,15 +32,15 @@
  */
 public class SafeReadNode extends SafeAccessNode implements Lowerable {
 
-    public SafeReadNode(ValueNode object, LocationNode location, Stamp stamp, long leafGraphId) {
-        super(object, location, stamp, leafGraphId);
+    public SafeReadNode(ValueNode object, LocationNode location, Stamp stamp) {
+        super(object, location, stamp);
         assert object != null && location != null;
     }
 
     @Override
     public void lower(LoweringTool tool) {
         StructuredGraph graph = (StructuredGraph) graph();
-        ValueNode guard = tool.createNullCheckGuard(object(), leafGraphId());
+        ValueNode guard = tool.createNullCheckGuard(object());
         ReadNode read = graph.add(new ReadNode(object(), location(), stamp()));
         read.dependencies().add(guard);
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeWriteNode.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeWriteNode.java	Fri Feb 01 17:32:59 2013 +0100
@@ -49,8 +49,8 @@
         return true;
     }
 
-    public SafeWriteNode(ValueNode object, ValueNode value, LocationNode location, long leafGraphId) {
-        super(object, location, StampFactory.forVoid(), leafGraphId);
+    public SafeWriteNode(ValueNode object, ValueNode value, LocationNode location) {
+        super(object, location, StampFactory.forVoid());
         this.value = value;
     }
 
@@ -61,7 +61,7 @@
     @Override
     public void lower(LoweringTool tool) {
         StructuredGraph graph = (StructuredGraph) graph();
-        ValueNode guard = tool.createNullCheckGuard(object(), leafGraphId());
+        ValueNode guard = tool.createNullCheckGuard(object());
         WriteNode write = graph.add(new WriteNode(object(), value(), location()));
         write.dependencies().add(guard);
         graph.replaceFixedWithFixed(this, write);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java	Fri Feb 01 17:32:59 2013 +0100
@@ -52,7 +52,7 @@
 
     public void expand(BoxingMethodPool pool) {
         ResolvedJavaField field = pool.getBoxField(kind());
-        LoadFieldNode loadField = graph().add(new LoadFieldNode(source, field, StructuredGraph.INVALID_GRAPH_ID));
+        LoadFieldNode loadField = graph().add(new LoadFieldNode(source, field));
         loadField.setProbability(probability());
         ((StructuredGraph) graph()).replaceFixedWithFixed(this, loadField);
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Fri Feb 01 17:32:59 2013 +0100
@@ -85,7 +85,7 @@
                     ResolvedJavaType receiverType = receiverStamp.type();
                     ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(displacement());
                     if (field != null) {
-                        return this.graph().add(new LoadFieldNode(object(), field, StructuredGraph.INVALID_GRAPH_ID));
+                        return this.graph().add(new LoadFieldNode(object(), field));
                     }
                 }
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Fri Feb 01 17:32:59 2013 +0100
@@ -105,7 +105,7 @@
                     ResolvedJavaType receiverType = receiverStamp.type();
                     ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(displacement());
                     if (field != null) {
-                        return this.graph().add(new StoreFieldNode(object(), field, value(), StructuredGraph.INVALID_GRAPH_ID));
+                        return this.graph().add(new StoreFieldNode(object(), field, value()));
                     }
                 }
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java	Fri Feb 01 17:32:59 2013 +0100
@@ -37,7 +37,6 @@
     @Input private ValueNode object;
 
     protected final ResolvedJavaField field;
-    private final long leafGraphId;
 
     public ValueNode object() {
         return object;
@@ -49,11 +48,10 @@
      * @param object the instruction producing the receiver object
      * @param field the compiler interface representation of the field
      */
-    public AccessFieldNode(Stamp stamp, ValueNode object, ResolvedJavaField field, long leafGraphId) {
+    public AccessFieldNode(Stamp stamp, ValueNode object, ResolvedJavaField field) {
         super(stamp);
         this.object = object;
         this.field = field;
-        this.leafGraphId = leafGraphId;
         assert field.getDeclaringClass().isInitialized();
     }
 
@@ -66,10 +64,6 @@
         return field;
     }
 
-    public long leafGraphId() {
-        return leafGraphId;
-    }
-
     /**
      * Checks whether this field access is an access to a static field.
      * 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java	Fri Feb 01 17:32:59 2013 +0100
@@ -35,7 +35,6 @@
 
     @Input private ValueNode index;
     private final Kind elementType;
-    private final long leafGraphId;
 
     public ValueNode index() {
         return index;
@@ -49,11 +48,10 @@
      * @param index the instruction producing the index
      * @param elementKind the type of the elements of the array
      */
-    protected AccessIndexedNode(Stamp stamp, ValueNode array, ValueNode index, Kind elementKind, long leafGraphId) {
+    protected AccessIndexedNode(Stamp stamp, ValueNode array, ValueNode index, Kind elementKind) {
         super(stamp, array);
         this.index = index;
         this.elementType = elementKind;
-        this.leafGraphId = leafGraphId;
     }
 
     /**
@@ -65,10 +63,6 @@
         return elementType;
     }
 
-    public long leafGraphId() {
-        return leafGraphId;
-    }
-
     @Override
     public void lower(LoweringTool tool) {
         tool.getRuntime().lower(this, tool);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Fri Feb 01 17:32:59 2013 +0100
@@ -41,8 +41,8 @@
      * @param object the receiver object
      * @param field the compiler interface field
      */
-    public LoadFieldNode(ValueNode object, ResolvedJavaField field, long leafGraphId) {
-        super(createStamp(field), object, field, leafGraphId);
+    public LoadFieldNode(ValueNode object, ResolvedJavaField field) {
+        super(createStamp(field), object, field);
     }
 
     private static Stamp createStamp(ResolvedJavaField field) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java	Fri Feb 01 17:32:59 2013 +0100
@@ -40,8 +40,8 @@
      * @param index the instruction producing the index
      * @param elementKind the element type
      */
-    public LoadIndexedNode(ValueNode array, ValueNode index, Kind elementKind, long leafGraphId) {
-        super(createStamp(array, elementKind), array, index, elementKind, leafGraphId);
+    public LoadIndexedNode(ValueNode array, ValueNode index, Kind elementKind) {
+        super(createStamp(array, elementKind), array, index, elementKind);
     }
 
     private static Stamp createStamp(ValueNode array, Kind kind) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java	Fri Feb 01 17:32:59 2013 +0100
@@ -63,8 +63,8 @@
      * @param field the compiler interface field
      * @param value the node representing the value to store to the field
      */
-    public StoreFieldNode(ValueNode object, ResolvedJavaField field, ValueNode value, long leafGraphId) {
-        super(StampFactory.forVoid(), object, field, leafGraphId);
+    public StoreFieldNode(ValueNode object, ResolvedJavaField field, ValueNode value) {
+        super(StampFactory.forVoid(), object, field);
         this.value = value;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java	Fri Feb 01 17:32:59 2013 +0100
@@ -61,8 +61,8 @@
      * @param elementKind the element type
      * @param value the value to store into the array
      */
-    public StoreIndexedNode(ValueNode array, ValueNode index, Kind elementKind, ValueNode value, long leafGraphId) {
-        super(StampFactory.forVoid(), array, index, elementKind, leafGraphId);
+    public StoreIndexedNode(ValueNode array, ValueNode index, Kind elementKind, ValueNode value) {
+        super(StampFactory.forVoid(), array, index, elementKind);
         this.value = value;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java	Fri Feb 01 17:32:59 2013 +0100
@@ -109,7 +109,7 @@
 
     public abstract void emitDeoptimizeOnOverflow(DeoptimizationAction action, DeoptimizationReason reason, Object deoptInfo);
 
-    public abstract void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason, Object deoptInfo, long leafGraphId);
+    public abstract void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason, Object deoptInfo);
 
     public abstract Value emitCall(RuntimeCallTarget callTarget, CallingConvention cc, boolean canTrap, Value... args);
 
@@ -117,7 +117,7 @@
 
     public abstract void emitConditional(ConditionalNode i);
 
-    public abstract void emitGuardCheck(BooleanNode comp, DeoptimizationReason deoptReason, DeoptimizationAction deoptAction, boolean negated, long leafGraphId);
+    public abstract void emitGuardCheck(BooleanNode comp, DeoptimizationReason deoptReason, DeoptimizationAction deoptAction, boolean negated);
 
     public abstract void emitSwitch(SwitchNode i);
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java	Fri Feb 01 17:32:59 2013 +0100
@@ -34,11 +34,11 @@
 
     GraalCodeCacheProvider getRuntime();
 
-    ValueNode createNullCheckGuard(ValueNode object, long leafGraphId);
+    ValueNode createNullCheckGuard(ValueNode object);
 
-    ValueNode createGuard(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, long leafGraphId);
+    ValueNode createGuard(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action);
 
-    ValueNode createGuard(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated, long leafGraphId);
+    ValueNode createGuard(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated);
 
     Assumptions assumptions();
 
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java	Fri Feb 01 17:32:59 2013 +0100
@@ -93,7 +93,7 @@
             BeginNode ifBlockBegin = findBeginNode(ifNode);
             Debug.log("Converting %s on %-5s branch of %s to guard for remaining branch %s. IfBegin=%s", deopt, deoptBegin == ifNode.trueSuccessor() ? "true" : "false", ifNode, otherBegin,
                             ifBlockBegin);
-            FixedGuardNode guard = graph.add(new FixedGuardNode(conditionNode, deopt.reason(), deopt.action(), negated, deopt.leafGraphId()));
+            FixedGuardNode guard = graph.add(new FixedGuardNode(conditionNode, deopt.reason(), deopt.action(), negated));
             otherBegin.replaceAtUsages(ifBlockBegin);
             FixedNode next = otherBegin.next();
             otherBegin.setNext(null);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertUnreachedToGuardPhase.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertUnreachedToGuardPhase.java	Fri Feb 01 17:32:59 2013 +0100
@@ -59,7 +59,7 @@
                 }
                 if (insertGuard != null) {
                     GuardNode guard = graph.unique(new GuardNode(ifNode.condition(), BeginNode.prevBegin(ifNode), DeoptimizationReason.UnreachedCode, DeoptimizationAction.InvalidateReprofile,
-                                    inverted, ifNode.leafGraphId()));
+                                    inverted));
                     graph.addBeforeFixed(ifNode, graph.add(new ValueAnchorNode(guard)));
                     GraphUtil.killCFG(delete);
                     graph.removeSplit(ifNode, inverted ? ifNode.falseSuccessor() : ifNode.trueSuccessor());
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/EliminatePartiallyRedundantGuardsPhase.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/EliminatePartiallyRedundantGuardsPhase.java	Fri Feb 01 17:32:59 2013 +0100
@@ -37,7 +37,6 @@
 
     private static final DebugMetric metricPRGuardsEliminatedAtMerge = Debug.metric("PRGuardsEliminatedAtMerge");
     private static final DebugMetric metricPRGuardsEliminatedAtSplit = Debug.metric("PRGuardsEliminatedAtSplit");
-    private static final DebugMetric metricPRGuardsDifferentGraphId = Debug.metric("PRGuardsDifferentGraphId");
 
     private final boolean eliminateAtSplit;
     private final boolean eliminateAtMerge;
@@ -142,7 +141,7 @@
         for (GuardNode guard : hits) {
             PhiNode phi = graph.add(new PhiNode(PhiType.Guard, merge));
             for (EndNode otherEnd : merge.forwardEnds()) {
-                phi.addInput(graph.unique(new GuardNode(guard.condition(), BeginNode.prevBegin(otherEnd), guard.reason(), guard.action(), guard.negated(), guard.getLeafGraphId())));
+                phi.addInput(graph.unique(new GuardNode(guard.condition(), BeginNode.prevBegin(otherEnd), guard.reason(), guard.action(), guard.negated())));
             }
             guard.replaceAndDelete(phi);
             metricPRGuardsEliminatedAtMerge.increment();
@@ -176,7 +175,6 @@
             }
             DeoptimizationReason reason = null;
             DeoptimizationAction action = DeoptimizationAction.None;
-            long leafGraphId = -1;
             Set<BeginNode> begins = new HashSet<>(3);
             for (GuardNode guard : guards) {
                 BeginNode begin = (BeginNode) guard.dependencies().first();
@@ -189,21 +187,11 @@
                 } else if (reason != guard.reason()) {
                     reason = DeoptimizationReason.None;
                 }
-                if (leafGraphId == -1) {
-                    leafGraphId = guard.getLeafGraphId();
-                } else if (leafGraphId != guard.getLeafGraphId()) {
-                    metricPRGuardsDifferentGraphId.increment();
-                    leafGraphId = -1;
-                    break;
-                }
-            }
-            if (leafGraphId < 0) {
-                continue;
             }
             if (begins.size() == controlSplit.successors().count()) {
                 hits = true;
                 Condition condition = entry.getKey();
-                GuardNode newGuard = controlSplit.graph().unique(new GuardNode(condition.conditionNode, BeginNode.prevBegin(controlSplit), reason, action, condition.negated, leafGraphId));
+                GuardNode newGuard = controlSplit.graph().unique(new GuardNode(condition.conditionNode, BeginNode.prevBegin(controlSplit), reason, action, condition.negated));
                 for (GuardNode guard : guards) {
                     guard.replaceAndDelete(newGuard);
                     metricPRGuardsEliminatedAtSplit.increment();
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Fri Feb 01 17:32:59 2013 +0100
@@ -49,9 +49,9 @@
     private static final String inliningDecisionsScopeString = "InliningDecisions";
 
     /**
-     * Meters the size (in bytecodes) of all methods processed during compilation (i.e., top level and all
-     * inlined methods), irrespective of how many bytecodes in each method are actually parsed
-     * (which may be none for methods whose IR is retrieved from a cache).
+     * Meters the size (in bytecodes) of all methods processed during compilation (i.e., top level
+     * and all inlined methods), irrespective of how many bytecodes in each method are actually
+     * parsed (which may be none for methods whose IR is retrieved from a cache).
      */
     public static final DebugMetric InlinedBytecodes = Debug.metric("InlinedBytecodes");
 
@@ -227,8 +227,8 @@
 
         protected static void inline(Invoke invoke, ResolvedJavaMethod concrete, InliningCallback callback, Assumptions assumptions, boolean receiverNullCheck) {
             Class<? extends FixedWithNextNode> macroNodeClass = getMacroNodeClass(concrete);
+            StructuredGraph graph = (StructuredGraph) invoke.graph();
             if (macroNodeClass != null) {
-                StructuredGraph graph = (StructuredGraph) invoke.graph();
                 FixedWithNextNode macroNode;
                 try {
                     macroNode = macroNodeClass.getConstructor(Invoke.class).newInstance(invoke);
@@ -253,6 +253,10 @@
                 InlinedBytecodes.add(concrete.getCodeSize());
                 assumptions.recordMethodContents(concrete);
                 InliningUtil.inline(invoke, calleeGraph, receiverNullCheck);
+
+                graph.getLeafGraphIds().add(calleeGraph.graphId());
+                // we might at some point cache already-inlined graphs, so add recursively:
+                graph.getLeafGraphIds().addAll(calleeGraph.getLeafGraphIds());
             }
         }
 
@@ -326,7 +330,7 @@
             ConstantNode typeHub = ConstantNode.forConstant(type.getEncoding(Representation.ObjectHub), runtime, graph);
             LoadHubNode receiverHub = graph.add(new LoadHubNode(receiver, typeHub.kind()));
             CompareNode typeCheck = CompareNode.createCompareNode(Condition.EQ, receiverHub, typeHub);
-            FixedGuardNode guard = graph.add(new FixedGuardNode(typeCheck, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile, invoke.leafGraphId()));
+            FixedGuardNode guard = graph.add(new FixedGuardNode(typeCheck, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile));
             ValueAnchorNode anchor = graph.add(new ValueAnchorNode());
             assert invoke.predecessor() != null;
 
@@ -444,7 +448,7 @@
             if (shouldFallbackToInvoke()) {
                 unknownTypeSux = createInvocationBlock(graph, invoke, returnMerge, returnValuePhi, exceptionMerge, exceptionObjectPhi, notRecordedTypeProbability, false);
             } else {
-                unknownTypeSux = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TypeCheckedInliningViolated, invoke.leafGraphId()));
+                unknownTypeSux = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TypeCheckedInliningViolated));
             }
             successors[successors.length - 1] = BeginNode.begin(unknownTypeSux);
 
@@ -549,7 +553,7 @@
             LoadHubNode receiverHub = graph.add(new LoadHubNode(invoke.methodCallTarget().receiver(), hubKind));
             graph.addBeforeFixed(invoke.node(), receiverHub);
 
-            BeginNode unknownTypeSux = BeginNode.begin(graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TypeCheckedInliningViolated, invoke.leafGraphId())));
+            BeginNode unknownTypeSux = BeginNode.begin(graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TypeCheckedInliningViolated)));
             BeginNode[] successors = new BeginNode[]{calleeEntryNode, unknownTypeSux};
             FixedNode dispatchOnType = createDispatchOnType(graph, receiverHub, successors);
 
@@ -966,10 +970,8 @@
                 }
             }
         }
-        replacements.put(entryPointNode, BeginNode.prevBegin(invoke.node())); // ensure proper
-                                                                              // anchoring of things
-                                                                              // that were anchored
-                                                                              // to the StartNode
+        // ensure proper anchoring of things that were anchored to the StartNode
+        replacements.put(entryPointNode, BeginNode.prevBegin(invoke.node()));
 
         assert invoke.node().successors().first() != null : invoke;
         assert invoke.node().predecessor() != null;
@@ -1001,7 +1003,7 @@
         } else {
             if (unwindNode != null) {
                 UnwindNode unwindDuplicate = (UnwindNode) duplicates.get(unwindNode);
-                DeoptimizeNode deoptimizeNode = new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.NotCompiledExceptionHandler, invoke.leafGraphId());
+                DeoptimizeNode deoptimizeNode = new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.NotCompiledExceptionHandler);
                 unwindDuplicate.replaceAndDelete(graph.add(deoptimizeNode));
                 // move the deopt upwards if there is a monitor exit that tries to use the
                 // "after exception" frame state
@@ -1091,8 +1093,8 @@
         NodeInputList<ValueNode> parameters = callTarget.arguments();
         ValueNode firstParam = parameters.size() <= 0 ? null : parameters.get(0);
         if (!callTarget.isStatic() && firstParam.kind() == Kind.Object && !firstParam.objectStamp().nonNull()) {
-            graph.addBeforeFixed(invoke.node(), graph.add(new FixedGuardNode(graph.unique(new IsNullNode(firstParam)), DeoptimizationReason.NullCheckException,
-                            DeoptimizationAction.InvalidateReprofile, true, invoke.leafGraphId())));
+            graph.addBeforeFixed(invoke.node(),
+                            graph.add(new FixedGuardNode(graph.unique(new IsNullNode(firstParam)), DeoptimizationReason.NullCheckException, DeoptimizationAction.InvalidateReprofile, true)));
         }
     }
 
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Fri Feb 01 17:32:59 2013 +0100
@@ -65,13 +65,13 @@
         }
 
         @Override
-        public ValueNode createNullCheckGuard(ValueNode object, long leafGraphId) {
-            return createGuard(object.graph().unique(new IsNullNode(object)), DeoptimizationReason.NullCheckException, DeoptimizationAction.InvalidateReprofile, true, leafGraphId);
+        public ValueNode createNullCheckGuard(ValueNode object) {
+            return createGuard(object.graph().unique(new IsNullNode(object)), DeoptimizationReason.NullCheckException, DeoptimizationAction.InvalidateReprofile, true);
         }
 
         @Override
-        public ValueNode createGuard(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, long leafGraphId) {
-            return createGuard(condition, deoptReason, action, false, leafGraphId);
+        public ValueNode createGuard(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action) {
+            return createGuard(condition, deoptReason, action, false);
         }
 
         @Override
@@ -80,7 +80,7 @@
         }
 
         @Override
-        public ValueNode createGuard(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated, long leafGraphId) {
+        public ValueNode createGuard(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) {
             if (GraalOptions.OptEliminateGuards) {
                 for (Node usage : condition.usages()) {
                     if (!activeGuards.isNew(usage) && activeGuards.isMarked(usage)) {
@@ -88,7 +88,7 @@
                     }
                 }
             }
-            GuardNode newGuard = guardAnchor.graph().unique(new GuardNode(condition, guardAnchor, deoptReason, action, negated, leafGraphId));
+            GuardNode newGuard = guardAnchor.graph().unique(new GuardNode(condition, guardAnchor, deoptReason, action, negated));
             if (GraalOptions.OptEliminateGuards) {
                 activeGuards.grow();
                 activeGuards.mark(newGuard);
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BranchProbabilityNode.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BranchProbabilityNode.java	Fri Feb 01 17:32:59 2013 +0100
@@ -64,9 +64,9 @@
         assert begin.predecessor() instanceof IfNode : "explicit branch probability cannot follow a merge, only if nodes";
         IfNode ifNode = (IfNode) begin.predecessor();
         if (ifNode.trueSuccessor() == begin) {
-            ifNode.setTakenProbability(probability);
+            ifNode.setTrueSuccessorProbability(probability);
         } else {
-            ifNode.setTakenProbability(1 - probability);
+            ifNode.setTrueSuccessorProbability(1 - probability);
         }
 
         FixedNode next = next();
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/MacroNode.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/MacroNode.java	Fri Feb 01 17:32:59 2013 +0100
@@ -62,7 +62,7 @@
     protected InvokeNode createInvoke() {
         InvokeKind invokeKind = Modifier.isStatic(targetMethod.getModifiers()) ? InvokeKind.Static : InvokeKind.Special;
         MethodCallTargetNode callTarget = graph().add(new MethodCallTargetNode(invokeKind, targetMethod, arguments.toArray(new ValueNode[arguments.size()]), returnType));
-        InvokeNode invoke = graph().add(new InvokeNode(callTarget, bci, StructuredGraph.INVALID_GRAPH_ID));
+        InvokeNode invoke = graph().add(new InvokeNode(callTarget, bci));
         invoke.setStateAfter(stateAfter());
         return invoke;
     }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/CyclicMaterializeStoreNode.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/CyclicMaterializeStoreNode.java	Fri Feb 01 17:32:59 2013 +0100
@@ -76,10 +76,10 @@
         ResolvedJavaType type = object.objectStamp().type();
         FixedWithNextNode store;
         if (target instanceof Integer) {
-            store = graph.add(new StoreIndexedNode(object, ConstantNode.forInt((int) target, graph), type.getComponentType().getKind(), value, -1));
+            store = graph.add(new StoreIndexedNode(object, ConstantNode.forInt((int) target, graph), type.getComponentType().getKind(), value));
         } else {
             assert target instanceof ResolvedJavaField;
-            store = graph.add(new StoreFieldNode(object, (ResolvedJavaField) target, value, -1));
+            store = graph.add(new StoreFieldNode(object, (ResolvedJavaField) target, value));
         }
         graph.replaceFixedWithFixed(this, store);
     }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/MaterializeObjectNode.java	Fri Feb 01 15:18:22 2013 +0100
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/MaterializeObjectNode.java	Fri Feb 01 17:32:59 2013 +0100
@@ -88,7 +88,7 @@
 
             if (!defaultEntries) {
                 for (int i = 0; i < virtual.entryCount(); i++) {
-                    graph.addBeforeFixed(this, graph.add(new StoreFieldNode(newInstance, virtual.field(i), values.get(i), -1)));
+                    graph.addBeforeFixed(this, graph.add(new StoreFieldNode(newInstance, virtual.field(i), values.get(i))));
                 }
             }
         } else {
@@ -107,7 +107,7 @@
 
             if (!defaultEntries) {
                 for (int i = 0; i < virtual.entryCount(); i++) {
-                    graph.addBeforeFixed(this, graph.add(new StoreIndexedNode(newArray, ConstantNode.forInt(i, graph), element.getKind(), values.get(i), -1)));
+                    graph.addBeforeFixed(this, graph.add(new StoreIndexedNode(newArray, ConstantNode.forInt(i, graph), element.getKind(), values.get(i))));
                 }
             }
         }
--- a/src/share/vm/code/debugInfoRec.cpp	Fri Feb 01 15:18:22 2013 +0100
+++ b/src/share/vm/code/debugInfoRec.cpp	Fri Feb 01 17:32:59 2013 +0100
@@ -127,14 +127,14 @@
   _oopmaps->add_gc_map(pc_offset, map);
 }
 
-void DebugInformationRecorder::add_safepoint(int pc_offset, jlong leaf_graph_id, OopMap* map) {
+void DebugInformationRecorder::add_safepoint(int pc_offset, OopMap* map) {
   assert(!_oop_recorder->is_complete(), "not frozen yet");
   // Store the new safepoint
 
   // Add the oop map
   add_oopmap(pc_offset, map);
 
-  add_new_pc_offset(pc_offset, leaf_graph_id);
+  add_new_pc_offset(pc_offset);
 
   assert(_recording_state == rs_null, "nesting of recording calls");
   debug_only(_recording_state = rs_safepoint);
@@ -150,7 +150,7 @@
   debug_only(_recording_state = rs_non_safepoint);
 }
 
-void DebugInformationRecorder::add_new_pc_offset(int pc_offset, jlong leaf_graph_id) {
+void DebugInformationRecorder::add_new_pc_offset(int pc_offset) {
   assert(_pcs_length == 0 || last_pc()->pc_offset() < pc_offset,
          "must specify a new, larger pc offset");
 
@@ -168,7 +168,7 @@
   assert(_pcs_size > _pcs_length, "There must be room for after expanding");
 
   _pcs[_pcs_length++] = PcDesc(pc_offset, DebugInformationRecorder::serialized_null,
-                               DebugInformationRecorder::serialized_null, leaf_graph_id);
+                               DebugInformationRecorder::serialized_null);
 }
 
 
--- a/src/share/vm/code/debugInfoRec.hpp	Fri Feb 01 15:18:22 2013 +0100
+++ b/src/share/vm/code/debugInfoRec.hpp	Fri Feb 01 17:32:59 2013 +0100
@@ -82,7 +82,7 @@
   void add_oopmap(int pc_offset, OopMap* map);
 
   // adds a jvm mapping at pc-offset, for a safepoint only
-  void add_safepoint(int pc_offset, jlong leaf_graph_id, OopMap* map);
+  void add_safepoint(int pc_offset, OopMap* map);
 
   // adds a jvm mapping at pc-offset, for a non-safepoint (profile point)
   void add_non_safepoint(int pc_offset);
@@ -196,7 +196,7 @@
     guarantee(_pcs_length > 1, "a safepoint must be declared already");
     return &_pcs[_pcs_length-2];
   }
-  void add_new_pc_offset(int pc_offset, jlong leaf_graph_id = -1);
+  void add_new_pc_offset(int pc_offset);
   void end_scopes(int pc_offset, bool is_safepoint);
 
   int  serialize_monitor_values(GrowableArray<MonitorValue*>* monitors);
--- a/src/share/vm/code/nmethod.cpp	Fri Feb 01 15:18:22 2013 +0100
+++ b/src/share/vm/code/nmethod.cpp	Fri Feb 01 17:32:59 2013 +0100
@@ -586,7 +586,8 @@
   ExceptionHandlerTable* handler_table,
   ImplicitExceptionTable* nul_chk_table,
   AbstractCompiler* compiler,
-  int comp_level
+  int comp_level,
+  GrowableArray<jlong>* leaf_graph_ids
 #ifdef GRAAL
   , Handle installed_code
 #endif
@@ -594,6 +595,7 @@
 {
   assert(debug_info->oop_recorder() == code_buffer->oop_recorder(), "shared OR");
   code_buffer->finalize_oop_references(method);
+  size_t leaf_graph_ids_size = leaf_graph_ids == NULL ? 0 : round_to(sizeof(jlong) * leaf_graph_ids->length(), oopSize);
   // create nmethod
   nmethod* nm = NULL;
   { MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
@@ -603,7 +605,8 @@
       + round_to(dependencies->size_in_bytes() , oopSize)
       + round_to(handler_table->size_in_bytes(), oopSize)
       + round_to(nul_chk_table->size_in_bytes(), oopSize)
-      + round_to(debug_info->data_size()       , oopSize);
+      + round_to(debug_info->data_size()       , oopSize)
+      + leaf_graph_ids_size;
     nm = new (nmethod_size)
       nmethod(method(), nmethod_size, compile_id, entry_bci, offsets,
               orig_pc_offset, debug_info, dependencies, code_buffer, frame_size,
@@ -611,7 +614,8 @@
               handler_table,
               nul_chk_table,
               compiler,
-              comp_level
+              comp_level,
+              leaf_graph_ids
 #ifdef GRAAL
               , installed_code
 #endif
@@ -693,7 +697,8 @@
     _dependencies_offset     = _scopes_pcs_offset;
     _handler_table_offset    = _dependencies_offset;
     _nul_chk_table_offset    = _handler_table_offset;
-    _nmethod_end_offset      = _nul_chk_table_offset;
+    _leaf_graph_ids_offset   = _nul_chk_table_offset;
+    _nmethod_end_offset      = _leaf_graph_ids_offset;
     _compile_id              = compile_id;
     _comp_level              = CompLevel_none;
     _entry_point             = code_begin()          + offsets->value(CodeOffsets::Entry);
@@ -839,7 +844,8 @@
   ExceptionHandlerTable* handler_table,
   ImplicitExceptionTable* nul_chk_table,
   AbstractCompiler* compiler,
-  int comp_level
+  int comp_level,
+  GrowableArray<jlong>* leaf_graph_ids
 #ifdef GRAAL
   , Handle installed_code
 #endif
@@ -905,6 +911,8 @@
       _unwind_handler_offset = -1;
     }
 
+    size_t leaf_graph_ids_size = leaf_graph_ids == NULL ? 0 : round_to(sizeof(jlong) * leaf_graph_ids->length(), oopSize);
+
     _oops_offset             = data_offset();
     _metadata_offset         = _oops_offset          + round_to(code_buffer->total_oop_size(), oopSize);
     _scopes_data_offset      = _metadata_offset      + round_to(code_buffer->total_metadata_size(), wordSize);
@@ -913,7 +921,8 @@
     _dependencies_offset     = _scopes_pcs_offset    + adjust_pcs_size(debug_info->pcs_size());
     _handler_table_offset    = _dependencies_offset  + round_to(dependencies->size_in_bytes (), oopSize);
     _nul_chk_table_offset    = _handler_table_offset + round_to(handler_table->size_in_bytes(), oopSize);
-    _nmethod_end_offset      = _nul_chk_table_offset + round_to(nul_chk_table->size_in_bytes(), oopSize);
+    _leaf_graph_ids_offset   = _nul_chk_table_offset + round_to(nul_chk_table->size_in_bytes(), oopSize);
+    _nmethod_end_offset      = _leaf_graph_ids_offset + leaf_graph_ids_size;
 
     _entry_point             = code_begin()          + offsets->value(CodeOffsets::Entry);
     _verified_entry_point    = code_begin()          + offsets->value(CodeOffsets::Verified_Entry);
@@ -936,6 +945,10 @@
     handler_table->copy_to(this);
     nul_chk_table->copy_to(this);
 
+    if (leaf_graph_ids != NULL && leaf_graph_ids_size > 0) {
+      memcpy(leaf_graph_ids_begin(), leaf_graph_ids->adr_at(0), leaf_graph_ids_size);
+    }
+
     // we use the information of entry points to find out if a method is
     // static or non static
     assert(compiler->is_c2() ||
--- a/src/share/vm/code/nmethod.hpp	Fri Feb 01 15:18:22 2013 +0100
+++ b/src/share/vm/code/nmethod.hpp	Fri Feb 01 17:32:59 2013 +0100
@@ -159,6 +159,7 @@
   int _dependencies_offset;
   int _handler_table_offset;
   int _nul_chk_table_offset;
+  int _leaf_graph_ids_offset;
   int _nmethod_end_offset;
 
   // location in frame (offset for sp) that deopt can store the original
@@ -267,9 +268,10 @@
           ExceptionHandlerTable* handler_table,
           ImplicitExceptionTable* nul_chk_table,
           AbstractCompiler* compiler,
-          int comp_level
+          int comp_level,
+          GrowableArray<jlong>* leaf_graph_ids
 #ifdef GRAAL
-          , Handle installed_code = NULL
+          , Handle installed_code
 #endif
           );
 
@@ -307,7 +309,8 @@
                               ExceptionHandlerTable* handler_table,
                               ImplicitExceptionTable* nul_chk_table,
                               AbstractCompiler* compiler,
-                              int comp_level
+                              int comp_level,
+                              GrowableArray<jlong>* leaf_graph_ids = NULL
 #ifdef GRAAL
                               , Handle installed_code = NULL
 #endif
@@ -383,7 +386,9 @@
   address handler_table_begin   () const          { return           header_begin() + _handler_table_offset ; }
   address handler_table_end     () const          { return           header_begin() + _nul_chk_table_offset ; }
   address nul_chk_table_begin   () const          { return           header_begin() + _nul_chk_table_offset ; }
-  address nul_chk_table_end     () const          { return           header_begin() + _nmethod_end_offset   ; }
+  address nul_chk_table_end     () const          { return           header_begin() + _leaf_graph_ids_offset; }
+  jlong*  leaf_graph_ids_begin  () const          { return  (jlong*)(header_begin() + _leaf_graph_ids_offset); }
+  jlong*  leaf_graph_ids_end    () const          { return  (jlong*)(header_begin() + _nmethod_end_offset)  ; }
 
   // Sizes
   int consts_size       () const                  { return            consts_end       () -            consts_begin       (); }
--- a/src/share/vm/code/pcDesc.cpp	Fri Feb 01 15:18:22 2013 +0100
+++ b/src/share/vm/code/pcDesc.cpp	Fri Feb 01 17:32:59 2013 +0100
@@ -29,12 +29,11 @@
 #include "code/scopeDesc.hpp"
 #include "memory/resourceArea.hpp"
 
-PcDesc::PcDesc(int pc_offset, int scope_decode_offset, int obj_decode_offset, jlong leaf_graph_id) {
+PcDesc::PcDesc(int pc_offset, int scope_decode_offset, int obj_decode_offset) {
   _pc_offset           = pc_offset;
   _scope_decode_offset = scope_decode_offset;
   _obj_decode_offset   = obj_decode_offset;
   _flags               = 0;
-  GRAAL_ONLY(_leaf_graph_id = leaf_graph_id);
 }
 
 address PcDesc::real_pc(const nmethod* code) const {
@@ -44,11 +43,7 @@
 void PcDesc::print(nmethod* code) {
 #ifndef PRODUCT
   ResourceMark rm;
-  if (code->is_compiled_by_graal()) {
-    tty->print_cr("PcDesc(pc=0x%lx offset=%x bits=%x leaf_graph_id=%d):", real_pc(code), pc_offset(), _flags, leaf_graph_id());
-  } else {
-    tty->print_cr("PcDesc(pc=0x%lx offset=%x bits=%x):", real_pc(code), pc_offset(), _flags);
-  }
+  tty->print_cr("PcDesc(pc=0x%lx offset=%x bits=%x):", real_pc(code), pc_offset(), _flags);
 
   if (scope_decode_offset() == DebugInformationRecorder::serialized_null) {
     return;
--- a/src/share/vm/code/pcDesc.hpp	Fri Feb 01 15:18:22 2013 +0100
+++ b/src/share/vm/code/pcDesc.hpp	Fri Feb 01 17:32:59 2013 +0100
@@ -38,7 +38,6 @@
   int _pc_offset;           // offset from start of nmethod
   int _scope_decode_offset; // offset for scope in nmethod
   int _obj_decode_offset;
-  GRAAL_ONLY(jlong _leaf_graph_id;)
 
   enum {
     PCDESC_reexecute               = 1 << 0,
@@ -57,7 +56,6 @@
   int pc_offset() const           { return _pc_offset;   }
   int scope_decode_offset() const { return _scope_decode_offset; }
   int obj_decode_offset() const   { return _obj_decode_offset; }
-  jlong leaf_graph_id() const     { return GRAAL_ONLY(_leaf_graph_id) NOT_GRAAL(-1); }
 
   void set_pc_offset(int x)           { _pc_offset           = x; }
   void set_scope_decode_offset(int x) { _scope_decode_offset = x; }
@@ -65,7 +63,7 @@
 
   // Constructor (only used for static in nmethod.cpp)
   // Also used by ScopeDesc::sender()]
-  PcDesc(int pc_offset, int scope_decode_offset, int obj_decode_offset, jlong leaf_graph_id);
+  PcDesc(int pc_offset, int scope_decode_offset, int obj_decode_offset);
 
   enum {
     // upper and lower exclusive limits real offsets:
@@ -84,7 +82,6 @@
     return _scope_decode_offset == pd->_scope_decode_offset &&
       _obj_decode_offset == pd->_obj_decode_offset &&
       _flags == pd->_flags
-      GRAAL_ONLY(&& _leaf_graph_id == pd->_leaf_graph_id)
       ;
   }
 
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Fri Feb 01 15:18:22 2013 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Fri Feb 01 17:32:59 2013 +0100
@@ -288,6 +288,17 @@
   }
 }
 
+GrowableArray<jlong>* get_leaf_graph_ids(Handle& comp_result) {
+  arrayOop leafGraphArray = (arrayOop) CompilationResult::leafGraphIds(HotSpotCompilationResult::comp(comp_result));
+
+  GrowableArray<jlong>* result = new GrowableArray<jlong>(leafGraphArray->length());
+  for (int i = 0; i < leafGraphArray->length(); i++) {
+    result->append(((jlong*) leafGraphArray->base(T_LONG))[i]);
+  }
+
+  return result;
+}
+
 // constructor used to create a method
 CodeInstaller::CodeInstaller(Handle& comp_result, methodHandle method, GraalEnv::CodeInstallResult& result, nmethod*& nm, Handle installed_code) {
   GraalCompiler::initialize_buffer_blob();
@@ -304,9 +315,10 @@
   }
 
   int stack_slots = _total_frame_size / HeapWordSize; // conversion to words
+  GrowableArray<jlong>* leaf_graph_ids = get_leaf_graph_ids(comp_result);
 
   result = GraalEnv::register_method(method, nm, entry_bci, &_offsets, _custom_stack_area_offset, &buffer, stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table,
-    &_implicit_exception_table, GraalCompiler::instance(), _debug_recorder, _dependencies, NULL, -1, true, false, installed_code);
+    &_implicit_exception_table, GraalCompiler::instance(), _debug_recorder, _dependencies, NULL, -1, true, false, leaf_graph_ids, installed_code);
 
   method->clear_queued_for_compilation();
 }
@@ -552,7 +564,7 @@
 
   // address instruction = _instructions->start() + pc_offset;
   // jint next_pc_offset = Assembler::locate_next_instruction(instruction) - _instructions->start();
-  _debug_recorder->add_safepoint(pc_offset, -1, create_oop_map(_total_frame_size, _parameter_count, debug_info));
+  _debug_recorder->add_safepoint(pc_offset, create_oop_map(_total_frame_size, _parameter_count, debug_info));
 
   oop frame = DebugInfo::bytecodePosition(debug_info);
   if (frame != NULL) {
@@ -615,8 +627,7 @@
 
   if (debug_info != NULL) {
     oop frame = DebugInfo::bytecodePosition(debug_info);
-    jlong leaf_graph_id = frame == NULL ? -1 : BytecodeFrame::leafGraphId(frame);
-    _debug_recorder->add_safepoint(next_pc_offset, leaf_graph_id, create_oop_map(_total_frame_size, _parameter_count, debug_info));
+    _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(_total_frame_size, _parameter_count, debug_info));
     if (frame != NULL) {
       record_scope(next_pc_offset, frame, new GrowableArray<ScopeValue*>());
     } else {
--- a/src/share/vm/graal/graalEnv.cpp	Fri Feb 01 15:18:22 2013 +0100
+++ b/src/share/vm/graal/graalEnv.cpp	Fri Feb 01 17:32:59 2013 +0100
@@ -418,6 +418,7 @@
                                 int compile_id,
                                 bool has_debug_info,
                                 bool has_unsafe_access,
+                                GrowableArray<jlong>* leaf_graph_ids,
                                 Handle installed_code) {
   GRAAL_EXCEPTION_CONTEXT;
   NMethodSweeper::possibly_sweep();
@@ -463,7 +464,7 @@
                                debug_info, dependencies, code_buffer,
                                frame_words, oop_map_set,
                                handler_table, inc_table,
-                               compiler, comp_level, installed_code);
+                               compiler, comp_level, leaf_graph_ids, installed_code);
 
     // Free codeBlobs
     //code_buffer->free_blob();
--- a/src/share/vm/graal/graalEnv.hpp	Fri Feb 01 15:18:22 2013 +0100
+++ b/src/share/vm/graal/graalEnv.hpp	Fri Feb 01 17:32:59 2013 +0100
@@ -146,6 +146,7 @@
                        int                       compile_id,
                        bool                      has_debug_info,
                        bool                      has_unsafe_access,
+                       GrowableArray<jlong>*     leaf_graph_ids,
                        Handle                    installed_code);
 
   // converts the Klass* representing the holder of a method into a
--- a/src/share/vm/graal/graalJavaAccess.hpp	Fri Feb 01 15:18:22 2013 +0100
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Fri Feb 01 17:32:59 2013 +0100
@@ -48,7 +48,7 @@
  */
 
 #define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, boolean_field, long_field, float_field, oop_field, static_oop_field)                \
-  start_class(HotSpotResolvedObjectType)                                                                                                                         \
+  start_class(HotSpotResolvedObjectType)                                                                                                                       \
     long_field(HotSpotResolvedObjectType, metaspaceKlass)                                                                                                      \
     oop_field(HotSpotResolvedObjectType, javaMirror, "Ljava/lang/Class;")                                                                                      \
   end_class                                                                                                                                                    \
@@ -98,6 +98,7 @@
   start_class(CompilationResult)                                                                                                                               \
     int_field(CompilationResult, frameSize)                                                                                                                    \
     int_field(CompilationResult, customStackAreaOffset)                                                                                                        \
+    oop_field(CompilationResult, leafGraphIds, "[J")                                                                                                           \
     oop_field(CompilationResult, targetCode, "[B")                                                                                                             \
     oop_field(CompilationResult, assumptions, "Lcom/oracle/graal/api/code/Assumptions;")                                                                       \
     int_field(CompilationResult, targetCodeSize)                                                                                                               \
@@ -127,7 +128,7 @@
   start_class(CompilationResult_DataPatch)                                                                                                                     \
     oop_field(CompilationResult_DataPatch, constant, "Lcom/oracle/graal/api/meta/Constant;")                                                                   \
     int_field(CompilationResult_DataPatch, alignment)                                                                                                          \
-    boolean_field(CompilationResult_DataPatch, inlined)                                                                                                           \
+    boolean_field(CompilationResult_DataPatch, inlined)                                                                                                        \
   end_class                                                                                                                                                    \
   start_class(CompilationResult_Safepoint)                                                                                                                     \
     oop_field(CompilationResult_Safepoint, debugInfo, "Lcom/oracle/graal/api/code/DebugInfo;")                                                                 \
@@ -152,7 +153,6 @@
     int_field(BytecodeFrame, numLocals)                                                                                                                        \
     int_field(BytecodeFrame, numStack)                                                                                                                         \
     int_field(BytecodeFrame, numLocks)                                                                                                                         \
-    long_field(BytecodeFrame, leafGraphId)                                                                                                                     \
     boolean_field(BytecodeFrame, rethrowException)                                                                                                             \
     boolean_field(BytecodeFrame, duringCall)                                                                                                                   \
   end_class                                                                                                                                                    \
--- a/src/share/vm/runtime/deoptimization.cpp	Fri Feb 01 15:18:22 2013 +0100
+++ b/src/share/vm/runtime/deoptimization.cpp	Fri Feb 01 17:32:59 2013 +0100
@@ -209,13 +209,13 @@
   assert(deoptee.is_compiled_frame(), "Wrong frame type");
 
 #ifdef GRAAL
-  PcDesc* pc_desc = ((nmethod*) deoptee.cb())->pc_desc_at(deoptee.pc());
-  if (pc_desc != NULL && pc_desc->leaf_graph_id() != -1) {
-    GraalCompiler* compiler = (GraalCompiler*) ((nmethod*) deoptee.cb())->compiler();
+  nmethod* nm = (nmethod*) deoptee.cb();
+  GraalCompiler* compiler = (GraalCompiler*) nm->compiler();
+  for (jlong* p = nm->leaf_graph_ids_begin(); p != nm->leaf_graph_ids_end(); p++) {
     if (PrintDeoptimizationDetails) {
-      tty->print_cr("leaf graph id: %d", pc_desc->leaf_graph_id());
+      tty->print_cr("leaf graph id: %d", *p);
     }
-    compiler->deopt_leaf_graph(pc_desc->leaf_graph_id());
+    compiler->deopt_leaf_graph(*p);
   }
 #endif