diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java
index d202fe1015cfe2a332ff77da078972284f3fecf1..9d15a921074ee56752d4aeae6f3c7cb48bf0f3e4 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java
@@ -35,6 +35,7 @@ import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.NodeChild;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.dsl.TypeSystemReference;
+import com.oracle.truffle.api.frame.FrameSlot;
 import com.oracle.truffle.api.frame.FrameSlotTypeException;
 import com.oracle.truffle.api.frame.MaterializedFrame;
 import com.oracle.truffle.api.frame.VirtualFrame;
@@ -55,7 +56,6 @@ import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout;
 import com.oracle.truffle.r.nodes.RASTUtils;
 import com.oracle.truffle.r.nodes.RRootNode;
 import com.oracle.truffle.r.nodes.access.ConstantNode;
-import com.oracle.truffle.r.nodes.access.FrameSlotNode;
 import com.oracle.truffle.r.nodes.access.variables.LocalReadVariableNode;
 import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
@@ -234,11 +234,11 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
     }
 
     protected FunctionDispatch createUninitializedCall() {
-        return FunctionDispatchNodeGen.create(this, null, explicitArgs == null ? false : true);
+        return FunctionDispatchNodeGen.create(this, explicitArgs != null, null);
     }
 
     protected FunctionDispatch createUninitializedExplicitCall() {
-        return FunctionDispatchNodeGen.create(this, null, true);
+        return FunctionDispatchNodeGen.create(this, true, null);
     }
 
     /**
@@ -284,7 +284,7 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
                     @Cached("createBinaryProfile()") ConditionProfile resultIsBuiltinProfile) {
         RBuiltinDescriptor builtin = builtinProfile.profile(function.getRBuiltin());
         Object dispatchObject = dispatchArgument.execute(frame);
-        dispatchTempSlot.initialize(frame, dispatchObject, () -> internalDispatchCall = null);
+        FrameSlot slot = dispatchTempSlot.initialize(frame, dispatchObject);
         try {
             RStringVector type = classHierarchyNode.execute(dispatchObject);
             S3Args s3Args;
@@ -301,13 +301,13 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
                 s3Args = null;
                 resultFunction = function;
             }
-            if (internalDispatchCall == null) {
+            if (internalDispatchCall == null || internalDispatchCall.tempFrameSlot != slot) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                internalDispatchCall = insert(FunctionDispatchNodeGen.create(this, new Object[]{dispatchTempSlot.getIdentifier()}, false));
+                internalDispatchCall = insert(FunctionDispatchNodeGen.create(this, false, slot));
             }
             return internalDispatchCall.execute(frame, resultFunction, lookupVarArgs(frame), s3Args, null);
         } finally {
-            dispatchTempSlot.cleanup(frame, dispatchObject);
+            TemporarySlotNode.cleanup(frame, dispatchObject, slot);
         }
     }
 
@@ -548,11 +548,11 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
         return getParentCallNode().getFunctionNode();
     }
 
-    public CallArgumentsNode createArguments(Object[] dispatchTempIdentifiers, boolean modeChange, boolean modeChangeAppliesToAll) {
+    public CallArgumentsNode createArguments(FrameSlot tempFrameSlot, boolean modeChange, boolean modeChangeAppliesToAll) {
         RNode[] args = new RNode[arguments.length];
         for (int i = 0; i < arguments.length; i++) {
-            if (dispatchTempIdentifiers != null && i < dispatchTempIdentifiers.length) {
-                args[i] = new GetTempNode(dispatchTempIdentifiers[i], arguments[i]);
+            if (tempFrameSlot != null && i == 0) {
+                args[i] = new GetTempNode(tempFrameSlot, arguments[i]);
             } else {
                 args[i] = arguments[i] == null ? null : RASTUtils.cloneNode(arguments[i].asRNode());
             }
@@ -570,7 +570,7 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
      */
     public static RNode createInternalCall(RCallNode internalCallArg, RFunction function) {
         CompilerAsserts.neverPartOfCompilation();
-        return new InternalNode(FunctionDispatchNodeGen.create(internalCallArg, null, false), function, internalCallArg.lookupVarArgs != null);
+        return new InternalNode(FunctionDispatchNodeGen.create(internalCallArg, false, null), function, internalCallArg.lookupVarArgs != null);
     }
 
     @NodeInfo(cost = NodeCost.NONE)
