diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprof.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprof.java
index f6b5274db4285effd5d473bcfb84dbddca83d8ab..49efa1fd131ed509dc5d88b3a5ffebe7056d6fdb 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprof.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprof.java
@@ -81,7 +81,7 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
  * the function name.
  *
  */
-public abstract class Rprof extends RExternalBuiltinNode.Arg8 implements RDataFactory.Listener, MemoryCopyTracer.Listener {
+public abstract class Rprof extends RExternalBuiltinNode.Arg8 implements MemoryCopyTracer.Listener {
 
     static {
         Casts casts = new Casts(Rprof.class);
@@ -114,8 +114,7 @@ public abstract class Rprof extends RExternalBuiltinNode.Arg8 implements RDataFa
                     warning(RError.Message.GENERIC, "Rprof: gc profiling not supported");
                 }
                 if (memProfiling) {
-                    RDataFactory.addListener(this);
-                    RDataFactory.setTracingState(true);
+                    RDataFactory.addListener(LISTENER);
                     MemoryCopyTracer.addListener(this);
                     MemoryCopyTracer.setTracingState(true);
                 }
@@ -133,24 +132,26 @@ public abstract class Rprof extends RExternalBuiltinNode.Arg8 implements RDataFa
         return RNull.instance;
     }
 
-    @Override
-    @TruffleBoundary
-    public void reportAllocation(RTypedValue data) {
-        RprofState profState = RprofState.get();
-        if (profState.memoryQuad == null) {
-            return;
-        }
-        long size = RObjectSize.getObjectSize(data, Rprofmem.myIgnoreObjectHandler);
-        if (data instanceof RAbstractVector) {
-            if (size >= Rprofmem.LARGE_VECTOR) {
-                profState.memoryQuad.largeV += size;
+    private static final RDataFactory.Listener LISTENER = new RDataFactory.Listener() {
+        @Override
+        @TruffleBoundary
+        public void reportAllocation(RTypedValue data) {
+            RprofState profState = RprofState.get();
+            if (profState.memoryQuad == null) {
+                return;
+            }
+            long size = RObjectSize.getObjectSize(data, Rprofmem.myIgnoreObjectHandler);
+            if (data instanceof RAbstractVector) {
+                if (size >= Rprofmem.LARGE_VECTOR) {
+                    profState.memoryQuad.largeV += size;
+                } else {
+                    profState.memoryQuad.smallV += size;
+                }
             } else {
-                profState.memoryQuad.smallV += size;
+                profState.memoryQuad.nodes += size;
             }
-        } else {
-            profState.memoryQuad.nodes += size;
         }
-    }
+    };
 
     @Override
     @TruffleBoundary
@@ -362,7 +363,7 @@ public abstract class Rprof extends RExternalBuiltinNode.Arg8 implements RDataFa
             out.close();
             this.setOut(null);
             if (this.memoryProfiling) {
-                RDataFactory.setTracingState(false);
+                RDataFactory.removeListener(LISTENER);
                 MemoryCopyTracer.setTracingState(false);
             }
         }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprofmem.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprofmem.java
index 34a5b00b398ed1f03bc1408f29547dbac905126e..197dc7b9bd1672be42b9ed79677a120422757e34 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprofmem.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprofmem.java
@@ -49,7 +49,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.instrument.InstrumentationState.RprofState;
 
-public abstract class Rprofmem extends RExternalBuiltinNode.Arg3 implements RDataFactory.Listener {
+public abstract class Rprofmem extends RExternalBuiltinNode.Arg3 {
 
     static {
         Casts casts = new Casts(Rprofmem.class);
@@ -75,8 +75,7 @@ public abstract class Rprofmem extends RExternalBuiltinNode.Arg3 implements RDat
             try {
                 PrintStream out = new PrintStream(new FileOutputStream(filename, append));
                 profmemState.initialize(out, thresholdVec.getDataAt(0));
-                RDataFactory.addListener(this);
-                RDataFactory.setTracingState(true);
+                RDataFactory.addListener(LISTENER);
             } catch (IOException ex) {
                 throw error(RError.Message.GENERIC, String.format("Rprofmem: cannot open profile file '%s'", filename));
             }
@@ -116,39 +115,40 @@ public abstract class Rprofmem extends RExternalBuiltinNode.Arg3 implements RDat
 
     static final RObjectSize.IgnoreObjectHandler myIgnoreObjectHandler = new MyIgnoreObjectHandler();
 
-    @Override
-    @TruffleBoundary
-    public void reportAllocation(RTypedValue data) {
-        // We could do some in memory buffering
-        // TODO write out full stack
-        RprofmemState profmemState = RprofmemState.get();
-        Frame frame = Utils.getActualCurrentFrame();
-        if (frame == null) {
-            // not an R evaluation, some internal use
-            return;
-        }
-        RFunction func = RArguments.getFunction(frame);
-        if (func == null) {
-            return;
-        }
-        String name = func.getRootNode().getName();
-
-        long size = RObjectSize.getObjectSize(data, myIgnoreObjectHandler);
-        if (data instanceof RAbstractVector && size >= LARGE_VECTOR) {
-            if (size > profmemState.threshold) {
-                profmemState.out().printf("%d: %s\n", size, name);
+    private static final RDataFactory.Listener LISTENER = new RDataFactory.Listener() {
+        @Override
+        public void reportAllocation(RTypedValue data) {
+            // We could do some in memory buffering
+            // TODO write out full stack
+            RprofmemState profmemState = RprofmemState.get();
+            Frame frame = Utils.getActualCurrentFrame();
+            if (frame == null) {
+                // not an R evaluation, some internal use
+                return;
             }
-        } else {
-            int pageCount = profmemState.pageCount;
-            long pcs = pageCount + size;
-            if (pcs > PAGE_SIZE) {
-                profmemState.out().printf("new page: %s\n", name);
-                profmemState.pageCount = (int) (pcs - PAGE_SIZE);
+            RFunction func = RArguments.getFunction(frame);
+            if (func == null) {
+                return;
+            }
+            String name = func.getRootNode().getName();
+
+            long size = RObjectSize.getObjectSize(data, myIgnoreObjectHandler);
+            if (data instanceof RAbstractVector && size >= LARGE_VECTOR) {
+                if (size > profmemState.threshold) {
+                    profmemState.out().printf("%d: %s\n", size, name);
+                }
             } else {
-                profmemState.pageCount = (int) pcs;
+                int pageCount = profmemState.pageCount;
+                long pcs = pageCount + size;
+                if (pcs > PAGE_SIZE) {
+                    profmemState.out().printf("new page: %s\n", name);
+                    profmemState.pageCount = (int) (pcs - PAGE_SIZE);
+                } else {
+                    profmemState.pageCount = (int) pcs;
+                }
             }
         }
-    }
+    };
 
     private static final class RprofmemState extends RprofState {
         private double threshold;
@@ -170,7 +170,7 @@ public abstract class Rprofmem extends RExternalBuiltinNode.Arg3 implements RDat
 
         @Override
         public void cleanup(int status) {
-            RDataFactory.setTracingState(false);
+            RDataFactory.removeListener(LISTENER);
             closeAndResetOut();
         }
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java
index 7cbc81998e59b454d7561bebff83e620f9c87894..233e19751c62ee09b130210e66b4b37f6c368652 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java
@@ -267,7 +267,7 @@ public abstract class AsVector extends RBuiltinNode.Arg2 {
             }
 
             @Fallback
-            protected Object castPairlist(@SuppressWarnings("unused") Object x) {
+            protected Object castPairlist(Object x) {
                 throw RInternalError.unimplemented("non-list casts to pairlist for " + x.getClass().getSimpleName());
             }
         }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TrigExpFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TrigExpFunctions.java
index 37c52d914213c99ec840b355c900296434d26319..cfa92609f7ff7a5199b7d485f1b0f1a8fc9a69bc 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TrigExpFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TrigExpFunctions.java
@@ -31,12 +31,9 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
 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;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.profiles.LoopConditionProfile;
-import com.oracle.truffle.api.profiles.ValueProfile;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RError.Message;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInterop.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInterop.java
index d87fd82091ed6cbb1fc7a5d44dc98354595db5a7..5678a43e44ebf87f4187beb81d79cf104d02cfec 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInterop.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInterop.java
@@ -133,10 +133,9 @@ public class FastRInterop {
             return parse(mimeType, source).call();
         }
 
-        @SuppressWarnings("unused")
         @Specialization()
         @TruffleBoundary
-        protected Object eval(RMissing mimeType, String source, RMissing path) {
+        protected Object eval(@SuppressWarnings("unused") RMissing mimeType, @SuppressWarnings("unused") String source, @SuppressWarnings("unused") RMissing path) {
             throw RError.error(this, RError.Message.INVALID_ARG, "mimeType");
         }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRStats.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRStats.java
index 458fa6ebeff90250e215b59b64ec750d1755edde..e09fae33d35e17af9fa7cddbd887b530101b596e 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRStats.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRStats.java
@@ -158,7 +158,7 @@ public class FastRStats {
     }
 
     @RBuiltin(name = ".fastr.stats.typecounts", visibility = OFF, kind = PRIMITIVE, parameterNames = {"filename", "append"}, behavior = COMPLEX)
-    public abstract static class FastRProfTypecounts extends RBuiltinNode.Arg2 implements RDataFactory.Listener {
+    public abstract static class FastRProfTypecounts extends RBuiltinNode.Arg2 {
         @Override
         public Object[] getDefaultParameterValues() {
             return new Object[]{"Rproftypecounts.out", RRuntime.LOGICAL_FALSE};
@@ -190,8 +190,7 @@ public class FastRStats {
                 try {
                     PrintStream out = new PrintStream(new FileOutputStream(filenameVec.getDataAt(0), append));
                     state.setOut(out);
-                    RDataFactory.addListener(this);
-                    RDataFactory.setTracingState(true);
+                    RDataFactory.addListener(LISTENER);
                 } catch (IOException ex) {
                     throw error(RError.Message.GENERIC, String.format("Rprofmem: cannot open profile file '%s'", filenameVec.getDataAt(0)));
                 }
@@ -202,36 +201,38 @@ public class FastRStats {
         protected void endProfiling() {
             State state = State.get();
             if (state.out() != null) {
-                RDataFactory.setTracingState(false);
+                RDataFactory.removeListener(LISTENER);
                 state.cleanup(0);
             }
         }
 
-        @Override
-        public void reportAllocation(RTypedValue data) {
-            Class<? extends RTypedValue> klass = data.getClass();
-            boolean isVector = (data instanceof RAbstractVector);
-            State state = State.get();
-            Map<Class<? extends RTypedValue>, SortedMap<Integer, State.Counter>> typecountsMap = state.getTypecountsMap();
-            SortedMap<Integer, State.Counter> countsMap = typecountsMap.get(klass);
-            if (countsMap == null) {
-                countsMap = new TreeMap<>();
-                typecountsMap.put(klass, countsMap);
-            }
-            int length;
-            if (isVector) {
-                RAbstractVector vector = (RAbstractVector) data;
-                length = vector.getLength();
-            } else {
-                length = 1;
-            }
-            State.Counter count = countsMap.get(length);
-            if (count == null) {
-                count = new State.Counter();
-                countsMap.put(length, count);
+        private static final RDataFactory.Listener LISTENER = new RDataFactory.Listener() {
+            @Override
+            public void reportAllocation(RTypedValue data) {
+                Class<? extends RTypedValue> klass = data.getClass();
+                boolean isVector = (data instanceof RAbstractVector);
+                State state = State.get();
+                Map<Class<? extends RTypedValue>, SortedMap<Integer, State.Counter>> typecountsMap = state.getTypecountsMap();
+                SortedMap<Integer, State.Counter> countsMap = typecountsMap.get(klass);
+                if (countsMap == null) {
+                    countsMap = new TreeMap<>();
+                    typecountsMap.put(klass, countsMap);
+                }
+                int length;
+                if (isVector) {
+                    RAbstractVector vector = (RAbstractVector) data;
+                    length = vector.getLength();
+                } else {
+                    length = 1;
+                }
+                State.Counter count = countsMap.get(length);
+                if (count == null) {
+                    count = new State.Counter();
+                    countsMap.put(length, count);
+                }
+                count.incCount();
             }
-            count.incCount();
-        }
+        };
 
         private static class State extends RprofState {
             public static class Counter {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemShow.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemShow.java
index b91d1b1de25cb5a3653aea0248d688f8cc54784f..b85dfe90a71c3f4139f114e8e635e2e814b22cbf 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemShow.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemShow.java
@@ -77,7 +77,7 @@ public abstract class FastRprofmemShow extends RBuiltinNode.Arg6 {
     private static Object show(int levels, boolean desc, Integer entryId, boolean printParents, String view, MemAllocProfilerPaths snapshot) {
         MemAllocProfilerPaths usedSnapshot = snapshot;
         if (FastRprofmem.HOTSPOTS_VIEW.equals(view)) {
-            usedSnapshot = usedSnapshot.toHotSpots();
+            usedSnapshot = usedSnapshot.toHS();
         }
         FastRprofmem.getProfilerPrinter().show(usedSnapshot, entryId, levels, desc, printParents);
         return RNull.instance;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemSnapshot.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemSnapshot.java
index 9c04dc658bc114f5bd21ddb4001aa2aa4a5323d4..4c86181456f608bc689590e8168bc6b681a6d02c 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemSnapshot.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemSnapshot.java
@@ -57,7 +57,7 @@ public abstract class FastRprofmemSnapshot extends RBuiltinNode.Arg2 {
         MemAllocProfilerPaths snapshot = MemAllocProfilerStacks.getInstance().getStackPaths().getOrMakeSnapshot(name);
 
         if (FastRprofmem.HOTSPOTS_VIEW.equals(view)) {
-            snapshot = snapshot.toHotSpots();
+            snapshot = snapshot.toHS();
         }
 
         return snapshot.toTruffleObject();
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemSource.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemSource.java
index 5339bbaac4633efe60166d41b95cb4b33f8b61a3..3c008c7eec1fbbdd89b1461b122cc9b5779c4654 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemSource.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemSource.java
@@ -22,7 +22,6 @@
  */
 package com.oracle.truffle.r.nodes.builtin.fastr.memprof;
 
-import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.singleElement;
 import static com.oracle.truffle.r.nodes.builtin.fastr.memprof.FastRprofmem.castSnapshotArg;
 import static com.oracle.truffle.r.nodes.builtin.fastr.memprof.FastRprofmem.castViewArg;
@@ -59,18 +58,16 @@ public abstract class FastRprofmemSource extends RBuiltinNode.Arg3 {
     public Object showSource(int entryId, String view, TruffleObject snapshotTO) {
         MemAllocProfilerPaths paths = MemAllocProfilerPaths.fromTruffleObject(snapshotTO);
         return showSource(entryId, view, paths);
-
     }
 
     private static Object showSource(int entryId, String view, MemAllocProfilerPaths snap) {
         MemAllocProfilerPaths snapshot = snap;
         if (FastRprofmem.HOTSPOTS_VIEW.equals(view)) {
-            snapshot = snapshot.toHotSpots();
+            snapshot = snapshot.toHS();
         }
 
         FastRprofmem.getProfilerPrinter().source(snapshot, entryId);
 
         return RNull.instance;
     }
-
 }
diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/ResultTypesAnalyserTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/ResultTypesAnalyserTest.java
index 19dea4141a5e586b2ec7d72acdda23230574ff71..85f11a3b1d14ee85e26a22ab081fb7ab713378a2 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/ResultTypesAnalyserTest.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/ResultTypesAnalyserTest.java
@@ -22,8 +22,6 @@
  */
 package com.oracle.truffle.r.nodes.castsTests;
 
-import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.emptyIntegerVector;
-import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullConstant;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.atomicIntegerValue;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.atomicLogicalValue;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.chain;
@@ -32,6 +30,7 @@ import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.constant;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.dimEq;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.doubleToInt;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.elementAt;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.emptyIntegerVector;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.eq;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.intNA;
@@ -43,14 +42,15 @@ import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.mapIf;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.matrix;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.missingValue;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.not;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullConstant;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.size;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.squareMatrix;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
-import static com.oracle.truffle.r.nodes.casts.TypeExpr.atom;
 import static com.oracle.truffle.r.nodes.casts.MarkLookup.mark;
+import static com.oracle.truffle.r.nodes.casts.TypeExpr.atom;
 
 import java.lang.reflect.Type;
 import java.util.Map;
@@ -71,7 +71,6 @@ import com.oracle.truffle.r.nodes.casts.TypeExpr;
 import com.oracle.truffle.r.nodes.castsTests.CastBuilderTest.DummyBuiltin;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
-import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
 import com.oracle.truffle.r.runtime.data.RAttributable;
 import com.oracle.truffle.r.runtime.data.RComplex;
 import com.oracle.truffle.r.runtime.data.RComplexVector;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java
index cea19e14d2bdd51e5a2799cfceb1d3c6643494bf..11d21398eea17528bccbe66516ea56d603fcd9d3 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java
@@ -32,7 +32,6 @@ import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
-import com.oracle.truffle.api.interop.TruffleObject;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.nodes.NodeInfo;
 import com.oracle.truffle.api.object.DynamicObject;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java
index 2275f18416e2fc3eff142454221e2d1b776665c6..d08d2bbf5c8e189d38541eb96a7d61eab2593f5b 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java
@@ -33,7 +33,6 @@ import com.oracle.truffle.api.profiles.ValueProfile;
 import com.oracle.truffle.r.nodes.attributes.ArrayAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SetAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode;
-import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.context.RContext;
@@ -49,8 +48,6 @@ import com.oracle.truffle.r.runtime.data.RS4Object;
 import com.oracle.truffle.r.runtime.data.RSymbol;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
-import com.oracle.truffle.r.runtime.interop.Foreign2R;
-import com.oracle.truffle.r.runtime.interop.Foreign2RNodeGen;
 import com.oracle.truffle.r.runtime.interop.ForeignArray2R;
 import com.oracle.truffle.r.runtime.interop.ForeignArray2RNodeGen;
 
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 d12bdff737d486141602d4b7d42c4a1d42bc3dae..a35713f109e9678f39be3d906553676602dc6ac3 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
@@ -66,10 +66,10 @@ import com.oracle.truffle.r.runtime.builtins.RBuiltinKind;
 import com.oracle.truffle.r.runtime.builtins.RBuiltinLookup;
 import com.oracle.truffle.r.runtime.conn.ConnectionSupport;
 import com.oracle.truffle.r.runtime.conn.StdConnections;
+import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RFunction;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.RTruffleObject;
-import com.oracle.truffle.r.runtime.data.RTypedValue;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.ffi.DLL;
 import com.oracle.truffle.r.runtime.ffi.RFFIFactory;
@@ -77,7 +77,6 @@ import com.oracle.truffle.r.runtime.instrument.InstrumentationState;
 import com.oracle.truffle.r.runtime.nodes.RCodeBuilder;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
 import com.oracle.truffle.r.runtime.rng.RRNG;
-import com.oracle.truffle.r.runtime.data.RDataFactory;
 
 /**
  * Encapsulates the runtime state ("context") of an R session. All access to that state from the
@@ -398,6 +397,7 @@ public final class RContext implements RTruffleObject {
 
         this.allocationReporter = env.lookup(AllocationReporter.class);
         this.allocationReporter.addPropertyChangeListener(ALLOCATION_ACTIVATION_LISTENER);
+        RDataFactory.setAllocationTracingEnabled(allocationReporter.isActive());
     }
 
     /**
@@ -812,7 +812,7 @@ public final class RContext implements RTruffleObject {
     private static final PropertyChangeListener ALLOCATION_ACTIVATION_LISTENER = new PropertyChangeListener() {
         @Override
         public void propertyChange(PropertyChangeEvent event) {
-            RDataFactory.setTracingState(event.getNewValue() == Boolean.TRUE);
+            RDataFactory.setAllocationTracingEnabled(event.getNewValue() == Boolean.TRUE);
         }
     };
 
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java
index c3c0ff363ab66b62382450ff2396d1f30faa6170..56ac7016f2aeca68bf68e7df478fa14287a4b246 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java
@@ -31,10 +31,10 @@ import com.oracle.truffle.api.Assumption;
 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.RootCallTarget;
+import com.oracle.truffle.api.Truffle;
 import com.oracle.truffle.api.frame.FrameDescriptor;
 import com.oracle.truffle.api.frame.MaterializedFrame;
 import com.oracle.truffle.api.instrumentation.AllocationReporter;
-import com.oracle.truffle.api.utilities.CyclicAssumption;
 import com.oracle.truffle.r.runtime.FastROptions;
 import com.oracle.truffle.r.runtime.RCaller;
 import com.oracle.truffle.r.runtime.RInternalError;
@@ -160,7 +160,6 @@ public final class RDataFactory {
     }
 
     public static RComplexVector createComplexVector(double[] data, boolean complete, int[] dims, RStringVector names) {
-
         return traceDataCreated(new RComplexVector(data, complete, dims, names));
     }
 
@@ -223,7 +222,6 @@ public final class RDataFactory {
     }
 
     public static RLogicalVector createLogicalVector(byte[] data, boolean complete, int[] dims, RStringVector names) {
-
         return traceDataCreated(new RLogicalVector(data, complete, dims, names));
     }
 
@@ -233,30 +231,25 @@ public final class RDataFactory {
 
     public static RIntSequence createAscendingRange(int start, int end) {
         assert start <= end;
-
         return traceDataCreated(new RIntSequence(start, 1, end - start + 1));
     }
 
     public static RIntSequence createDescendingRange(int start, int end) {
         assert start > end;
-
         return traceDataCreated(new RIntSequence(start, -1, start - end + 1));
     }
 
     public static RIntSequence createIntSequence(int start, int stride, int length) {
-
         return traceDataCreated(new RIntSequence(start, stride, length));
     }
 
     public static RDoubleSequence createAscendingRange(double start, double end) {
         assert start <= end;
-
         return traceDataCreated(new RDoubleSequence(start, 1, (int) ((end - start) + 1)));
     }
 
     public static RDoubleSequence createDescendingRange(double start, double end) {
         assert start > end;
-
         return traceDataCreated(new RDoubleSequence(start, -1, (int) ((start - end) + 1)));
     }
 
@@ -398,7 +391,6 @@ public final class RDataFactory {
     }
 
     public static RList createList(Object[] data, int[] newDimensions, RStringVector names) {
-
         return traceDataCreated(new RList(data, newDimensions, names));
     }
 
@@ -565,53 +557,71 @@ public final class RDataFactory {
      * allocated. Owing to the use of the Assumption, there should be no overhead when disabled.
      */
 
-    private static Deque<Listener> listeners = new ConcurrentLinkedDeque<>();
+    private static final Deque<Listener> listeners = new ConcurrentLinkedDeque<>();
+    private static boolean allocationTracingEnabled = false;
 
-    @CompilationFinal private static byte enabled = RRuntime.LOGICAL_NA;
+    @CompilationFinal private static StateAssumption stateAssumption = new StateAssumption();
 
-    private static final CyclicAssumption noAllocationTracingAssumption = new CyclicAssumption("data allocation");
+    /**
+     * As long as "off" is valid, the feature is off. It is on as long as "on" is valid.
+     */
+    public static final class StateAssumption {
+        private final Assumption off = Truffle.getRuntime().createAssumption("off");
+        private final Assumption on = Truffle.getRuntime().createAssumption("on");
 
-    public static void setTracingState(boolean newState) {
-        byte newStateLogical = RRuntime.asLogical(newState);
-        if (enabled != newStateLogical) {
-            noAllocationTracingAssumption.invalidate();
-            enabled = newStateLogical;
+        public boolean isEnabled() {
+            return !off.isValid() && on.isValid();
         }
-    }
 
-    private static <T> T traceDataCreated(T data) {
-        if (RRuntime.isNA(enabled)) {
-            RContext ctx = RContext.getThreadLocalInstance();
-            if (ctx != null) {
-                setTracingState(ctx.getAllocationReporter().isActive());
+        public StateAssumption setState(boolean enabled) {
+            if (enabled && !stateAssumption.isEnabled()) {
+                assert !isEnabled();
+                off.invalidate();
+                return this;
+            } else if (!enabled && stateAssumption.isEnabled()) {
+                assert isEnabled();
+                on.invalidate();
+                return new StateAssumption();
+            } else {
+                // no change needed
+                return this;
             }
         }
+    }
 
-        if (enabled == RRuntime.LOGICAL_TRUE) {
+    public static synchronized void setAllocationTracingEnabled(boolean enabled) {
+        allocationTracingEnabled = enabled;
+        updateTracingState();
+    }
 
-            if (noAllocationTracingAssumption.getAssumption().isValid()) {
-                reportAllocation(data);
-            }
+    private static synchronized void updateTracingState() {
+        boolean enabled = !listeners.isEmpty() || allocationTracingEnabled;
+        stateAssumption = stateAssumption.setState(enabled);
+    }
 
-            for (Listener listener : listeners) {
-                listener.reportAllocation((RTypedValue) data);
-            }
+    private static <T> T traceDataCreated(T data) {
+        if (stateAssumption.isEnabled()) {
+            reportDataCreated(data);
         }
-
         return data;
     }
 
     @TruffleBoundary
-    private static void reportAllocation(Object data) {
-        RContext ctx = RContext.getThreadLocalInstance();
-        assert ctx != null;
-        AllocationReporter allocationReporter = ctx.getAllocationReporter();
-
-        allocationReporter.onEnter(null, 0, AllocationReporter.SIZE_UNKNOWN);
+    private static void reportDataCreated(Object data) {
+        System.out.println("reportDataCreated " + listeners.size() + " " + allocationTracingEnabled);
+        if (allocationTracingEnabled) {
+            RContext ctx = RContext.getThreadLocalInstance();
+            assert ctx != null;
+            AllocationReporter allocationReporter = ctx.getAllocationReporter();
 
-        long size = data instanceof RTypedValue ? getSize((RTypedValue) data) : AllocationReporter.SIZE_UNKNOWN;
-        allocationReporter.onReturnValue(data, 0, size);
+            allocationReporter.onEnter(null, 0, AllocationReporter.SIZE_UNKNOWN);
 
+            long size = data instanceof RTypedValue ? getSize((RTypedValue) data) : AllocationReporter.SIZE_UNKNOWN;
+            allocationReporter.onReturnValue(data, 0, size);
+        }
+        for (Listener listener : listeners) {
+            listener.reportAllocation((RTypedValue) data);
+        }
     }
 
     public interface Listener {
@@ -630,8 +640,14 @@ public final class RDataFactory {
      * Sets the listener of memory tracing events. For the time being there can only be one
      * listener. This can be extended to an array should we need more listeners.
      */
-    public static void addListener(Listener listener) {
+    public static synchronized void addListener(Listener listener) {
         listeners.addLast(listener);
+        updateTracingState();
+    }
+
+    public static synchronized void removeListener(Listener listener) {
+        listeners.remove(listener);
+        updateTracingState();
     }
 
     private static Object[] createRNullArray(int size) {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/instrument/memprof/MemAllocProfilerPaths.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/instrument/memprof/MemAllocProfilerPaths.java
index 75ca4b5c90c3a2d68c36d9fe8310e4962f18dcb5..14aa7cb15f71b13727bd376943f858337223de31 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/instrument/memprof/MemAllocProfilerPaths.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/instrument/memprof/MemAllocProfilerPaths.java
@@ -47,8 +47,8 @@ public final class MemAllocProfilerPaths {
     private final Map<Integer, Entry> entryMap = new ConcurrentHashMap<>();
     private volatile Entry root = new Entry(this, null, "", null);
 
-    private MemAllocProfilerPaths hotSpotsView;
-    private long hotSpotsViewVersion;
+    private MemAllocProfilerPaths hsView;
+    private long hsViewVersion;
 
     /**
      * Clear the model.
@@ -93,14 +93,14 @@ public final class MemAllocProfilerPaths {
         return clonePaths();
     }
 
-    public synchronized MemAllocProfilerPaths toHotSpots() {
+    public synchronized MemAllocProfilerPaths toHS() {
         long curVer = version.get();
-        if (curVer == hotSpotsViewVersion && hotSpotsView != null) {
-            return hotSpotsView;
+        if (curVer == hsViewVersion && hsView != null) {
+            return hsView;
         }
-        hotSpotsViewVersion = curVer;
-        hotSpotsView = invert().groupBySrcSection();
-        return hotSpotsView;
+        hsViewVersion = curVer;
+        hsView = invert().groupBySrcSection();
+        return hsView;
     }
 
     @SuppressWarnings("unused")
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/ForeignArray2R.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/ForeignArray2R.java
index 895d6114c9ff47d3d6e754709d816e4f1698670b..03ef1cf845dae2efc974b9ef9071df0ff8a4856c 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/ForeignArray2R.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/ForeignArray2R.java
@@ -22,10 +22,12 @@
  */
 package com.oracle.truffle.r.runtime.interop;
 
+import java.util.ArrayList;
+import java.util.List;
+
 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;
 import com.oracle.truffle.api.dsl.ImportStatic;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.interop.ArityException;
@@ -43,8 +45,6 @@ import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.nodes.RBaseNode;
-import java.util.ArrayList;
-import java.util.List;
 
 @ImportStatic({Message.class, RRuntime.class})
 public abstract class ForeignArray2R extends RBaseNode {