diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
index aa0b4bacc234e8d706393cefa5c5d644c7481f02..57b539b5cba18f93336be010442e9b081cc7d5d8 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
@@ -581,6 +581,8 @@ public class BasePackage extends RBuiltinPackage {
         add(TraceFunctions.PrimUnTrace.class, TraceFunctionsFactory.PrimUnTraceNodeGen::create);
         add(TraceFunctions.TraceOnOff.class, TraceFunctionsFactory.TraceOnOffNodeGen::create);
         add(TraceFunctions.Tracemem.class, TraceFunctionsFactory.TracememNodeGen::create);
+        add(TraceFunctions.Retracemem.class, TraceFunctionsFactory.RetracememNodeGen::create);
+        add(TraceFunctions.Untracemem.class, TraceFunctionsFactory.UntracememNodeGen::create);
         add(Transpose.class, TransposeNodeGen::create);
         add(TrigExpFunctions.Acos.class, TrigExpFunctionsFactory.AcosNodeGen::create);
         add(TrigExpFunctions.Acosh.class, TrigExpFunctionsFactory.AcoshNodeGen::create);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TraceFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TraceFunctions.java
index c32d2e369e9fffa66730b7ddf5688d68bb3f9697..28b9b86b15e00cc0372e18cfb545fb76868d7c81 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TraceFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TraceFunctions.java
@@ -22,19 +22,30 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.missingValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
+
 import java.io.IOException;
 import java.util.HashSet;
 
 import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.api.Truffle;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.frame.Frame;
+import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
 import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.builtin.base.GetFunctionsFactory.GetNodeGen;
 import com.oracle.truffle.r.nodes.builtin.helpers.TraceHandling;
+import com.oracle.truffle.r.runtime.RArguments;
 import com.oracle.truffle.r.runtime.RBuiltin;
 import com.oracle.truffle.r.runtime.RBuiltinKind;
+import com.oracle.truffle.r.runtime.RCaller;
 import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.RVisibility;
@@ -42,6 +53,7 @@ import com.oracle.truffle.r.runtime.conn.StdConnections;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.MemoryTracer;
 import com.oracle.truffle.r.runtime.data.RFunction;
+import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
@@ -118,35 +130,126 @@ public class TraceFunctions {
         }
     }
 
