diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
index 85ca75efe10bfc6d7e4a9c9268ace0ce35dc4ce7..866f2b489630e7dcdd4e25dc36819cf5205d163c 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
@@ -357,7 +357,7 @@ final class REngine implements RContext.Engine {
     public Object evalFunction(RFunction func, Object... args) {
         ArgumentsSignature argsSig = ((RRootNode) func.getRootNode()).getSignature();
         MaterializedFrame frame = Utils.getActualCurrentFrame().materialize();
-        Object[] rArgs = RArguments.create(func, frame == null ? null : RArguments.getCall(frame), frame, frame == null ? 1 : RArguments.getDepth(frame) + 1, args, argsSig);
+        Object[] rArgs = RArguments.create(func, frame == null ? null : RArguments.getCall(frame), frame, frame == null ? 1 : RArguments.getDepth(frame) + 1, args, argsSig, null);
         return func.getTarget().call(rArgs);
     }
 
@@ -521,13 +521,13 @@ final class REngine implements RContext.Engine {
             if (FastROptions.NewStateTransition && resultValue instanceof RShareable) {
                 ((RShareable) resultValue).incRefCount();
             }
-            function.getTarget().call(RArguments.create(function, null, REnvironment.globalEnv().getFrame(), 1, new Object[]{resultValue, RMissing.instance}, PRINT_SIGNATURE));
+            function.getTarget().call(RArguments.create(function, null, REnvironment.globalEnv().getFrame(), 1, new Object[]{resultValue, RMissing.instance}, PRINT_SIGNATURE, null));
             if (FastROptions.NewStateTransition && resultValue instanceof RShareable) {
                 ((RShareable) resultValue).decRefCount();
             }
         } else {
             // we only have the .Internal print.default method available
-            getPrintInternal().getTarget().call(RArguments.create(printInternal, null, REnvironment.globalEnv().getFrame(), 1, new Object[]{resultValue}, PRINT_INTERNAL_SIGNATURE));
+            getPrintInternal().getTarget().call(RArguments.create(printInternal, null, REnvironment.globalEnv().getFrame(), 1, new Object[]{resultValue}, PRINT_INTERNAL_SIGNATURE, null));
         }
     }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java
