From e102de11f2d642d431317cc9e199380eb49feadc Mon Sep 17 00:00:00 2001 From: Lukas Stadler <lukas.stadler@oracle.com> Date: Thu, 21 Sep 2017 12:11:16 +0200 Subject: [PATCH] use upcall for str2type and simulate DllInfo layout --- .../ffi/impl/common/JavaUpCallsRFFIImpl.java | 29 ++++----- .../impl/llvm/TruffleLLVM_RFFIFactory.java | 1 - .../fficall/src/common/rffi_upcalls.h | 2 + .../Rinternals_truffle_common.h | 5 ++ .../r/runtime/data/NativeDataAccess.java | 15 ++++- .../oracle/truffle/r/runtime/ffi/CRFFI.java | 60 ++++++++++--------- .../com/oracle/truffle/r/runtime/ffi/DLL.java | 8 ++- 7 files changed, 71 insertions(+), 49 deletions(-) diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java index 4b6e458e78..0fd2bf80d7 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java @@ -1554,23 +1554,8 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { } } - private HashMap<String, Integer> name2typeTable; - - @Override - @TruffleBoundary - public int Rf_str2type(String name) { - if (name == null) { - return -1; - } - initName2typeTable(); - Integer result = name2typeTable.get(name); - return result != null ? result : -1; - } - - private void initName2typeTable() { - if (name2typeTable != null) { - return; - } + private static HashMap<String, Integer> name2typeTable; + static { name2typeTable = new HashMap<>(26); name2typeTable.put("NULL", SEXPTYPE.NILSXP.code); /* real types */ name2typeTable.put("symbol", SEXPTYPE.SYMSXP.code); @@ -1600,6 +1585,16 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { name2typeTable.put("name", SEXPTYPE.SYMSXP.code); } + @Override + @TruffleBoundary + public int Rf_str2type(String name) { + if (name == null) { + return -1; + } + Integer result = name2typeTable.get(name); + return result != null ? result : -1; + } + @Override public int registerRoutines(Object dllInfoObj, int nstOrd, int num, Object routines) { DLLInfo dllInfo = guaranteeInstanceOf(dllInfoObj, DLLInfo.class); diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_RFFIFactory.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_RFFIFactory.java index e7bd3e199c..1146e3b1c9 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_RFFIFactory.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_RFFIFactory.java @@ -24,7 +24,6 @@ package com.oracle.truffle.r.ffi.impl.llvm; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.r.runtime.context.RContext.ContextState; import com.oracle.truffle.r.runtime.ffi.BaseRFFI; import com.oracle.truffle.r.runtime.ffi.CRFFI; import com.oracle.truffle.r.runtime.ffi.CallRFFI; diff --git a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h index 07299d0366..3d29cb9f88 100644 --- a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h +++ b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h @@ -280,6 +280,8 @@ typedef SEXP (*call_getvar)(); typedef SEXP (*call_R_ParseVector)(SEXP text, int n, SEXP srcFile); +typedef SEXPTYPE (*call_Rf_str2type)(const char *s); + // connections typedef int (*call_FASTR_getConnectionChar)(SEXP connection); diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h index 8460b04e7b..9ec235c0bf 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h +++ b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h @@ -1370,6 +1370,11 @@ int FASTR_getConnectionChar(SEXP conn) { return ((call_FASTR_getConnectionChar) callbacks[FASTR_getConnectionChar_x])(conn); } +SEXPTYPE Rf_str2type(const char *s) { + TRACE0(); + return ((call_Rf_str2type) callbacks[Rf_str2type_x])(s); +} + // Must match ordinal value for DLL.NativeSymbolType #define C_NATIVE_TYPE 0 #define CALL_NATIVE_TYPE 1 diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/NativeDataAccess.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/NativeDataAccess.java index 83cf3e9f2c..9c2e312f17 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/NativeDataAccess.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/NativeDataAccess.java @@ -90,6 +90,10 @@ public final class NativeDataAccess { // no instances } + public interface CustomNativeMirror { + long getCustomMirrorAddress(); + } + private static final boolean TRACE_MIRROR_ALLOCATION_SITES = false; public static boolean isNativeMirror(Object o) { @@ -116,6 +120,15 @@ public final class NativeDataAccess { this.id = counter.incrementAndGet(); } + /** + * Creates a new mirror with a specified native address as both ID and address. The buffer + * will be freed when the Java object is collected. + */ + NativeMirror(long address) { + this.id = address; + this.dataAddress = address; + } + void allocateNative(Object source, int len, int elementBase, int elementSize) { assert dataAddress == 0; dataAddress = UnsafeAdapter.UNSAFE.allocateMemory(len * elementSize); @@ -180,7 +193,7 @@ public final class NativeDataAccess { RObject obj = (RObject) arg; NativeMirror mirror = (NativeMirror) obj.getNativeMirror(); if (mirror == null) { - obj.setNativeMirror(mirror = new NativeMirror()); + obj.setNativeMirror(mirror = arg instanceof CustomNativeMirror ? new NativeMirror(((CustomNativeMirror) arg).getCustomMirrorAddress()) : new NativeMirror()); // System.out.println(String.format("adding %16x = %s", mirror.id, // obj.getClass().getSimpleName())); nativeMirrors.put(mirror.id, new WeakReference<>(obj)); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java index 3f96e6fb35..3a6ce0d011 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java @@ -56,7 +56,6 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.nodes.RBaseNode; import sun.misc.Unsafe; @@ -145,10 +144,10 @@ abstract class TemporaryWrapper implements TruffleObject { if (vector instanceof RVector<?> && ((RVector<?>) vector).isTemporary()) { NativeDataAccess.asPointer(vector); reuseVector = true; - address = allocateNative((RVector<?>) vector); + address = allocateNative(); } else { reuseVector = false; - address = allocate(vector); + address = allocate(); } return address; } @@ -157,15 +156,15 @@ abstract class TemporaryWrapper implements TruffleObject { if (address == 0 || reuseVector) { return vector; } else { - return copyBack(address, vector); + return copyBack(); } } - protected abstract long allocate(RAbstractVector vector); + protected abstract long allocate(); - protected abstract long allocateNative(RVector<?> vector); + protected abstract long allocateNative(); - protected abstract RAbstractAtomicVector copyBack(long address, RAbstractVector vector); + protected abstract RAbstractAtomicVector copyBack(); } // TODO: fortran only takes a pointer to the first string @@ -177,29 +176,32 @@ final class StringWrapper extends TemporaryWrapper { @Override public long asPointer() { - address = allocate(vector); + address = allocate(); return address; } @Override - protected long allocateNative(RVector<?> vector) { + protected long allocateNative() { throw RInternalError.shouldNotReachHere(); } @Override @TruffleBoundary - public long allocate(RAbstractVector vector) { + public long allocate() { + return allocateNativeStringVector((RAbstractStringVector) vector); + } + + public static long allocateNativeStringVector(RAbstractStringVector vector) { // We allocate contiguous memory that we'll use to store both the array of pointers (char**) // and the arrays of characters (char*). Given vector of size N, we allocate memory for N // adresses (long) and after those we put individual strings character by character, the // pointers from the first segment of this memory will be pointing to the starts of those // strings. - RAbstractStringVector v = (RAbstractStringVector) vector; - int length = v.getLength(); + int length = vector.getLength(); int size = length * Long.BYTES; byte[][] bytes = new byte[length][]; for (int i = 0; i < length; i++) { - String element = v.getDataAt(i); + String element = vector.getDataAt(i); bytes[i] = element.getBytes(StandardCharsets.US_ASCII); size += bytes[i].length + 1; } @@ -217,7 +219,7 @@ final class StringWrapper extends TemporaryWrapper { @Override @TruffleBoundary - protected RStringVector copyBack(long address, RAbstractVector vector) { + protected RStringVector copyBack() { RStringVector result = ((RAbstractStringVector) vector).materialize(); boolean reuseResult = result.isTemporary() && !result.hasNativeMemoryData(); String[] data = reuseResult ? result.getInternalManagedData() : new String[result.getLength()]; @@ -250,7 +252,7 @@ final class IntWrapper extends TemporaryWrapper { @Override @TruffleBoundary - public long allocate(RAbstractVector vector) { + public long allocate() { RAbstractIntVector v = (RAbstractIntVector) vector; int length = v.getLength(); long memory = UnsafeAdapter.UNSAFE.allocateMemory(length * Unsafe.ARRAY_INT_INDEX_SCALE); @@ -262,13 +264,13 @@ final class IntWrapper extends TemporaryWrapper { @Override @TruffleBoundary - protected long allocateNative(RVector<?> vector) { + protected long allocateNative() { return ((RIntVector) vector).allocateNativeContents(); } @Override @TruffleBoundary - protected RIntVector copyBack(long address, RAbstractVector vector) { + protected RIntVector copyBack() { RIntVector result = RDataFactory.createIntVectorFromNative(address, vector.getLength()); result.copyAttributesFrom(vector); return result; @@ -283,7 +285,7 @@ final class LogicalWrapper extends TemporaryWrapper { @Override @TruffleBoundary - public long allocate(RAbstractVector vector) { + public long allocate() { RAbstractLogicalVector v = (RAbstractLogicalVector) vector; int length = v.getLength(); long memory = UnsafeAdapter.UNSAFE.allocateMemory(length * Unsafe.ARRAY_INT_INDEX_SCALE); @@ -295,13 +297,13 @@ final class LogicalWrapper extends TemporaryWrapper { @Override @TruffleBoundary - protected long allocateNative(RVector<?> vector) { + protected long allocateNative() { return ((RLogicalVector) vector).allocateNativeContents(); } @Override @TruffleBoundary - protected RLogicalVector copyBack(long address, RAbstractVector vector) { + protected RLogicalVector copyBack() { RLogicalVector result = RDataFactory.createLogicalVectorFromNative(address, vector.getLength()); result.copyAttributesFrom(vector); return result; @@ -316,7 +318,7 @@ final class DoubleWrapper extends TemporaryWrapper { @Override @TruffleBoundary - public long allocate(RAbstractVector vector) { + public long allocate() { RAbstractDoubleVector v = (RAbstractDoubleVector) vector; int length = v.getLength(); long memory = UnsafeAdapter.UNSAFE.allocateMemory(length * Unsafe.ARRAY_DOUBLE_INDEX_SCALE); @@ -328,13 +330,13 @@ final class DoubleWrapper extends TemporaryWrapper { @Override @TruffleBoundary - protected long allocateNative(RVector<?> vector) { + protected long allocateNative() { return ((RDoubleVector) vector).allocateNativeContents(); } @Override @TruffleBoundary - protected RDoubleVector copyBack(long address, RAbstractVector vector) { + protected RDoubleVector copyBack() { RDoubleVector result = RDataFactory.createDoubleVectorFromNative(address, vector.getLength()); result.copyAttributesFrom(vector); return result; @@ -349,7 +351,7 @@ final class ComplexWrapper extends TemporaryWrapper { @Override @TruffleBoundary - public long allocate(RAbstractVector vector) { + public long allocate() { RAbstractComplexVector v = (RAbstractComplexVector) vector; int length = v.getLength(); long memory = UnsafeAdapter.UNSAFE.allocateMemory(length * Unsafe.ARRAY_DOUBLE_INDEX_SCALE * 2); @@ -363,13 +365,13 @@ final class ComplexWrapper extends TemporaryWrapper { @Override @TruffleBoundary - protected long allocateNative(RVector<?> vector) { + protected long allocateNative() { return ((RComplexVector) vector).allocateNativeContents(); } @Override @TruffleBoundary - protected RComplexVector copyBack(long address, RAbstractVector vector) { + protected RComplexVector copyBack() { RComplexVector result = RDataFactory.createComplexVectorFromNative(address, vector.getLength()); result.copyAttributesFrom(vector); return result; @@ -384,7 +386,7 @@ final class RawWrapper extends TemporaryWrapper { @Override @TruffleBoundary - public long allocate(RAbstractVector vector) { + public long allocate() { RAbstractRawVector v = (RAbstractRawVector) vector; int length = v.getLength(); long memory = UnsafeAdapter.UNSAFE.allocateMemory(length * Unsafe.ARRAY_BYTE_INDEX_SCALE); @@ -396,13 +398,13 @@ final class RawWrapper extends TemporaryWrapper { @Override @TruffleBoundary - protected long allocateNative(RVector<?> vector) { + protected long allocateNative() { return ((RRawVector) vector).allocateNativeContents(); } @Override @TruffleBoundary - protected RRawVector copyBack(long address, RAbstractVector vector) { + protected RRawVector copyBack() { RRawVector result = RDataFactory.createRawVectorFromNative(address, vector.getLength()); result.copyAttributesFrom(vector); return result; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java index 8535b479e5..82c66ae469 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java @@ -35,6 +35,7 @@ import com.oracle.truffle.r.runtime.Utils; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.context.RContext.ContextKind; import com.oracle.truffle.r.runtime.context.RContext.ContextState; +import com.oracle.truffle.r.runtime.data.NativeDataAccess.CustomNativeMirror; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RExternalPtr; import com.oracle.truffle.r.runtime.data.RList; @@ -176,7 +177,7 @@ public class DLL { } } - public static final class DLLInfo extends RObject implements RTruffleObject { + public static final class DLLInfo extends RObject implements RTruffleObject, CustomNativeMirror { private static final RStringVector NAMES = RDataFactory.createStringVector(new String[]{"name", "path", "dynamicLookup", "handle", "info"}, RDataFactory.COMPLETE_VECTOR); public static final String DLL_INFO_REFERENCE = "DLLInfoReference"; private static final RStringVector INFO_REFERENCE_CLASS = RDataFactory.createStringVectorFromScalar(DLL_INFO_REFERENCE); @@ -284,6 +285,11 @@ public class DLL { public String toString() { return String.format("name: %s, path: %s, dynamicLookup: %b, forceSymbols %b", name, path, dynamicLookup, forceSymbols); } + + @Override + public long getCustomMirrorAddress() { + return StringWrapper.allocateNativeStringVector(RDataFactory.createStringVector(new String[]{path, name}, true)); + } } public static final class SymbolInfo { -- GitLab