changeset 16573:a2ec1ac769e4

Add simple infopoint nodes which do not contain debugging informations for values. Use them when shouldDebugNonSafepoints is true.
author Gilles Duboscq <duboscq@ssw.jku.at>
date Fri, 18 Jul 2014 11:14:54 +0200
parents 7531cdfed73c
children 042b5e9aeb76
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodePosition.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/InfopointReason.java graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILNodeLIRBuilder.java graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXNodeLIRBuilder.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeLIRBuilder.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FullInfopointOp.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InfopointOp.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/SimpleInfopointOp.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FullInfopointNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InfopointNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SimpleInfopointNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeLIRBuilderTool.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/graal/graalCodeInstaller.hpp
diffstat 30 files changed, 457 insertions(+), 220 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodePosition.java	Wed Jul 16 14:27:48 2014 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodePosition.java	Fri Jul 18 11:14:54 2014 +0200
@@ -32,7 +32,7 @@
  * system to reconstruct a source-level stack trace for exceptions and to create
  * {@linkplain BytecodeFrame frames} for deoptimization.
  */
-public abstract class BytecodePosition implements Serializable {
+public class BytecodePosition implements Serializable {
 
     private static final long serialVersionUID = 8633885274526033515L;
 
@@ -42,7 +42,7 @@
 
     /**
      * Constructs a new object representing a given parent/caller, a given method, and a given BCI.
-     * 
+     *
      * @param caller the parent position
      * @param method the method
      * @param bci a BCI within the method
@@ -56,7 +56,7 @@
 
     /**
      * Converts this code position to a string representation.
-     * 
+     *
      * @return a string representation of this code position
      */
     @Override
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Wed Jul 16 14:27:48 2014 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Fri Jul 18 11:14:54 2014 +0200
@@ -620,9 +620,24 @@
      */
     public void addInfopoint(Infopoint infopoint) {
         // The infopoints list must always be sorted
-        if (!infopoints.isEmpty() && infopoints.get(infopoints.size() - 1).pcOffset >= infopoint.pcOffset) {
-            // This re-sorting should be very rare
-            Collections.sort(infopoints);
+        if (!infopoints.isEmpty()) {
+            Infopoint previousInfopoint = infopoints.get(infopoints.size() - 1);
+            if (previousInfopoint.pcOffset > infopoint.pcOffset) {
+                // This re-sorting should be very rare
+                Collections.sort(infopoints);
+                previousInfopoint = infopoints.get(infopoints.size() - 1);
+            }
+            if (previousInfopoint.pcOffset == infopoint.pcOffset) {
+                if (infopoint.reason.canBeOmited()) {
+                    return;
+                }
+                if (previousInfopoint.reason.canBeOmited()) {
+                    Infopoint removed = infopoints.remove(infopoints.size() - 1);
+                    assert removed == previousInfopoint;
+                } else {
+                    throw new RuntimeException("Infopoints that can not be omited should have distinct PCs");
+                }
+            }
         }
         infopoints.add(infopoint);
     }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/InfopointReason.java	Wed Jul 16 14:27:48 2014 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/InfopointReason.java	Fri Jul 18 11:14:54 2014 +0200
@@ -26,13 +26,21 @@
  * A reason for infopoint insertion.
  */
 public enum InfopointReason {
+    UNKNOWN(false),
+    SAFEPOINT(false),
+    CALL(false),
+    IMPLICIT_EXCEPTION(false),
+    METHOD_START(true),
+    METHOD_END(true),
+    LINE_NUMBER(true);
 
-    UNKNOWN,
-    SAFEPOINT,
-    CALL,
-    IMPLICIT_EXCEPTION,
-    METHOD_START,
-    METHOD_END,
-    LINE_NUMBER;
+    private InfopointReason(boolean canBeOmited) {
+        this.canBeOmited = canBeOmited;
+    }
 
+    private final boolean canBeOmited;
+
+    public boolean canBeOmited() {
+        return canBeOmited;
+    }
 }
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java	Wed Jul 16 14:27:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java	Fri Jul 18 11:14:54 2014 +0200
@@ -473,11 +473,6 @@
     }
 
     @Override
-    public void visitInfopointNode(InfopointNode i) {
-        append(new InfopointOp(stateFor(i.getState()), i.reason));
-    }
-
-    @Override
     public AMD64LIRGenerator getLIRGeneratorTool() {
         return (AMD64LIRGenerator) gen;
     }
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILNodeLIRBuilder.java	Wed Jul 16 14:27:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILNodeLIRBuilder.java	Fri Jul 18 11:14:54 2014 +0200
@@ -59,10 +59,4 @@
     public void visitBreakpointNode(BreakpointNode node) {
         throw GraalInternalError.unimplemented();
     }
-
-    @Override
-    public void visitInfopointNode(InfopointNode i) {
-        // TODO Auto-generated method stub
-        throw GraalInternalError.unimplemented();
-    }
 }
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXNodeLIRBuilder.java	Wed Jul 16 14:27:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXNodeLIRBuilder.java	Fri Jul 18 11:14:54 2014 +0200
@@ -123,9 +123,4 @@
         // append(new PTXSafepointOp(info, runtime().config, this));
         Debug.log("visitSafePointNode unimplemented");
     }
