Skip to content
Snippets Groups Projects
Commit d8b723e2 authored by Zbynek Slajchrt's avatar Zbynek Slajchrt
Browse files

Sulong's new lookup mechanism adopted

parent 1f1aab1c
No related branches found
No related tags found
No related merge requests found
......@@ -31,10 +31,12 @@ import com.oracle.truffle.api.interop.ForeignAccess;
import com.oracle.truffle.api.interop.InteropException;
import com.oracle.truffle.api.interop.Message;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnknownIdentifierException;
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.r.ffi.impl.llvm.TruffleLLVM_CallFactory.ToNativeNodeGen;
import com.oracle.truffle.r.ffi.impl.llvm.TruffleLLVM_CallFactory.TruffleLLVM_InvokeCallNodeGen;
import com.oracle.truffle.r.ffi.impl.llvm.TruffleLLVM_DLL.LLVM_Handle;
import com.oracle.truffle.r.ffi.impl.llvm.upcalls.BytesToNativeCharArrayCall;
import com.oracle.truffle.r.ffi.impl.llvm.upcalls.CharSXPToNativeArrayCall;
import com.oracle.truffle.r.ffi.impl.upcalls.Callbacks;
......@@ -46,6 +48,7 @@ import com.oracle.truffle.r.runtime.data.RDataFactory;
import com.oracle.truffle.r.runtime.data.RScalar;
import com.oracle.truffle.r.runtime.data.RVector;
import com.oracle.truffle.r.runtime.ffi.CallRFFI;
import com.oracle.truffle.r.runtime.ffi.DLL;
import com.oracle.truffle.r.runtime.ffi.FFIUnwrapNode;
import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
import com.oracle.truffle.r.runtime.ffi.NativeCallInfo;
......@@ -95,8 +98,9 @@ final class TruffleLLVM_Call implements CallRFFI {
callbacks = (TruffleObject) context.getEnv().asGuestValue(callbacksArray);
LLVM_Handle rdllInfo = (LLVM_Handle) DLL.getRdllInfo().handle;
SymbolHandle setClbkAddrSymbolHandle = new SymbolHandle(rdllInfo.parsedIRs[0].lookup("Rinternals_setCallbacksAddress"));
Node setClbkAddrExecuteNode = Message.EXECUTE.createNode();
SymbolHandle setClbkAddrSymbolHandle = new SymbolHandle(context.getEnv().importSymbol("@" + "Rinternals_setCallbacksAddress"));
setCallbacksAddress = setClbkAddrSymbolHandle.asTruffleObject();
// Initialize the callbacks global variable
ForeignAccess.sendExecute(setClbkAddrExecuteNode, setCallbacksAddress, context.getEnv().asGuestValue(new TruffleObject[0]));
......@@ -123,8 +127,13 @@ final class TruffleLLVM_Call implements CallRFFI {
public static void initVariables(RContext context) {
// must have parsed the variables module in libR
LLVM_Handle rdllInfo = (LLVM_Handle) DLL.getRdllInfo().handle;
for (INIT_VAR_FUN initVarFun : INIT_VAR_FUN.values()) {
initVarFun.symbolHandle = new SymbolHandle(context.getEnv().importSymbol("@" + initVarFun.funName));
try {
initVarFun.symbolHandle = new SymbolHandle(rdllInfo.parsedIRs[0].lookup(initVarFun.funName));
} catch (UnknownIdentifierException e) {
throw RInternalError.shouldNotReachHere(e);
}
}
Node executeNode = Message.EXECUTE.createNode();
RFFIVariables[] variables = RFFIVariables.initialize(context);
......
......@@ -23,14 +23,25 @@
package com.oracle.truffle.r.ffi.impl.llvm;
import java.nio.file.FileSystems;
import java.util.EnumMap;
import com.oracle.truffle.api.CompilerAsserts;
import com.oracle.truffle.api.interop.ForeignAccess;
import com.oracle.truffle.api.interop.Message;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnknownIdentifierException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.r.ffi.impl.common.LibPaths;
import com.oracle.truffle.r.ffi.impl.llvm.TruffleLLVM_DLL.LLVM_Handle;
import com.oracle.truffle.r.ffi.impl.llvm.TruffleLLVM_DLL.ParsedLLVM_IR;
import com.oracle.truffle.r.runtime.REnvVars;
import com.oracle.truffle.r.runtime.RInternalError;
import com.oracle.truffle.r.runtime.context.RContext;
import com.oracle.truffle.r.runtime.context.RContext.ContextState;
import com.oracle.truffle.r.runtime.ffi.BaseRFFI;
import com.oracle.truffle.r.runtime.ffi.DLL;
import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
import com.oracle.truffle.r.runtime.ffi.DLLRFFI;
import com.oracle.truffle.r.runtime.ffi.LapackRFFI;
import com.oracle.truffle.r.runtime.ffi.MiscRFFI;
......@@ -104,9 +115,53 @@ final class TruffleLLVM_Context extends RFFIContext {
callState.beforeDispose(context);
}
private final EnumMap<NativeFunction, TruffleObject> nativeFunctions = new EnumMap<>(NativeFunction.class);
@Override
public TruffleObject lookupNativeFunction(NativeFunction function) {
Object symValue = RContext.getInstance().getEnv().importSymbol("@" + function.getCallName());
return (TruffleObject) symValue;
CompilerAsserts.neverPartOfCompilation();
if (!nativeFunctions.containsKey(function)) {
TruffleObject[] lookupObjects = new TruffleObject[0];
if (function.getLibrary() == NativeFunction.baseLibrary()) {
TruffleObject lookupObject = (TruffleObject) ((LLVM_Handle) DLL.getRdllInfo().handle).parsedIRs[0].lookupObject;
lookupObjects = new TruffleObject[]{lookupObject};
} else if (function.getLibrary() == NativeFunction.anyLibrary()) {
DLLInfo dllInfo = DLL.findLibraryContainingSymbol(RContext.getInstance(), function.getCallName());
if (dllInfo == null) {
throw RInternalError.shouldNotReachHere("Could not find library containing symbol " + function.getCallName());
}
lookupObjects = getLookupObjects(dllInfo);
} else {
DLLInfo dllInfo = DLL.findLibrary(function.getLibrary());
if (dllInfo == null) {
throw RInternalError.shouldNotReachHere("Could not find library " + function.getLibrary());
}
lookupObjects = getLookupObjects(dllInfo);
}
TruffleObject target = null;
final Node lookupNode = Message.READ.createNode();
for (int i = 0; i < lookupObjects.length; i++) {
try {
target = (TruffleObject) ForeignAccess.sendRead(lookupNode, lookupObjects[i], function.getCallName());
break;
} catch (UnknownIdentifierException e) {
continue;
} catch (UnsupportedMessageException e) {
RInternalError.shouldNotReachHere();
}
}
nativeFunctions.put(function, target);
}
return nativeFunctions.get(function);
}
private static TruffleObject[] getLookupObjects(DLLInfo dllInfo) {
TruffleObject[] lookupObjects;
final ParsedLLVM_IR[] parsedIRs = ((LLVM_Handle) dllInfo.handle).parsedIRs;
lookupObjects = new TruffleObject[parsedIRs.length];
for (int i = 0; i < parsedIRs.length; i++) {
lookupObjects[i] = (TruffleObject) parsedIRs[i].lookupObject;
}
return lookupObjects;
}
}
......@@ -44,6 +44,11 @@ import java.util.zip.ZipInputStream;
import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.interop.ForeignAccess;
import com.oracle.truffle.api.interop.Message;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnknownIdentifierException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.r.runtime.RInternalError;
......@@ -94,6 +99,7 @@ public class TruffleLLVM_DLL implements DLLRFFI {
*/
@Override
public ContextState initialize(RContext context) {
// TODO: Is it really needed when using the new lookup mechanism?
if (!context.isInitial()) {
for (LLVM_IR ir : truffleDLL.libRModules) {
parseLLVM("libR", ir);
......@@ -105,8 +111,8 @@ public class TruffleLLVM_DLL implements DLLRFFI {
for (DLLInfo dllInfo : loadedDLLs) {
if (dllInfo.handle instanceof LLVM_Handle) {
LLVM_Handle llvmHandle = (LLVM_Handle) dllInfo.handle;
for (LLVM_IR ir : llvmHandle.irs) {
parseLLVM(llvmHandle.libName, ir);
for (ParsedLLVM_IR parsedIR : llvmHandle.parsedIRs) {
parseLLVM(llvmHandle.libName, parsedIR.ir);
}
}
}
......@@ -128,14 +134,34 @@ public class TruffleLLVM_DLL implements DLLRFFI {
return new ContextStateImpl();
}
static class ParsedLLVM_IR {
final LLVM_IR ir;
final Object lookupObject;
ParsedLLVM_IR(LLVM_IR ir, Object lookupObject) {
this.ir = ir;
this.lookupObject = lookupObject;
}
Object lookup(String symbol) throws UnknownIdentifierException {
try {
return ForeignAccess.sendRead(Message.READ.createNode(), (TruffleObject) lookupObject, symbol);
} catch (UnsupportedMessageException e) {
throw RInternalError.shouldNotReachHere(e);
}
}
}
static class LLVM_Handle {
private final String libName;
private final LLVM_IR[] irs;
final String libName;
final ParsedLLVM_IR[] parsedIRs;
LLVM_Handle(String libName, LLVM_IR[] irs) {
LLVM_Handle(String libName, ParsedLLVM_IR[] irs) {
this.libName = libName;
this.irs = irs;
this.parsedIRs = irs;
}
}
@FunctionalInterface
......@@ -236,10 +262,13 @@ public class TruffleLLVM_DLL implements DLLRFFI {
} else {
loadNativeLibs(ar.nativeLibs);
}
for (LLVM_IR ir : irs) {
parseLLVM(libName, ir);
ParsedLLVM_IR[] parsedIRs = new ParsedLLVM_IR[irs.length];
for (int i = 0; i < irs.length; i++) {
LLVM_IR ir = irs[i];
Object irLookupObject = parseLLVM(libName, ir).call();
parsedIRs[i] = new ParsedLLVM_IR(ir, irLookupObject);
}
return new LLVM_Handle(libName, irs);
return new LLVM_Handle(libName, parsedIRs);
} catch (Exception ex) {
CompilerDirectives.transferToInterpreter();
StringBuilder sb = new StringBuilder();
......@@ -276,15 +305,30 @@ public class TruffleLLVM_DLL implements DLLRFFI {
}
private static class TruffleLLVM_DLSymNode extends Node implements DLSymNode {
@Child private Node lookupNode = Message.READ.createNode();
@Override
public SymbolHandle execute(Object handle, String symbol) throws UnsatisfiedLinkError {
assert handle instanceof LLVM_Handle;
Object symValue = RContext.getInstance().getEnv().importSymbol("@" + symbol);
LLVM_Handle llvmHandle = (LLVM_Handle) handle;
Object symValue = null;
for (int i = 0; i < llvmHandle.parsedIRs.length; i++) {
ParsedLLVM_IR pir = llvmHandle.parsedIRs[i];
try {
symValue = ForeignAccess.sendRead(lookupNode, (TruffleObject) pir.lookupObject, symbol);
break;
} catch (UnknownIdentifierException e) {
continue;
} catch (UnsupportedMessageException e) {
RInternalError.shouldNotReachHere();
}
}
if (symValue == null) {
throw new UnsatisfiedLinkError();
}
return new SymbolHandle(symValue);
}
}
private static class TruffleLLVM_DLCloseNode extends Node implements DLCloseNode {
......@@ -321,25 +365,10 @@ public class TruffleLLVM_DLL implements DLLRFFI {
*/
private LLVM_IR[] libRModules;
private static final String[] PARSE_ERRORS = new String[0];
private static boolean parseFails(String libName, LLVM_IR ir) {
for (int i = 0; i < PARSE_ERRORS.length / 2; i++) {
String plibName = PARSE_ERRORS[i * 2];
String pModule = PARSE_ERRORS[i * 2 + 1];
if (libName.equals(plibName) && ir.name.equals(pModule)) {
return true;
}
}
return false;
}
private static void parseLLVM(String libName, LLVM_IR ir) {
private static CallTarget parseLLVM(String libName, LLVM_IR ir) {
if (ir instanceof LLVM_IR.Binary) {
LLVM_IR.Binary bir = (LLVM_IR.Binary) ir;
if (!parseFails(libName, ir)) {
parseBinary(libName, bir);
}
return parseBinary(libName, bir);
} else {
throw RInternalError.unimplemented("LLVM text IR");
}
......
......@@ -23,6 +23,7 @@
package com.oracle.truffle.r.ffi.impl.llvm;
import static com.oracle.truffle.r.runtime.ffi.NativeFunction.anyLibrary;
import static com.oracle.truffle.r.runtime.ffi.NativeFunction.baseLibrary;
import java.nio.charset.StandardCharsets;
......@@ -67,7 +68,9 @@ final class TruffleLLVM_DownCallNodeFactory extends DownCallNodeFactory {
CompilerAsserts.neverPartOfCompilation();
String library = fn.getLibrary();
DLLInfo dllInfo = null;
if (library != anyLibrary()) {
if (library == baseLibrary()) {
dllInfo = DLL.getRdllInfo();
} else if (library != anyLibrary()) {
dllInfo = DLL.findLibrary(library);
}
SymbolHandle result = DLL.findSymbol(fn.getCallName(), dllInfo);
......
......@@ -29,11 +29,11 @@ import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.r.ffi.impl.common.JavaUpCallsRFFIImpl;
import com.oracle.truffle.r.ffi.impl.common.RFFIUtils;
import com.oracle.truffle.r.ffi.impl.llvm.TruffleLLVM_DLL.LLVM_Handle;
import com.oracle.truffle.r.ffi.impl.upcalls.Callbacks;
import com.oracle.truffle.r.runtime.REnvVars;
import com.oracle.truffle.r.runtime.RError;
import com.oracle.truffle.r.runtime.RInternalError;
import com.oracle.truffle.r.runtime.context.RContext;
import com.oracle.truffle.r.runtime.data.CharSXPWrapper;
import com.oracle.truffle.r.runtime.data.RDouble;
import com.oracle.truffle.r.runtime.data.RInteger;
......@@ -42,10 +42,9 @@ import com.oracle.truffle.r.runtime.data.RScalar;
import com.oracle.truffle.r.runtime.data.RString;
import com.oracle.truffle.r.runtime.data.RTypedValue;
import com.oracle.truffle.r.runtime.ffi.DLL;
import com.oracle.truffle.r.runtime.ffi.FFIUnwrapNode;
import com.oracle.truffle.r.runtime.ffi.DLL.CEntry;
import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
import com.oracle.truffle.r.runtime.ffi.FFIUnwrapNode;
import com.oracle.truffle.r.runtime.ffi.VectorRFFIWrapper;
import com.oracle.truffle.r.runtime.ffi.interop.NativeCharArray;
......@@ -58,7 +57,12 @@ public class TruffleLLVM_UpCallsRFFIImpl extends JavaUpCallsRFFIImpl {
private TruffleObject setSymbolHandle;
void initialize() {
setSymbolHandle = new SymbolHandle(RContext.getInstance().getEnv().importSymbol("@" + "Rdynload_setSymbol")).asTruffleObject();
LLVM_Handle rdllInfo = (LLVM_Handle) DLL.getRdllInfo().handle;
try {
setSymbolHandle = (TruffleObject) rdllInfo.parsedIRs[0].lookup("Rdynload_setSymbol");
} catch (Exception e) {
RInternalError.shouldNotReachHere(e);
}
}
public Object charSXPToNativeCharArray(Object x) {
......
......@@ -829,6 +829,10 @@ public class DLL {
return null;
}
public static DLLInfo getRdllInfo() {
return ContextStateImpl.libRdllInfo;
}
/**
* Search for symbol {@code name} in library defined by {@code dllInfo}, or {@code null} for
* search in all loaded libraries. Used in the rare cases where no Truffle execution context
......
......@@ -43,11 +43,22 @@ C_LIBNAME := liburand.so
C_OBJECTS := $(subst $(SRC),$(OBJ),$(C_SOURCES:.c=.o))
C_LIB := $(OBJ)/$(C_LIBNAME)
INCLUDE_DIR := $(NATIVE_PROJECT)/include
ifeq ($(FASTR_RFFI),llvm)
all: $(C_LIB)
else
C_LIB_LLVM_DUMMY := $(C_LIB)l
all: $(C_LIB) $(C_LIB_LLVM_DUMMY)
$(C_LIB_LLVM_DUMMY):
touch $(C_LIB_LLVM_DUMMY)
endif
$(C_LIB): $(OBJ) $(C_OBJECTS)
$(DYLIB_LD) $(DYLIB_LDFLAGS) -o $(C_LIB) $(C_OBJECTS)
......
......@@ -162,6 +162,7 @@ suite = {
"output" : "com.oracle.truffle.r.test.native",
"results" :[
"urand/lib/liburand.so",
"urand/lib/liburand.sol",
],
"workingSets" : "FastR",
},
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment