diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/ReadVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/ReadVariableNode.java
index 3e91b9c182a6158aaaaeefcce677ea497c862d9c..494f6364b7bd123b1cdbafa31f9eebc3fb737b9a 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/ReadVariableNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/ReadVariableNode.java
@@ -214,16 +214,19 @@ public final class ReadVariableNode extends RNode implements RSyntaxNode, Visibi
         try {
             result = read.execute(frame, variableFrame);
         } catch (InvalidAssumptionException | LayoutChangedException | FrameSlotTypeException e) {
-            initializeRead(frame, variableFrame);
-            try {
-                result = read.execute(frame, variableFrame);
-            } catch (InvalidAssumptionException | LayoutChangedException | FrameSlotTypeException e2) {
-                /*
-                 * This could be written a bit simpler using a loop, but partial evaluation will not
-                 * see that it never actually loops in compiled code, and thus create suboptimal
-                 * code.
-                 */
-                throw RInternalError.shouldNotReachHere("read initialization problem");
+            int iterations = 0;
+            while (true) {
+                iterations++;
+                initializeRead(frame, variableFrame);
+                try {
+                    result = read.execute(frame, variableFrame);
+                } catch (InvalidAssumptionException | LayoutChangedException | FrameSlotTypeException e2) {
+                    if (iterations > 10) {
+                        throw new RInternalError("too many iterations during RVN initialization");
+                    }
+                    continue;
+                }
+                break;
             }
         }
         if (needsCopying && copyProfile.profile(result instanceof RAbstractVector)) {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RContext.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RContext.java
index bb5b80d0733097c8feaf57a3ec5914c1ffc3f002..f32952e2a3f4a21c2c973f1ce4e3d8693f331039 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RContext.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RContext.java
@@ -374,7 +374,6 @@ public final class RContext extends ExecutionContext {
         RConnection(ConnectionSupport.class, false),
         StdConnections(StdConnections.class, true),
         RNG(RRNG.class, false),
-        FrameSlotChangeMonitor(FrameSlotChangeMonitor.class, false),
         RFFI(RFFIContextStateFactory.class, false),
         RSerialize(RSerialize.class, false);
 
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/FrameSlotChangeMonitor.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/FrameSlotChangeMonitor.java
index 4c79c0cb67d7bd5e6d4ee1ed74bec86113e9c0ad..f78a463ad04acc69155b1bfca6f5bb83f437aa29 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/FrameSlotChangeMonitor.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/FrameSlotChangeMonitor.java
@@ -29,7 +29,6 @@ import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.utilities.*;
 import com.oracle.truffle.r.runtime.*;
-import com.oracle.truffle.r.runtime.RContext.ContextState;
 import com.oracle.truffle.r.runtime.data.*;
 
 /**
@@ -41,7 +40,7 @@ import com.oracle.truffle.r.runtime.data.*;
  * cheap as possible, it checks only local reads - which is fast - and does a more costly check on
  * "<<-" but invalidates the assumption as soon as "eval" and the like comes into play.<br/>
  */
-public final class FrameSlotChangeMonitor implements RContext.StateFactory {
+public final class FrameSlotChangeMonitor {
 
     public static final FrameDescriptor NAMESPACE_BASE_MARKER_FRAME_DESCRIPTOR = new FrameDescriptor();
 
@@ -100,14 +99,11 @@ public final class FrameSlotChangeMonitor implements RContext.StateFactory {
         }
     }
 
-    private static final class ContextStateImpl implements ContextState {
-        private final WeakHashMap<FrameDescriptor, StableValue<MaterializedFrame>> descriptorEnclosingFrameAssumptions = new WeakHashMap<>();
-        private final WeakHashMap<FrameDescriptor, Boolean> descriptorSingletonAssumptions = new WeakHashMap<>();
-        private final WeakHashMap<FrameDescriptor, StableValue<FrameDescriptor>> descriptorEnclosingDescriptorAssumptions = new WeakHashMap<>();
+    private static final WeakHashMap<FrameDescriptor, StableValue<MaterializedFrame>> descriptorEnclosingFrameAssumptions = new WeakHashMap<>();
+    private static final WeakHashMap<FrameDescriptor, Boolean> descriptorSingletonAssumptions = new WeakHashMap<>();
+    private static final WeakHashMap<FrameDescriptor, StableValue<FrameDescriptor>> descriptorEnclosingDescriptorAssumptions = new WeakHashMap<>();
 
-        private int rewriteFrameDescriptorAssumptionsCount;
-
-    }
+    private static int rewriteFrameDescriptorAssumptionsCount;
 
     /**
      * Retrieves the not-changed-locally {@link Assumption} for the given frame slot.
@@ -130,7 +126,7 @@ public final class FrameSlotChangeMonitor implements RContext.StateFactory {
     // method for creating new frame slots
 
     public static FrameSlot addFrameSlot(FrameDescriptor fd, Object identifier, FrameSlotKind kind) {
-        boolean isSingletonFrame = getFrameSlotChangeMonitorState().descriptorSingletonAssumptions.containsKey(fd);
+        boolean isSingletonFrame = descriptorSingletonAssumptions.containsKey(fd);
         return fd.addFrameSlot(identifier, new FrameSlotInfoImpl(isSingletonFrame, identifier), kind);
     }
 
@@ -224,26 +220,24 @@ public final class FrameSlotChangeMonitor implements RContext.StateFactory {
      */
     public static synchronized void initializeNonFunctionFrameDescriptor(FrameDescriptor originalFrameDescriptor, boolean isNamespaceBase) {
         FrameDescriptor frameDescriptor = isNamespaceBase ? NAMESPACE_BASE_MARKER_FRAME_DESCRIPTOR : originalFrameDescriptor;
-        getFrameSlotChangeMonitorState().descriptorEnclosingFrameAssumptions.put(frameDescriptor, StableValue.invalidated());
-        ContextStateImpl contextState = getFrameSlotChangeMonitorState();
-        contextState.descriptorEnclosingDescriptorAssumptions.put(frameDescriptor, StableValue.invalidated());
+        descriptorEnclosingFrameAssumptions.put(frameDescriptor, StableValue.invalidated());
+        descriptorEnclosingDescriptorAssumptions.put(frameDescriptor, StableValue.invalidated());
         if (!isNamespaceBase) {
-            contextState.descriptorSingletonAssumptions.put(originalFrameDescriptor, Boolean.FALSE);
+            descriptorSingletonAssumptions.put(originalFrameDescriptor, Boolean.FALSE);
         }
     }
 
     public static synchronized void initializeFunctionFrameDescriptor(FrameDescriptor frameDescriptor) {
-        ContextStateImpl contextState = getFrameSlotChangeMonitorState();
-        contextState.descriptorEnclosingFrameAssumptions.put(frameDescriptor, StableValue.invalidated());
-        contextState.descriptorEnclosingDescriptorAssumptions.put(frameDescriptor, StableValue.invalidated());
+        descriptorEnclosingFrameAssumptions.put(frameDescriptor, StableValue.invalidated());
+        descriptorEnclosingDescriptorAssumptions.put(frameDescriptor, StableValue.invalidated());
     }
 
     public static synchronized StableValue<MaterializedFrame> getEnclosingFrameAssumption(FrameDescriptor descriptor) {
-        return getFrameSlotChangeMonitorState().descriptorEnclosingFrameAssumptions.get(descriptor);
+        return descriptorEnclosingFrameAssumptions.get(descriptor);
     }
 
     public static synchronized StableValue<FrameDescriptor> getEnclosingFrameDescriptorAssumption(FrameDescriptor descriptor) {
-        return getFrameSlotChangeMonitorState().descriptorEnclosingDescriptorAssumptions.get(descriptor);
+        return descriptorEnclosingDescriptorAssumptions.get(descriptor);
     }
 
     /**
@@ -260,8 +254,7 @@ public final class FrameSlotChangeMonitor implements RContext.StateFactory {
         if (value != null) {
             value.getAssumption().invalidate();
         }
-        ContextStateImpl contextState = getFrameSlotChangeMonitorState();
-        StableValue<FrameDescriptor> currentValue = contextState.descriptorEnclosingDescriptorAssumptions.get(frameDescriptor);
+        StableValue<FrameDescriptor> currentValue = descriptorEnclosingDescriptorAssumptions.get(frameDescriptor);
         if (currentValue.getAssumption().isValid()) {
             if (currentValue.getValue() == newValue) {
                 return currentValue;
@@ -270,9 +263,9 @@ public final class FrameSlotChangeMonitor implements RContext.StateFactory {
             }
         }
         currentValue = new StableValue<>(newValue, "enclosing frame descriptor");
-        contextState.descriptorEnclosingDescriptorAssumptions.put(frameDescriptor, currentValue);
+        descriptorEnclosingDescriptorAssumptions.put(frameDescriptor, currentValue);
         if (value != null && value != StableValue.<FrameDescriptor> invalidated()) {
-            assert contextState.rewriteFrameDescriptorAssumptionsCount++ < 100;
+            assert rewriteFrameDescriptorAssumptionsCount++ < 100;
         }
         return currentValue;
     }
@@ -284,8 +277,7 @@ public final class FrameSlotChangeMonitor implements RContext.StateFactory {
         if (value != null) {
             value.getAssumption().invalidate();
         }
-        ContextStateImpl contextState = getFrameSlotChangeMonitorState();
-        StableValue<MaterializedFrame> currentValue = contextState.descriptorEnclosingFrameAssumptions.get(frameDescriptor);
+        StableValue<MaterializedFrame> currentValue = descriptorEnclosingFrameAssumptions.get(frameDescriptor);
         if (currentValue == null) {
             return null;
         }
@@ -298,10 +290,10 @@ public final class FrameSlotChangeMonitor implements RContext.StateFactory {
         }
         if (currentValue == StableValue.<MaterializedFrame> invalidated()) {
             currentValue = new StableValue<>(newValue, "enclosing frame");
-            contextState.descriptorEnclosingFrameAssumptions.put(frameDescriptor, currentValue);
+            descriptorEnclosingFrameAssumptions.put(frameDescriptor, currentValue);
             return currentValue;
         } else {
-            contextState.descriptorEnclosingFrameAssumptions.remove(frameDescriptor);
+            descriptorEnclosingFrameAssumptions.remove(frameDescriptor);
             return null;
         }
     }
@@ -312,13 +304,12 @@ public final class FrameSlotChangeMonitor implements RContext.StateFactory {
     }
 
     private static synchronized boolean checkSingletonFrameInternal(VirtualFrame vf) {
-        ContextStateImpl contextState = getFrameSlotChangeMonitorState();
-        Boolean value = contextState.descriptorSingletonAssumptions.get(vf.getFrameDescriptor());
+        Boolean value = descriptorSingletonAssumptions.get(vf.getFrameDescriptor());
         if (value == null) {
             return false;
         } else if (value == Boolean.FALSE) {
             out("marking frame descriptor %s as singleton", vf.getFrameDescriptor());
-            contextState.descriptorSingletonAssumptions.put(vf.getFrameDescriptor(), Boolean.TRUE);
+            descriptorSingletonAssumptions.put(vf.getFrameDescriptor(), Boolean.TRUE);
             return true;
         } else {
             out("marking frame descriptor %s as non-singleton", vf.getFrameDescriptor());
@@ -328,7 +319,7 @@ public final class FrameSlotChangeMonitor implements RContext.StateFactory {
                     out("  invalidating singleton slot %s", slot.getIdentifier());
                 }
             }
-            contextState.descriptorSingletonAssumptions.remove(vf.getFrameDescriptor());
+            descriptorSingletonAssumptions.remove(vf.getFrameDescriptor());
             return false;
         }
     }
@@ -337,7 +328,7 @@ public final class FrameSlotChangeMonitor implements RContext.StateFactory {
         CompilerAsserts.neverPartOfCompilation();
         StableValue<Object> stableValue = getFrameSlotInfo(frameSlot).getStableValue();
         if (stableValue != null) {
-            assert getFrameSlotChangeMonitorState().descriptorSingletonAssumptions.containsKey(descriptor) : "single frame slot within non-singleton descriptor";
+            assert descriptorSingletonAssumptions.containsKey(descriptor) : "single frame slot within non-singleton descriptor";
             assert stableValue.getValue() == value || (stableValue.getValue() != null && (stableValue.getValue().equals(value) || !stableValue.getAssumption().isValid())) : stableValue.getValue() +
                             " vs. " + value;
         }
@@ -350,16 +341,4 @@ public final class FrameSlotChangeMonitor implements RContext.StateFactory {
             info.setValue(value);
         }
     }
-
-    public ContextState newContext(RContext context, Object... objects) {
-        if (context.getKind() == RContext.Kind.SHARE_PARENT_RW) {
-            return context.getParent().getThisContextState(RContext.ClassStateKind.FrameSlotChangeMonitor);
-        } else {
-            return new ContextStateImpl();
-        }
-    }
-
-    private static ContextStateImpl getFrameSlotChangeMonitorState() {
-        return (ContextStateImpl) RContext.getContextState(RContext.ClassStateKind.FrameSlotChangeMonitor);
-    }
 }