diff --git a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/image/SqueakImageContext.java b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/image/SqueakImageContext.java index d716e49e7..c49a20b8c 100644 --- a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/image/SqueakImageContext.java +++ b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/image/SqueakImageContext.java @@ -11,6 +11,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.HashMap; +import java.util.Map; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; @@ -168,6 +169,7 @@ public final class SqueakImageContext { /* Plugins */ @CompilationFinal private InterpreterProxy interpreterProxy; + public final Map loadedLibraries = new HashMap<>(); public final B2D b2d = new B2D(this); public final BitBlt bitblt = new BitBlt(this); public String[] dropPluginFileList = new String[0]; @@ -624,15 +626,11 @@ public boolean supportsNFI() { return env.getInternalLanguages().containsKey("nfi"); } - public InterpreterProxy getOrCreateInterpreterProxy() { + public InterpreterProxy getInterpreterProxy(final MaterializedFrame frame, final int numReceiverAndArguments) { if (interpreterProxy == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); interpreterProxy = new InterpreterProxy(this); } - return interpreterProxy; - } - - public InterpreterProxy getInterpreterProxy(final MaterializedFrame frame, final int numReceiverAndArguments) { return interpreterProxy.instanceFor(frame, numReceiverAndArguments); } diff --git a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/plugins/ffi/InterpreterProxy.java b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/plugins/ffi/InterpreterProxy.java index eeeac92af..dc19c9ae1 100644 --- a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/plugins/ffi/InterpreterProxy.java +++ b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/plugins/ffi/InterpreterProxy.java @@ -8,13 +8,10 @@ import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; import java.util.function.Predicate; import java.util.stream.Collectors; import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.exception.AbstractTruffleException; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.interop.ArityException; import com.oracle.truffle.api.interop.InteropLibrary; @@ -53,7 +50,6 @@ public final class InterpreterProxy { // since this class is a singleton, a private instance variable will suffice @SuppressWarnings("FieldCanBeLocal") private final TruffleClosure[] closures; private final Object interpreterProxyPointer; - private final Map loadedLibraries = new HashMap<>(); /////////////////////////// // INTERPRETER VARIABLES // @@ -175,53 +171,11 @@ public InterpreterProxy instanceFor(final MaterializedFrame currentFrame, final return this; } - public Object lookupModuleLibrary(final String moduleName) { - final Object moduleLibrary = loadedLibraries.computeIfAbsent(moduleName, (String s) -> { - if (loadedLibraries.containsKey(moduleName)) { - // if moduleName was associated with null - return null; - } - final Object library; - try { - library = NFIUtils.loadLibrary(context, moduleName, "{ setInterpreter(POINTER):SINT64; }"); - } catch (AbstractTruffleException e) { - if (e.getMessage().equals("Unknown identifier: setInterpreter")) { - // module has no setInterpreter, cannot be loaded - return null; - } - throw e; - } - if (library == null) { - return null; - } - try { - // TODO: also call shutdownModule():SINT64 at some point - final Object initialiseModuleSymbol = NFIUtils.loadMember(context, library, "initialiseModule", "():SINT64"); - final InteropLibrary initialiseModuleInteropLibrary = NFIUtils.getInteropLibrary(initialiseModuleSymbol); - initialiseModuleInteropLibrary.execute(initialiseModuleSymbol); - } catch (UnknownIdentifierException e) { - // module has no initializer, ignore - } catch (UnsupportedTypeException | ArityException | UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - try { - final InteropLibrary moduleInteropLibrary = NFIUtils.getInteropLibrary(library); - moduleInteropLibrary.invokeMember(library, "setInterpreter", getPointer()); - } catch (UnsupportedMessageException | ArityException | UnsupportedTypeException | UnknownIdentifierException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - return library; - }); - // computeIfAbsent would not put null value - loadedLibraries.putIfAbsent(moduleName, moduleLibrary); - return moduleLibrary; - } - /////////////////// // MISCELLANEOUS // /////////////////// - private Object getPointer() { + public Object getPointer() { return interpreterProxyPointer; } diff --git a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/plugins/ffi/PrimExternalCallNode.java b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/plugins/ffi/PrimExternalCallNode.java index 8e1bca30a..baa2793e3 100644 --- a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/plugins/ffi/PrimExternalCallNode.java +++ b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/plugins/ffi/PrimExternalCallNode.java @@ -8,6 +8,7 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.exception.AbstractTruffleException; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.ArityException; @@ -35,7 +36,7 @@ public PrimExternalCallNode(final Object functionSymbol, final InteropLibrary fu public static PrimExternalCallNode load(final String moduleName, final String functionName, final int numReceiverAndArguments) { final SqueakImageContext context = SqueakImageContext.getSlow(); - final Object moduleLibrary = context.getOrCreateInterpreterProxy().lookupModuleLibrary(moduleName); + final Object moduleLibrary = lookupModuleLibrary(context, moduleName); if (moduleLibrary == null) { return null; // module not found } @@ -48,6 +49,48 @@ public static PrimExternalCallNode load(final String moduleName, final String fu } } + private static Object lookupModuleLibrary(final SqueakImageContext context, final String moduleName) { + final Object moduleLibrary = context.loadedLibraries.computeIfAbsent(moduleName, (String s) -> { + if (context.loadedLibraries.containsKey(moduleName)) { + // if moduleName was associated with null + return null; + } + final Object library; + try { + library = NFIUtils.loadLibrary(context, moduleName, "{ setInterpreter(POINTER):SINT64; }"); + } catch (AbstractTruffleException e) { + if (e.getMessage().equals("Unknown identifier: setInterpreter")) { + // module has no setInterpreter, cannot be loaded + return null; + } + throw e; + } + if (library == null) { + return null; + } + try { + // TODO: also call shutdownModule():SINT64 at some point + final Object initialiseModuleSymbol = NFIUtils.loadMember(context, library, "initialiseModule", "():SINT64"); + final InteropLibrary initialiseModuleInteropLibrary = NFIUtils.getInteropLibrary(initialiseModuleSymbol); + initialiseModuleInteropLibrary.execute(initialiseModuleSymbol); + } catch (UnknownIdentifierException e) { + // module has no initializer, ignore + } catch (UnsupportedTypeException | ArityException | UnsupportedMessageException e) { + throw CompilerDirectives.shouldNotReachHere(e); + } + try { + final InteropLibrary moduleInteropLibrary = NFIUtils.getInteropLibrary(library); + moduleInteropLibrary.invokeMember(library, "setInterpreter", context.getInterpreterProxy(null, 0).getPointer()); + } catch (UnsupportedMessageException | ArityException | UnsupportedTypeException | UnknownIdentifierException e) { + throw CompilerDirectives.shouldNotReachHere(e); + } + return library; + }); + // computeIfAbsent would not put null value + context.loadedLibraries.putIfAbsent(moduleName, moduleLibrary); + return moduleLibrary; + } + @Override public Object execute(final VirtualFrame frame) { return doExternalCall(frame.materialize());