@@ -654,11 +654,11 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
 
     private static final class GetTempNode extends RNode {
 
-        @Child private FrameSlotNode slot;
+        private final FrameSlot slot;
         private final RSyntaxNode arg;
 
-        GetTempNode(Object identifier, RSyntaxNode arg) {
-            slot = FrameSlotNode.createTemp(identifier, false);
+        GetTempNode(FrameSlot slot, RSyntaxNode arg) {
+            this.slot = slot;
             this.arg = arg;
         }
 
@@ -670,7 +670,7 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
         @Override
         public Object execute(VirtualFrame frame) {
             try {
-                return frame.getObject(slot.executeFrameSlot(frame));
+                return frame.getObject(slot);
             } catch (FrameSlotTypeException e) {
                 throw RInternalError.shouldNotReachHere();
             }
@@ -691,13 +691,14 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
         protected static final int CACHE_SIZE = 4;
 
         private final RCallNode originalCall;
-        private final Object[] dispatchTempIdentifiers;
         private final boolean explicitArgs;
 
-        public FunctionDispatch(RCallNode originalCall, Object[] dispatchTempIdentifiers, boolean explicitArgs) {
+        private final FrameSlot tempFrameSlot;
+
+        public FunctionDispatch(RCallNode originalCall, boolean explicitArgs, FrameSlot tempFrameSlot) {
             this.originalCall = originalCall;
-            this.dispatchTempIdentifiers = dispatchTempIdentifiers;
             this.explicitArgs = explicitArgs;
+            this.tempFrameSlot = tempFrameSlot;
         }
 
         protected LeafCallNode createCacheNode(RootCallTarget cachedTarget) {
@@ -717,7 +718,7 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
             if (explicitArgs) {
                 return PrepareArguments.createExplicit(root);
             } else {
-                CallArgumentsNode args = originalCall.createArguments(dispatchTempIdentifiers, root.getBuiltin() == null, true);
+                CallArgumentsNode args = originalCall.createArguments(tempFrameSlot, root.getBuiltin() == null, true);
                 return PrepareArguments.create(root, args, noOpt);
             }
         }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/TemporarySlotNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/TemporarySlotNode.java
index cab3f3c4da90b28fb840338a03006ebcd7bb9b31..03e13b0d068b6a277a8511029d130b4bab6ba20b 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/TemporarySlotNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/TemporarySlotNode.java
@@ -37,33 +37,35 @@ public final class TemporarySlotNode extends Node {
 
     @CompilationFinal private FrameSlot tempSlot;
     private int tempIdentifier;
-    private Object identifier;
 
-    public void initialize(VirtualFrame frame, Object value, Runnable invalidate) {
+    public FrameSlot initialize(VirtualFrame frame, Object value) {
         if (tempSlot == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            tempSlot = frame.getFrameDescriptor().findOrAddFrameSlot(identifier = defaultTempIdentifiers[0], FrameSlotKind.Object);
-            invalidate.run();
+            tempSlot = frame.getFrameDescriptor().findOrAddFrameSlot(defaultTempIdentifiers[0], FrameSlotKind.Object);
         }
+        FrameSlot slot = tempSlot;
         try {
-            if (frame.getObject(tempSlot) != null) {
+            if (frame.getObject(slot) != null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
                 // keep the complete loop in the slow path
                 do {
                     tempIdentifier++;
-                    identifier = tempIdentifier < defaultTempIdentifiers.length ? defaultTempIdentifiers[tempIdentifier] : new Object();
-                    tempSlot = frame.getFrameDescriptor().findOrAddFrameSlot(identifier, FrameSlotKind.Object);
-                    invalidate.run();
-                } while (frame.getObject(tempSlot) != null);
+                    Object identifier = tempIdentifier < defaultTempIdentifiers.length ? defaultTempIdentifiers[tempIdentifier] : new Object();
+                    tempSlot = slot = frame.getFrameDescriptor().findOrAddFrameSlot(identifier, FrameSlotKind.Object);
+                    if (frame.getObject(slot) == null) {
+                        break;
+                    }
+                } while (true);
             }
         } catch (FrameSlotTypeException e) {
             CompilerDirectives.transferToInterpreter();
             throw RInternalError.shouldNotReachHere();
         }
-        frame.setObject(tempSlot, value);
+        frame.setObject(slot, value);
+        return slot;
     }
 
-    public void cleanup(VirtualFrame frame, Object object) {
+    public static void cleanup(VirtualFrame frame, Object object, FrameSlot tempSlot) {
         try {
             assert frame.getObject(tempSlot) == object;
         } catch (FrameSlotTypeException e) {
@@ -71,8 +73,4 @@ public final class TemporarySlotNode extends Node {
         }
         frame.setObject(tempSlot, null);
     }
-
-    public Object getIdentifier() {
-        return identifier;
-    }
 }