From d71ee15f5234c674882e1d09c3999023972c6fe3 Mon Sep 17 00:00:00 2001
From: Lukas Stadler <lukas.stadler@oracle.com>
Date: Wed, 13 Dec 2017 09:36:18 +0100
Subject: [PATCH] String.format calls are always slow path

---
 .../r/engine/interop/RForeignAccessFactoryImpl.java    |  2 +-
 .../r/ffi/impl/managed/Managed_RFFIFactory.java        |  3 ++-
 .../oracle/truffle/r/ffi/impl/nodes/CoerceNodes.java   | 10 ++++++----
 .../oracle/truffle/r/nodes/builtin/base/Substr.java    |  2 +-
 .../truffle/r/nodes/control/AbstractLoopNode.java      |  2 ++
 .../com/oracle/truffle/r/runtime/RInternalError.java   |  9 +++++++--
 6 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java
index 1749545bb3..b90ce24ede 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java
@@ -123,7 +123,7 @@ public final class RForeignAccessFactoryImpl implements RForeignAccessFactory {
             if (access != null) {
                 return access;
             } else {
-                throw RInternalError.unimplemented("missing foreign access factory for " + obj.getClass().getSimpleName());
+                throw RInternalError.unimplemented("missing foreign access factory for %s", obj.getClass().getSimpleName());
             }
         }
     }
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_RFFIFactory.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_RFFIFactory.java
index 9a6e29a594..6b6ed65054 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_RFFIFactory.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_RFFIFactory.java
@@ -23,6 +23,7 @@
 package com.oracle.truffle.r.ffi.impl.managed;
 
 import com.oracle.truffle.api.CompilerAsserts;
+import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.interop.TruffleObject;
 import com.oracle.truffle.api.nodes.Node;
@@ -167,8 +168,8 @@ public final class Managed_RFFIFactory extends RFFIFactory {
         return new ManagedRFFIContext();
     }
 
-    @TruffleBoundary
     static RError unsupported(String name) {
+        CompilerDirectives.transferToInterpreter();
         throw RError.error(RError.NO_CALLER, Message.GENERIC, String.format("Feature '%s' is not supported by managed FFI, i.e. it requires running native code.", name));
     }
 }
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/CoerceNodes.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/CoerceNodes.java
index 64a35769df..63bbc904a2 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/CoerceNodes.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/CoerceNodes.java
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.r.ffi.impl.nodes;
 
+import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Fallback;
@@ -193,15 +194,16 @@ public final class CoerceNodes {
 
         @Specialization(replaces = {"doCachedNotList", "doCached"}, guards = {"!isS4Object(value)", "isValidMode(mode)"})
         Object doCached(Object value, int mode) {
+            CompilerDirectives.transferToInterpreter();
             String type = value != null ? value.getClass().getSimpleName() : "null";
-            throw RInternalError.unimplemented(String.format("Rf_coerceVector unimplemented for type %s or mode %s.", type, mode));
+            throw RInternalError.unimplemented("Rf_coerceVector unimplemented for type %s or mode %s.", type, mode);
         }
 
         @Fallback
-        @TruffleBoundary
         Object doFallback(Object value, Object mode) {
+            CompilerDirectives.transferToInterpreter();
             String type = value != null ? value.getClass().getSimpleName() : "null";
-            throw RInternalError.unimplemented(String.format("Rf_coerceVector unimplemented for type %s or mode %s.", type, mode));
+            throw RInternalError.unimplemented("Rf_coerceVector unimplemented for type %s or mode %s.", type, mode);
         }
 
         static boolean isS4Object(Object obj) {
@@ -256,7 +258,7 @@ public final class CoerceNodes {
                 case RAWSXP:
                     return CastRawNode.createForRFFI(true, preserveDims, preserveAttrs);
                 default:
-                    throw RInternalError.unimplemented(String.format("Rf_coerceVector called with unimplemented mode %d (type %s).", mode, type));
+                    throw RInternalError.unimplemented("Rf_coerceVector called with unimplemented mode %d (type %s).", mode, type);
             }
         }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Substr.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Substr.java
index 968038ad02..4ccb4cf140 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Substr.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Substr.java
@@ -55,7 +55,7 @@ public abstract class Substr extends RBuiltinNode.Arg3 {
 
     @SuppressWarnings("unused")
     @Specialization(guards = "emptyArg(arg)")
-    protected RStringVector substrEmptyArg(VirtualFrame frame, RAbstractStringVector arg, RAbstractIntVector start, RAbstractIntVector stop) {
+    protected RStringVector substrEmptyArg(RAbstractStringVector arg, RAbstractIntVector start, RAbstractIntVector stop) {
         return RDataFactory.createEmptyStringVector();
     }
 
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/AbstractLoopNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/AbstractLoopNode.java
index eb77c8a598..cc5a512ce2 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/AbstractLoopNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/AbstractLoopNode.java
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.r.nodes.control;
 
+import com.oracle.truffle.api.CompilerAsserts;
 import com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.nodes.RepeatingNode;
@@ -43,6 +44,7 @@ public abstract class AbstractLoopNode extends OperatorNode {
 
     @Override
     public String toString() {
+        CompilerAsserts.neverPartOfCompilation();
         RootNode rootNode = getRootNode();
         String function = "?";
         if (rootNode instanceof RRootNode) {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RInternalError.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RInternalError.java
index 4095b0ad6d..1c6a328bec 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RInternalError.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RInternalError.java
@@ -52,12 +52,12 @@ public final class RInternalError extends Error implements TruffleException {
     private final String verboseStackTrace;
 
     public RInternalError(String message, Object... args) {
-        super(String.format(message, args));
+        super(Utils.stringFormat(message, args));
         verboseStackTrace = createVerboseStackTrace();
     }
 
     public RInternalError(Throwable cause, String message, Object... args) {
-        super(String.format(message, args), cause);
+        super(Utils.stringFormat(message, args), cause);
         verboseStackTrace = createVerboseStackTrace();
     }
 
@@ -106,6 +106,11 @@ public final class RInternalError extends Error implements TruffleException {
         throw new RInternalError("not implemented: %s", message);
     }
 
+    public static RuntimeException unimplemented(String format, Object... args) {
+        CompilerDirectives.transferToInterpreter();
+        throw new RInternalError("not implemented: %s", String.format(format, args));
+    }
+
     public static RuntimeException shouldNotReachHere() {
         CompilerDirectives.transferToInterpreter();
         throw new RInternalError("should not reach here");
-- 
GitLab