-
-    @Override
-    public void visitInfopointNode(InfopointNode i) {
-        throw GraalInternalError.unimplemented("PTXLIRGenerator.visitInfopointNode()");
-    }
 }
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeLIRBuilder.java	Wed Jul 16 14:27:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeLIRBuilder.java	Fri Jul 18 11:14:54 2014 +0200
@@ -26,7 +26,6 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
-import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.lir.sparc.*;
 import com.oracle.graal.nodes.*;
@@ -56,9 +55,4 @@
         Value[] parameters = visitInvokeArguments(gen.getResult().getFrameMap().registerConfig.getCallingConvention(CallingConvention.Type.JavaCall, null, sig, gen.target(), false), node.arguments());
         append(new SPARCBreakpointOp(parameters));
     }
-
-    @Override
-    public void visitInfopointNode(InfopointNode i) {
-        append(new InfopointOp(stateFor(i.getState()), i.reason));
-    }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Wed Jul 16 14:27:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Fri Jul 18 11:14:54 2014 +0200
@@ -693,7 +693,7 @@
      * Parses a Java method in debug mode to produce a graph with extra infopoints.
      */
     protected StructuredGraph parseDebug(Method m) {
-        return parse0(m, getCustomGraphBuilderSuite(GraphBuilderConfiguration.getEagerInfopointDefault()));
+        return parse0(m, getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault()));
     }
 
     private StructuredGraph parse0(Method m, PhaseSuite<HighTierContext> graphBuilderSuite) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java	Wed Jul 16 14:27:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java	Fri Jul 18 11:14:54 2014 +0200
@@ -76,14 +76,14 @@
         final Method method = getMethod("testMethod");
         final StructuredGraph graph = parseDebug(method);
         int graphLineSPs = 0;
