From 3e35010af23ef19dc718af95a7564c8bfb3a0251 Mon Sep 17 00:00:00 2001
From: Lukas Stadler <lukas.stadler@oracle.com>
Date: Tue, 3 May 2016 14:36:59 +0200
Subject: [PATCH] better caching of signatures in CallArgumentsNode

---
 .../r/nodes/function/CallArgumentsNode.java   | 27 ++++++++++++++++---
 .../truffle/r/nodes/function/RCallNode.java   |  5 +---
 .../truffle/r/runtime/data/RLanguage.java     |  5 ----
 3 files changed, 24 insertions(+), 13 deletions(-)

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 2175be7d03..a9fbc9be4e 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 944d1f1fb2..06593f0cd3 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 46b363d3d6..195e6058db 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?
-- 
GitLab