From 9f5247a71ee9f3d47a0d873898c3f6dfe91a910d Mon Sep 17 00:00:00 2001
From: Mick Jordan <mick.jordan@oracle.com>
Date: Wed, 20 Jul 2016 09:03:16 -0700
Subject: [PATCH] RFFIUtils: add call death to tracing; use unbuffered stream

---
 .../truffle/r/runtime/ffi/RFFIUtils.java      | 55 ++++++++++++-------
 1 file changed, 34 insertions(+), 21 deletions(-)

diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIUtils.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIUtils.java
index 9672551088..227c57c707 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIUtils.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIUtils.java
@@ -25,7 +25,7 @@ package com.oracle.truffle.r.runtime.ffi;
 import java.io.FileDescriptor;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.PrintStream;
+import java.io.OutputStream;
 import java.nio.file.Path;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
@@ -62,10 +62,13 @@ public class RFFIUtils {
      * time in event of multiple concurrent instances (which happens with RStudio).
      */
     private static final String TRACEFILE = "fastr_trace_nativecalls.log";
-    private static FileOutputStream traceFileStream;
-    private static PrintStream traceStream;
+    private static OutputStream traceStream;
+    /**
+     * Records the call depth. TBD: make context specific
+     */
+    private static int depth;
 
-    private static void initialize() {
+    public static void initialize() {
         if (!initialized) {
             traceEnabled = alwaysTrace || FastROptions.TraceNativeCalls.getBooleanValue();
             if (traceEnabled) {
@@ -84,8 +87,7 @@ public class RFFIUtils {
     private static void initTraceStream() {
         Path tracePath = Utils.getLogPath(TRACEFILE);
         try {
-            traceFileStream = new FileOutputStream(tracePath.toString());
-            traceStream = new PrintStream(traceFileStream);
+            traceStream = new FileOutputStream(tracePath.toString());
         } catch (IOException ex) {
             System.err.println(ex.getMessage());
             System.exit(1);
@@ -93,8 +95,8 @@ public class RFFIUtils {
     }
 
     /**
-     * Upcalled from native when tracing to get FD of the {@link #traceFileStream}. Allows the same
-     * fd to be used on both sides of the JNI boundary.
+     * Upcalled from native when tracing to get FD of the {@link #traceStream}. Allows the same fd
+     * to be used on both sides of the JNI boundary.
      */
     @SuppressWarnings("unused")
     private static FileDescriptor getTraceFileDescriptor() {
@@ -103,7 +105,7 @@ public class RFFIUtils {
                 // Happens if native has tracing enabled and Java does not
                 initTraceStream();
             }
-            return traceFileStream.getFD();
+            return ((FileOutputStream) traceStream).getFD();
         } catch (IOException ex) {
             System.err.println(ex.getMessage());
             System.exit(1);
@@ -112,10 +114,10 @@ public class RFFIUtils {
     }
 
     private enum CallMode {
-        UP("Up"),
-        UP_RETURN("UpReturn"),
-        DOWN("Down"),
-        DOWN_RETURN("DownReturn");
+        UP("U"),
+        UP_RETURN("UR"),
+        DOWN("D"),
+        DOWN_RETURN("DR");
 
         private final String printName;
 
@@ -125,34 +127,45 @@ public class RFFIUtils {
     }
 
     public static void traceUpCall(String name, Object... args) {
-        traceCall(CallMode.UP, name, args);
+        traceCall(CallMode.UP, name, depth, args);
     }
 
-    public static void traceUpCallReturn(String name, Object... args) {
-        traceCall(CallMode.UP_RETURN, name, args);
+    public static void traceUpCallReturn(String name, Object result) {
+        traceCall(CallMode.UP_RETURN, name, depth, result);
     }
 
     public static void traceDownCall(String name, Object... args) {
-        traceCall(CallMode.DOWN, name, args);
+        traceCall(CallMode.DOWN, name, ++depth, args);
+    }
+
+    public static void traceDownCallReturn(String name, Object result) {
+        traceCall(CallMode.DOWN_RETURN, name, depth--, result);
     }
 
     public static boolean traceEnabled() {
         return traceEnabled;
     }
 
-    private static void traceCall(CallMode mode, String name, Object... args) {
-        initialize();
+    private static void traceCall(CallMode mode, String name, int depthValue, Object... args) {
+        assert initialized;
         if (traceEnabled) {
             StringBuffer sb = new StringBuffer();
             sb.append("CallRFFI[");
             sb.append(mode.printName);
+            sb.append(':');
+            sb.append(depthValue);
             sb.append(']');
             sb.append(name);
             sb.append('(');
             printArgs(sb, args);
             sb.append(')');
-            traceStream.println(sb.toString());
-            traceStream.flush();
+            try {
+                traceStream.write(sb.toString().getBytes());
+                traceStream.write('\n');
+                traceStream.flush();
+            } catch (IOException ex) {
+                // ignore
+            }
         }
     }
 
-- 
GitLab