changeset 21294:d5ee8f60459d

Improve accuracy of info point states
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Mon, 11 May 2015 10:29:42 -0700
parents 21607a6101eb
children 3703ad7bf6b5
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodePosition.java graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderConfiguration.java graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SimpleInfopointNode.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java
diffstat 8 files changed, 109 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodePosition.java	Mon May 11 10:06:21 2015 -0700
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodePosition.java	Mon May 11 10:29:42 2015 -0700
@@ -109,4 +109,15 @@
     public BytecodePosition getCaller() {
         return caller;
     }
+
+    /*
+     * Adds a caller to the current position returning the new position.
+     */
+    public BytecodePosition addCaller(BytecodePosition link) {
+        if (getCaller() == null) {
+            return new BytecodePosition(link, getMethod(), getBCI());
+        } else {
+            return new BytecodePosition(getCaller().addCaller(link), getMethod(), getBCI());
+        }
+    }
 }
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderConfiguration.java	Mon May 11 10:06:21 2015 -0700
+++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderConfiguration.java	Mon May 11 10:29:42 2015 -0700
@@ -229,6 +229,10 @@
         return debugInfoMode.ordinal() >= DebugInfoMode.Full.ordinal();
     }
 
+    public boolean insertSimpleDebugInfo() {
+        return debugInfoMode == DebugInfoMode.Simple;
+    }
+
     public boolean doLivenessAnalysis() {
         return doLivenessAnalysis;
     }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java	Mon May 11 10:06:21 2015 -0700
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java	Mon May 11 10:29:42 2015 -0700
@@ -73,6 +73,9 @@
         @Option(help = "Do not bail out but throw an exception on failed loop explosion.", type = OptionType.Debug)
         public static final OptionValue<Boolean> FailedLoopExplosionIsFatal = new OptionValue<>(false);
 
+        @Option(help = "When creating info points hide the methods of the substitutions.", type = OptionType.Debug)
+        public static final OptionValue<Boolean> HideSubstitutionStates = new OptionValue<>(false);
+
         // @formatter:on
     }
 
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Mon May 11 10:06:21 2015 -0700
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Mon May 11 10:29:42 2015 -0700
@@ -2084,9 +2084,14 @@
                 int bci = block.startBci;
                 BytecodesParsed.add(block.endBci - bci);
 
+                /* Reset line number for new block */
+                if (graphBuilderConfig.insertSimpleDebugInfo()) {
+                    previousLineNumber = -1;
+                }
+
                 while (bci < endBCI) {
-                    if (graphBuilderConfig.insertNonSafepointDebugInfo() && lnt != null) {
-                        currentLineNumber = lnt.getLineNumber(bci);
+                    if (graphBuilderConfig.insertNonSafepointDebugInfo()) {
+                        currentLineNumber = lnt != null ? lnt.getLineNumber(bci) : (graphBuilderConfig.insertFullDebugInfo() ? -1 : bci);
                         if (currentLineNumber != previousLineNumber) {
                             append(createInfoPointNode(InfopointReason.LINE_NUMBER));
                             previousLineNumber = currentLineNumber;
@@ -2158,7 +2163,16 @@
                 if (graphBuilderConfig.insertFullDebugInfo()) {
                     return new FullInfopointNode(reason, createFrameState(bci()));
                 } else {
-                    return new SimpleInfopointNode(reason, new BytecodePosition(null, method, bci()));
+                    BytecodePosition position = createBytecodePosition();
+                    // Update the previous infopoint position if no new fixed nodes were inserted
+                    if (lastInstr instanceof SimpleInfopointNode) {
+                        SimpleInfopointNode lastInfopoint = (SimpleInfopointNode) lastInstr;
+                        if (lastInfopoint.getReason() == reason) {
+                            lastInfopoint.setPosition(position);
+                            return lastInfopoint;
+                        }
+                    }
+                    return new SimpleInfopointNode(reason, position);
                 }
             }
 
@@ -2425,6 +2439,10 @@
             public FrameState createStateAfter() {
                 return createFrameState(stream.nextBCI());
             }
+
+            private BytecodePosition createBytecodePosition() {
+                return frameState.createBytecodePosition(bci());
+            }
         }
     }
 
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java	Mon May 11 10:06:21 2015 -0700
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java	Mon May 11 10:29:42 2015 -0700
@@ -233,6 +233,39 @@
         return graph.add(new FrameState(outerFrameState, method, bci, locals, stack, stackSize, lockedObjects, Arrays.asList(monitorIds), rethrowException, duringCall));
     }
 
