changeset 15564:a3b0ecef8a15

Truffle: Provide default implementation on non-Graal VMs for stack trace functionality.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Thu, 08 May 2014 22:53:28 +0200
parents de3dca7cc6fd
children 6b7c5c7d0d81
files graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultDirectCallNode.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLStackTraceBuiltin.java
diffstat 5 files changed, 91 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- 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()));
         }
     }
 
--- 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);
+        }
     }
 }
--- 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
--- 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<LinkedList<FrameInstance>> stackTraces = new ThreadLocal<>();
+    private ThreadLocal<FrameInstance> 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<FrameInstance> getThreadLocalStackTrace() {
+        LinkedList<FrameInstance> 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<FrameInstance> 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();
     }
 }
--- 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));