diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallArgumentsNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallArgumentsNode.java
index 2175be7d030ab6664ce01b7a2e5ab52691aa31f8..a9fbc9be4e7a714c57cf21e8d47bc528186c9075 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallArgumentsNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallArgumentsNode.java
@@ -28,10 +28,12 @@ import java.util.IdentityHashMap;
 import com.oracle.truffle.api.CompilerAsserts;
 import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.RootCallTarget;
 import com.oracle.truffle.api.frame.Frame;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.nodes.ExplodeLoop;
+import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.r.nodes.access.FrameSlotNode;
 import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
 import com.oracle.truffle.r.nodes.function.PromiseHelperNode.PromiseCheckHelperNode;
@@ -163,12 +165,29 @@ public final class CallArgumentsNode extends RBaseNode implements UnmatchedArgum
         }
     }
 
-    @ExplodeLoop
+    private ArgumentsSignature cachedVarArgsSignature;
+    private ArgumentsSignature cachedResultSignature;
+    private final BranchProfile regenerateSignatureProfile = BranchProfile.create();
+
     public ArgumentsSignature flattenNames(RArgsValuesAndNames varArgs) {
-        String[] names = null;
         if (!containsVarArgsSymbol()) {
             return signature;
         }
+        ArgumentsSignature varArgsSignature = varArgs.getSignature();
+        if (cachedVarArgsSignature == null) {
+            CompilerDirectives.transferToInterpreter();
+        }
+        if (varArgsSignature == cachedVarArgsSignature) {
+            return cachedResultSignature;
+        }
+        regenerateSignatureProfile.enter();
+        cachedVarArgsSignature = varArgsSignature;
+        return cachedResultSignature = flattenNamesInternal(varArgsSignature);
+    }
+
+    @TruffleBoundary
+    private ArgumentsSignature flattenNamesInternal(ArgumentsSignature varArgs) {
+        String[] names = null;
         int size = arguments.length + (varArgs.getLength() - 1) * varArgsSymbolIndices.length;
         names = new String[size];
         int vargsSymbolsIndex = 0;
@@ -184,10 +203,10 @@ public final class CallArgumentsNode extends RBaseNode implements UnmatchedArgum
         return ArgumentsSignature.get(names);
     }
 
-    private static int flattenVarArgNames(RArgsValuesAndNames varArgInfo, String[] names, int startIndex) {
+    private static int flattenVarArgNames(ArgumentsSignature varArgInfo, String[] names, int startIndex) {
         int index = startIndex;
         for (int j = 0; j < varArgInfo.getLength(); j++) {
-            names[index] = varArgInfo.getSignature().getName(j);
+            names[index] = varArgInfo.getName(j);
             index++;
         }
         return index;
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 944d1f1fb24625ea734dbefbbfa81d8b06ec6bc5..06593f0cd3b723173cda71c2377d482b23d90489 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
@@ -461,21 +461,18 @@ public abstract class RCallNode extends RNode implements RSyntaxNode, RSyntaxCal
         }
         final S3Args s3Args;
         final RFunction resultFunction;
-        final ArgumentsSignature argsSignature;
         if (result == null) {
             s3Args = null;
             resultFunction = function;
-            argsSignature = ArgumentsSignature.empty(args.length);
         } else {
             if (resultIsBuiltinProfile.profile(result.function.isBuiltin())) {
                 s3Args = null;
-                argsSignature = ArgumentsSignature.empty(args.length);
             } else {
                 s3Args = new S3Args(builtin.getName(), result.clazz, dotMethod, frame.materialize(), null, result.groupMatch ? dispatch.getGroupGenericName() : null);
-                argsSignature = explicitArgs != null ? ((RArgsValuesAndNames) explicitArgs.execute(frame)).getSignature() : callArguments.flattenNames(lookupVarArgs(frame));
             }
             resultFunction = result.function;
         }
+        ArgumentsSignature argsSignature = explicitArgs != null ? ((RArgsValuesAndNames) explicitArgs.execute(frame)).getSignature() : callArguments.flattenNames(lookupVarArgs(frame));
         return call.execute(frame, resultFunction, new RArgsValuesAndNames(args, argsSignature), s3Args);
     }
 
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java
index 46b363d3d63d4a37c0bb477f2babf628b8616ca4..195e6058db649979020a4478418898e70ffc11ab 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java
@@ -127,11 +127,6 @@ public class RLanguage extends RSharingAttributeStorage implements RAbstractCont
         return RLanguage.class;
     }
 
-    @Override
-    public RLanguage getNonShared() {
-        return (RLanguage) getNonShared();
-    }
-
     @Override
     public RShareable materializeToShareable() {
         // TODO is copy necessary?