-    @RBuiltin(name = "tracemem", kind = RBuiltinKind.PRIMITIVE, parameterNames = "x")
-    public abstract static class Tracemem extends RBuiltinNode {
-
+    public abstract static class TracememBase extends RBuiltinNode {
         static {
-            MemoryTracer.setListener(new TracememListener());
+            MemoryTracer.setListener(new TracememBase.TracememListener());
         }
 
-        @Specialization
-        protected String execute(Object x) {
+        protected static HashSet<Object> getTracedObjects() {
+            return RContext.getInstance().getInstrumentationState().getTracemem().getTracedObjects();
+        }
+
+        protected static String formatHashCode(Object x) {
+            return String.format("<0x%x>", x.hashCode());
+        }
+
+        protected static void startTracing(Object x) {
             getTracedObjects().add(x);
             MemoryTracer.reportEvents();
-            return String.format("<0x%x>", x.hashCode());
         }
 
-        private static HashSet<Object> getTracedObjects() {
-            return RContext.getInstance().getInstrumentationState().getTracemem().getTracedObjects();
+        protected static void printToStdout(String msg) {
+            try {
+                StdConnections.getStdout().writeString(msg, true);
+            } catch (IOException ex) {
+                throw RError.error(RError.NO_CALLER, RError.Message.GENERIC, ex.getMessage());
+            }
+        }
+
+        @TruffleBoundary
+        protected static String getStackTrace() {
+            final StringBuffer result = new StringBuffer();
+            Truffle.getRuntime().iterateFrames(frame -> {
+                Frame unwrapped = RArguments.unwrap(frame.getFrame(FrameAccess.READ_ONLY, true));
+                if (RArguments.isRFrame(unwrapped)) {
+                    RCaller call = RArguments.getCall(unwrapped);
+                    if (call != null && call.isValidCaller()) {
+                        result.append(RContext.getRRuntimeASTAccess().getCallerSource(call));
+                        result.append(' ');
+                    }
+                }
+                return null;
+            });
+            return result.toString();
         }
 
         private static final class TracememListener implements MemoryTracer.Listener {
             public void reportCopying(RAbstractVector src, RAbstractVector dest) {
                 if (getTracedObjects().contains(src)) {
-                    String msg = String.format("tracemem[0x%x -> 0x%x]", src.hashCode(), dest.hashCode());
-                    try {
-                        StdConnections.getStdout().writeString(msg, true);
-                    } catch (IOException ex) {
-                        throw RError.error(RError.NO_CALLER, RError.Message.GENERIC, ex.getMessage());
-                    }
+                    printToStdout(String.format("tracemem[0x%x -> 0x%x]: %s", src.hashCode(), dest.hashCode(), getStackTrace()));
                 }
             }
         }
     }
+
+    /**
+     * Note: tracemem does not support scalars: these are stored in frame directly not wrapped in a
+     * vector class. When these are manipulated as 'vectors', they are wrapped temporarily, such
+     * temporary vector wrappers cannot be traced however.
+     */
+    @RBuiltin(name = "tracemem", kind = RBuiltinKind.PRIMITIVE, parameterNames = "x")
+    public abstract static class Tracemem extends TracememBase {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("x").mustBe(nullValue().not(), Message.TRACEMEM_NOT_NULL);
+        }
+
+        @Specialization
+        protected String execute(Object x) {
+            startTracing(x);
+            return formatHashCode(x);
+        }
+    }
+
+    /**
+     * {@code retracemem} differences from {@code tracemem} are that it fails silently when R is not
+     * build with memory tracing support or x is NULL and it has additional parameter with an
+     * unclear meaning.
+     */
+    @RBuiltin(name = "retracemem", kind = RBuiltinKind.PRIMITIVE, visibility = RVisibility.CUSTOM, parameterNames = {"x", "previous"})
+    public abstract static class Retracemem extends TracememBase {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("previous").defaultError(Message.INVALID_ARGUMENT, "previous").mustBe(stringValue().or(missingValue()));
+        }
+
+        @Specialization
+        protected Object execute(Object x, @SuppressWarnings("unused") RNull previous) {
+            return getResult(x);
+        }
+
+        @Specialization
+        protected Object execute(Object x, @SuppressWarnings("unused") RMissing previous) {
+            return getResult(x);
+        }
+
+        @Specialization
+        protected Object execute(Object x, String previous) {
+            Object result = getResult(x);
+            if (x != null && x != RNull.instance) {
+                startTracing(x);
+                printToStdout(String.format("tracemem[%s -> 0x%x]: %s", previous, x.hashCode(), getStackTrace()));
+            }
+            return result;
+        }
+
+        private Object getResult(Object x) {
+            if (!isRNull(x) && getTracedObjects().contains(x)) {
+                RContext.getInstance().setVisible(true);
+                return formatHashCode(x);
+            } else {
+                RContext.getInstance().setVisible(false);
+                return RNull.instance;
+            }
+        }
+    }
+
+    @RBuiltin(name = "untracemem", kind = RBuiltinKind.PRIMITIVE, visibility = RVisibility.OFF, parameterNames = "x")
+    public abstract static class Untracemem extends TracememBase {
+        @Specialization
+        protected RNull execute(Object x) {
+            getTracedObjects().remove(x);
+            return RNull.instance;
+        }
+    }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java
index 66ac8ced4bcd2759534d469d1ee878725afa55aa..ab4d7f7aa168b40243a84301ffea87c404b6a355 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java
@@ -387,7 +387,7 @@ public final class CastBuilder {
 
         @Override
         public <T, R extends T> TypePredicateArgumentFilter<T, R> nullValue() {
-            return TypePredicateArgumentFilter.fromLambda(x -> x == RNull.instance || x == null);
+            return new TypePredicateArgumentFilter<>(x -> x == RNull.instance || x == null, true);
         }
 
         @Override
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
index 9c03b86cda3f4eaebdb99d8e69b6d5db469cc628..a8f59145f0f482a83e6843221d86805c11a89064 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
@@ -270,6 +270,7 @@ public final class RError extends RuntimeException {
         EMPTY_WHAT("empty 'what' specified"),
         LINE_ELEMENTS("line %d did not have %d elements"),
         ITEMS_NOT_MULTIPLE("number of items read is not a multiple of the number of columns"),
+        TRACEMEM_NOT_NULL("cannot trace NULL"),
         // below: GNU R gives also expression for the argument
         NOT_FUNCTION("'%s' is not a function, character or symbol"),
         NON_CHARACTER("non-character argument"),
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
index 3a285e948547d4cb29445245e3eaf160adc50bb6..6193f530100b87f5c340d8d9c5947519039398ad 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
@@ -40693,14 +40693,6 @@ logical(0)
 [145]  NA   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
 [163]   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_retracemem.testretracemem1
-#argv <- list(FALSE, FALSE);retracemem(argv[[1]],argv[[2]]);
-Error in retracemem(argv[[1]], argv[[2]]) : invalid 'previous' argument
-
-##com.oracle.truffle.r.test.builtins.TestBuiltin_retracemem.testretracemem2
-#argv <- list(structure(3.14159265358979, class = structure('3.14159265358979', class = 'testit')), structure(3.14159265358979, class = structure('3.14159265358979', class = 'testit')));retracemem(argv[[1]],argv[[2]]);
-Error in retracemem(argv[[1]], argv[[2]]) : invalid 'previous' argument
-
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_rev.testRev
 #{ rev(1:3) }
 [1] 3 2 1
@@ -48821,9 +48813,38 @@ character(0)
 #argv <- structure(list(x = c('na', NA, 'banana')), .Names = 'x');do.call('toupper', argv)
 [1] "NA"     NA       "BANANA"
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_tracemem.basicTests
-#v <- c(1,10); addr<-tracemem(v); f<-function(x) x[[1]]<-42; out<-capture.output(f(v)); addr<-sub('>','',sub('<','',addr)); grep(paste0('tracemem[', addr), out, fixed=TRUE)
-[1] 1
+##com.oracle.truffle.r.test.builtins.TestBuiltin_tracemem.argumentErrors
+#retracemem(NULL)
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_tracemem.argumentErrors
+#retracemem(c(1,10,100), 1:10)
+Error in retracemem(c(1, 10, 100), 1:10) : invalid 'previous' argument
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_tracemem.argumentErrors
+#tracemem(NULL)
+Error in tracemem(NULL) : cannot trace NULL
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_tracemem.list
+#v <- list(1,10,100); tracemem(v); x <- v; x[[1]]<-42;
+[1] "<0x112db18>"
+tracemem[0x112db18 -> 0x1699c30]:
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_tracemem.retracemem
+#v <- c(1,10,100); tracemem(v); x <- v[-1]; retracemem(x, retracemem(v)); u <- x; u[[1]] <- 42;
+[1] "<0x17f8b18>"
+tracemem[<0x17f8b18> -> 0x251dd78]:
+tracemem[0x251dd78 -> 0x251ddb0]:
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_tracemem.vectors
+#v <- c(1,10,100); tracemem(v); x <- v; y <- v; x[[1]]<-42; untracemem(v); y[[2]] <- 84
+[1] "<0x1b8eb18>"
+tracemem[0x1b8eb18 -> 0x20fabe8]:
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_tracemem.vectors
+#v <- c(1,10,100); tracemem(v); x <- v; y <- v; x[[1]]<-42; y[[2]] <- 84
+[1] "<0x24b2b18>"
+tracemem[0x24b2b18 -> 0x2a1ebe8]:
+tracemem[0x24b2b18 -> 0x2a1ea80]:
 
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_trigamma.testtrigamma1
 #argv <- list(structure(c(9.16602362697115, 1.16602362697115, 3.16602362697115, 6.16602362697115, 6.16602362697115, 2.16602362697115, 8.16602362697115, 1.16602362697115, 7.16602362697115, 19.1660236269712, 2.16602362697115), .Names = c('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11')));trigamma(argv[[1]]);
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java
index b002045656a8214a91587222a65aedb82e056adf..257566d7e83fdf6d15a746ff079664c03fdd5138 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java
@@ -22,6 +22,7 @@ import java.nio.file.Paths;
 import java.nio.file.SimpleFileVisitor;
 import java.nio.file.attribute.BasicFileAttributes;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.Map.Entry;
 import java.util.SortedMap;
 import java.util.TreeMap;
@@ -68,6 +69,7 @@ public class TestBase {
         IgnoreWarningContext, // the warning context is ignored
         MayIgnoreErrorContext,
         MayIgnoreWarningContext,
+        ContainsReferences, // replaces references in form of 0xbcdef1 for numbers
         IgnoreWhitespace;
     }
 
@@ -353,6 +355,11 @@ public class TestBase {
      */
     private static final boolean FULL_COMPARE_ERRORS = false;
 
+    /**
+     * To implement {@link Output#ContainsReferences}.
+     **/
+    private static final Pattern REFERENCE_PATTERN = Pattern.compile("(?<id>(0x[0-9abcdefx]+))");
+
     /**
      * Test a given string with R source against expected output. This is (currently) an exact
      * match, so any warnings or errors will cause a failure until FastR matches GnuR in that
@@ -459,6 +466,7 @@ public class TestBase {
         boolean mayContainError = TestTrait.contains(traits, Output.MayIgnoreErrorContext);
         boolean ambiguousError = TestTrait.contains(traits, Output.IgnoreErrorMessage);
         boolean ignoreWhitespace = TestTrait.contains(traits, Output.IgnoreWhitespace);
+        boolean containsReferences = TestTrait.contains(traits, Output.ContainsReferences);
         boolean nonSharedContext = TestTrait.contains(traits, Context.NonShared);
         boolean longTimeout = TestTrait.contains(traits, Context.LongTimeout);
 
@@ -477,7 +485,7 @@ public class TestBase {
                     result = result.replaceAll("\\s+", "");
                 }
 
-                CheckResult checkResult = checkResult(whiteLists, input, expected, result, containsWarning, mayContainWarning, containsError, mayContainError, ambiguousError);
+                CheckResult checkResult = checkResult(whiteLists, input, expected, result, containsWarning, mayContainWarning, containsError, mayContainError, ambiguousError, containsReferences);
 
                 result = checkResult.result;
                 expected = checkResult.expected;
@@ -539,14 +547,18 @@ public class TestBase {
     }
 
     private CheckResult checkResult(WhiteList[] whiteLists, String input, String originalExpected, String originalResult, boolean containsWarning, boolean mayContainWarning, boolean containsError,
-                    boolean mayContainError, boolean ambiguousError) {
+                    boolean mayContainError, boolean ambiguousError, boolean convertReferences) {
         boolean ok;
         String result = originalResult;
         String expected = originalExpected;
+        if (convertReferences) {
+            result = convertReferencesInOutput(result);
+            expected = convertReferencesInOutput(expected);
+        }
         if (input.equals("c(1i,1i,1i)/(-(1/0))")) {
             System.console();
         }
-        if (expected.equals(result) || searchWhiteLists(whiteLists, input, expected, result, containsWarning, mayContainWarning, containsError, mayContainError, ambiguousError)) {
+        if (expected.equals(result) || searchWhiteLists(whiteLists, input, expected, result, containsWarning, mayContainWarning, containsError, mayContainError, ambiguousError, convertReferences)) {
             ok = true;
             if (containsError && !ambiguousError) {
                 System.out.println("unexpected correct error message: " + getTestContext());
@@ -575,8 +587,23 @@ public class TestBase {
         return new CheckResult(ok, result, expected);
     }
 
+    private static String convertReferencesInOutput(String result) {
+        Matcher matcher = REFERENCE_PATTERN.matcher(result);
+        HashMap<String, Integer> idsMap = new HashMap<>();
+        int currentId = 1;
+        while (matcher.find()) {
+            if (idsMap.putIfAbsent(matcher.group("id"), currentId) == null) {
+                currentId++;
+            }
+        }
+        for (Entry<String, Integer> item : idsMap.entrySet()) {
+            result = result.replace(item.getKey(), item.getValue().toString());
+        }
+        return result;
+    }
+
     private boolean searchWhiteLists(WhiteList[] whiteLists, String input, String expected, String result, boolean containsWarning, boolean mayContainWarning, boolean containsError,
-                    boolean mayContainError, boolean ambiguousError) {
+                    boolean mayContainError, boolean ambiguousError, boolean convertReferences) {
         if (whiteLists == null) {
             return false;
         }
@@ -584,13 +611,13 @@ public class TestBase {
             WhiteList.Results wlr = list.get(input);
             if (wlr != null) {
                 // Sanity check that "expected" matches the entry in the WhiteList
-                CheckResult checkedResult = checkResult(null, input, wlr.expected, expected, containsWarning, mayContainWarning, containsError, mayContainError, ambiguousError);
+                CheckResult checkedResult = checkResult(null, input, wlr.expected, expected, containsWarning, mayContainWarning, containsError, mayContainError, ambiguousError, convertReferences);
                 if (!checkedResult.ok) {
                     System.out.println("expected output does not match: " + wlr.expected + " vs. " + expected);
                     return false;
                 }
                 // Substitute the FastR output and try to match that
-                CheckResult fastRResult = checkResult(null, input, wlr.fastR, result, containsWarning, mayContainWarning, containsError, mayContainError, ambiguousError);
+                CheckResult fastRResult = checkResult(null, input, wlr.fastR, result, containsWarning, mayContainWarning, containsError, mayContainError, ambiguousError, convertReferences);
                 if (fastRResult.ok) {
                     list.markUsed(input);
                     return true;
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_retracemem.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_retracemem.java
deleted file mode 100644
index ae260d0e65b227cb5ccdee90bea38ccda0e052c8..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_retracemem.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * This material is distributed under the GNU General Public License
- * Version 2. You may review the terms of this license at
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates
- *
- * All rights reserved.
- */
-package com.oracle.truffle.r.test.builtins;
-
-import org.junit.Test;
-
-import com.oracle.truffle.r.test.TestBase;
-
-// Checkstyle: stop line length check
-public class TestBuiltin_retracemem extends TestBase {
-
-    @Test
-    public void testretracemem1() {
-        assertEval(Ignored.Unknown, "argv <- list(FALSE, FALSE);retracemem(argv[[1]],argv[[2]]);");
-    }
-
-    @Test
-    public void testretracemem2() {
-        assertEval(Ignored.Unknown,
-                        "argv <- list(structure(3.14159265358979, class = structure('3.14159265358979', class = 'testit')), structure(3.14159265358979, class = structure('3.14159265358979', class = 'testit')));retracemem(argv[[1]],argv[[2]]);");
-    }
-}
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_tracemem.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_tracemem.java
index ecf20b6ec0a226252b35dc5eeb90d6316af29bdf..7b4e4e6f413c56d80610c894335b45f40983ee96 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_tracemem.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_tracemem.java
@@ -27,12 +27,32 @@ import org.junit.Test;
 
 import com.oracle.truffle.r.test.TestBase;
 
+/**
+ * Tests tracemem and related builtins.
+ */
 public class TestBuiltin_tracemem extends TestBase {
     @Test
-    public void basicTests() {
-        // tracemem returns the hash in form of "<0x0fa0abcd>", we get rid of the "<" and ">" to
-        // match it against the output that is produced by copying 'v', which should be in the form
-        // of "tracemem[0x0fa0abcd->someotherhash]".
-        assertEval("v <- c(1,10); addr<-tracemem(v); f<-function(x) x[[1]]<-42; out<-capture.output(f(v)); addr<-sub('>','',sub('<','',addr)); grep(paste0('tracemem[', addr), out, fixed=TRUE)");
+    public void argumentErrors() {
+        assertEval("tracemem(NULL)");
+        assertEval("retracemem(NULL)");
+        assertEval("retracemem(c(1,10,100), 1:10)");
+    }
+
+    @Test
+    public void vectors() {
+        assertEval(Output.ContainsReferences, "v <- c(1,10,100); tracemem(v); x <- v; y <- v; x[[1]]<-42; y[[2]] <- 84");
+        assertEval(Output.ContainsReferences, "v <- c(1,10,100); tracemem(v); x <- v; y <- v; x[[1]]<-42; untracemem(v); y[[2]] <- 84");
+    }
+
+    @Test
+    public void list() {
+        assertEval(Output.ContainsReferences, "v <- list(1,10,100); tracemem(v); x <- v; x[[1]]<-42;");
+    }
+
+    @Test
+    public void retracemem() {
+        // intended semantics of retracemem is not clear, this tests what is definitely intended:
+        // retracemem starts tracing of its first argument
+        assertEval(Output.ContainsReferences, "v <- c(1,10,100); tracemem(v); x <- v[-1]; retracemem(x, retracemem(v)); u <- x; u[[1]] <- 42;");
     }
 }
diff --git a/mx.fastr/copyrights/overrides b/mx.fastr/copyrights/overrides
index d00961fd8b0f297a0227a0f693c8284c0eda0c20..d96749ae9fc4718ebdb10ce11c9e0a786bbbe931 100644
--- a/mx.fastr/copyrights/overrides
+++ b/mx.fastr/copyrights/overrides
@@ -566,7 +566,6 @@ com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_reg
 com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rep_len.java,purdue.copyright
 com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rep.java,purdue.copyright
 com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_repint.java,purdue.copyright
-com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_retracemem.java,purdue.copyright
 com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rev.java,purdue.copyright
 com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_round.java,purdue.copyright
 com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_row.java,purdue.copyright