# HG changeset patch # User Michael Van De Vanter # Date 1449550109 28800 # Node ID 4a83dc15e774bdf6f01e409982b81d6338296d69 # Parent c434681cd164ee9d951e6506f036047bef7210dc Truffle/Debugging: reorganize Debugger/Suspended event to pass stack as FrameInstances; delete FrameDebugDescription diff -r c434681cd164 -r 4a83dc15e774 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Debugger.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Debugger.java Mon Dec 07 18:21:03 2015 -0800 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Debugger.java Mon Dec 07 20:48:29 2015 -0800 @@ -680,8 +680,11 @@ */ private MaterializedFrame haltedFrame; - /** Subset of the Truffle stack corresponding to the current execution. */ - private List contextStack; + /** + * Subset of the Truffle stack corresponding to the current execution, not including the + * current frame. + */ + private List contextStack; private DebugExecutionContext(Source executionSource, DebugExecutionContext previousContext) { this(executionSource, previousContext, -1); @@ -759,11 +762,10 @@ final List recentWarnings = new ArrayList<>(warnings); warnings.clear(); - final List frames = new ArrayList<>(); + final List frames = new ArrayList<>(); // Map the Truffle stack for this execution, ignore nested executions // Ignore frames for which no CallNode is available. - // The top/current/0 frame is not produced by the iterator. - frames.add(new FrameDebugDescription(0, haltedNode, haltedFrame)); + // The top/current/0 frame is not produced by the iterator; reported separately Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor() { int stackIndex = 1; int frameIndex = 1; @@ -775,7 +777,7 @@ if (callNode != null) { final SourceSection sourceSection = callNode.getEncapsulatingSourceSection(); if (sourceSection != null && !sourceSection.getIdentifier().equals("")) { - frames.add(new FrameDebugDescription(frameIndex, frameInstance)); + frames.add(frameInstance); frameIndex++; } else if (TRACE) { if (callNode != null) { @@ -783,7 +785,7 @@ } else { contextTrace("HIDDEN frame added"); } - frames.add(new FrameDebugDescription(frameIndex, frameInstance)); + frames.add(frameInstance); frameIndex++; } } else if (TRACE) { @@ -792,7 +794,7 @@ } else { contextTrace("HIDDEN frame added"); } - frames.add(new FrameDebugDescription(frameIndex, frameInstance)); + frames.add(frameInstance); frameIndex++; } stackIndex++; @@ -813,7 +815,7 @@ try { // Pass control to the debug client with current execution suspended - ACCESSOR.dispatchEvent(vm, new SuspendedEvent(Debugger.this, contextStack, recentWarnings)); + ACCESSOR.dispatchEvent(vm, new SuspendedEvent(Debugger.this, haltedNode, haltedFrame, contextStack, recentWarnings)); // Debug client finished normally, execution resumes // Presume that the client has set a new strategy (or default to Continue) running = true; diff -r c434681cd164 -r 4a83dc15e774 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/FrameDebugDescription.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/FrameDebugDescription.java Mon Dec 07 18:21:03 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2015, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.truffle.api.debug; - -import com.oracle.truffle.api.frame.FrameInstance; -import com.oracle.truffle.api.frame.FrameInstance.FrameAccess; -import com.oracle.truffle.api.frame.MaterializedFrame; -import com.oracle.truffle.api.nodes.Node; - -/** - * Summary of information about a frame for use by debugging clients. - */ -public final class FrameDebugDescription { - private final int index; - private final Node node; - private final MaterializedFrame frame; - - FrameDebugDescription(int index, Node node, MaterializedFrame frame) { - this.index = index; - this.node = node; - this.frame = frame; - } - - FrameDebugDescription(int index, FrameInstance frameInstance) { - this.index = index; - this.node = frameInstance.getCallNode(); - this.frame = frameInstance.getFrame(FrameAccess.MATERIALIZE, true).materialize(); - } - - /** - * Position in the current stack: {@code 0} at the top. - */ - public int index() { - return index; - } - - /** - * AST location of the call that created the frame. - */ - public Node node() { - return node; - } - - public MaterializedFrame frame() { - return frame; - } -} diff -r c434681cd164 -r 4a83dc15e774 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/SuspendedEvent.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/SuspendedEvent.java Mon Dec 07 18:21:03 2015 -0800 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/SuspendedEvent.java Mon Dec 07 20:48:29 2015 -0800 @@ -30,6 +30,8 @@ import java.util.List; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.frame.FrameInstance; +import com.oracle.truffle.api.frame.FrameInstance.FrameAccess; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.instrument.StandardSyntaxTag; import com.oracle.truffle.api.nodes.Node; @@ -58,15 +60,19 @@ } private final Debugger debugger; - private final List stack; + private final Node haltedNode; + private final MaterializedFrame haltedFrame; + private final List stack; private final List warnings; - SuspendedEvent(Debugger debugger, List stack, List warnings) { + SuspendedEvent(Debugger debugger, Node haltedNode, MaterializedFrame haltedFrame, List stack, List warnings) { this.debugger = debugger; + this.haltedNode = haltedNode; + this.haltedFrame = haltedFrame; this.stack = stack; this.warnings = warnings; if (TRACE) { - trace("Execution suspended at Node=" + stack.get(0).node()); + trace("Execution suspended at Node=" + haltedNode); } } @@ -83,11 +89,11 @@ } public Node getNode() { - return stack.get(0).node(); + return haltedNode; } public MaterializedFrame getFrame() { - return stack.get(0).frame(); + return haltedFrame; } public List getRecentWarnings() { @@ -96,12 +102,13 @@ /** * Gets the stack frames from the currently halted - * {@link com.oracle.truffle.api.vm.PolyglotEngine} execution. + * {@link com.oracle.truffle.api.vm.PolyglotEngine} execution, not counting the Node and Frame + * where halted. * * @return list of stack frames */ @CompilerDirectives.TruffleBoundary - public List getStack() { + public List getStack() { return stack; } @@ -188,20 +195,20 @@ * Evaluates given code snippet in the context of currently suspended execution. * * @param code the snippet to evaluate - * @param frameNumber null in case the evaluation should happen in top most frame, - * non-null value to specify a frame from those {@link #getStack() currently on - * stack} to perform the evaluation in context of + * @param frameNumber specify a frame from those {@link #getStack() currently on stack} to + * perform the evaluation in context of * @return the computed value * @throws IOException in case an evaluation goes wrong */ public Object eval(String code, Integer frameNumber) throws IOException { - int n = 0; - if (frameNumber != null) { - if (frameNumber < 0 || frameNumber >= stack.size()) { - throw new IOException("invalid frame number"); - } - n = frameNumber; + if (frameNumber < 0 || frameNumber >= stack.size()) { + throw new IOException("invalid frame number"); } - return debugger.evalInContext(this, code, stack.get(n).node(), stack.get(n).frame()); + if (frameNumber == 0) { + return debugger.evalInContext(this, code, haltedNode, haltedFrame); + } + final FrameInstance instance = stack.get(frameNumber - 1); + final MaterializedFrame frame = instance.getFrame(FrameAccess.MATERIALIZE, true).materialize(); + return debugger.evalInContext(this, code, instance.getCallNode(), frame); } } diff -r c434681cd164 -r 4a83dc15e774 truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLHandler.java --- a/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLHandler.java Mon Dec 07 18:21:03 2015 -0800 +++ b/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLHandler.java Mon Dec 07 20:48:29 2015 -0800 @@ -29,9 +29,10 @@ import java.util.Collection; import java.util.List; -import com.oracle.truffle.api.debug.FrameDebugDescription; -import com.oracle.truffle.api.frame.Frame; +import com.oracle.truffle.api.frame.FrameInstance; +import com.oracle.truffle.api.frame.FrameInstance.FrameAccess; import com.oracle.truffle.api.frame.FrameSlot; +import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.instrument.ASTPrinter; import com.oracle.truffle.api.instrument.KillException; import com.oracle.truffle.api.instrument.QuitException; @@ -150,10 +151,11 @@ public REPLMessage[] receive(REPLMessage request, REPLServer replServer) { final Visualizer visualizer = replServer.getVisualizer(); final ArrayList replies = new ArrayList<>(); - final List stack = replServer.getCurrentContext().getStack(); - - for (int i = 0; i < stack.size(); i++) { - replies.add(btMessage(i, stack.get(i).node(), visualizer)); + final Context currentContext = replServer.getCurrentContext(); + final List stack = currentContext.getStack(); + replies.add(btMessage(0, currentContext.getNode(), visualizer)); + for (int i = 1; i <= stack.size(); i++) { + replies.add(btMessage(i, stack.get(i - 1).getCallNode(), visualizer)); } if (replies.size() > 0) { return replies.toArray(new REPLMessage[0]); @@ -469,17 +471,24 @@ if (frameNumber == null) { return finishReplyFailed(createReply(), "no frame number specified"); } - final List stack = replServer.getCurrentContext().getStack(); - if (frameNumber < 0 || frameNumber >= stack.size()) { + final Context currentContext = replServer.getCurrentContext(); + final List stack = currentContext.getStack(); + if (frameNumber < 0 || frameNumber > stack.size()) { return finishReplyFailed(createReply(), "frame number " + frameNumber + " out of range"); } final Visualizer visualizer = replServer.getVisualizer(); - final FrameDebugDescription frameDescription = stack.get(frameNumber); - final Frame frame = frameDescription.frame(); - final Node node = frameDescription.node(); + MaterializedFrame frame; + Node node; + if (frameNumber == 0) { + frame = currentContext.getFrame(); + node = currentContext.getNode(); + } else { + final FrameInstance instance = stack.get(frameNumber - 1); + frame = instance.getFrame(FrameAccess.MATERIALIZE, true).materialize(); + node = instance.getCallNode(); + } List slots = frame.getFrameDescriptor().getSlots(); - if (slots.size() == 0) { final REPLMessage emptyFrameMessage = createFrameInfoMessage(replServer, frameNumber, node); return finishReplySucceeded(emptyFrameMessage, "empty frame"); diff -r c434681cd164 -r 4a83dc15e774 truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLServer.java --- a/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLServer.java Mon Dec 07 18:21:03 2015 -0800 +++ b/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLServer.java Mon Dec 07 20:48:29 2015 -0800 @@ -39,8 +39,8 @@ import com.oracle.truffle.api.debug.Breakpoint.State; import com.oracle.truffle.api.debug.Debugger; import com.oracle.truffle.api.debug.ExecutionEvent; -import com.oracle.truffle.api.debug.FrameDebugDescription; import com.oracle.truffle.api.debug.SuspendedEvent; +import com.oracle.truffle.api.frame.FrameInstance; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.instrument.StandardSyntaxTag; import com.oracle.truffle.api.instrument.SyntaxTag; @@ -377,11 +377,25 @@ } /** - * Provides access to the execution stack. + * @return Node where halted + */ + Node getNode() { + return event.getNode(); + } + + /** + * @return Frame where halted + */ + MaterializedFrame getFrame() { + return event.getFrame(); + } + + /** + * Provides access to the execution stack, not counting the node/frame where halted. * * @return immutable list of stack elements */ - List getStack() { + List getStack() { return event.getStack(); }