changeset 15064:f675818d9ad0

new getStackTrace and getCurrentFrame functionality in TruffleRuntime
author Lukas Stadler <lukas.stadler@oracle.com>
date Fri, 11 Apr 2014 11:53:11 +0200
parents 36e1a11a72b3
children f5ef63b5b5ed b8ab8de26519
files graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotFrameInstance.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/ReadOnlyFrame.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/ForceMaterializeNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ThreadSafetyTest.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CallTarget.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/RootCallTarget.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameInstance.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallNode.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/DefaultTruffleRuntime.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/MaterializedFrameNotify.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/CallNode.java graal/com.oracle.truffle.sl.test/tests/HelloEqualsWorld.output graal/com.oracle.truffle.sl.test/tests/HelloEqualsWorld.sl graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLHelloEqualsWorldBuiltin.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLStackTraceBuiltin.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLDirectDispatchNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLGenericDispatchNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java
diffstat 25 files changed, 832 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotFrameInstance.java	Fri Apr 11 11:53:11 2014 +0200
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 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.truffle.hotspot;
+
+import java.lang.reflect.*;
+
+import com.oracle.graal.api.code.stack.*;
+import com.oracle.graal.graph.*;
+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.*;
+
+public abstract class HotSpotFrameInstance implements FrameInstance {
+
+    private final InspectedFrame stackFrame;
+
+    public HotSpotFrameInstance(InspectedFrame stackFrame) {
+        this.stackFrame = stackFrame;
+    }
+
+    protected abstract int getNotifyIndex();
+
+    protected abstract int getCallTargetIndex();
+
+    protected abstract int getFrameIndex();
+
+    @SlowPath
+    public Frame getFrame(FrameAccess access, boolean slowPath) {
+        if (access == FrameAccess.NONE) {
+            return null;
+        }
+        if (!slowPath) {
+            MaterializedFrameNotify notify = (MaterializedFrameNotify) stackFrame.getLocal(getNotifyIndex());
+            if (access.ordinal() > notify.getOutsideFrameAccess().ordinal()) {
+                notify.setOutsideFrameAccess(access);
+            }
+            if (stackFrame.isVirtual(getFrameIndex())) {
+                stackFrame.materializeVirtualObjects(true);
+            }
+        }
+        switch (access) {
+            case READ_ONLY: {
+                Frame frame = (Frame) stackFrame.getLocal(getFrameIndex());
+                // assert that it is really used read only
+                assert (frame = new ReadOnlyFrame(frame)) != null;
+                return frame;
+            }
+            case READ_WRITE:
+            case MATERIALIZE:
+                if (stackFrame.isVirtual(getFrameIndex())) {
+                    stackFrame.materializeVirtualObjects(false);
+                }
+                return (Frame) stackFrame.getLocal(getFrameIndex());
+            default:
+                throw GraalInternalError.unimplemented();
+        }
+    }
+
+    public boolean isVirtualFrame() {
+        return stackFrame.isVirtual(getFrameIndex());
+    }
+
+    public CallTarget getCallTarget() {
+        return (CallTarget) stackFrame.getLocal(getCallTargetIndex());
+    }
+
+    public CallNode getCallNode() {
+        Object receiver = stackFrame.getLocal(getNotifyIndex());
+        if (receiver instanceof CallNode) {
+            return (CallNode) receiver;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * This class represents a frame that is taken from the
+     * {@link DefaultCallNode#callProxy(MaterializedFrameNotify, CallTarget, VirtualFrame, Object[])}
+     * method.
+     */
+    public static final class NextFrame extends HotSpotFrameInstance {
+        public static final Method METHOD;
+        static {
+            try {
+                METHOD = DefaultCallNode.class.getDeclaredMethod("callProxy", MaterializedFrameNotify.class, CallTarget.class, VirtualFrame.class, Object[].class);
+            } catch (NoSuchMethodException | SecurityException e) {
+                throw new GraalInternalError(e);
+            }
+        }
+        private static final int NOTIFY_INDEX = 0;
+        private static final int CALL_TARGET_INDEX = 1;
+        private static final int FRAME_INDEX = 2;
+
+        public NextFrame(InspectedFrame stackFrame) {
+            super(stackFrame);
+        }
+
+        @Override
+        protected int getNotifyIndex() {
+            return NOTIFY_INDEX;
+        }
+
+        @Override
+        protected int getCallTargetIndex() {
+            return CALL_TARGET_INDEX;
+        }
+
+        @Override
+        protected int getFrameIndex() {
+            return FRAME_INDEX;
+        }
+    }
+
+    /**
+     * This class represents a frame that is taken from the
+     * {@link RootCallTarget#callProxy(VirtualFrame)} method.
+     */
+    @SuppressWarnings("javadoc")
+    public static final class CurrentFrame extends HotSpotFrameInstance {
+        public static final Method METHOD;
+        static {
+            try {
+                METHOD = RootCallTarget.class.getDeclaredMethod("callProxy", VirtualFrame.class);
+            } catch (NoSuchMethodException | SecurityException e) {
+                throw new GraalInternalError(e);
+            }
+        }
+        private static final int NOTIFY_INDEX = 0;
+        private static final int CALL_TARGET_INDEX = 0;
+        private static final int FRAME_INDEX = 1;
+
+        public CurrentFrame(InspectedFrame stackFrame) {
+            super(stackFrame);
+        }
+
+        @Override
+        public Frame getFrame(FrameAccess access, boolean slowPath) {
+            if (!slowPath) {
+                throw new UnsupportedOperationException("cannot access current frame as fast path");
+            }
+            return super.getFrame(access, slowPath);
+        }
+
+        @Override
+        protected int getNotifyIndex() {
+            return NOTIFY_INDEX;
+        }
+
+        @Override
+        protected int getCallTargetIndex() {
+            return CALL_TARGET_INDEX;
+        }
+
+        @Override
+        protected int getFrameIndex() {
+            return FRAME_INDEX;
+        }
+    }
+}
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Fri Apr 11 11:52:19 2014 +0200
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Fri Apr 11 11:53:11 2014 +0200
@@ -31,6 +31,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.CallingConvention.Type;
+import com.oracle.graal.api.code.stack.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.target.*;
@@ -48,6 +49,7 @@
 import com.oracle.graal.runtime.*;
 import com.oracle.graal.truffle.*;
 import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.CompilerDirectives.*;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.impl.*;
 import com.oracle.truffle.api.nodes.*;
@@ -63,6 +65,7 @@
 
     private TruffleCompiler truffleCompiler;
     private Replacements truffleReplacements;
+    private StackIntrospection stackIntrospection;
     private ArrayList<String> includes;
     private ArrayList<String> excludes;
 
@@ -212,4 +215,42 @@
         RuntimeProvider runtimeProvider = Graal.getRequiredCapability(RuntimeProvider.class);
         return runtimeProvider.getHostBackend().getProviders();
     }
+
+    @SlowPath
+    public Iterable<FrameInstance> getStackTrace() {
+        if (stackIntrospection == null) {
+            stackIntrospection = Graal.getRequiredCapability(StackIntrospection.class);
+        }
+        ResolvedJavaMethod method = getGraalProviders().getMetaAccess().lookupJavaMethod(HotSpotFrameInstance.NextFrame.METHOD);
+        final Iterator<InspectedFrame> frames = stackIntrospection.getStackTrace(method, method).iterator();
+        class FrameIterator implements Iterator<FrameInstance> {
+            public boolean hasNext() {
+                return frames.hasNext();
+            }
+
+            public FrameInstance next() {
+                InspectedFrame frame = frames.next();
+                return new HotSpotFrameInstance.NextFrame(frame);
+            }
+        }
+        return new Iterable<FrameInstance>() {
+            public Iterator<FrameInstance> iterator() {
+                return new FrameIterator();
+            }
+        };
+    }
+
+    public FrameInstance getCurrentFrame() {
+        if (stackIntrospection == null) {
+            stackIntrospection = Graal.getRequiredCapability(StackIntrospection.class);
+        }
+        ResolvedJavaMethod method = getGraalProviders().getMetaAccess().lookupJavaMethod(HotSpotFrameInstance.CurrentFrame.METHOD);
+        Iterator<InspectedFrame> frames = stackIntrospection.getStackTrace(method, method).iterator();
+        if (frames.hasNext()) {
+            return new HotSpotFrameInstance.CurrentFrame(frames.next());
+        } else {
+            System.out.println("no current frame found");
+            return null;
+        }
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/ReadOnlyFrame.java	Fri Apr 11 11:53:11 2014 +0200
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 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.truffle.hotspot;
+
+import com.oracle.graal.graph.*;
+import com.oracle.truffle.api.frame.*;
+
+class ReadOnlyFrame implements Frame {
+    private final Frame delegate;
+
+    public ReadOnlyFrame(Frame delegate) {
+        this.delegate = delegate;
+    }
+
+    public FrameDescriptor getFrameDescriptor() {
+        return delegate.getFrameDescriptor();
+    }
+
+    public Object[] getArguments() {
+        return delegate.getArguments().clone();
+    }
+
+    public Object getObject(FrameSlot slot) throws FrameSlotTypeException {
+        return delegate.getObject(slot);
+    }
+
+    public void setObject(FrameSlot slot, Object value) {
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    public byte getByte(FrameSlot slot) throws FrameSlotTypeException {
+        return delegate.getByte(slot);
+    }
+
+    public void setByte(FrameSlot slot, byte value) {
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    public boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException {
+        return delegate.getBoolean(slot);
+    }
+
+    public void setBoolean(FrameSlot slot, boolean value) {
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    public int getInt(FrameSlot slot) throws FrameSlotTypeException {
+        return delegate.getInt(slot);
+    }
+
+    public void setInt(FrameSlot slot, int value) {
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    public long getLong(FrameSlot slot) throws FrameSlotTypeException {
+        return delegate.getLong(slot);
+    }
+
+    public void setLong(FrameSlot slot, long value) {
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    public float getFloat(FrameSlot slot) throws FrameSlotTypeException {
+        return delegate.getFloat(slot);
+    }
+
+    public void setFloat(FrameSlot slot, float value) {
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    public double getDouble(FrameSlot slot) throws FrameSlotTypeException {
+        return delegate.getDouble(slot);
+    }
+
+    public void setDouble(FrameSlot slot, double value) {
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    public Object getValue(FrameSlot slot) {
+        return delegate.getValue(slot);
+    }
+
+    public MaterializedFrame materialize() {
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    public boolean isObject(FrameSlot slot) {
+        return delegate.isObject(slot);
+    }
+
+    public boolean isByte(FrameSlot slot) {
+        return delegate.isByte(slot);
+    }
+
+    public boolean isBoolean(FrameSlot slot) {
+        return delegate.isBoolean(slot);
+    }
+
+    public boolean isInt(FrameSlot slot) {
+        return delegate.isInt(slot);
+    }
+
+    public boolean isLong(FrameSlot slot) {
+        return delegate.isLong(slot);
+    }
+
+    public boolean isFloat(FrameSlot slot) {
+        return delegate.isFloat(slot);
+    }
+
+    public boolean isDouble(FrameSlot slot) {
+        return delegate.isDouble(slot);
+    }
+}
\ No newline at end of file
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNode.java	Fri Apr 11 11:52:19 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNode.java	Fri Apr 11 11:53:11 2014 +0200
@@ -26,6 +26,7 @@
 
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.impl.*;
 import com.oracle.truffle.api.nodes.*;
 import com.oracle.truffle.api.nodes.NodeUtil.NodeCountFilter;
@@ -74,14 +75,14 @@
     }
 
     @Override
-    public Object call(Object[] arguments) {
+    public Object call(VirtualFrame frame, Object[] arguments) {
         if (CompilerDirectives.inInterpreter()) {
             interpreterCall();
             if (inliningCounter.get() > 0 || inliningForced) {
                 return getCurrentCallTarget().callInlined(arguments);
             }
         }
-        return getCurrentCallTarget().call(arguments);
+        return callProxy(this, getCurrentCallTarget(), frame, arguments);
     }
 
     private void interpreterCall() {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Fri Apr 11 11:52:19 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Fri Apr 11 11:53:11 2014 +0200
@@ -162,13 +162,17 @@
 
     public final Object executeHelper(Object[] args) {
         VirtualFrame frame = createFrame(getRootNode().getFrameDescriptor(), args);
-        return getRootNode().execute(frame);
+        return callProxy(frame);
     }
 
     public static FrameWithoutBoxing createFrame(FrameDescriptor descriptor, Object[] args) {
         return new FrameWithoutBoxing(descriptor, args);
     }
 
+    public static FrameWithoutBoxing createMaterializedFrame(FrameDescriptor descriptor, Object[] args) {
+        return new FrameWithoutBoxing(descriptor, args);
+    }
+
     @Override
     public void reportLoopCount(int count) {
         compilationProfile.reportLoopCount(count);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/ForceMaterializeNode.java	Fri Apr 11 11:53:11 2014 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 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.truffle.nodes.frame;
+
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.type.*;
+
+public class ForceMaterializeNode extends FixedWithNextNode implements LIRGenLowerable {
+
+    @Input private ValueNode object;
+
+    public ForceMaterializeNode(ValueNode object) {
+        super(StampFactory.forVoid());
+        this.object = object;
+    }
+
+    public void generate(NodeLIRBuilder generator) {
+        // nothing to do
+    }
+
+    @NodeIntrinsic
+    public native static void force(Object object);
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java	Fri Apr 11 11:52:19 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java	Fri Apr 11 11:53:11 2014 +0200
@@ -31,6 +31,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.truffle.*;
 import com.oracle.graal.truffle.nodes.*;
+import com.oracle.graal.truffle.nodes.frame.*;
 import com.oracle.graal.truffle.nodes.typesystem.*;
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.frame.*;
@@ -165,4 +166,10 @@
     public static Object unsafeGetFinalObject(Object receiver, long offset, boolean condition, Object locationIdentity) {
         return CustomizedUnsafeLoadFinalNode.load(receiver, offset, condition, locationIdentity, Kind.Object);
     }
+
+    @MethodSubstitution
+    public static void materialize(Object obj) {
+        ForceMaterializeNode.force(obj);
+    }
+
 }
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ThreadSafetyTest.java	Fri Apr 11 11:52:19 2014 +0200
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ThreadSafetyTest.java	Fri Apr 11 11:53:11 2014 +0200
@@ -176,7 +176,7 @@
         int execute(VirtualFrame frame) {
             int arg = (Integer) frame.getArguments()[0];
             if (arg > 0) {
-                return (int) callNode.call(new Object[]{(arg - 1)});
+                return (int) callNode.call(frame, new Object[]{(arg - 1)});
             } else {
                 return valueNode.execute(frame);
             }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CallTarget.java	Fri Apr 11 11:52:19 2014 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CallTarget.java	Fri Apr 11 11:53:11 2014 +0200
@@ -42,4 +42,6 @@
     public final Object call() {
         return call(NO_ARGUMENTS);
     }
+
+    public abstract void setNeedsMaterializedFrame();
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Fri Apr 11 11:52:19 2014 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Fri Apr 11 11:53:11 2014 +0200
@@ -619,4 +619,13 @@
     @Target({ElementType.TYPE})
     public @interface ValueType {
     }
+
+    /**
+     * Ensures that the given object is not virtual, i.e., not removed by Escape Analysis at the
+     * point of this call.
+     *
+     * @param obj the object to exclude from Escape Analysis
+     */
+    public static void materialize(Object obj) {
+    }
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/RootCallTarget.java	Fri Apr 11 11:52:19 2014 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/RootCallTarget.java	Fri Apr 11 11:53:11 2014 +0200
@@ -24,6 +24,7 @@
  */
 package com.oracle.truffle.api;
 
+import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.nodes.*;
 
 /**
@@ -48,4 +49,13 @@
     public final RootNode getRootNode() {
         return rootNode;
     }
+
+    protected final Object callProxy(VirtualFrame frame) {
+        try {
+            return getRootNode().execute(frame);
+        } finally {
+            // this assertion is needed to keep the values from being cleared as non-live locals
+            assert frame != null && this != null;
+        }
+    }
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java	Fri Apr 11 11:52:19 2014 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java	Fri Apr 11 11:53:11 2014 +0200
@@ -25,6 +25,7 @@
 package com.oracle.truffle.api;
 
 import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.impl.*;
 import com.oracle.truffle.api.nodes.*;
 
 /**
@@ -90,4 +91,20 @@
      * @return the newly created materialized frame object
      */
     MaterializedFrame createMaterializedFrame(Object[] arguments, FrameDescriptor frameDescriptor);
+
+    /**
+     * Accesses the current stack, i.e., the contents of the {@link Frame}s and the associated
+     * {@link CallTarget}s. For this functionality to work each call needs to go through
+     * {@link DefaultCallNode#callProxy(MaterializedFrameNotify, CallTarget, VirtualFrame, Object[])}
+     * instead of calling {@link CallTarget#call(Object[])} directly.
+     *
+     * @return a lazy collection of {@link FrameInstance}.
+     */
+    Iterable<FrameInstance> getStackTrace();
+
+    /**
+     * Accesses the current frame, i.e., the frame of the closest {@link CallTarget}. It is
+     * important to note that this {@link FrameInstance} supports only slow path access.
+     */
+    FrameInstance getCurrentFrame();
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameInstance.java	Fri Apr 11 11:53:11 2014 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 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.  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.frame;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.nodes.*;
+
+public interface FrameInstance {
+
+    public static enum FrameAccess {
+        NONE,
+        READ_ONLY,
+        READ_WRITE,
+        MATERIALIZE
+    }
+
+    Frame getFrame(FrameAccess access, boolean slowPath);
+
+    boolean isVirtualFrame();
+
+    CallNode getCallNode();
+
+    CallTarget getCallTarget();
+}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallNode.java	Fri Apr 11 11:52:19 2014 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallNode.java	Fri Apr 11 11:53:11 2014 +0200
@@ -25,17 +25,44 @@
 package com.oracle.truffle.api.impl;
 
 import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.CompilerDirectives.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.frame.FrameInstance.*;
 import com.oracle.truffle.api.nodes.*;
 
-public class DefaultCallNode extends CallNode {
+public class DefaultCallNode extends CallNode implements MaterializedFrameNotify {
+
+    @CompilationFinal private FrameAccess outsideFrameAccess = FrameAccess.NONE;
 
     public DefaultCallNode(CallTarget target) {
         super(target);
     }
 
     @Override
-    public Object call(Object[] arguments) {
-        return getCurrentCallTarget().call(arguments);
+    public Object call(VirtualFrame frame, Object[] arguments) {
+        return callProxy(this, getCurrentCallTarget(), frame, arguments);
+    }
+
+    public static Object callProxy(MaterializedFrameNotify notify, CallTarget callTarget, VirtualFrame frame, Object[] arguments) {
+        try {
+            if (notify.getOutsideFrameAccess() != FrameAccess.NONE) {
+                CompilerDirectives.materialize(frame);
+            }
+            return callTarget.call(arguments);
+        } finally {
+            // this assertion is needed to keep the values from being cleared as non-live locals
+            assert notify != null & callTarget != null & frame != null;
+        }
+    }
+
+    @Override
+    public FrameAccess getOutsideFrameAccess() {
+        return outsideFrameAccess;
+    }
+
+    @Override
+    public void setOutsideFrameAccess(FrameAccess outsideFrameAccess) {
+        this.outsideFrameAccess = outsideFrameAccess;
     }
 
     @Override
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java	Fri Apr 11 11:52:19 2014 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java	Fri Apr 11 11:53:11 2014 +0200
@@ -25,6 +25,7 @@
 package com.oracle.truffle.api.impl;
 
 import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.nodes.*;
 
@@ -34,6 +35,8 @@
  */
 public class DefaultCallTarget extends RootCallTarget {
 
+    @CompilationFinal protected boolean needsMaterializedFrame = true;
+
     protected DefaultCallTarget(RootNode function) {
         super(function);
     }
@@ -41,6 +44,11 @@
     @Override
     public Object call(Object[] args) {
         VirtualFrame frame = new DefaultVirtualFrame(getRootNode().getFrameDescriptor(), args);
-        return getRootNode().execute(frame);
+        return callProxy(frame);
+    }
+
+    @Override
+    public void setNeedsMaterializedFrame() {
+        needsMaterializedFrame = true;
     }
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java	Fri Apr 11 11:52:19 2014 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java	Fri Apr 11 11:53:11 2014 +0200
@@ -81,4 +81,14 @@
     public Assumption createAssumption(String name) {
         return new DefaultAssumption(name);
     }
+
+    public Iterable<FrameInstance> getStackTrace() {
+        // TODO(lstadler) implement this using ThreadLocal
+        return null;
+    }
+
+    public FrameInstance getCurrentFrame() {
+        // TODO(lstadler) implement this using ThreadLocal
+        return null;
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/MaterializedFrameNotify.java	Fri Apr 11 11:53:11 2014 +0200
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 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.  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.impl;
+
+import com.oracle.truffle.api.frame.FrameInstance.*;
+
+public interface MaterializedFrameNotify {
+
+    FrameAccess getOutsideFrameAccess();
+
+    void setOutsideFrameAccess(FrameAccess outsideFrameAccess);
+}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/CallNode.java	Fri Apr 11 11:52:19 2014 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/CallNode.java	Fri Apr 11 11:53:11 2014 +0200
@@ -25,11 +25,14 @@
 package com.oracle.truffle.api.nodes;
 
 import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
+import com.oracle.truffle.api.frame.*;
 
 /**
- * Represents a call to a {@link CallTarget} in the Truffle AST. Addtionally to calling the
- * {@link CallTarget} this {@link Node} enables the runtime system to implement further
- * optimizations. Optimizations that can possibly applied to a {@link CallNode} are inlining and
+ * Represents a call to a {@link CallTarget} in the Truffle AST. In addition to calling the
+ * {@link CallTarget}, this {@link Node} enables the runtime system to implement further
+ * optimizations. Optimizations that can possibly be applied to a {@link CallNode} are inlining and
  * splitting. Inlining inlines this call site into the call graph of the parent {@link CallTarget}.
  * Splitting duplicates the {@link CallTarget} using {@link RootNode#split()} to collect call site
  * sensitive profiling information.
@@ -54,7 +57,7 @@
      * @param arguments the arguments that should be passed to the callee
      * @return the return result of the call
      */
-    public abstract Object call(Object[] arguments);
+    public abstract Object call(VirtualFrame frame, Object[] arguments);
 
     /**
      * Returns the originally supplied {@link CallTarget} when this call node was created. Please
@@ -115,14 +118,14 @@
     }
 
     /**
-     * Returns the splitted {@link CallTarget} if this method is split.
+     * Returns the split {@link CallTarget} if this method is split.
      *
      * @return the split {@link CallTarget}
      */
     public abstract CallTarget getSplitCallTarget();
 
     /**
-     * Returns the used call target when {@link #call(Object[])} is invoked. If the
+     * Returns the used call target when {@link #call(VirtualFrame, Object[])} is invoked. If the
      * {@link CallTarget} was split this method returns the {@link CallTarget} returned by
      * {@link #getSplitCallTarget()}.
      *
@@ -152,5 +155,4 @@
         }
         return null;
     }
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/HelloEqualsWorld.output	Fri Apr 11 11:53:11 2014 +0200
@@ -0,0 +1,90 @@
+Initial stack trace:
+Frame: root doIt, a=0, hello=null
+Frame: root main, i=0
+After 123 assignment:
+Frame: root doIt, a=0, hello=123
+Frame: root main, i=0
+After hello assignment:
+Frame: root doIt, a=0, hello=world
+Frame: root main, i=0
+Initial stack trace:
+Frame: root doIt, a=1, hello=null
+Frame: root main, i=1
+After 123 assignment:
+Frame: root doIt, a=1, hello=123
+Frame: root main, i=1
+After hello assignment:
+Frame: root doIt, a=1, hello=world
+Frame: root main, i=1
+Initial stack trace:
+Frame: root doIt, a=2, hello=null
+Frame: root main, i=2
+After 123 assignment:
+Frame: root doIt, a=2, hello=123
+Frame: root main, i=2
+After hello assignment:
+Frame: root doIt, a=2, hello=world
+Frame: root main, i=2
+Initial stack trace:
+Frame: root doIt, a=3, hello=null
+Frame: root main, i=3
+After 123 assignment:
+Frame: root doIt, a=3, hello=123
+Frame: root main, i=3
+After hello assignment:
+Frame: root doIt, a=3, hello=world
+Frame: root main, i=3
+Initial stack trace:
+Frame: root doIt, a=4, hello=null
+Frame: root main, i=4
+After 123 assignment:
+Frame: root doIt, a=4, hello=123
+Frame: root main, i=4
+After hello assignment:
+Frame: root doIt, a=4, hello=world
+Frame: root main, i=4
+Initial stack trace:
+Frame: root doIt, a=5, hello=null
+Frame: root main, i=5
+After 123 assignment:
+Frame: root doIt, a=5, hello=123
+Frame: root main, i=5
+After hello assignment:
+Frame: root doIt, a=5, hello=world
+Frame: root main, i=5
+Initial stack trace:
+Frame: root doIt, a=6, hello=null
+Frame: root main, i=6
+After 123 assignment:
+Frame: root doIt, a=6, hello=123
+Frame: root main, i=6
+After hello assignment:
+Frame: root doIt, a=6, hello=world
+Frame: root main, i=6
+Initial stack trace:
+Frame: root doIt, a=7, hello=null
+Frame: root main, i=7
+After 123 assignment:
+Frame: root doIt, a=7, hello=123
+Frame: root main, i=7
+After hello assignment:
+Frame: root doIt, a=7, hello=world
+Frame: root main, i=7
+Initial stack trace:
+Frame: root doIt, a=8, hello=null
+Frame: root main, i=8
+After 123 assignment:
+Frame: root doIt, a=8, hello=123
+Frame: root main, i=8
+After hello assignment:
+Frame: root doIt, a=8, hello=world
+Frame: root main, i=8
+Initial stack trace:
+Frame: root doIt, a=9, hello=null
+Frame: root main, i=9
+After 123 assignment:
+Frame: root doIt, a=9, hello=123
+Frame: root main, i=9
+After hello assignment:
+Frame: root doIt, a=9, hello=world
+Frame: root main, i=9
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/HelloEqualsWorld.sl	Fri Apr 11 11:53:11 2014 +0200
@@ -0,0 +1,22 @@
+function doIt(a) {
+  println("Initial stack trace:");
+  println(stacktrace());
+  
+  hello = 123;
+  println("After 123 assignment:");
+  println(stacktrace());
+  
+  helloEqualsWorld();
+  println("After hello assignment:");
+  println(stacktrace());
+  
+//  readln();
+}
+
+function main() {
+  i = 0;
+  while (i < 10) {
+    doIt(i);
+    i = i + 1;
+  }
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLHelloEqualsWorldBuiltin.java	Fri Apr 11 11:53:11 2014 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012, 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.truffle.sl.builtins;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
+import com.oracle.truffle.api.nodes.*;
+
+/**
+ * This builtin sets the variable named "hello" in the caller frame to the string "world".
+ */
+@NodeInfo(shortName = "helloEqualsWorld")
+public abstract class SLHelloEqualsWorldBuiltin extends SLBuiltinNode {
+
+    @Specialization
+    public Object change() {
+        FrameInstance frameInstance = Truffle.getRuntime().getStackTrace().iterator().next();
+        Frame frame = frameInstance.getFrame(FrameAccess.READ_WRITE, false);
+        FrameSlot slot = frame.getFrameDescriptor().findOrAddFrameSlot("hello");
+        frame.setObject(slot, "world");
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLStackTraceBuiltin.java	Fri Apr 11 11:53:11 2014 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012, 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.truffle.sl.builtins;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.CompilerDirectives.SlowPath;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
+import com.oracle.truffle.api.nodes.*;
+
+/**
+ * Returns a string representation of the current stack. This includes the {@link CallTarget}s and
+ * the contents of the {@link Frame}. Note that this is implemented as a slow path by passing
+ * {@code true} to {@link FrameInstance#getFrame(FrameAccess, boolean)}.
+ */
+@NodeInfo(shortName = "stacktrace")
+public abstract class SLStackTraceBuiltin extends SLBuiltinNode {
+
+    @Specialization
+    public String trace() {
+        return createStackTrace();
+    }
+
+    @SlowPath
+    private static String createStackTrace() {
+        StringBuilder str = new StringBuilder();
+        for (FrameInstance frame : Truffle.getRuntime().getStackTrace()) {
+            dumpFrame(str, frame.getCallNode().getRootNode(), frame.getFrame(FrameAccess.READ_ONLY, true), frame.isVirtualFrame());
+        }
+        return str.toString();
+    }
+
+    private static void dumpFrame(StringBuilder str, RootNode rootNode, Frame frame, boolean isVirtual) {
+        if (str.length() > 0) {
+            str.append("\n");
+        }
+        str.append("Frame: ").append(rootNode).append(isVirtual ? " (virtual)" : "");
+        FrameDescriptor frameDescriptor = frame.getFrameDescriptor();
+        for (FrameSlot s : frameDescriptor.getSlots()) {
+            str.append(", ").append(s.getIdentifier()).append("=").append(frame.getValue(s));
+        }
+    }
+}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLDirectDispatchNode.java	Fri Apr 11 11:52:19 2014 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLDirectDispatchNode.java	Fri Apr 11 11:53:11 2014 +0200
@@ -92,7 +92,7 @@
                  * Now we are really ready to perform the call. We use a Truffle CallNode for that,
                  * because it does all the work for method inlining.
                  */
-                return callCachedTargetNode.call(arguments);
+                return callCachedTargetNode.call(frame, arguments);
 
             } catch (InvalidAssumptionException ex) {
                 /*
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLGenericDispatchNode.java	Fri Apr 11 11:52:19 2014 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLGenericDispatchNode.java	Fri Apr 11 11:53:11 2014 +0200
@@ -22,14 +22,19 @@
  */
 package com.oracle.truffle.sl.nodes.call;
 
+import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
+import com.oracle.truffle.api.impl.*;
 import com.oracle.truffle.sl.runtime.*;
 
 /**
  * Slow-path code for a call, used when the polymorphic inline cache exceeded its maximum size. Such
  * calls are not optimized any further, e.g., no method inlining is performed.
  */
-final class SLGenericDispatchNode extends SLAbstractDispatchNode {
+final class SLGenericDispatchNode extends SLAbstractDispatchNode implements MaterializedFrameNotify {
+
+    @CompilationFinal private FrameAccess outsideFrameAccess = FrameAccess.NONE;
 
     @Override
     protected Object executeDispatch(VirtualFrame frame, SLFunction function, Object[] arguments) {
@@ -37,6 +42,14 @@
          * SL has a quite simple call lookup: just ask the function for the current call target, and
          * call it.
          */
-        return function.getCallTarget().call(arguments);
+        return DefaultCallNode.callProxy(this, function.getCallTarget(), frame, arguments);
+    }
+
+    public FrameAccess getOutsideFrameAccess() {
+        return outsideFrameAccess;
+    }
+
+    public void setOutsideFrameAccess(FrameAccess outsideFrameAccess) {
+        this.outsideFrameAccess = outsideFrameAccess;
     }
 }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java	Fri Apr 11 11:52:19 2014 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java	Fri Apr 11 11:53:11 2014 +0200
@@ -97,6 +97,8 @@
         installBuiltin(SLPrintlnBuiltinFactory.getInstance());
         installBuiltin(SLNanoTimeBuiltinFactory.getInstance());
         installBuiltin(SLDefineFunctionBuiltinFactory.getInstance());
+        installBuiltin(SLStackTraceBuiltinFactory.getInstance());
+        installBuiltin(SLHelloEqualsWorldBuiltinFactory.getInstance());
     }
 
     private void installBuiltin(NodeFactory<? extends SLBuiltinNode> factory) {