diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Base.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Base.java
index 3cd51bce2da13484f1b3973c5b8283f452c89da4..22f48ef2cc55bcd9cc9a9124b82ad350ec416282 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Base.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Base.java
@@ -223,6 +223,19 @@ public class TruffleLLVM_Base implements BaseRFFI {
         }
     }
 
+    private static class TruffleLLVM_SetShutdownFlagNode extends TruffleLLVM_DownCallNode implements SetShutdownFlagNode {
+
+        @Override
+        protected NativeFunction getFunction() {
+            return NativeFunction.set_shutdown_phase;
+        }
+
+        @Override
+        public void execute(boolean value) {
+            call(value ? 1 : 0);
+        }
+    }
+
     @Override
     public GetpidNode createGetpidNode() {
         return new TruffleLLVM_GetpidNode();
@@ -272,4 +285,9 @@ public class TruffleLLVM_Base implements BaseRFFI {
     public GlobNode createGlobNode() {
         return new TruffleLLVM_GlobNode();
     }
+
+    @Override
+    public SetShutdownFlagNode createSetShutdownFlagNode() {
+        return new TruffleLLVM_SetShutdownFlagNode();
+    }
 }
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_Base.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_Base.java
index 20c7d3f17d6845b66cbf9054c9c4bfa42a78c3a4..7054d39681aadfd43ce7c3c824a95474c4865ba1 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_Base.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_Base.java
@@ -200,4 +200,17 @@ public class Managed_Base implements BaseRFFI {
     public GlobNode createGlobNode() {
         return null;
     }
+
+    private static final class ManagedSetShutdownFlagNode extends Node implements SetShutdownFlagNode {
+
+        @Override
+        public void execute(boolean value) {
+            // do nothing
+        }
+    }
+
+    @Override
+    public SetShutdownFlagNode createSetShutdownFlagNode() {
+        return new ManagedSetShutdownFlagNode();
+    }
 }
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/NFIContext.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/NFIContext.java
index 712210240126b220fb57a17b1525ed9151093a8b..47f28cbce9c159adb4bf9e0af9349fe3e04a19b8 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/NFIContext.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/NFIContext.java
@@ -27,6 +27,7 @@ import java.util.ArrayList;
 import com.oracle.truffle.r.ffi.impl.common.LibPaths;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.context.RContext.ContextState;
+import com.oracle.truffle.r.runtime.ffi.BaseRFFI;
 import com.oracle.truffle.r.runtime.ffi.DLL;
 import com.oracle.truffle.r.runtime.ffi.DLLRFFI;
 import com.oracle.truffle.r.runtime.ffi.RFFIContext;
@@ -49,9 +50,20 @@ class NFIContext extends RFFIContext {
             // force initialization of NFI
             DLLRFFI.DLOpenRootNode.create(context).call(librffiPath, false, false);
         }
+        if (RContext.getContextCnt() == 0) {
+            BaseRFFI.SetShutdownFlagRootNode.create().getCallTarget().call(false);
+        }
         return this;
     }
 
