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