# HG changeset patch # User Thomas Wuerthinger # Date 1399582408 -7200 # Node ID a3b0ecef8a156e7f74cc3e7ebb1e99cad546424a # Parent de3dca7cc6fdacb51b5232e24328f6600f21727c Truffle: Provide default implementation on non-Graal VMs for stack trace functionality. diff -r de3dca7cc6fd -r a3b0ecef8a15 graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java --- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Thu May 08 15:00:52 2014 +0200 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Thu May 08 22:53:28 2014 +0200 @@ -55,7 +55,6 @@ import com.oracle.truffle.api.*; import com.oracle.truffle.api.CompilerDirectives.SlowPath; import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.impl.*; import com.oracle.truffle.api.nodes.*; /** @@ -119,7 +118,7 @@ if (target instanceof OptimizedCallTarget) { return OptimizedDirectCallNode.create((OptimizedCallTarget) target); } else { - return new DefaultDirectCallNode(target); + throw new IllegalStateException(String.format("Unexpected call target class %s!", target.getClass())); } } diff -r de3dca7cc6fd -r a3b0ecef8a15 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java Thu May 08 15:00:52 2014 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java Thu May 08 22:53:28 2014 +0200 @@ -35,11 +35,13 @@ public class DefaultCallTarget implements RootCallTarget { private final RootNode rootNode; + private final DefaultTruffleRuntime defaultTruffleRuntime; - public DefaultCallTarget(RootNode function) { + public DefaultCallTarget(RootNode function, DefaultTruffleRuntime defaultTruffleRuntime) { this.rootNode = function; this.rootNode.adoptChildren(); this.rootNode.setCallTarget(this); + this.defaultTruffleRuntime = defaultTruffleRuntime; } @Override @@ -53,7 +55,29 @@ @Override public Object call(Object... args) { - VirtualFrame frame = new DefaultVirtualFrame(getRootNode().getFrameDescriptor(), args); - return getRootNode().execute(frame); + final VirtualFrame frame = new DefaultVirtualFrame(getRootNode().getFrameDescriptor(), args); + FrameInstance oldCurrentFrame = defaultTruffleRuntime.setCurrentFrame(new FrameInstance() { + + public Frame getFrame(FrameAccess access, boolean slowPath) { + return frame; + } + + public boolean isVirtualFrame() { + return false; + } + + public Node getCallNode() { + return null; + } + + public CallTarget getCallTarget() { + return DefaultCallTarget.this; + } + }); + try { + return getRootNode().execute(frame); + } finally { + defaultTruffleRuntime.setCurrentFrame(oldCurrentFrame); + } } } diff -r de3dca7cc6fd -r a3b0ecef8a15 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultDirectCallNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultDirectCallNode.java Thu May 08 15:00:52 2014 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultDirectCallNode.java Thu May 08 22:53:28 2014 +0200 @@ -34,14 +34,40 @@ public final class DefaultDirectCallNode extends DirectCallNode { private boolean inliningForced; + private final DefaultTruffleRuntime defaultTruffleRuntime; - public DefaultDirectCallNode(CallTarget target) { + public DefaultDirectCallNode(CallTarget target, DefaultTruffleRuntime defaultTruffleRuntime) { super(target); + this.defaultTruffleRuntime = defaultTruffleRuntime; } @Override - public Object call(VirtualFrame frame, Object[] arguments) { - return getCurrentCallTarget().call(arguments); + public Object call(final VirtualFrame frame, Object[] arguments) { + final CallTarget currentCallTarget = defaultTruffleRuntime.getCurrentFrame().getCallTarget(); + FrameInstance frameInstance = new FrameInstance() { + + public Frame getFrame(FrameAccess access, boolean slowPath) { + return frame; + } + + public boolean isVirtualFrame() { + return false; + } + + public Node getCallNode() { + return DefaultDirectCallNode.this; + } + + public CallTarget getCallTarget() { + return currentCallTarget; + } + }; + defaultTruffleRuntime.pushFrame(frameInstance); + try { + return getCurrentCallTarget().call(arguments); + } finally { + defaultTruffleRuntime.popFrame(); + } } @Override diff -r de3dca7cc6fd -r a3b0ecef8a15 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java Thu May 08 15:00:52 2014 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java Thu May 08 22:53:28 2014 +0200 @@ -24,6 +24,8 @@ */ package com.oracle.truffle.api.impl; +import java.util.*; + import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; @@ -37,6 +39,9 @@ */ public final class DefaultTruffleRuntime implements TruffleRuntime { + private ThreadLocal> stackTraces = new ThreadLocal<>(); + private ThreadLocal currentFrames = new ThreadLocal<>(); + public DefaultTruffleRuntime() { if (Truffle.getRuntime() != null) { throw new IllegalArgumentException("Cannot instantiate DefaultTruffleRuntime. Use Truffle.getRuntime() instead."); @@ -50,11 +55,11 @@ @Override public RootCallTarget createCallTarget(RootNode rootNode) { - return new DefaultCallTarget(rootNode); + return new DefaultCallTarget(rootNode, this); } public DirectCallNode createDirectCallNode(CallTarget target) { - return new DefaultDirectCallNode(target); + return new DefaultDirectCallNode(target, this); } public IndirectCallNode createIndirectCallNode() { @@ -86,13 +91,34 @@ return new DefaultAssumption(name); } + private LinkedList getThreadLocalStackTrace() { + LinkedList result = stackTraces.get(); + if (result == null) { + result = new LinkedList<>(); + stackTraces.set(result); + } + return result; + } + + public FrameInstance setCurrentFrame(FrameInstance newValue) { + FrameInstance oldValue = currentFrames.get(); + currentFrames.set(newValue); + return oldValue; + } + + public void pushFrame(FrameInstance frame) { + getThreadLocalStackTrace().addFirst(frame); + } + + public void popFrame() { + getThreadLocalStackTrace().removeFirst(); + } + public Iterable getStackTrace() { - // TODO(lstadler) implement this using ThreadLocal - return null; + return getThreadLocalStackTrace(); } public FrameInstance getCurrentFrame() { - // TODO(lstadler) implement this using ThreadLocal - return null; + return currentFrames.get(); } } diff -r de3dca7cc6fd -r a3b0ecef8a15 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLStackTraceBuiltin.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLStackTraceBuiltin.java Thu May 08 15:00:52 2014 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLStackTraceBuiltin.java Thu May 08 22:53:28 2014 +0200 @@ -55,11 +55,11 @@ return str.toString(); } - private static void dumpFrame(StringBuilder str, CallTarget rootNode, Frame frame, boolean isVirtual) { + private static void dumpFrame(StringBuilder str, CallTarget callTarget, Frame frame, boolean isVirtual) { if (str.length() > 0) { str.append("\n"); } - str.append("Frame: ").append(rootNode).append(isVirtual ? " (virtual)" : ""); + str.append("Frame: ").append(callTarget).append(isVirtual ? " (virtual)" : ""); FrameDescriptor frameDescriptor = frame.getFrameDescriptor(); for (FrameSlot s : frameDescriptor.getSlots()) { str.append(", ").append(s.getIdentifier()).append("=").append(frame.getValue(s));