diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java
index b68c032aa9ea3457a5092660f12e54102c21fe7f..0c91b000ba52e6f8a9319b5296345a20f1661dd3 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java
@@ -23,12 +23,9 @@
 package com.oracle.truffle.r.engine.interop;
 
 import com.oracle.truffle.api.CompilerAsserts;
-import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.TruffleLanguage;
 import com.oracle.truffle.api.interop.ForeignAccess;
 import com.oracle.truffle.api.interop.MessageResolution;
-import com.oracle.truffle.api.interop.TruffleObject;
-import com.oracle.truffle.api.vm.PolyglotEngine;
 import com.oracle.truffle.r.engine.TruffleRLanguage;
 import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.context.RContext;
@@ -49,106 +46,59 @@ import com.oracle.truffle.r.runtime.ffi.CharSXPWrapper;
 import com.oracle.truffle.r.runtime.ffi.DLL;
 
 /**
- * A {@link ForeignAccess} instance captures the {@link Thread} that creates it and all uses are
- * checked against the current thread. Therefore, in a world with multiple {@link PolyglotEngine}s,
- * aka multiple {@link Thread} and {@link RContext} instances, it is not possible to use a simple
- * global constant value for the {@link ForeignAccess} instance that could be associated directly
- * with the {@link TruffleObject} class.
- *
- * This factory provides a generic solution for all FastR types (all of which are
- * {@link TruffleObject}s), at some cost in performance.
- *
  * For most types we use the {@link MessageResolution} facility to automatically generate the
  * factory for creating the {@link ForeignAccess} instance. The exceptions are the (many) subclasses
  * of {@link RAbstractVector} as these have the same handling but the generator cannot handle
  * abstract classes.
- *
  */
 public final class RForeignAccessFactoryImpl implements RForeignAccessFactory {
-    private static final class TableEntry {
-        private final Class<? extends RTruffleObject> clazz; // for sanity check
-        private final ForeignAccess foreignAccess;
-        /**
-         * {@link PolyglotEngine} checks the thread on a {@link ForeignAccess}.
-         */
-        private final Thread thread;
-
-        private TableEntry(Class<? extends RTruffleObject> clazz, ForeignAccess foreignAccess) {
-            this.clazz = clazz;
-            this.foreignAccess = foreignAccess;
-            this.thread = Thread.currentThread();
-        }
-    }
-
-    private final TableEntry[] table = new TableEntry[32];
-    int tableIndex;
 
-    private synchronized ForeignAccess get(RTruffleObject obj) {
-        Class<? extends RTruffleObject> objclazz = obj.getClass();
-        Thread thread = Thread.currentThread();
-        for (int i = 0; i < tableIndex; i++) {
-            TableEntry te = table[i];
-            if (te.clazz == objclazz && te.thread == thread) {
-                return te.foreignAccess;
-            }
-        }
-        return createForeignAccess(objclazz);
-    }
-
-    @TruffleBoundary
-    private static ForeignAccess createForeignAccess(Class<? extends RTruffleObject> clazz) {
-        ForeignAccess foreignAccess = null;
-        String name = clazz.getSimpleName();
-        if (RNull.class.isAssignableFrom(clazz)) {
-            foreignAccess = RNullMRForeign.ACCESS;
-        } else if (RList.class.isAssignableFrom(clazz)) {
-            foreignAccess = RListMRForeign.ACCESS;
-        } else if (REnvironment.class.isAssignableFrom(clazz)) {
-            foreignAccess = REnvironmentMRForeign.ACCESS;
-        } else if (RPairList.class.isAssignableFrom(clazz)) {
-            foreignAccess = RPairListMRForeign.ACCESS;
-        } else if (RFunction.class.isAssignableFrom(clazz)) {
-            foreignAccess = RFunctionMRForeign.ACCESS;
-        } else if (DLL.DLLInfo.class.isAssignableFrom(clazz)) {
-            foreignAccess = DLLInfoMRForeign.ACCESS;
-        } else if (DLL.DotSymbol.class.isAssignableFrom(clazz)) {
-            foreignAccess = DLLDotSymbolMRForeign.ACCESS;
-        } else if (RSymbol.class.isAssignableFrom(clazz)) {
-            foreignAccess = RSymbolMRForeign.ACCESS;
-        } else if (RExternalPtr.class.isAssignableFrom(clazz)) {
-            foreignAccess = RExternalPtrMRForeign.ACCESS;
-        } else if (RUnboundValue.class.isAssignableFrom(clazz)) {
-            foreignAccess = RUnboundValueMRForeign.ACCESS;
-        } else if (NativeRawArray.class.isAssignableFrom(clazz)) {
-            foreignAccess = NativeRawArrayMRForeign.ACCESS;
-        } else if (NativeLogicalArray.class.isAssignableFrom(clazz)) {
-            foreignAccess = NativeLogicalArrayMRForeign.ACCESS;
-        } else if (NativeCharArray.class.isAssignableFrom(clazz)) {
-            foreignAccess = NativeCharArrayMRForeign.ACCESS;
-        } else if (NativeDoubleArray.class.isAssignableFrom(clazz)) {
-            foreignAccess = NativeDoubleArrayMRForeign.ACCESS;
-        } else if (NativeIntegerArray.class.isAssignableFrom(clazz)) {
-            foreignAccess = NativeIntegerArrayMRForeign.ACCESS;
-        } else if (RInteger.class.isAssignableFrom(clazz)) {
-            foreignAccess = RIntegerMRForeign.ACCESS;
-        } else if (RDouble.class.isAssignableFrom(clazz)) {
-            foreignAccess = RDoubleMRForeign.ACCESS;
-        } else if (CharSXPWrapper.class.isAssignableFrom(clazz)) {
-            foreignAccess = CharSXPWrapperMRForeign.ACCESS;
+    @Override
+    public ForeignAccess getForeignAccess(RTruffleObject obj) {
+        CompilerAsserts.neverPartOfCompilation("getForeignAccess");
+        if (obj instanceof RNull) {
+            return RNullMRForeign.ACCESS;
+        } else if (obj instanceof RList) {
+            return RListMRForeign.ACCESS;
+        } else if (obj instanceof REnvironment) {
+            return REnvironmentMRForeign.ACCESS;
+        } else if (obj instanceof RPairList) {
+            return RPairListMRForeign.ACCESS;
+        } else if (obj instanceof RFunction) {
+            return RFunctionMRForeign.ACCESS;
+        } else if (obj instanceof DLL.DLLInfo) {
+            return DLLInfoMRForeign.ACCESS;
+        } else if (obj instanceof DLL.DotSymbol) {
+            return DLLDotSymbolMRForeign.ACCESS;
+        } else if (obj instanceof RSymbol) {
+            return RSymbolMRForeign.ACCESS;
+        } else if (obj instanceof RExternalPtr) {
+            return RExternalPtrMRForeign.ACCESS;
+        } else if (obj instanceof RUnboundValue) {
+            return RUnboundValueMRForeign.ACCESS;
+        } else if (obj instanceof NativeRawArray) {
+            return NativeRawArrayMRForeign.ACCESS;
+        } else if (obj instanceof NativeLogicalArray) {
+            return NativeLogicalArrayMRForeign.ACCESS;
+        } else if (obj instanceof NativeCharArray) {
+            return NativeCharArrayMRForeign.ACCESS;
+        } else if (obj instanceof NativeDoubleArray) {
+            return NativeDoubleArrayMRForeign.ACCESS;
+        } else if (obj instanceof NativeIntegerArray) {
+            return NativeIntegerArrayMRForeign.ACCESS;
+        } else if (obj instanceof RInteger) {
+            return RIntegerMRForeign.ACCESS;
+        } else if (obj instanceof RDouble) {
+            return RDoubleMRForeign.ACCESS;
+        } else if (obj instanceof CharSXPWrapper) {
+            return CharSXPWrapperMRForeign.ACCESS;
         } else {
-            if (RAbstractVector.class.isAssignableFrom(clazz)) {
-                foreignAccess = ForeignAccess.create(RAbstractVector.class, new RAbstractVectorAccessFactory());
+            if (obj instanceof RAbstractVector) {
+                return ForeignAccess.create(RAbstractVector.class, new RAbstractVectorAccessFactory());
             } else {
-                throw RInternalError.unimplemented("foreignAccess: " + name);
+                throw RInternalError.unimplemented("missing foreign access factory for " + obj.getClass().getSimpleName());
             }
         }
-        return foreignAccess;
-    }
-
-    @Override
-    public ForeignAccess getForeignAccess(RTruffleObject obj) {
-        CompilerAsserts.neverPartOfCompilation("getForeignAccess");
-        return get(obj);
     }
 
     @Override