diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RFunctionMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RFunctionMR.java
index 8001e760664966b084c5d2bf830e1bbef491ca2d..18e449ccd9ec65ea6751cef97723f671cee3ba14 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RFunctionMR.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RFunctionMR.java
@@ -41,6 +41,7 @@ import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.context.RContext.RCloseable;
 import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
 import com.oracle.truffle.r.runtime.data.RFunction;
+import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor;
 
 @MessageResolution(receiverType = RFunction.class, language = TruffleRLanguage.class)
 public class RFunctionMR {
@@ -54,8 +55,12 @@ public class RFunctionMR {
     @Resolve(message = "EXECUTE")
     public abstract static class RFunctionExecuteNode extends Node {
         private static final FrameDescriptor emptyFrameDescriptor = new FrameDescriptor("R interop frame");
-        private final Object argsIdentifier = new Object();
-        private final FrameSlot slot = emptyFrameDescriptor.addFrameSlot(argsIdentifier, FrameSlotKind.Object);
+        private static final Object argsIdentifier = new Object();
+        private static final FrameSlot slot = emptyFrameDescriptor.addFrameSlot(argsIdentifier, FrameSlotKind.Object);
+
+        static {
+            FrameSlotChangeMonitor.initializeFunctionFrameDescriptor("<function>", emptyFrameDescriptor);
+        }
 
         @Child private RCallBaseNode call = RCallNode.createExplicitCall(argsIdentifier);
         @Child private Node findContext = TruffleRLanguage.INSTANCE.actuallyCreateFindContextNode();
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateSubstr.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateSubstr.java
index 87164398f9c4faa89ef1b5a24336595f8890893e..c986eecf12694fb6ff66f2febf017262bae6aa70 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateSubstr.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateSubstr.java
@@ -22,8 +22,8 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
-import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/BaseWriteVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/BaseWriteVariableNode.java
index ab139b59ceaa374eecaac5b3a7f81c9c00f0d010..2cb9365d10f83e6c89a11fba7878740f17dd0b86 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/BaseWriteVariableNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/BaseWriteVariableNode.java
@@ -166,15 +166,16 @@ abstract class BaseWriteVariableNode extends WriteVariableNode {
      * @param frameSlot The frame slot of the value.
      * @param invalidateProfile The invalidation profile.
      */
-    protected static Object handleActiveBinding(VirtualFrame execFrame, Frame lookupFrame, Object value, FrameSlot frameSlot, BranchProfile invalidateProfile) {
-        Object object = null;
-        if (FrameSlotChangeMonitor.isActiveBinding(frameSlot)) {
-            try {
-                object = lookupFrame.getObject(frameSlot);
-            } catch (FrameSlotTypeException e) {
-                // ignore
-            }
-            assert object != null && ActiveBinding.isActiveBinding(object);
+    protected static Object handleActiveBinding(VirtualFrame execFrame, Frame lookupFrame, Object value, FrameSlot frameSlot, BranchProfile invalidateProfile,
+                    ConditionProfile isActiveBindingProfile) {
+        Object object;
+        try {
+            object = lookupFrame.getObject(frameSlot);
+        } catch (FrameSlotTypeException e) {
+            object = null;
+        }
+
+        if (isActiveBindingProfile.profile(object != null && ActiveBinding.isActiveBinding(object))) {
             return ((ActiveBinding) object).writeValue(value);
         } else {
             FrameSlotChangeMonitor.setObjectAndInvalidate(lookupFrame, frameSlot, value, false, invalidateProfile);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteLocalFrameVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteLocalFrameVariableNode.java
index e319aeab360e2bf3469ce972fed40924fcc6d6ca..8e953b84205f56107b7a2953ecfc76e6ec387434 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteLocalFrameVariableNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteLocalFrameVariableNode.java
@@ -32,6 +32,7 @@ import com.oracle.truffle.api.frame.FrameSlot;
 import com.oracle.truffle.api.frame.FrameSlotKind;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.profiles.BranchProfile;
+import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.api.profiles.ValueProfile;
 import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor;
 import com.oracle.truffle.r.runtime.nodes.RNode;
@@ -56,6 +57,7 @@ public abstract class WriteLocalFrameVariableNode extends BaseWriteVariableNode
 
     private final ValueProfile storedObjectProfile = ValueProfile.createClassProfile();
     private final BranchProfile invalidateProfile = BranchProfile.create();
+    private final ConditionProfile isActiveBindingProfile = ConditionProfile.createBinaryProfile();
     @CompilationFinal private Assumption containsNoActiveBinding;
 
     protected WriteLocalFrameVariableNode(Object name, Mode mode) {
@@ -95,12 +97,12 @@ public abstract class WriteLocalFrameVariableNode extends BaseWriteVariableNode
             CompilerDirectives.transferToInterpreterAndInvalidate();
             containsNoActiveBinding = FrameSlotChangeMonitor.getContainsNoActiveBindingAssumption(frame.getFrameDescriptor());
         }
-        if (containsNoActiveBinding != null && containsNoActiveBinding.isValid()) {
+        if (containsNoActiveBinding.isValid()) {
             Object newValue = shareObjectValue(frame, frameSlot, storedObjectProfile.profile(value), mode, false);
             FrameSlotChangeMonitor.setObjectAndInvalidate(frame, frameSlot, newValue, false, invalidateProfile);
         } else {
             // it's a local variable lookup; so use 'frame' for both, executing and looking up
-            return handleActiveBinding(frame, frame, value, frameSlot, invalidateProfile);
+            return handleActiveBinding(frame, frame, value, frameSlot, invalidateProfile, isActiveBindingProfile);
         }
         return value;
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperFrameVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperFrameVariableNode.java
index 7cd8ff8d00ca2cf280b5e0ca8696671cbe1da35b..bbc7d82a5b0ba896a54ac9f00fe83370596eb4a5 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperFrameVariableNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperFrameVariableNode.java
@@ -73,6 +73,7 @@ abstract class WriteSuperFrameVariableNode extends BaseWriteVariableNode {
         private final ValueProfile storedObjectProfile = ValueProfile.createClassProfile();
         private final BranchProfile invalidateProfile = BranchProfile.create();
         private final ValueProfile enclosingFrameProfile = ValueProfile.createClassProfile();
+        private final ConditionProfile isActiveBindingProfile = ConditionProfile.createBinaryProfile();
 
         private final Mode mode;
         @CompilationFinal private Assumption containsNoActiveBinding;
@@ -110,7 +111,7 @@ abstract class WriteSuperFrameVariableNode extends BaseWriteVariableNode {
                 Object newValue = shareObjectValue(profiledFrame, frameSlot, storedObjectProfile.profile(value), mode, true);
                 FrameSlotChangeMonitor.setObjectAndInvalidate(profiledFrame, frameSlot, newValue, true, invalidateProfile);
             } else {
-                handleActiveBinding(frame, profiledFrame, value, frameSlot, invalidateProfile);
+                handleActiveBinding(frame, profiledFrame, value, frameSlot, invalidateProfile, isActiveBindingProfile);
             }
         }
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/LocalReadVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/LocalReadVariableNode.java
index c5cf895eeb19867a13b975ae293018ffd56fc868..5e1b476097b7ad544331269c48dfe303268c9b88 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/LocalReadVariableNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/LocalReadVariableNode.java
@@ -116,7 +116,7 @@ public final class LocalReadVariableNode extends Node {
             containsNoActiveBindingAssumption = FrameSlotChangeMonitor.getContainsNoActiveBindingAssumption(profiledVariableFrame.getFrameDescriptor());
         }
         // special treatment for active binding: call bound function
-        if (containsNoActiveBindingAssumption != null && !containsNoActiveBindingAssumption.isValid() && ActiveBinding.isActiveBinding(result)) {
+        if (!containsNoActiveBindingAssumption.isValid() && ActiveBinding.isActiveBinding(result)) {
             return ((ActiveBinding) result).readValue();
         }
 
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java
index 119494163dd6870b7c87dc556c2965f9a33ba57a..dd4a98c59592abbfd8e0cba0283966ed148a55ff 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java
@@ -53,7 +53,6 @@ import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.RTypedValue;
 import com.oracle.truffle.r.runtime.env.REnvironment;
-import com.oracle.truffle.r.runtime.env.frame.ActiveBinding;
 import com.oracle.truffle.r.runtime.nodes.RBaseNode;
 
 public abstract class ClassHierarchyNode extends UnaryNode {
@@ -150,13 +149,6 @@ public abstract class ClassHierarchyNode extends UnaryNode {
         return obj instanceof RTypedValue;
     }
 
-    @TruffleBoundary
-    @Specialization
-    protected RStringVector getClassHrActiveBinding(ActiveBinding object) {
-        Object result = RContext.getEngine().evalFunction(object.getFunction(), REnvironment.baseEnv().getFrame(), RCaller.createInvalid(null), RDataFactory.createEmptyStringVector());
-        return execute(result);
-    }
-
     @Specialization(guards = "!isRTypedValue(object)")
     protected RStringVector getClassHrTruffleObject(@SuppressWarnings("unused") TruffleObject object) {
         return truffleObjectClassHeader;
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 1211aea3fc2c3bd7186e9ad82f4f6f77c00ec8a4..0f4f3a09ad999efe14c1b044aad6d5cfe733f300 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
@@ -467,9 +467,6 @@ public final class FrameSlotChangeMonitor {
         @CompilationFinal private StableValue<Object> stableValue;
         private int invalidationCount;
 
-        // TODO @CompilationFinal ?
-        @CompilationFinal private boolean activeBinding;
-
         FrameSlotInfoImpl(boolean isSingletonFrame, boolean isGlobalEnv, Object identifier) {
             if (isSingletonFrame) {
                 stableValue = new StableValue<>(null, identifier.toString());
@@ -509,7 +506,6 @@ public final class FrameSlotChangeMonitor {
             if (stableValue != null && stableValue.getValue() != value) {
                 invalidateStableValue(value, slot);
             }
-            activeBinding = ActiveBinding.isActiveBinding(value);
         }
 
         private void invalidateStableValue(Object value, FrameSlot slot) {
@@ -528,10 +524,6 @@ public final class FrameSlotChangeMonitor {
         public StableValue<Object> getStableValue() {
             return stableValue;
         }
-
-        public boolean isActiveBinding() {
-            return activeBinding;
-        }
     }
 
     /**
@@ -658,13 +650,7 @@ public final class FrameSlotChangeMonitor {
 
     public static synchronized Assumption getContainsNoActiveBindingAssumption(FrameDescriptor descriptor) {
         CompilerAsserts.neverPartOfCompilation();
-        final FrameDescriptorMetaData frameDescriptorMetaData = frameDescriptors.get(descriptor);
-        return frameDescriptorMetaData != null ? frameDescriptorMetaData.getContainsNoActiveBindingAssumption() : null;
-    }
-
-    public static synchronized boolean isContainsNoActiveBindingAssumptionValid(FrameDescriptor descriptor) {
-        Assumption assumption = getContainsNoActiveBindingAssumption(descriptor);
-        return assumption != null ? assumption.isValid() : true;
+        return frameDescriptors.get(descriptor).getContainsNoActiveBindingAssumption();
     }
 
     public static synchronized StableValue<Object> getStableValueAssumption(FrameDescriptor descriptor, FrameSlot frameSlot, Object value) {
@@ -686,8 +672,4 @@ public final class FrameSlotChangeMonitor {
     public static boolean isValidFrameDescriptor(FrameDescriptor frameDesc) {
         return getMetaData(frameDesc) != null;
     }
-
-    public static boolean isActiveBinding(FrameSlot slot) {
-        return ((FrameSlotInfoImpl) slot.getInfo()).isActiveBinding();
-    }
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/REnvTruffleFrameAccess.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/REnvTruffleFrameAccess.java
index 44cf86ac904bd69f45284fa1c1571c16c130118d..2c62896ff5aa889a89b1eccd9b9dd37f237debb6 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/REnvTruffleFrameAccess.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/REnvTruffleFrameAccess.java
@@ -28,10 +28,7 @@ import java.util.HashSet;
 import java.util.Set;
 import java.util.regex.Pattern;
 
-import com.oracle.truffle.api.Assumption;
 import com.oracle.truffle.api.CompilerAsserts;
-import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.frame.FrameDescriptor;
 import com.oracle.truffle.api.frame.FrameSlot;
@@ -58,8 +55,6 @@ public final class REnvTruffleFrameAccess extends REnvFrameAccess {
      */
     private Set<String> lockedBindings;
 
-    @CompilationFinal private Assumption containsNoActiveBindingAssumption;
-
     public REnvTruffleFrameAccess(MaterializedFrame frame) {
         this.frame = frame;
     }
@@ -76,14 +71,9 @@ public final class REnvTruffleFrameAccess extends REnvFrameAccess {
         if (slot == null) {
             return null;
         } else {
-
             Object value = frame.getValue(slot);
-            if (containsNoActiveBindingAssumption == null) {
-                CompilerDirectives.transferToInterpreterAndInvalidate();
-                containsNoActiveBindingAssumption = FrameSlotChangeMonitor.getContainsNoActiveBindingAssumption(fd);
-            }
             // special treatment for active binding: call bound function
-            if (containsNoActiveBindingAssumption != null && !containsNoActiveBindingAssumption.isValid() && ActiveBinding.isActiveBinding(value)) {
+            if (ActiveBinding.isActiveBinding(value)) {
                 return ((ActiveBinding) value).readValue();
             }
             return value;
@@ -119,14 +109,14 @@ public final class REnvTruffleFrameAccess extends REnvFrameAccess {
                 FrameSlotChangeMonitor.setDoubleAndInvalidate(frame, slot, (double) value, false, null);
                 break;
             case Object:
-                if (FrameSlotChangeMonitor.isActiveBinding(slot)) {
-                    Object object;
-                    try {
-                        object = frame.getObject(slot);
-                    } catch (FrameSlotTypeException e) {
-                        object = null;
-                    }
-                    assert (object != null && ActiveBinding.isActiveBinding(object));
+                Object object;
+                try {
+                    object = frame.getObject(slot);
+                } catch (FrameSlotTypeException e) {
+                    object = null;
+                }
+
+                if (object != null && ActiveBinding.isActiveBinding(object)) {
                     ((ActiveBinding) object).writeValue(value);
                 } else {
                     FrameSlotChangeMonitor.setObjectAndInvalidate(frame, slot, value, false, null);