+    @Override
+    public void beforeDispose(RContext context) {
+        if (RContext.getContextCnt() == 1) {
+            BaseRFFI.SetShutdownFlagRootNode.create().getCallTarget().call(true);
+        }
+        super.beforeDispose(context);
+    }
+
     @Override
     public void afterDowncall() {
         for (Long ptr : transientAllocations) {
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/NativeFunction.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/NativeFunction.java
index cf1c2d76c38e1b39042c2fe93a716eab11f01def..1e8dd4776e2a52586222f95968803c1600086c3c 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/NativeFunction.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/NativeFunction.java
@@ -78,7 +78,8 @@ public enum NativeFunction {
     dqrls("([double], sint32, sint32, [double], sint32, double, [double], [double], [double], [sint32], [sint32], [double], [double]): void", "call_misc_"),
     // stats
     fft_factor("(sint32, [sint32], [sint32]): void", TruffleNFI_Utils::lookupAndBindStats),
-    fft_work("([double], sint32, sint32, sint32, sint32, [double], [sint32]): sint32", TruffleNFI_Utils::lookupAndBindStats);
+    fft_work("([double], sint32, sint32, sint32, sint32, [double], [sint32]): sint32", TruffleNFI_Utils::lookupAndBindStats),
+    set_shutdown_phase("(uint8): void", TruffleNFI_Utils::lookupAndBind);
 
     private final int argumentCount;
     private final String signature;
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Base.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Base.java
index c38173bfd4b8ecddc57ac170309aa2126fd95970..69b7d456b22989af06b22c0ad4708eea1167cbe4 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Base.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Base.java
@@ -213,6 +213,19 @@ public class TruffleNFI_Base implements BaseRFFI {
         }
     }
 
+    private static class TruffleNFI_SetShutdownFlagNode extends TruffleNFI_DownCallNode implements SetShutdownFlagNode {
+
+        @Override
+        protected NativeFunction getFunction() {
+            return NativeFunction.set_shutdown_phase;
+        }
+
+        @Override
+        public void execute(boolean value) {
+            call(value ? 1 : 0);
+        }
+    }
+
     @Override
     public GetpidNode createGetpidNode() {
         return new TruffleNFI_GetpidNode();
@@ -262,4 +275,9 @@ public class TruffleNFI_Base implements BaseRFFI {
     public GlobNode createGlobNode() {
         return new TruffleNFI_GlobNode();
     }
+
+    @Override
+    public SetShutdownFlagNode createSetShutdownFlagNode() {
+        return new TruffleNFI_SetShutdownFlagNode();
+    }
 }
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h
index 9ec235c0bf90a484764528a552c801065e3fae51..583fee9348251042d78bd2bcb00ff56c65674652 100644
--- a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h
+++ b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h
@@ -828,8 +828,8 @@ void SET_PRCODE(SEXP x, SEXP v) {
 }
 
 int TRUELENGTH(SEXP x) {
-    TRACE0();
-    unimplemented("unimplemented");
+    TRACE(TARGp, x);
+    // TODO do not throw an error for now
     return 0;
 }
 
@@ -1342,7 +1342,9 @@ void R_PreserveObject(SEXP x) {
 
 void R_ReleaseObject(SEXP x) {
     TRACE0();
-    ((call_R_ReleaseObject) callbacks[R_ReleaseObject_x])(x);
+    if(!is_shutdown_phase()) {
+    	((call_R_ReleaseObject) callbacks[R_ReleaseObject_x])(x);
+    }
 }
 
 void R_dot_Last(void) {
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.c b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.c
index 12c143c3461d9367be0347fca288aa1b3e94b0d2..be3bf7cf24c906e88dd543e50492b2e380e69345 100644
--- a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.c
+++ b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.c
@@ -41,6 +41,8 @@ void init_utils(TruffleEnv *env) {
     }
 }
 
+static unsigned char shutdown_phase = 0;
+
 #define ERROR_JMP_BUF_STACK_SIZE 32
 static jmp_buf *callErrorJmpBufStack[ERROR_JMP_BUF_STACK_SIZE];
 static int callErrorJmpBufStackIndex = 0;
@@ -79,6 +81,14 @@ static void popJmpBuf() {
     popJmpBuf();                    \
     return result;
 
+void set_shutdown_phase(unsigned char value) {
+	shutdown_phase = value;
+}
+
+int is_shutdown_phase() {
+	return shutdown_phase;
+}
+
 void dot_call_void0(callvoid0func fun) {
     DO_CALL_VOID(fun());
 }
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.h b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.h
index 8de8be4ec35234407051080baee058e64ac83210..fc9621f2dc2f4e571282d920d5de29cd1205b9db 100644
--- a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.h
+++ b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.h
@@ -53,6 +53,10 @@ typedef void (*callvoid0func)(void);
 
 typedef void (*callvoid1func)(SEXP arg1);
 
+void set_shutdown_phase(unsigned char value);
+
+int is_shutdown_phase();
+
 void dot_call_void0(callvoid0func);
 
 void dot_call_void1(callvoid1func, SEXP);
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 265f759518f8b13c32f0b4dd8fcd8aab203e9f49..2232e1e75853eac5b55d828b1426021b137b9b57 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
@@ -48,6 +48,7 @@ import java.util.TimeZone;
 import java.util.WeakHashMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Supplier;
 
 import com.oracle.truffle.api.Assumption;
@@ -292,6 +293,8 @@ public final class RContext implements RTruffleObject {
      */
     private static boolean embedded;
 
+    private static final AtomicInteger CONTEXT_CNT = new AtomicInteger(0);
+
     /*
      * Workarounds to finesse project circularities between runtime/nodes.
      */
@@ -372,6 +375,10 @@ public final class RContext implements RTruffleObject {
         return embedded;
     }
 
+    public static int getContextCnt() {
+        return CONTEXT_CNT.get();
+    }
+
     /**
      * Sets the fields that do not depend on complex initialization.
      *
@@ -523,6 +530,7 @@ public final class RContext implements RTruffleObject {
         if (initial && !embedded) {
             initialContextInitialized = true;
         }
+        CONTEXT_CNT.incrementAndGet();
         return this;
     }
 
@@ -574,6 +582,7 @@ public final class RContext implements RTruffleObject {
             if (contextKind == ContextKind.SHARE_PARENT_RW) {
                 parentContext.sharedChild = null;
             }
+            CONTEXT_CNT.decrementAndGet();
             state = EnumSet.of(State.DISPOSED);
 
             this.allocationReporter.removePropertyChangeListener(ALLOCATION_ACTIVATION_LISTENER);
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/BaseRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/BaseRFFI.java
index 2a6ad6919008ef22802b97f96c276d9377bab21f..6ae84cd4766ac2767a066db82a03561c75321728 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/BaseRFFI.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/BaseRFFI.java
@@ -27,6 +27,7 @@ import java.util.ArrayList;
 
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.nodes.NodeInterface;
+import com.oracle.truffle.r.runtime.data.RNull;
 
 /**
  * A statically typed interface to exactly those native functions required by the R {@code base}
@@ -163,6 +164,14 @@ public interface BaseRFFI {
         }
     }
 
+    interface SetShutdownFlagNode extends NodeInterface {
+        void execute(boolean value);
+
+        static SetShutdownFlagNode create() {
+            return RFFIFactory.getBaseRFFI().createSetShutdownFlagNode();
+        }
+    }
+
     /*
      * The RFFI implementation influences exactly what subclass of the above nodes is created. Each
      * implementation must therefore, implement these methods that are called by the associated
@@ -189,6 +198,8 @@ public interface BaseRFFI {
 
     GlobNode createGlobNode();
 
+    SetShutdownFlagNode createSetShutdownFlagNode();
+
     /*
      * Some functions are called from non-Truffle contexts, which requires a RootNode
      */
@@ -273,4 +284,27 @@ public interface BaseRFFI {
             return unameRootNode;
         }
     }
+
+    final class SetShutdownFlagRootNode extends RFFIRootNode<SetShutdownFlagNode> {
+        protected SetShutdownFlagRootNode() {
+            super(RFFIFactory.getBaseRFFI().createSetShutdownFlagNode());
+        }
+
+        private static SetShutdownFlagRootNode setShutdownFlagRootNode;
+
+        @Override
+        public Object execute(VirtualFrame frame) {
+            Object[] args = frame.getArguments();
+            rffiNode.execute((boolean) args[0]);
+            return RNull.instance;
+        }
+
+        public static SetShutdownFlagRootNode create() {
+            if (setShutdownFlagRootNode == null) {
+                setShutdownFlagRootNode = new SetShutdownFlagRootNode();
+            }
+            return setShutdownFlagRootNode;
+        }
+    }
+
 }