Skip to content

Commit

Permalink
Add InterpreterProxy and loaded modules to context
Browse files Browse the repository at this point in the history
They are context-specific and cannot be re-used in a different context, which for example happens during testing.
  • Loading branch information
fniephaus committed Feb 9, 2024
1 parent 4a95838 commit cf2f6b1
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -165,6 +168,8 @@ public final class SqueakImageContext {
@CompilationFinal private ClassObject wideStringClass;

/* Plugins */
@CompilationFinal private InterpreterProxy interpreterProxy;
public final Map<String, Object> loadedLibraries = new HashMap<>();
public final B2D b2d = new B2D(this);
public final BitBlt bitblt = new BitBlt(this);
public String[] dropPluginFileList = new String[0];
Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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() {
Expand Down Expand Up @@ -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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<String, Object> loadedLibraries = new HashMap<>();

public PrimExternalCallNode(final Object moduleLibrary, final InteropLibrary moduleInteropLibrary, final Object functionSymbol, final InteropLibrary functionInteropLibrary,
final int numReceiverAndArguments) {
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand All @@ -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);
}
Expand All @@ -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
Expand All @@ -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) {
Expand Down

0 comments on commit cf2f6b1

Please sign in to comment.