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 04dbd25f6..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; @@ -19,6 +20,7 @@ import com.oracle.truffle.api.TruffleFile; import com.oracle.truffle.api.TruffleLanguage.ContextReference; import com.oracle.truffle.api.TruffleLanguage.ParsingRequest; +import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.instrumentation.AllocationReporter; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.library.Message; @@ -64,6 +66,7 @@ import de.hpi.swa.trufflesqueak.nodes.plugins.BitBlt; import de.hpi.swa.trufflesqueak.nodes.plugins.JPEGReader; import de.hpi.swa.trufflesqueak.nodes.plugins.Zip; +import de.hpi.swa.trufflesqueak.nodes.plugins.ffi.InterpreterProxy; import de.hpi.swa.trufflesqueak.shared.SqueakImageLocator; import de.hpi.swa.trufflesqueak.tools.SqueakMessageInterceptor; import de.hpi.swa.trufflesqueak.util.ArrayUtils; @@ -165,6 +168,8 @@ public final class SqueakImageContext { @CompilationFinal private ClassObject wideStringClass; /* 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]; @@ -621,6 +626,14 @@ public boolean supportsNFI() { return env.getInternalLanguages().containsKey("nfi"); } + public InterpreterProxy getInterpreterProxy(final MaterializedFrame frame, final int numReceiverAndArguments) { + if (interpreterProxy == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + interpreterProxy = new InterpreterProxy(this); + } + return interpreterProxy.instanceFor(frame, numReceiverAndArguments); + } + public PointersObject getScheduler() { if (scheduler == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); 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 aa87360e3..02b37b19a 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 @@ -11,6 +11,7 @@ import java.util.function.Predicate; import java.util.stream.Collectors; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.interop.ArityException; import com.oracle.truffle.api.interop.InteropLibrary; @@ -43,7 +44,6 @@ import de.hpi.swa.trufflesqueak.util.NFIUtils.TruffleExecutable; public final class InterpreterProxy { - private static InterpreterProxy INSTANCE; private final SqueakImageContext context; private MaterializedFrame frame; private int numReceiverAndArguments; @@ -63,26 +63,26 @@ public final class InterpreterProxy { // INSTANCE CREATION // /////////////////////// - private InterpreterProxy(final SqueakImageContext context, final MaterializedFrame frame, final int numReceiverAndArguments) - throws UnsupportedMessageException, UnknownIdentifierException, UnsupportedTypeException, ArityException { + public InterpreterProxy(final SqueakImageContext context) { this.context = context; - this.frame = frame; - this.numReceiverAndArguments = numReceiverAndArguments; - - final TruffleExecutable[] executables = getExecutables(); - closures = new TruffleClosure[executables.length]; - for (int i = 0; i < executables.length; i++) { - closures[i] = executables[i].createClosure(context); - } + try { + final TruffleExecutable[] executables = getExecutables(); + closures = new TruffleClosure[executables.length]; + for (int i = 0; i < executables.length; i++) { + closures[i] = executables[i].createClosure(context); + } - final String truffleExecutablesSignatures = Arrays.stream(closures).map(obj -> obj.executable.nfiSignature).collect(Collectors.joining(",")); - final Object interpreterProxy = NFIUtils.loadLibrary(context, "InterpreterProxy", - "{ createInterpreterProxy(" + truffleExecutablesSignatures + "):POINTER; }"); - assert interpreterProxy != null : "InterpreterProxy module not found!"; + final String truffleExecutablesSignatures = Arrays.stream(closures).map(obj -> obj.executable.nfiSignature).collect(Collectors.joining(",")); + final Object interpreterProxy = NFIUtils.loadLibrary(context, "InterpreterProxy", + "{ createInterpreterProxy(" + truffleExecutablesSignatures + "):POINTER; }"); + assert interpreterProxy != null : "InterpreterProxy module not found!"; - final InteropLibrary interpreterProxyLibrary = NFIUtils.getInteropLibrary(interpreterProxy); - interpreterProxyPointer = interpreterProxyLibrary.invokeMember( - interpreterProxy, "createInterpreterProxy", (Object[]) closures); + final InteropLibrary interpreterProxyLibrary = NFIUtils.getInteropLibrary(interpreterProxy); + interpreterProxyPointer = interpreterProxyLibrary.invokeMember( + interpreterProxy, "createInterpreterProxy", (Object[]) closures); + } catch (UnsupportedMessageException | UnknownIdentifierException | UnsupportedTypeException | ArityException e) { + throw CompilerDirectives.shouldNotReachHere(e); + } } private TruffleExecutable[] getExecutables() { @@ -164,25 +164,18 @@ private TruffleExecutable[] getExecutables() { }; } - public static InterpreterProxy instanceFor(final SqueakImageContext context, final MaterializedFrame frame, final int numReceiverAndArguments) - throws UnsupportedMessageException, UnknownIdentifierException, UnsupportedTypeException, ArityException { - if (INSTANCE == null) { - INSTANCE = new InterpreterProxy(context, frame, numReceiverAndArguments); - return INSTANCE; - } - assert INSTANCE.context == context : "received new SqueakImageContext"; - - INSTANCE.frame = frame; - INSTANCE.numReceiverAndArguments = numReceiverAndArguments; - return INSTANCE; + public InterpreterProxy instanceFor(final MaterializedFrame frame, final int numReceiverAndArguments) { + this.frame = frame; + this.numReceiverAndArguments = numReceiverAndArguments; + return this; } /////////////////// // MISCELLANEOUS // /////////////////// - public static Object getPointer() { - return INSTANCE.interpreterProxyPointer; + public Object getPointer() { + return interpreterProxyPointer; } public void postPrimitiveCleanups() { 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 d0bddbd24..ace081393 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 @@ -6,9 +6,6 @@ */ package de.hpi.swa.trufflesqueak.nodes.plugins.ffi; -import java.util.HashMap; -import java.util.Map; - import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.exception.AbstractTruffleException; @@ -32,7 +29,6 @@ public final class PrimExternalCallNode extends AbstractPrimitiveNode { private final Object functionSymbol; private final InteropLibrary functionInteropLibrary; private final int numReceiverAndArguments; - private static final Map loadedLibraries = new HashMap<>(); public PrimExternalCallNode(final Object moduleLibrary, final InteropLibrary moduleInteropLibrary, final Object functionSymbol, final InteropLibrary functionInteropLibrary, final int numReceiverAndArguments) { @@ -46,8 +42,8 @@ public PrimExternalCallNode(final Object moduleLibrary, final InteropLibrary mod public static PrimExternalCallNode load(final String moduleName, final String functionName, final int numReceiverAndArguments) { final SqueakImageContext context = SqueakImageContext.getSlow(); - final Object moduleLibrary = loadedLibraries.computeIfAbsent(moduleName, (String s) -> { - if (loadedLibraries.containsKey(moduleName)) { + final Object moduleLibrary = context.loadedLibraries.computeIfAbsent(moduleName, (String s) -> { + if (context.loadedLibraries.containsKey(moduleName)) { // if moduleName was associated with null return null; } @@ -77,7 +73,7 @@ public static PrimExternalCallNode load(final String moduleName, final String fu return library; }); // computeIfAbsent would not put null value - loadedLibraries.putIfAbsent(moduleName, moduleLibrary); + context.loadedLibraries.putIfAbsent(moduleName, moduleLibrary); if (moduleLibrary == null) { // module not found return null; @@ -95,8 +91,8 @@ public static PrimExternalCallNode load(final String moduleName, final String fu private void setInterpreter() { try { - InterpreterProxy.instanceFor(getContext(), null, 0); - moduleInteropLibrary.invokeMember(moduleLibrary, "setInterpreter", InterpreterProxy.getPointer()); + final InterpreterProxy interpreterProxy = getContext().getInterpreterProxy(null, 0); + moduleInteropLibrary.invokeMember(moduleLibrary, "setInterpreter", interpreterProxy.getPointer()); } catch (UnsupportedMessageException | ArityException | UnsupportedTypeException | UnknownIdentifierException e) { throw CompilerDirectives.shouldNotReachHere(e); } @@ -117,7 +113,7 @@ public Object executeWithArguments(final VirtualFrame frame, final Object... rec private Object doExternalCall(final MaterializedFrame frame) { InterpreterProxy interpreterProxy = null; try { - interpreterProxy = InterpreterProxy.instanceFor(getContext(), frame, numReceiverAndArguments); + interpreterProxy = getContext().getInterpreterProxy(frame, numReceiverAndArguments); // A send (AbstractSendNode.executeVoid) will decrement the stack pointer by // numReceiverAndArguments @@ -138,7 +134,7 @@ private Object doExternalCall(final MaterializedFrame frame) { throw PrimitiveFailed.andTransferToInterpreter((int) failReason); } return returnValue; - } catch (UnsupportedMessageException | UnknownIdentifierException | ArityException | UnsupportedTypeException e) { + } catch (UnsupportedMessageException | ArityException | UnsupportedTypeException e) { throw CompilerDirectives.shouldNotReachHere(e); } finally { if (interpreterProxy != null) {