From 156bb9e837bfb8334a3295381f795c3dffa42111 Mon Sep 17 00:00:00 2001
From: stepan <stepan.sindelar@oracle.com>
Date: Fri, 1 Sep 2017 12:27:49 +0200
Subject: [PATCH] Implement R_PreserveObject and R_ReleaseObject for NFI

---
 .../r/ffi/impl/common/JavaUpCallsRFFIImpl.java      | 13 +++++++++----
 .../r/ffi/impl/upcalls/MemoryUpCallsRFFI.java       |  4 ++--
 .../fficall/src/common/rffi_upcalls.h               |  2 +-
 .../oracle/truffle/r/runtime/context/RContext.java  | 11 +++++++++++
 mx.fastr/copyrights/overrides                       |  1 +
 5 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java
index 141b9841a2..df5375d70c 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java
@@ -32,6 +32,7 @@ import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Function;
@@ -1465,13 +1466,17 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
     }
 
     @Override
-    public int R_PreserveObject(Object obj) {
-        throw RInternalError.unimplemented();
+    public void R_PreserveObject(Object obj) {
+        guaranteeInstanceOf(obj, RObject.class);
+        HashSet<RObject> list = RContext.getInstance().preserveList;
+        list.add((RObject) obj);
     }
 
     @Override
-    public int R_ReleaseObject(Object obj) {
-        throw RInternalError.unimplemented();
+    public void R_ReleaseObject(Object obj) {
+        guaranteeInstanceOf(obj, RObject.class);
+        HashSet<RObject> list = RContext.getInstance().preserveList;
+        list.remove(obj);
     }
 
     @Override
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/MemoryUpCallsRFFI.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/MemoryUpCallsRFFI.java
index b0ce956cb2..62776b2be6 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/MemoryUpCallsRFFI.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/MemoryUpCallsRFFI.java
@@ -25,9 +25,9 @@ package com.oracle.truffle.r.ffi.impl.upcalls;
 public interface MemoryUpCallsRFFI {
     // Checkstyle: stop method name check
 
-    int R_PreserveObject(Object obj);
+    void R_PreserveObject(Object obj);
 
-    int R_ReleaseObject(Object obj);
+    void R_ReleaseObject(Object obj);
 
     Object Rf_protect(Object x);
 
diff --git a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h
index c58a2d95b6..a2bb060620 100644
--- a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h
+++ b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h
@@ -295,7 +295,7 @@ typedef void (*call_Rf_unprotect)(int x);
 typedef int (*call_R_ProtectWithIndex)(SEXP x);
 typedef void (*call_R_Reprotect)(SEXP x, int y);
 typedef void (*call_Rf_unprotect_ptr)(SEXP x);
-typedef SEXP (*call_R_PreserveObject)(SEXP x);
+typedef void (*call_R_PreserveObject)(SEXP x);
 typedef void (*call_R_ReleaseObject)(SEXP x);
 
 #endif
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java
index 4d1f4bf43f..bfeebda3a4 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java
@@ -42,6 +42,7 @@ import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.EnumSet;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.TimeZone;
@@ -356,8 +357,18 @@ public final class RContext implements RTruffleObject {
     public final WeakHashMap<Path, REnvironment> srcfileEnvironments = new WeakHashMap<>();
     public final List<String> libraryPaths = new ArrayList<>(1);
     public final Map<Integer, Thread> threads = new ConcurrentHashMap<>();
+
+    /**
+     * Stack used by RFFI to implement the PROTECT/UNPROTECT functions.
+     */
     public final ArrayList<RObject> protectStack = new ArrayList<>();
 
+    /**
+     * FastR equivalent of GNUR's special dedicated global list that is GC root and so any vectors
+     * added to it will be guaranteed to be preserved.
+     */
+    public final HashSet<RObject> preserveList = new HashSet<>();
+
     private final AllocationReporter allocationReporter;
 
     private ContextState[] contextStates() {
diff --git a/mx.fastr/copyrights/overrides b/mx.fastr/copyrights/overrides
index e69add7b7a..2fdbdd1da8 100644
--- a/mx.fastr/copyrights/overrides
+++ b/mx.fastr/copyrights/overrides
@@ -54,6 +54,7 @@ com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/ToolsText.ja
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/CountFields.java,gnu_r.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Download.java,gnu_r_gentleman_ihaka2.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Menu.java,gnu_r.copyright
+com.oracle.truffle.r.native/fficall/src/truffle_common/Rembedded.c,gnu_r.copyright
 com.oracle.truffle.r.native/fficall/src/common/arithmetic_fastr.c,gnu_r_gentleman_ihaka.copyright
 com.oracle.truffle.r.native/fficall/src/common/coerce_fastr.c,gnu_r_gentleman_ihaka.copyright
 com.oracle.truffle.r.native/fficall/src/common/errors_fastr.c,gnu_r.core.copyright
-- 
GitLab