index ccae99507587b08e757eafab30372c7e2d027c9d..086772bf3127f6752b8a4549cbeb43ab1f916c22 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java
@@ -63,6 +63,8 @@ public abstract class DoCall extends RBuiltinNode {
     @Child private ClassHierarchyNode classHierarchyNode;
     @Child private RootCallNode internalDispatchCall;
 
+    @Child private RArgumentsNode argsNode = RArgumentsNode.create();
+
     private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
     private final BranchProfile errorProfile = BranchProfile.create();
     private final BranchProfile containsRLanguageProfile = BranchProfile.create();
@@ -163,7 +165,7 @@ public abstract class DoCall extends RBuiltinNode {
             needsCallerFrame = true;
         }
         callerFrame = needsCallerFrame ? getCallerFrame(frame, callerFrame) : null;
-        Object[] callArgs = RArguments.create(func, RDataFactory.createCaller(this), callerFrame, RArguments.getDepth(frame) + 1, reorderedArgs.getArguments(), reorderedArgs.getSignature());
+        Object[] callArgs = argsNode.execute(func, RDataFactory.createCaller(this), callerFrame, RArguments.getDepth(frame) + 1, reorderedArgs.getArguments(), reorderedArgs.getSignature(), null);
         RArguments.setIsIrregular(callArgs, true);
         return callCache.execute(frame, func.getTarget(), callArgs);
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetFunctions.java
index ad7d788e1f1f0a78a719aa14408b062070a28b00..47e27bcf44e380f8cbfe737c8575a770e217e87d 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetFunctions.java
@@ -32,6 +32,7 @@ import com.oracle.truffle.api.utilities.*;
 import com.oracle.truffle.r.nodes.*;
 import com.oracle.truffle.r.nodes.builtin.*;
 import com.oracle.truffle.r.nodes.function.*;
+import com.oracle.truffle.r.nodes.function.signature.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.data.model.*;
@@ -126,6 +127,7 @@ public class GetFunctions {
         private final BranchProfile wrongLengthErrorProfile = BranchProfile.create();
 
         @Child private CallInlineCacheNode callCache = CallInlineCacheNodeGen.create();
+        @Child private RArgumentsNode argsNode;
 
         @CompilationFinal private boolean needsCallerFrame;
 
@@ -243,8 +245,12 @@ public class GetFunctions {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
                 needsCallerFrame = true;
             }
+            if (argsNode == null) {
+                CompilerDirectives.transferToInterpreterAndInvalidate();
+                argsNode = insert(RArgumentsNode.create());
+            }
             MaterializedFrame callerFrame = needsCallerFrame ? frame.materialize() : null;
-            Object[] callArgs = RArguments.create(ifnFunc, RDataFactory.createCaller(this), callerFrame, RArguments.getDepth(frame) + 1, new Object[]{x}, ArgumentsSignature.empty(1));
+            Object[] callArgs = argsNode.execute(ifnFunc, RDataFactory.createCaller(this), callerFrame, RArguments.getDepth(frame) + 1, new Object[]{x}, ArgumentsSignature.empty(1), null);
             return callCache.execute(frame, ifnFunc.getTarget(), callArgs);
         }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java
index 77810ef13f87d5528c3fa91f86ebcfccf077aa7e..62cc82cc896527d934b89e902f03092cbbcbc5bc 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java
@@ -212,7 +212,7 @@ public class HiddenInternalFunctions {
                 try {
                     RSerialize.CallHook callHook = new RSerialize.CallHook() {
                         public Object eval(Object arg) {
-                            Object[] callArgs = RArguments.create(envhook, RDataFactory.createCaller(this), null, RArguments.getDepth(frame) + 1, new Object[]{arg}, SIGNATURE);
+                            Object[] callArgs = RArguments.create(envhook, RDataFactory.createCaller(this), null, RArguments.getDepth(frame) + 1, new Object[]{arg}, SIGNATURE, null);
                             return callCache.execute(new SubstituteVirtualFrame(frame), envhook.getTarget(), callArgs);
                         }
                     };
@@ -328,14 +328,19 @@ public class HiddenInternalFunctions {
 
         @Specialization
         protected RIntVector lazyLoadDBinsertValue(VirtualFrame frame, Object value, RAbstractStringVector file, byte asciiL, int compression, RFunction hook) {
+            return lazyLoadDBinsertValueInternal(frame.materialize(), value, file, asciiL, compression, hook);
+        }
+
+        @TruffleBoundary
+        private RIntVector lazyLoadDBinsertValueInternal(MaterializedFrame frame, Object value, RAbstractStringVector file, byte asciiL, int compression, RFunction hook) {
             if (compression != 1) {
                 throw RError.error(this, Message.GENERIC, "unsupported compression");
             }
 
             RSerialize.CallHook callHook = new RSerialize.CallHook() {
                 public Object eval(Object arg) {
-                    Object[] callArgs = RArguments.create(hook, RDataFactory.createCaller(this), null, RArguments.getDepth(frame) + 1, new Object[]{arg}, SIGNATURE);
-                    return callCache.execute(new SubstituteVirtualFrame(frame.materialize()), hook.getTarget(), callArgs);
+                    Object[] callArgs = RArguments.create(hook, RDataFactory.createCaller(this), null, RArguments.getDepth(frame) + 1, new Object[]{arg}, SIGNATURE, null);
+                    return callCache.execute(new SubstituteVirtualFrame(frame), hook.getTarget(), callArgs);
                 }
             };
 
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java
index 6eded7cf6e99a672216a2f65b686f9bcc465c6f8..ccab18e3cbeb3a2a421d9db5024e74fa66d97e92 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java
@@ -20,9 +20,10 @@ import com.oracle.truffle.api.utilities.*;
 import com.oracle.truffle.r.nodes.*;
 import com.oracle.truffle.r.nodes.builtin.*;
 import com.oracle.truffle.r.nodes.function.ArgumentMatcher.MatchPermutation;
+import com.oracle.truffle.r.nodes.function.signature.*;
 import com.oracle.truffle.r.nodes.unary.*;
 import com.oracle.truffle.r.runtime.*;
-import com.oracle.truffle.r.runtime.RArguments.*;
+import com.oracle.truffle.r.runtime.RArguments.S3Args;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.nodes.*;
 
@@ -32,6 +33,7 @@ public abstract class CallMatcherNode extends RBaseNode {
     protected final boolean argsAreEvaluated;
 
     @Child private PromiseHelperNode promiseHelper;
+    @Child private RArgumentsNode argsNode = RArgumentsNode.create();
 
     protected final ConditionProfile missingArgProfile = ConditionProfile.createBinaryProfile();
     protected final ConditionProfile emptyArgProfile = ConditionProfile.createBinaryProfile();
@@ -88,14 +90,14 @@ public abstract class CallMatcherNode extends RBaseNode {
         return new CallMatcherCachedNode(suppliedSignature, varArgSignatures, function, preparePermutation, permutation, specializer, forNextMethod, argsAreEvaluated, next);
     }
 
-    protected static final Object[] prepareArguments(VirtualFrame frame, Object[] reorderedArgs, ArgumentsSignature reorderedSignature, RFunction function, S3Args s3Args) {
+    protected Object[] prepareArguments(VirtualFrame frame, Object[] reorderedArgs, ArgumentsSignature reorderedSignature, RFunction function, S3Args s3Args) {
         RCaller caller = RArguments.getCall(frame);
         MaterializedFrame callerFrame = RArguments.getCallerFrame(frame);
         if (caller == null && callerFrame == null) {
             callerFrame = RArguments.getEnvironment(frame).getFrame();
             assert callerFrame != null;
         }
-        return RArguments.create(function, caller, callerFrame, RArguments.getDepth(frame) + 1, reorderedArgs, reorderedSignature, s3Args);
+        return argsNode.execute(function, caller, callerFrame, RArguments.getDepth(frame) + 1, reorderedArgs, reorderedSignature, s3Args);
     }
 
     protected final void evaluatePromises(VirtualFrame frame, RFunction function, Object[] args, int varArgIndex) {
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 3e4ea0110573fd434e1ae07bf1a16fd5aee59a3a..0755a6322e444a7d21e61719ed8a83ec74c3fc56 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
@@ -84,12 +84,12 @@ import com.oracle.truffle.r.runtime.nodes.*;
  *  U = {@link UninitializedCallNode}: Forms the uninitialized end of the function PIC
  *  D = {@link DispatchedCallNode}: Function fixed, no varargs
  *  G = {@link GenericCallNode}: Function arbitrary
- * 
+ *
  *  UV = {@link UninitializedCallNode} with varargs,
  *  UVC = {@link UninitializedVarArgsCacheCallNode} with varargs, for varargs cache
  *  DV = {@link DispatchedVarArgsCallNode}: Function fixed, with cached varargs
  *  DGV = {@link DispatchedGenericVarArgsCallNode}: Function fixed, with arbitrary varargs (generic case)
- * 
+ *
  * (RB = {@link RBuiltinNode}: individual functions that are builtins are represented by this node
  * which is not aware of caching). Due to {@link CachedCallNode} (see below) this is transparent to
  * the cache and just behaves like a D/DGV)
@@ -102,11 +102,11 @@ import com.oracle.truffle.r.runtime.nodes.*;
  * non varargs, max depth:
  * |
  * D-D-D-U
- * 
+ *
  * no varargs, generic (if max depth is exceeded):
  * |
  * D-D-D-D-G
- * 
+ *
  * varargs:
  * |
  * DV-DV-UV         <- function call target identity level cache
@@ -114,7 +114,7 @@ import com.oracle.truffle.r.runtime.nodes.*;
  *    DV
  *    |
  *    UVC           <- varargs signature level cache
- * 
+ *
  * varargs, max varargs depth exceeded:
  * |
  * DV-DV-UV
@@ -126,7 +126,7 @@ import com.oracle.truffle.r.runtime.nodes.*;
  *    DV
  *    |
  *    DGV
- * 
+ *
  * varargs, max function depth exceeded:
  * |
  * DV-DV-DV-DV-GV
@@ -874,6 +874,7 @@ public final class RCallNode extends RNode implements RSyntaxNode {
         @Child private CallArgumentsNode args;
         @Child private VarArgsCacheCallNode next;
         @Child private MatchedArgumentsNode matchedArgs;
+        @Child private RArgumentsNode argsNode = RArgumentsNode.create();
 
         private final ArgumentsSignature cachedSignature;
         private final boolean needsCallerFrame;
@@ -918,7 +919,7 @@ public final class RCallNode extends RNode implements RSyntaxNode {
                 call.cloneCallTarget();
             }
             MaterializedFrame callerFrame = needsCallerFrame ? frame.materialize() : null;
-            Object[] argsObject = RArguments.create(currentFunction, RDataFactory.createCaller(this), callerFrame, RArguments.getDepth(frame) + 1, matchedArgs.executeArray(frame),
+            Object[] argsObject = argsNode.execute(currentFunction, RDataFactory.createCaller(this), callerFrame, RArguments.getDepth(frame) + 1, matchedArgs.executeArray(frame),
                             matchedArgs.getSignature(), s3Args);
             return call.call(frame, argsObject);
         }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/signature/RArgumentsNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/signature/RArgumentsNode.java
index 419f2d35b997668080c627493d45198c11befecf..5d79684a305df0d1fcc02fd95b4a8d1e1590d6aa 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/signature/RArgumentsNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/signature/RArgumentsNode.java
@@ -24,6 +24,7 @@ package com.oracle.truffle.r.nodes.function.signature;
 
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.RArguments.*;
 import com.oracle.truffle.r.runtime.data.*;
@@ -42,6 +43,11 @@ public abstract class RArgumentsNode extends RBaseNode {
         return new RArgumentsUninitializedNode();
     }
 
+    @Override
+    public NodeCost getCost() {
+        return NodeCost.NONE;
+    }
+
     private static final class RArgumentsUninitializedNode extends RArgumentsNode {
         @Override
         public Object[] execute(RFunction function, RCaller caller, MaterializedFrame callerFrame, int depth, Object[] evaluatedArgs, ArgumentsSignature signature, S3Args s3Args) {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RArguments.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RArguments.java
index 74107238c32ba5f56b762e3e8e8fc134716cc091..8890bf4e7a23152702f31505baa7c48b857c98ea 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RArguments.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RArguments.java
@@ -132,26 +132,13 @@ public final class RArguments {
         return ((HasSignature) function.getRootNode()).getSignature();
     }
 
-    public static Object[] create(RFunction functionObj, RCaller call, MaterializedFrame callerFrame, int depth, Object[] evaluatedArgs, ArgumentsSignature signature) {
-        MaterializedFrame enclosingFrame = functionObj.getEnclosingFrame();
-        return createInternal(functionObj, call, callerFrame, depth, evaluatedArgs, signature, enclosingFrame);
-    }
-
     public static Object[] create(RFunction functionObj, RCaller call, MaterializedFrame callerFrame, int depth, Object[] evaluatedArgs, ArgumentsSignature signature, S3Args s3Args) {
-        Object[] args = create(functionObj, call, callerFrame, depth, evaluatedArgs, signature);
-        args[INDEX_S3_ARGS] = s3Args;
-        return args;
+        CompilerAsserts.neverPartOfCompilation();
+        return create(functionObj, call, callerFrame, depth, evaluatedArgs, signature, functionObj.getEnclosingFrame(), s3Args);
     }
 
     public static Object[] create(RFunction functionObj, RCaller call, MaterializedFrame callerFrame, int depth, Object[] evaluatedArgs, ArgumentsSignature signature,
                     MaterializedFrame enclosingFrame, S3Args s3Args) {
-        Object[] args = createInternal(functionObj, call, callerFrame, depth, evaluatedArgs, signature, enclosingFrame);
-        args[INDEX_S3_ARGS] = s3Args;
-        return args;
-    }
-
-    public static Object[] createInternal(RFunction functionObj, RCaller call, MaterializedFrame callerFrame, int depth, Object[] evaluatedArgs, ArgumentsSignature signature,
-                    MaterializedFrame enclosingFrame) {
         assert evaluatedArgs != null && signature != null : evaluatedArgs + " " + signature;
         assert evaluatedArgs.length == signature.getLength() : Arrays.toString(evaluatedArgs) + " " + signature;
         assert signature == getSignature(functionObj) : signature + " vs. " + getSignature(functionObj);
@@ -164,6 +151,7 @@ public final class RArguments {
         a[INDEX_CALL] = call;
         a[INDEX_CALLER_FRAME] = callerFrame;
         a[INDEX_ENCLOSING_FRAME] = enclosingFrame;
+        a[INDEX_S3_ARGS] = s3Args;
         a[INDEX_DEPTH] = depth;
         a[INDEX_IS_IRREGULAR] = false;
         a[INDEX_SIGNATURE] = signature;