-        for (InfopointNode ipn : graph.getNodes().filter(InfopointNode.class)) {
-            if (ipn.reason == InfopointReason.LINE_NUMBER) {
+        for (FullInfopointNode ipn : graph.getNodes().filter(FullInfopointNode.class)) {
+            if (ipn.getReason() == InfopointReason.LINE_NUMBER) {
                 ++graphLineSPs;
             }
         }
         assertTrue(graphLineSPs > 0);
         CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
-        PhaseSuite<HighTierContext> graphBuilderSuite = getCustomGraphBuilderSuite(GraphBuilderConfiguration.getEagerInfopointDefault());
+        PhaseSuite<HighTierContext> graphBuilderSuite = getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault());
         final CompilationResult cr = compileGraph(graph, null, cc, graph.method(), getProviders(), getBackend(), getCodeCache().getTarget(), null, graphBuilderSuite, OptimisticOptimizations.ALL,
                         getProfilingInfo(graph), getSpeculationLog(), getSuites(), new CompilationResult(), CompilationResultBuilderFactory.Default);
         int lineSPs = 0;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java	Wed Jul 16 14:27:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java	Fri Jul 18 11:14:54 2014 +0200
@@ -232,7 +232,7 @@
         try (Scope s = Debug.scope("InliningTest", new DebugDumpScope(snippet))) {
             Method method = getMethod(snippet);
             StructuredGraph graph = eagerInfopointMode ? parseDebug(method) : parse(method);
-            PhaseSuite<HighTierContext> graphBuilderSuite = eagerInfopointMode ? getCustomGraphBuilderSuite(GraphBuilderConfiguration.getEagerInfopointDefault()) : getDefaultGraphBuilderSuite();
+            PhaseSuite<HighTierContext> graphBuilderSuite = eagerInfopointMode ? getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault()) : getDefaultGraphBuilderSuite();
             Assumptions assumptions = new Assumptions(true);
             HighTierContext context = new HighTierContext(getProviders(), assumptions, null, graphBuilderSuite, OptimisticOptimizations.ALL);
             Debug.dump(graph, "Graph");
@@ -277,10 +277,10 @@
     private static int[] countMethodInfopoints(StructuredGraph graph) {
         int start = 0;
         int end = 0;
-        for (InfopointNode ipn : graph.getNodes().filter(InfopointNode.class)) {
-            if (ipn.reason == InfopointReason.METHOD_START) {
+        for (FullInfopointNode ipn : graph.getNodes().filter(FullInfopointNode.class)) {
+            if (ipn.getReason() == InfopointReason.METHOD_START) {
                 ++start;
-            } else if (ipn.reason == InfopointReason.METHOD_END) {
+            } else if (ipn.getReason() == InfopointReason.METHOD_END) {
                 ++end;
             }
         }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java	Wed Jul 16 14:27:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java	Fri Jul 18 11:14:54 2014 +0200
@@ -602,6 +602,16 @@
     }
 
     @Override
+    public void visitFullInfopointNode(FullInfopointNode i) {
+        append(new FullInfopointOp(stateFor(i.getState()), i.getReason()));
+    }
+
+    @Override
+    public void visitSimpleInfopointNode(SimpleInfopointNode i) {
+        append(new SimpleInfopointOp(i.getReason(), i.getPosition()));
+    }
+
+    @Override
     public LIRGeneratorTool getLIRGeneratorTool() {
         return gen;
     }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java	Wed Jul 16 14:27:48 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java	Fri Jul 18 11:14:54 2014 +0200
@@ -192,11 +192,11 @@
     }
 
     @Override
-    public void visitInfopointNode(InfopointNode i) {
+    public void visitFullInfopointNode(FullInfopointNode i) {
         if (i.getState() != null && i.getState().bci == BytecodeFrame.AFTER_BCI) {
             Debug.log("Ignoring InfopointNode for AFTER_BCI");
         } else {
-            super.visitInfopointNode(i);
+            super.visitFullInfopointNode(i);
         }
     }
 
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java	Wed Jul 16 14:27:48 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java	Fri Jul 18 11:14:54 2014 +0200
@@ -141,12 +141,11 @@
     }
 
     @Override
-    public void visitInfopointNode(InfopointNode i) {
+    public void visitFullInfopointNode(FullInfopointNode i) {
         if (i.getState() != null && i.getState().bci == BytecodeFrame.AFTER_BCI) {
             Debug.log("Ignoring InfopointNode for AFTER_BCI");
         } else {
-            super.visitInfopointNode(i);
+            super.visitFullInfopointNode(i);
         }
     }
-
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Wed Jul 16 14:27:48 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Fri Jul 18 11:14:54 2014 +0200
@@ -52,6 +52,7 @@
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.phases.*;
 import com.oracle.graal.java.*;
+import com.oracle.graal.java.GraphBuilderConfiguration.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -133,7 +134,11 @@
 
         if (HotSpotGraalRuntime.runtime().getCompilerToVM().shouldDebugNonSafepoints()) {
             // need to tweak the graph builder config
-            suite.findPhase(GraphBuilderPhase.class).set(new GraphBuilderPhase(GraphBuilderConfiguration.getInfopointDefault()));
+            suite = suite.copy();
+            GraphBuilderPhase graphBuilderPhase = (GraphBuilderPhase) suite.findPhase(GraphBuilderPhase.class).previous();
+            GraphBuilderConfiguration graphBuilderConfig = graphBuilderPhase.getGraphBuilderConfig();
+            GraphBuilderPhase newGraphBuilderPhase = new GraphBuilderPhase(graphBuilderConfig.withDebugInfoMode(DebugInfoMode.Simple));
+            suite.findPhase(GraphBuilderPhase.class).set(newGraphBuilderPhase);
         }
 
         boolean osrCompilation = entryBCI != StructuredGraph.INVOCATION_ENTRY_BCI;
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java	Wed Jul 16 14:27:48 2014 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java	Fri Jul 18 11:14:54 2014 +0200
@@ -22,34 +22,57 @@
  */
 package com.oracle.graal.java;
 
+import java.util.*;
+
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 
 public class GraphBuilderConfiguration {
+    private static final ResolvedJavaType[] EMPTY = new ResolvedJavaType[]{};
 
     private final boolean eagerResolving;
     private final boolean omitAllExceptionEdges;
-    private ResolvedJavaType[] skippedExceptionTypes;
+    private final ResolvedJavaType[] skippedExceptionTypes;
+    private final DebugInfoMode debugInfoMode;
 
-    /**
-     * When the graph builder is in eager infopoint mode, it inserts {@link InfopointNode}s in
-     * places where no safepoints would be inserted: inlining boundaries, and line number switches.
-     * This is relevant when code is to be generated for native, machine-code level debugging.
-     */
-    private boolean eagerInfopointMode;
+    public static enum DebugInfoMode {
+        SafePointsOnly,
+        /**
+         * This mode inserts {@link FullInfopointNode}s in places where no safepoints would be
+         * inserted: inlining boundaries, and line number switches.
+         * <p>
+         * In this mode the infopoint only have a location (method and bytecode index) and no
+         * values.
+         * <p>
+         * This is useful to have better program counter to bci mapping and has no influence on the
+         * generated code. However it can increase the amount of metadata and does not allow access
+         * to accessing values at runtime.
+         */
+        Simple,
+        /**
+         * In this mode, infopoints are generated in the same locations as in {@link #Simple} mode
+         * but the infopoints have access to the runtime values.
+         * <p>
+         * This is relevant when code is to be generated for native, machine-code level debugging
+         * but can have a limit the amount of optimisation applied to the code.
+         */
+        Full,
+    }
 
-    protected GraphBuilderConfiguration(boolean eagerResolving, boolean omitAllExceptionEdges, boolean eagerInfopointMode) {
+    protected GraphBuilderConfiguration(boolean eagerResolving, boolean omitAllExceptionEdges, DebugInfoMode debugInfoMode, ResolvedJavaType[] skippedExceptionTypes) {
         this.eagerResolving = eagerResolving;
         this.omitAllExceptionEdges = omitAllExceptionEdges;
-        this.eagerInfopointMode = eagerInfopointMode;
-    }
-
-    public void setSkippedExceptionTypes(ResolvedJavaType[] skippedExceptionTypes) {
+        this.debugInfoMode = debugInfoMode;
         this.skippedExceptionTypes = skippedExceptionTypes;
     }
 
-    public void setEagerInfopointMode(boolean eagerInfopointMode) {
-        this.eagerInfopointMode = eagerInfopointMode;
+    public GraphBuilderConfiguration withSkippedExceptionTypes(ResolvedJavaType[] newSkippedExceptionTypes) {
+        return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, newSkippedExceptionTypes);
+    }
+
+    public GraphBuilderConfiguration withDebugInfoMode(DebugInfoMode newDebugInfoMode) {
+        ResolvedJavaType[] newSkippedExceptionTypes = skippedExceptionTypes == EMPTY ? EMPTY : Arrays.copyOf(skippedExceptionTypes, skippedExceptionTypes.length);
+        return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, newDebugInfoMode, newSkippedExceptionTypes);
     }
 
     public ResolvedJavaType[] getSkippedExceptionTypes() {
@@ -64,28 +87,28 @@
         return omitAllExceptionEdges;
     }
 
-    public boolean eagerInfopointMode() {
-        return eagerInfopointMode;
+    public boolean insertNonSafepointDebugInfo() {
+        return debugInfoMode.ordinal() >= DebugInfoMode.Simple.ordinal();
+    }
+
+    public boolean insertFullDebugInfo() {
+        return debugInfoMode.ordinal() >= DebugInfoMode.Full.ordinal();
     }
 
     public static GraphBuilderConfiguration getDefault() {
-        return new GraphBuilderConfiguration(false, false, false);
-    }
-
-    public static GraphBuilderConfiguration getInfopointDefault() {
-        return new GraphBuilderConfiguration(false, false, true);
+        return new GraphBuilderConfiguration(false, false, DebugInfoMode.SafePointsOnly, EMPTY);
     }
 
     public static GraphBuilderConfiguration getEagerDefault() {
-        return new GraphBuilderConfiguration(true, false, false);
+        return new GraphBuilderConfiguration(true, false, DebugInfoMode.SafePointsOnly, EMPTY);
     }
 
     public static GraphBuilderConfiguration getSnippetDefault() {
-        return new GraphBuilderConfiguration(true, true, false);
+        return new GraphBuilderConfiguration(true, true, DebugInfoMode.SafePointsOnly, EMPTY);
     }
 
-    public static GraphBuilderConfiguration getEagerInfopointDefault() {
-        return new GraphBuilderConfiguration(true, false, true);
+    public static GraphBuilderConfiguration getFullDebugDefault() {
+        return new GraphBuilderConfiguration(true, false, DebugInfoMode.Full, EMPTY);
     }
 
     /**
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Jul 16 14:27:48 2014 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri Jul 18 11:14:54 2014 +0200
@@ -69,6 +69,10 @@
         new Instance(context.getMetaAccess(), graphBuilderConfig, context.getOptimisticOptimizations()).run(graph);
     }
 
+    public GraphBuilderConfiguration getGraphBuilderConfig() {
+        return graphBuilderConfig;
+    }
+
     public static class Instance extends Phase {
 
         private LineNumberTable lnt;
@@ -139,7 +143,7 @@
         @Override
         protected void run(StructuredGraph graph) {
             ResolvedJavaMethod method = graph.method();
-            if (graphBuilderConfig.eagerInfopointMode()) {
+            if (graphBuilderConfig.insertNonSafepointDebugInfo()) {
                 lnt = method.getLineNumberTable();
                 previousLineNumber = -1;
             }
@@ -232,11 +236,12 @@
                         lastInstr = genMonitorEnter(methodSynchronizedObject);
                     }
                     frameState.clearNonLiveLocals(blockMap.startBlock, liveness, true);
-                    ((StateSplit) lastInstr).setStateAfter(frameState.create(0));
+                    assert bci() == 0;
+                    ((StateSplit) lastInstr).setStateAfter(frameState.create(bci()));
                     finishPrepare(lastInstr);
 
-                    if (graphBuilderConfig.eagerInfopointMode()) {
-                        InfopointNode ipn = currentGraph.add(new InfopointNode(InfopointReason.METHOD_START, frameState.create(0)));
+                    if (graphBuilderConfig.insertNonSafepointDebugInfo()) {
+                        InfopointNode ipn = currentGraph.add(createInfoPointNode(InfopointReason.METHOD_START));
                         lastInstr.setNext(ipn);
                         lastInstr = ipn;
                     }
@@ -835,8 +840,8 @@
             protected void genReturn(ValueNode x) {
                 frameState.setRethrowException(false);
                 frameState.clearStack();
-                if (graphBuilderConfig.eagerInfopointMode()) {
-                    append(new InfopointNode(InfopointReason.METHOD_END, frameState.create(bci())));
+                if (graphBuilderConfig.insertNonSafepointDebugInfo()) {
+                    append(createInfoPointNode(InfopointReason.METHOD_END));
                 }
 
                 synchronizedEpilogue(BytecodeFrame.AFTER_BCI, x);
@@ -1290,10 +1295,10 @@
                 BytecodesParsed.add(block.endBci - bci);
 
                 while (bci < endBCI) {
-                    if (graphBuilderConfig.eagerInfopointMode() && lnt != null) {
+                    if (graphBuilderConfig.insertNonSafepointDebugInfo() && lnt != null) {
                         currentLineNumber = lnt.getLineNumber(bci);
                         if (currentLineNumber != previousLineNumber) {
-                            append(new InfopointNode(InfopointReason.LINE_NUMBER, frameState.create(bci)));
+                            append(createInfoPointNode(InfopointReason.LINE_NUMBER));
                             previousLineNumber = currentLineNumber;
                         }
                     }
@@ -1356,6 +1361,14 @@
                 return instr;
             }
 
+            private InfopointNode createInfoPointNode(InfopointReason reason) {
+                if (graphBuilderConfig.insertFullDebugInfo()) {
+                    return new FullInfopointNode(reason, frameState.create(bci()));
+                } else {
+                    return new SimpleInfopointNode(reason, new BytecodePosition(null, method, bci()));
+                }
+            }
+
             private void traceState() {
                 if (traceLevel >= TRACELEVEL_STATE && Debug.isLogEnabled()) {
                     Debug.log(String.format("|   state [nr locals = %d, stack depth = %d, method = %s]", frameState.localsSize(), frameState.stackSize(), method));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FullInfopointOp.java	Fri Jul 18 11:14:54 2014 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.lir;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.lir.asm.*;
+
+/**
+ * Emits an infopoint (only mark the position).
+ */
+@Opcode("INFOPOINT")
+public class FullInfopointOp extends LIRInstruction {
+
+    @State protected LIRFrameState state;
+
+    private final InfopointReason reason;
+
+    public FullInfopointOp(LIRFrameState state, InfopointReason reason) {
+        this.state = state;
+        this.reason = reason;
+    }
+
+    @Override
+    public void emitCode(CompilationResultBuilder crb) {
+        crb.recordInfopoint(crb.asm.position(), state, reason);
+    }
+}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InfopointOp.java	Wed Jul 16 14:27:48 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.lir;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.lir.asm.*;
-
-/**
- * Emits an infopoint (only mark the position).
- */
-@Opcode("INFOPOINT")
-public class InfopointOp extends LIRInstruction {
-
-    @State protected LIRFrameState state;
-
-    private final InfopointReason reason;
-
-    public InfopointOp(LIRFrameState state, InfopointReason reason) {
-        this.state = state;
-        this.reason = reason;
-    }
-
-    @Override
-    public void emitCode(CompilationResultBuilder crb) {
-        crb.recordInfopoint(crb.asm.position(), state, reason);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/SimpleInfopointOp.java	Fri Jul 18 11:14:54 2014 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.lir;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.lir.asm.*;
+
+@Opcode("SIMPLE_INFOPOINT")
+public class SimpleInfopointOp extends LIRInstruction {
+    private final InfopointReason reason;
+    private final BytecodePosition position;
+
+    public SimpleInfopointOp(InfopointReason reason, BytecodePosition position) {
+        this.reason = reason;
+        this.position = position;
+    }
+
+    @Override
+    public void emitCode(CompilationResultBuilder crb) {
+        crb.recordInfopoint(crb.asm.position(), new DebugInfo(position, null), reason);
+    }
+}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java	Wed Jul 16 14:27:48 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java	Fri Jul 18 11:14:54 2014 +0200
@@ -146,6 +146,10 @@
     public void recordInfopoint(int pos, LIRFrameState info, InfopointReason reason) {
         // infopoints always need debug info
         DebugInfo debugInfo = info.debugInfo();
+        recordInfopoint(pos, debugInfo, reason);
+    }
+
+    public void recordInfopoint(int pos, DebugInfo debugInfo, InfopointReason reason) {
         compilationResult.recordInfopoint(pos, debugInfo, reason);
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FullInfopointNode.java	Fri Jul 18 11:14:54 2014 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.spi.*;
+
+/**
+ * Nodes of this type are inserted into the graph to denote points of interest to debugging.
+ */
+public class FullInfopointNode extends InfopointNode implements LIRLowerable, NodeWithState {
+    @Input(InputType.State) private FrameState state;
+
+    public FullInfopointNode(InfopointReason reason, FrameState state) {
+        super(reason);
+        this.state = state;
+    }
+
+    @Override
+    public void generate(NodeLIRBuilderTool generator) {
+        generator.visitFullInfopointNode(this);
+    }
+
+    public FrameState getState() {
+        return state;
+    }
+
+    @Override
+    public boolean verify() {
+        return state != null && super.verify();
+    }
+
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InfopointNode.java	Wed Jul 16 14:27:48 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InfopointNode.java	Fri Jul 18 11:14:54 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,35 +24,16 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.spi.*;
 
-/**
- * Nodes of this type are inserted into the graph to denote points of interest to debugging.
- */
-public class InfopointNode extends FixedWithNextNode implements LIRLowerable, NodeWithState {
+public abstract class InfopointNode extends FixedWithNextNode {
+    private final InfopointReason reason;
 
-    public final InfopointReason reason;
-    @Input(InputType.State) private FrameState state;
-
-    public InfopointNode(InfopointReason reason, FrameState state) {
+    public InfopointNode(InfopointReason reason) {
         super(StampFactory.forVoid());
         this.reason = reason;
-        this.state = state;
-    }
-
-    @Override
-    public void generate(NodeLIRBuilderTool generator) {
-        generator.visitInfopointNode(this);
     }
 
-    public FrameState getState() {
-        return state;
+    public InfopointReason getReason() {
+        return reason;
     }
-
-    @Override
-    public boolean verify() {
-        return state != null && super.verify();
-    }
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SimpleInfopointNode.java	Fri Jul 18 11:14:54 2014 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.spi.*;
+
+public class SimpleInfopointNode extends InfopointNode implements LIRLowerable, IterableNodeType {
+    private BytecodePosition position;
+
+    public SimpleInfopointNode(InfopointReason reason, BytecodePosition position) {
+        super(reason);
+        this.position = position;
+    }
+
+    @Override
+    public void generate(NodeLIRBuilderTool generator) {
+        generator.visitSimpleInfopointNode(this);
+    }
+
+    public BytecodePosition getPosition() {
+        return position;
+    }
+
+    public void addCaller(BytecodePosition caller) {
+        this.position = relink(this.position, caller);
+    }
+
+    private static BytecodePosition relink(BytecodePosition position, BytecodePosition link) {
+        if (position.getCaller() == null) {
+            return new BytecodePosition(link, position.getMethod(), position.getBCI());
+        } else {
+            return new BytecodePosition(relink(position.getCaller(), link), position.getMethod(), position.getBCI());
+        }
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeLIRBuilderTool.java	Wed Jul 16 14:27:48 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeLIRBuilderTool.java	Fri Jul 18 11:14:54 2014 +0200
@@ -60,7 +60,9 @@
 
     void visitBreakpointNode(BreakpointNode i);
 
-    void visitInfopointNode(InfopointNode i);
+    void visitFullInfopointNode(FullInfopointNode i);
+
+    void visitSimpleInfopointNode(SimpleInfopointNode i);
 
     LIRGeneratorTool getLIRGeneratorTool();
 
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Wed Jul 16 14:27:48 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Fri Jul 18 11:14:54 2014 +0200
@@ -314,6 +314,7 @@
             }
         }
 
+        processSimpleInfopoints(invoke, inlineGraph, duplicates);
         if (stateAfter != null) {
             processFrameStates(invoke, inlineGraph, duplicates, stateAtExceptionEdge);
             int callerLockDepth = stateAfter.nestedLockDepth();
@@ -353,6 +354,24 @@
         return duplicates;
     }
 
+    private static void processSimpleInfopoints(Invoke invoke, StructuredGraph inlineGraph, Map<Node, Node> duplicates) {
+        if (inlineGraph.getNodes(SimpleInfopointNode.class).isEmpty()) {
+            return;
+        }
+        BytecodePosition pos = new BytecodePosition(toBytecodePosition(invoke.stateAfter()), invoke.asNode().graph().method(), invoke.bci());
+        for (SimpleInfopointNode original : inlineGraph.getNodes(SimpleInfopointNode.class)) {
+            SimpleInfopointNode duplicate = (SimpleInfopointNode) duplicates.get(original);
+            duplicate.addCaller(pos);
+        }
+    }
+
+    private static BytecodePosition toBytecodePosition(FrameState fs) {
+        if (fs == null) {
+            return null;
+        }
+        return new BytecodePosition(toBytecodePosition(fs.outerFrameState()), fs.method(), fs.bci);
+    }
+
     protected static void processFrameStates(Invoke invoke, StructuredGraph inlineGraph, Map<Node, Node> duplicates, FrameState stateAtExceptionEdge) {
         FrameState stateAtReturn = invoke.stateAfter();
         FrameState outerFrameState = null;
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java	Wed Jul 16 14:27:48 2014 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java	Fri Jul 18 11:14:54 2014 +0200
@@ -160,8 +160,8 @@
                     FrameState pendingStateAfter = null;
                     for (final ScheduledNode node : list) {
                         FrameState stateAfter = node instanceof StateSplit ? ((StateSplit) node).stateAfter() : null;
-                        if (node instanceof InfopointNode) {
-                            stateAfter = ((InfopointNode) node).getState();
+                        if (node instanceof FullInfopointNode) {
+                            stateAfter = ((FullInfopointNode) node).getState();
                         }
 
                         if (pendingStateAfter != null && node instanceof FixedNode) {
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Wed Jul 16 14:27:48 2014 +0200
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Fri Jul 18 11:14:54 2014 +0200
@@ -164,7 +164,7 @@
             canonicalizer.apply(graph, context);
 
             // Additional inlining.
-            PhaseSuite<HighTierContext> graphBuilderSuite = getCustomGraphBuilderSuite(GraphBuilderConfiguration.getEagerInfopointDefault());
+            PhaseSuite<HighTierContext> graphBuilderSuite = getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault());
             graphBuilderSuite.appendPhase(canonicalizer);
             graphBuilderSuite.appendPhase(new DeadCodeEliminationPhase());
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Wed Jul 16 14:27:48 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Fri Jul 18 11:14:54 2014 +0200
@@ -78,10 +78,8 @@
         this.suites = backend.getSuites().getDefaultSuites();
 
         ResolvedJavaType[] skippedExceptionTypes = getSkippedExceptionTypes(providers.getMetaAccess());
-        GraphBuilderConfiguration eagerConfig = GraphBuilderConfiguration.getEagerDefault();
-        eagerConfig.setSkippedExceptionTypes(skippedExceptionTypes);
-        this.config = GraphBuilderConfiguration.getDefault();
-        this.config.setSkippedExceptionTypes(skippedExceptionTypes);
+        GraphBuilderConfiguration eagerConfig = GraphBuilderConfiguration.getEagerDefault().withSkippedExceptionTypes(skippedExceptionTypes);
+        this.config = GraphBuilderConfiguration.getDefault().withSkippedExceptionTypes(skippedExceptionTypes);
 
         this.truffleCache = new TruffleCacheImpl(providers, eagerConfig, config, TruffleCompilerImpl.Optimizations);
 
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Wed Jul 16 14:27:48 2014 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Fri Jul 18 11:14:54 2014 +0200
@@ -545,7 +545,7 @@
       ShouldNotReachHere();
     }
   }
-
+  jint last_pc_offset = -1;
   for (int i = 0; i < _sites->length(); i++) {
     oop site = ((objArrayOop) (_sites))->obj_at(i);
     jint pc_offset = CompilationResult_Site::pcOffset(site);
@@ -563,6 +563,7 @@
         // if the infopoint is not an actual safepoint, it must have one of the other reasons
         // (safeguard against new safepoint types that require handling above)
         assert(InfopointReason::METHOD_START() == reason || InfopointReason::METHOD_END() == reason || InfopointReason::LINE_NUMBER() == reason, "");
+        site_Infopoint(buffer, pc_offset, site);
       }
     } else if (site->is_a(CompilationResult_DataPatch::klass())) {
       TRACE_graal_4("datapatch at %i", pc_offset);
@@ -573,6 +574,7 @@
     } else {
       fatal("unexpected Site subclass");
     }
+    last_pc_offset = pc_offset;
   }
 
 #ifndef PRODUCT
@@ -670,83 +672,95 @@
   return true;
 }
 
-void CodeInstaller::record_scope(jint pc_offset, oop frame, GrowableArray<ScopeValue*>* objects) {
-  assert(frame->klass() == BytecodeFrame::klass(), "BytecodeFrame expected");
-  oop caller_frame = BytecodePosition::caller(frame);
+void CodeInstaller::record_scope(jint pc_offset, oop position, GrowableArray<ScopeValue*>* objects) {
+  oop frame = NULL;
+  if (position->is_a(BytecodeFrame::klass())) {
+    frame = position;
+  }
+  oop caller_frame = BytecodePosition::caller(position);
   if (caller_frame != NULL) {
     record_scope(pc_offset, caller_frame, objects);
   }
 
-  oop hotspot_method = BytecodePosition::method(frame);
+  oop hotspot_method = BytecodePosition::method(position);
   Method* method = getMethodFromHotSpotMethod(hotspot_method);
-  jint bci = BytecodePosition::bci(frame);
+  jint bci = BytecodePosition::bci(position);
   if (bci == BytecodeFrame::BEFORE_BCI()) {
     bci = SynchronizationEntryBCI;
   }
-  bool reexecute;
-  if (bci == SynchronizationEntryBCI){
-     reexecute = false;
-  } else {
-    Bytecodes::Code code = Bytecodes::java_code_at(method, method->bcp_from(bci));
-    reexecute = bytecode_should_reexecute(code);
-    if (frame != NULL) {
-      reexecute = (BytecodeFrame::duringCall(frame) == JNI_FALSE);
-    }
-  }
 
   if (TraceGraal >= 2) {
     tty->print_cr("Recording scope pc_offset=%d bci=%d method=%s", pc_offset, bci, method->name_and_sig_as_C_string());
   }
 
-  jint local_count = BytecodeFrame::numLocals(frame);
-  jint expression_count = BytecodeFrame::numStack(frame);
-  jint monitor_count = BytecodeFrame::numLocks(frame);
-  arrayOop values = (arrayOop) BytecodeFrame::values(frame);
-
-  assert(local_count + expression_count + monitor_count == values->length(), "unexpected values length");
-
-  GrowableArray<ScopeValue*>* locals = new GrowableArray<ScopeValue*> ();
-  GrowableArray<ScopeValue*>* expressions = new GrowableArray<ScopeValue*> ();
-  GrowableArray<MonitorValue*>* monitors = new GrowableArray<MonitorValue*> ();
-
-  if (TraceGraal >= 2) {
-    tty->print_cr("Scope at bci %d with %d values", bci, values->length());
-    tty->print_cr("%d locals %d expressions, %d monitors", local_count, expression_count, monitor_count);
-  }
-
-  for (jint i = 0; i < values->length(); i++) {
-    ScopeValue* second = NULL;
-    oop value=((objArrayOop) (values))->obj_at(i);
-    if (i < local_count) {
-      ScopeValue* first = get_scope_value(value, _total_frame_size, objects, second, _oop_recorder);
-      if (second != NULL) {
-        locals->append(second);
+  bool reexecute = false;
+  if (frame != NULL) {
+    if (bci == SynchronizationEntryBCI){
+       reexecute = false;
+    } else {
+      Bytecodes::Code code = Bytecodes::java_code_at(method, method->bcp_from(bci));
+      reexecute = bytecode_should_reexecute(code);
+      if (frame != NULL) {
+        reexecute = (BytecodeFrame::duringCall(frame) == JNI_FALSE);
       }
-      locals->append(first);
-    } else if (i < local_count + expression_count) {
-      ScopeValue* first = get_scope_value(value, _total_frame_size, objects, second, _oop_recorder);
-      if (second != NULL) {
-        expressions->append(second);
-      }
-      expressions->append(first);
-    } else {
-      monitors->append(get_monitor_value(value, _total_frame_size, objects, _oop_recorder));
-    }
-    if (second != NULL) {
-      i++;
-      assert(i < values->length(), "double-slot value not followed by Value.ILLEGAL");
-      assert(((objArrayOop) (values))->obj_at(i) == Value::ILLEGAL(), "double-slot value not followed by Value.ILLEGAL");
     }
   }
 
+  DebugToken* locals_token = NULL;
+  DebugToken* expressions_token = NULL;
+  DebugToken* monitors_token = NULL;
+  bool throw_exception = false;
 
-  _debug_recorder->dump_object_pool(objects);
+  if (frame != NULL) {
+    jint local_count = BytecodeFrame::numLocals(frame);
+    jint expression_count = BytecodeFrame::numStack(frame);
+    jint monitor_count = BytecodeFrame::numLocks(frame);
+    arrayOop values = (arrayOop) BytecodeFrame::values(frame);
+
+    assert(local_count + expression_count + monitor_count == values->length(), "unexpected values length");
+
+    GrowableArray<ScopeValue*>* locals = new GrowableArray<ScopeValue*> ();
+    GrowableArray<ScopeValue*>* expressions = new GrowableArray<ScopeValue*> ();
+    GrowableArray<MonitorValue*>* monitors = new GrowableArray<MonitorValue*> ();
+
+    if (TraceGraal >= 2) {
+      tty->print_cr("Scope at bci %d with %d values", bci, values->length());
+      tty->print_cr("%d locals %d expressions, %d monitors", local_count, expression_count, monitor_count);
+    }
 
-  DebugToken* locals_token = _debug_recorder->create_scope_values(locals);
-  DebugToken* expressions_token = _debug_recorder->create_scope_values(expressions);
-  DebugToken* monitors_token = _debug_recorder->create_monitor_values(monitors);
+    for (jint i = 0; i < values->length(); i++) {
+      ScopeValue* second = NULL;
+      oop value=((objArrayOop) (values))->obj_at(i);
+      if (i < local_count) {
+        ScopeValue* first = get_scope_value(value, _total_frame_size, objects, second, _oop_recorder);
+        if (second != NULL) {
+          locals->append(second);
+        }
+        locals->append(first);
+      } else if (i < local_count + expression_count) {
+        ScopeValue* first = get_scope_value(value, _total_frame_size, objects, second, _oop_recorder);
+        if (second != NULL) {
+          expressions->append(second);
+        }
+        expressions->append(first);
+      } else {
+        monitors->append(get_monitor_value(value, _total_frame_size, objects, _oop_recorder));
+      }
+      if (second != NULL) {
+        i++;
+        assert(i < values->length(), "double-slot value not followed by Value.ILLEGAL");
+        assert(((objArrayOop) (values))->obj_at(i) == Value::ILLEGAL(), "double-slot value not followed by Value.ILLEGAL");
+      }
+    }
 
-  bool throw_exception = BytecodeFrame::rethrowException(frame) == JNI_TRUE;
+    _debug_recorder->dump_object_pool(objects);
+
+    locals_token = _debug_recorder->create_scope_values(locals);
+    expressions_token = _debug_recorder->create_scope_values(expressions);
+    monitors_token = _debug_recorder->create_monitor_values(monitors);
+
+    throw_exception = BytecodeFrame::rethrowException(frame) == JNI_TRUE;
+  }
 
   _debug_recorder->describe_scope(pc_offset, method, NULL, bci, reexecute, throw_exception, false, false, locals_token, expressions_token, monitors_token);
 }
@@ -769,6 +783,20 @@
   _debug_recorder->end_safepoint(pc_offset);
 }
 
+void CodeInstaller::site_Infopoint(CodeBuffer& buffer, jint pc_offset, oop site) {
+  oop debug_info = CompilationResult_Infopoint::debugInfo(site);
+  assert(debug_info != NULL, "debug info expected");
+
+  _debug_recorder->add_non_safepoint(pc_offset);
+
+  oop position = DebugInfo::bytecodePosition(debug_info);
+  if (position != NULL) {
+    record_scope(pc_offset, position, NULL);
+  }
+
+  _debug_recorder->end_non_safepoint(pc_offset);
+}
+
 void CodeInstaller::site_Call(CodeBuffer& buffer, jint pc_offset, oop site) {
   oop target = CompilationResult_Call::target(site);
   InstanceKlass* target_klass = InstanceKlass::cast(target->klass());
--- a/src/share/vm/graal/graalCodeInstaller.hpp	Wed Jul 16 14:27:48 2014 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.hpp	Fri Jul 18 11:14:54 2014 +0200
@@ -115,6 +115,7 @@
   void assumption_CallSiteTargetValue(Handle assumption);
 
   void site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site);
+  void site_Infopoint(CodeBuffer& buffer, jint pc_offset, oop site);
   void site_Call(CodeBuffer& buffer, jint pc_offset, oop site);
   void site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site);
   void site_Mark(CodeBuffer& buffer, jint pc_offset, oop site);