+    public BytecodePosition createBytecodePosition(int bci) {
+        BytecodeParser parent = parser.getParent();
+        if (AbstractBytecodeParser.Options.HideSubstitutionStates.getValue()) {
+            if (parser.parsingReplacement()) {
+                IntrinsicContext intrinsic = parser.replacementContext.asIntrinsic();
+                if (intrinsic != null) {
+                    // Attribute to the method being replaced
+                    return new BytecodePosition(FrameState.toBytecodePosition(intrinsic.getInvokeStateBefore(parser.getGraph(), parent)), intrinsic.method, -1);
+                }
+            }
+            // If this is the recursive call in a partial intrinsification
+            // the frame(s) of the intrinsic method are omitted
+            while (parent != null && parent.parsingReplacement() && parent.replacementContext.asIntrinsic() != null) {
+                parent = parent.getParent();
+            }
+        }
+        return create(null, bci, parent);
+    }
+
+    private BytecodePosition create(BytecodePosition o, int bci, BytecodeParser parent) {
+        BytecodePosition outer = o;
+        if (outer == null && parent != null) {
+            outer = parent.getFrameState().createBytecodePosition(parent.bci());
+        }
+        if (bci == BytecodeFrame.AFTER_EXCEPTION_BCI && parent != null) {
+            return FrameState.toBytecodePosition(outerFrameState);
+        }
+        if (bci == BytecodeFrame.INVALID_FRAMESTATE_BCI) {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+        return new BytecodePosition(outer, method, bci);
+    }
+
     public HIRFrameStateBuilder copy() {
         return new HIRFrameStateBuilder(this);
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Mon May 11 10:06:21 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Mon May 11 10:29:42 2015 -0700
@@ -153,6 +153,17 @@
         this.outerFrameState = x;
     }
 
+    public BytecodePosition toBytecodePosition() {
+        return toBytecodePosition(this);
+    }
+
+    public static BytecodePosition toBytecodePosition(FrameState fs) {
+        if (fs == null) {
+            return null;
+        }
+        return new BytecodePosition(toBytecodePosition(fs.outerFrameState()), fs.method(), fs.bci);
+    }
+
     /**
      * @see BytecodeFrame#rethrowException
      */
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SimpleInfopointNode.java	Mon May 11 10:06:21 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SimpleInfopointNode.java	Mon May 11 10:29:42 2015 -0700
@@ -48,15 +48,7 @@
     }
 
     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());
-        }
+        this.position = position.addCaller(caller);
     }
 
     @Override
@@ -65,4 +57,21 @@
             graph().removeFixed(this);
         }
     }
+
+    public void setPosition(BytecodePosition position) {
+        this.position = position;
+    }
+
+    @Override
+    public boolean verify() {
+        BytecodePosition pos = position;
+        if (pos != null) {
+            // Verify that the outermost position belongs to this graph.
+            while (pos.getCaller() != null) {
+                pos = pos.getCaller();
+            }
+            assert pos.getMethod().equals(graph().method());
+        }
+        return super.verify();
+    }
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Mon May 11 10:06:21 2015 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Mon May 11 10:29:42 2015 -0700
@@ -427,11 +427,18 @@
     }
 
     public static BytecodePosition processSimpleInfopoint(Invoke invoke, SimpleInfopointNode infopointNode, BytecodePosition incomingPos) {
-        BytecodePosition pos = incomingPos != null ? incomingPos : new BytecodePosition(toBytecodePosition(invoke.stateAfter().outerFrameState()), invoke.asNode().graph().method(), invoke.bci());
+        BytecodePosition pos = processBytecodePosition(invoke, incomingPos);
         infopointNode.addCaller(pos);
+        assert infopointNode.verify();
         return pos;
     }
 
+    public static BytecodePosition processBytecodePosition(Invoke invoke, BytecodePosition incomingPos) {
+        assert invoke.stateAfter() != null;
+        assert incomingPos == null || incomingPos.equals(InliningUtil.processBytecodePosition(invoke, null)) : incomingPos + " " + InliningUtil.processBytecodePosition(invoke, null);
+        return incomingPos != null ? incomingPos : new BytecodePosition(FrameState.toBytecodePosition(invoke.stateAfter().outerFrameState()), invoke.stateAfter().method(), invoke.bci());
+    }
+
     public static void processMonitorId(FrameState stateAfter, MonitorIdNode monitorIdNode) {
         if (stateAfter != null) {
             int callerLockDepth = stateAfter.nestedLockDepth();
@@ -439,13 +446,6 @@
         }
     }
 
-    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, boolean alwaysDuplicateStateAfter) {
         FrameState stateAtReturn = invoke.stateAfter();
         FrameState outerFrameState = null;