Skip to content
Snippets Groups Projects
Commit d2afe6ff authored by Zbyněk Šlajchrt's avatar Zbyněk Šlajchrt
Browse files

[GR-8835] Sulong's new lookup mechanism adopted.

PullRequest: fastr/1650
parents 1f1aab1c d8b723e2
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