From 3cff6ab6f47f53b010361e93b6819b1c11efd2cb Mon Sep 17 00:00:00 2001 From: Mick Jordan <mick.jordan@oracle.com> Date: Mon, 5 Dec 2016 19:03:26 -0800 Subject: [PATCH] =?UTF-8?q?rffi=20upcalls=20don=E2=80=99t=20over-constrain?= =?UTF-8?q?=20return=20type?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../truffle/r/library/graphics/RGraphics.java | 2 +- .../fficall/src/jni/Rinternals.c | 8 +- .../r/nodes/builtin/base/foreign/Fft.java | 12 +- .../base/foreign/ForeignFunctions.java | 26 +-- .../r/runtime/ffi/JavaUpCallsRFFI.java | 8 +- .../r/runtime/ffi/generic/Generic_Grid.java | 4 +- .../r/runtime/ffi/generic/Generic_Tools.java | 2 +- .../truffle/r/runtime/ffi/jni/JNI_Call.java | 169 +++++++++--------- .../truffle/r/runtime/ffi/jni/JNI_Stats.java | 60 ++++--- .../runtime/ffi/jni/TraceUpCallsAdapter.java | 8 +- .../truffle/r/runtime/TempPathName.java | 2 +- .../truffle/r/runtime/context/RContext.java | 2 +- .../truffle/r/runtime/ffi/CallRFFI.java | 46 ++--- .../com/oracle/truffle/r/runtime/ffi/DLL.java | 7 +- .../truffle/r/runtime/ffi/StatsRFFI.java | 17 +- .../truffle/r/runtime/ffi/UpCallsRFFI.java | 8 +- 16 files changed, 211 insertions(+), 170 deletions(-) diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/RGraphics.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/RGraphics.java index 728a1efd4b..bfb6cdde08 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/RGraphics.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/RGraphics.java @@ -64,7 +64,7 @@ public class RGraphics { DLL.RegisteredNativeSymbol rns = DLL.RegisteredNativeSymbol.any(); DLL.SymbolHandle func = DLL.findSymbol("InitGraphics", null, rns); assert func != DLL.SYMBOL_NOT_FOUND; - RFFIFactory.getRFFI().getCallRFFI().invokeVoidCall(new NativeCallInfo("InitGraphics", func, DLL.findLibrary("graphics")), new Object[0]); + RFFIFactory.getRFFI().getCallRFFI().callRFFINode().invokeVoidCall(new NativeCallInfo("InitGraphics", func, DLL.findLibrary("graphics")), new Object[0]); } } } diff --git a/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c b/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c index aa4b3352b6..540621ad16 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c @@ -187,10 +187,10 @@ void init_internals(JNIEnv *env) { SET_SYMVALUE_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "SET_SYMVALUE", "(Ljava/lang/Object;Ljava/lang/Object;)V", 0); SET_STRING_ELT_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "SET_STRING_ELT", "(Ljava/lang/Object;ILjava/lang/Object;)V", 0); SET_VECTOR_ELT_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "SET_VECTOR_ELT", "(Ljava/lang/Object;ILjava/lang/Object;)V", 0); - RAW_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "RAW", "(Ljava/lang/Object;)[B", 0); - REAL_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "REAL", "(Ljava/lang/Object;)[D", 0); - LOGICAL_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "LOGICAL", "(Ljava/lang/Object;)[B", 0); - INTEGER_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "INTEGER", "(Ljava/lang/Object;)[I", 0); + RAW_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "RAW", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + REAL_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "REAL", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + LOGICAL_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "LOGICAL", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + INTEGER_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "INTEGER", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); STRING_ELT_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "STRING_ELT", "(Ljava/lang/Object;I)Ljava/lang/Object;", 0); VECTOR_ELT_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "VECTOR_ELT", "(Ljava/lang/Object;I)Ljava/lang/Object;", 0); LENGTH_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "LENGTH", "(Ljava/lang/Object;)I", 0); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Fft.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Fft.java index c15e41e818..16254566d5 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Fft.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Fft.java @@ -20,11 +20,13 @@ import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; import com.oracle.truffle.r.runtime.ffi.RFFIFactory; +import com.oracle.truffle.r.runtime.ffi.StatsRFFI; public abstract class Fft extends RExternalBuiltinNode.Arg2 { private final ConditionProfile zVecLgt1 = ConditionProfile.createBinaryProfile(); private final ConditionProfile noDims = ConditionProfile.createBinaryProfile(); + @Child private StatsRFFI.FFTNode fftNode = RFFIFactory.getRFFI().getStatsRFFI().fftNode(); @Override protected void createCasts(CastBuilder casts) { @@ -44,14 +46,14 @@ public abstract class Fft extends RExternalBuiltinNode.Arg2 { int[] maxp = new int[1]; if (noDims.profile(zVec.getDimensions() == null)) { int n = zVec.getLength(); - RFFIFactory.getRFFI().getStatsRFFI().fft_factor(n, maxf, maxp); + fftNode.executeFactor(n, maxf, maxp); if (maxf[0] == 0) { errorProfile.enter(); throw RError.error(this, RError.Message.FFT_FACTORIZATION); } double[] work = new double[4 * maxf[0]]; int[] iwork = new int[maxp[0]]; - retCode = RFFIFactory.getRFFI().getStatsRFFI().fft_work(z, 1, n, 1, inv, work, iwork); + retCode = fftNode.executeWork(z, 1, n, 1, inv, work, iwork); } else { int maxmaxf = 1; int maxmaxp = 1; @@ -60,7 +62,7 @@ public abstract class Fft extends RExternalBuiltinNode.Arg2 { /* do whole loop just for error checking and maxmax[fp] .. */ for (int i = 0; i < ndims; i++) { if (d[i] > 1) { - RFFIFactory.getRFFI().getStatsRFFI().fft_factor(d[i], maxf, maxp); + fftNode.executeFactor(d[i], maxf, maxp); if (maxf[0] == 0) { errorProfile.enter(); throw RError.error(this, RError.Message.FFT_FACTORIZATION); @@ -83,8 +85,8 @@ public abstract class Fft extends RExternalBuiltinNode.Arg2 { nspn *= n; n = d[i]; nseg /= n; - RFFIFactory.getRFFI().getStatsRFFI().fft_factor(n, maxf, maxp); - RFFIFactory.getRFFI().getStatsRFFI().fft_work(z, nseg, n, nspn, inv, work, iwork); + fftNode.executeFactor(n, maxf, maxp); + fftNode.executeWork(z, nseg, n, nspn, inv, work, iwork); } } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java index 0d79bffd1a..652e1209f8 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java @@ -109,6 +109,7 @@ import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; +import com.oracle.truffle.r.runtime.ffi.CallRFFI; import com.oracle.truffle.r.runtime.ffi.DLL; import com.oracle.truffle.r.runtime.ffi.RFFIFactory; import com.oracle.truffle.r.runtime.ffi.NativeCallInfo; @@ -150,6 +151,9 @@ public class ForeignFunctions { * handle. */ protected abstract static class LookupAdapter extends RBuiltinNode { + @Child private ExtractNativeCallInfoNode extractSymbolInfoNode = ExtractNativeCallInfoNodeGen.create(); + @Child protected CallRFFI.CallRFFINode callRFFINode = RFFIFactory.getRFFI().getCallRFFI().callRFFINode(); + protected static class UnimplementedExternal extends RExternalBuiltinNode { private final String name; @@ -198,8 +202,6 @@ public class ForeignFunctions { throw RError.nyi(this, getRBuiltin().name() + " specialization failure: " + (name == null ? "<unknown>" : name)); } - @Child private ExtractNativeCallInfoNode extractSymbolInfoNode = ExtractNativeCallInfoNodeGen.create(); - protected NativeCallInfo extractSymbolInfo(VirtualFrame frame, RList symbol) { return (NativeCallInfo) extractSymbolInfoNode.execute(frame, symbol); } @@ -609,7 +611,7 @@ public class ForeignFunctions { protected Object callNamedFunction(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, Object packageName, // @Cached("symbol") RList cached, // @Cached("extractSymbolInfo(frame, symbol)") NativeCallInfo nativeCallInfo) { - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(nativeCallInfo, args.getArguments()); + return callRFFINode.invokeCall(nativeCallInfo, args.getArguments()); } /** @@ -633,7 +635,7 @@ public class ForeignFunctions { errorProfile.enter(); throw RError.error(this, RError.Message.SYMBOL_NOT_IN_TABLE, symbol, "Call", packageName); } - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(new NativeCallInfo(symbol, func, rns.getDllInfo()), args.getArguments()); + return callRFFINode.invokeCall(new NativeCallInfo(symbol, func, rns.getDllInfo()), args.getArguments()); } @SuppressWarnings("unused") @@ -712,7 +714,7 @@ public class ForeignFunctions { @Cached("symbol") RList cached, // @Cached("extractSymbolInfo(frame, symbol)") NativeCallInfo nativeCallInfo) { Object list = encodeArgumentPairList(args, nativeCallInfo.name); - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(nativeCallInfo, new Object[]{list}); + return callRFFINode.invokeCall(nativeCallInfo, new Object[]{list}); } @Specialization @@ -730,7 +732,7 @@ public class ForeignFunctions { throw RError.error(this, RError.Message.SYMBOL_NOT_IN_TABLE, symbol, "External", packageName); } Object list = encodeArgumentPairList(args, symbol); - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(new NativeCallInfo(symbol, func, rns.getDllInfo()), new Object[]{list}); + return callRFFINode.invokeCall(new NativeCallInfo(symbol, func, rns.getDllInfo()), new Object[]{list}); } @Fallback @@ -788,7 +790,7 @@ public class ForeignFunctions { @Cached("extractSymbolInfo(frame, symbol)") NativeCallInfo nativeCallInfo) { Object list = encodeArgumentPairList(args, nativeCallInfo.name); // TODO: provide proper values for the CALL, OP and RHO parameters - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(nativeCallInfo, new Object[]{CALL, OP, list, RHO}); + return callRFFINode.invokeCall(nativeCallInfo, new Object[]{CALL, OP, list, RHO}); } @Specialization @@ -807,7 +809,7 @@ public class ForeignFunctions { } Object list = encodeArgumentPairList(args, symbol); // TODO: provide proper values for the CALL, OP and RHO parameters - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(new NativeCallInfo(symbol, func, rns.getDllInfo()), new Object[]{CALL, OP, list, RHO}); + return callRFFINode.invokeCall(new NativeCallInfo(symbol, func, rns.getDllInfo()), new Object[]{CALL, OP, list, RHO}); } @Fallback @@ -847,7 +849,7 @@ public class ForeignFunctions { protected Object callNamedFunction(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, @SuppressWarnings("unused") Object packageName) { NativeCallInfo nativeCallInfo = extractSymbolInfo(frame, symbol); Object list = encodeArgumentPairList(args, nativeCallInfo.name); - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(nativeCallInfo, new Object[]{list}); + return callRFFINode.invokeCall(nativeCallInfo, new Object[]{list}); } @Specialization @@ -864,7 +866,7 @@ public class ForeignFunctions { throw RError.error(this, RError.Message.C_SYMBOL_NOT_IN_TABLE, name); } Object list = encodeArgumentPairList(args, name); - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(new NativeCallInfo(name, func, rns.getDllInfo()), new Object[]{list}); + return callRFFINode.invokeCall(new NativeCallInfo(name, func, rns.getDllInfo()), new Object[]{list}); } @Fallback @@ -903,7 +905,7 @@ public class ForeignFunctions { @Specialization protected Object callNamedFunction(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, @SuppressWarnings("unused") Object packageName) { NativeCallInfo nativeCallInfo = extractSymbolInfo(frame, symbol); - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(nativeCallInfo, args.getArguments()); + return callRFFINode.invokeCall(nativeCallInfo, args.getArguments()); } @Specialization @@ -920,7 +922,7 @@ public class ForeignFunctions { errorProfile.enter(); throw RError.error(this, RError.Message.C_SYMBOL_NOT_IN_TABLE, name); } - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(new NativeCallInfo(name, func, rns.getDllInfo()), args.getArguments()); + return callRFFINode.invokeCall(new NativeCallInfo(name, func, rns.getDllInfo()), args.getArguments()); } @Fallback diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/JavaUpCallsRFFI.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/JavaUpCallsRFFI.java index 4f0611ede2..d51986b501 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/JavaUpCallsRFFI.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/JavaUpCallsRFFI.java @@ -627,7 +627,7 @@ public class JavaUpCallsRFFI implements UpCallsRFFI { } @Override - public byte[] RAW(Object x) { + public Object RAW(Object x) { if (tracer != null) { tracer.RAW(x); } @@ -641,7 +641,7 @@ public class JavaUpCallsRFFI implements UpCallsRFFI { } @Override - public byte[] LOGICAL(Object x) { + public Object LOGICAL(Object x) { if (tracer != null) { tracer.LOGICAL(x); } @@ -655,7 +655,7 @@ public class JavaUpCallsRFFI implements UpCallsRFFI { } @Override - public int[] INTEGER(Object x) { + public Object INTEGER(Object x) { if (tracer != null) { tracer.INTEGER(x); } @@ -679,7 +679,7 @@ public class JavaUpCallsRFFI implements UpCallsRFFI { } @Override - public double[] REAL(Object x) { + public Object REAL(Object x) { if (tracer != null) { tracer.REAL(x); } diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Grid.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Grid.java index 4b79d033cc..8e1df26de4 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Grid.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Grid.java @@ -66,12 +66,12 @@ public class Generic_Grid implements GridRFFI { @Override public Object initGrid(REnvironment gridEvalEnv) { long initGrid = GridProvider.gridProvider().getInitGrid(); - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(new NativeCallInfo("L_initGrid", new SymbolHandle(initGrid), DLL.findLibrary("grid")), new Object[]{gridEvalEnv}); + return RFFIFactory.getRFFI().getCallRFFI().callRFFINode().invokeCall(new NativeCallInfo("L_initGrid", new SymbolHandle(initGrid), DLL.findLibrary("grid")), new Object[]{gridEvalEnv}); } @Override public Object killGrid() { long killGrid = GridProvider.gridProvider().getKillGrid(); - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(new NativeCallInfo("L_killGrid", new SymbolHandle(killGrid), DLL.findLibrary("grid")), new Object[0]); + return RFFIFactory.getRFFI().getCallRFFI().callRFFINode().invokeCall(new NativeCallInfo("L_killGrid", new SymbolHandle(killGrid), DLL.findLibrary("grid")), new Object[0]); } } diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Tools.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Tools.java index fedd559f04..bd5724e4bb 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Tools.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Tools.java @@ -72,7 +72,7 @@ public class Generic_Tools implements ToolsRFFI { try { parseRdCritical.acquire(); long parseRd = ToolsProvider.toolsProvider().getParseRd(); - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(new NativeCallInfo("parseRd", new SymbolHandle(parseRd), DLL.findLibrary("tools")), + return RFFIFactory.getRFFI().getCallRFFI().callRFFINode().invokeCall(new NativeCallInfo("parseRd", new SymbolHandle(parseRd), DLL.findLibrary("tools")), new Object[]{con, srcfile, verbose, fragment, basename, warningCalls, macros, warndups}); } catch (Throwable ex) { throw RInternalError.shouldNotReachHere(ex, "error during Rd parsing"); diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Call.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Call.java index 2108c61447..8a36622c13 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Call.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Call.java @@ -49,12 +49,97 @@ import com.oracle.truffle.r.runtime.ffi.UpCallsRFFIFactory; */ public class JNI_Call implements CallRFFI { - protected JNI_Call() { - loadLibrary(); + public static class JNI_CallRFFINode extends CallRFFINode { + + @Override + @TruffleBoundary + public synchronized Object invokeCall(NativeCallInfo nativeCallInfo, Object[] args) { + long address = nativeCallInfo.address.asAddress(); + Object result = null; + if (traceEnabled()) { + traceDownCall(nativeCallInfo.name, args); + } + try { + switch (args.length) { + // @formatter:off + case 0: result = call0(address); break; + case 1: result = call1(address, args[0]); break; + case 2: result = call2(address, args[0], args[1]); break; + case 3: result = call3(address, args[0], args[1], args[2]); break; + case 4: result = call4(address, args[0], args[1], args[2], args[3]); break; + case 5: result = call5(address, args[0], args[1], args[2], args[3], args[4]); break; + case 6: result = call6(address, args[0], args[1], args[2], args[3], args[4], args[5]); break; + case 7: result = call7(address, args[0], args[1], args[2], args[3], args[4], args[5], args[6]); break; + case 8: result = call8(address, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]); break; + case 9: result = call9(address, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]); break; + default: + result = call(address, args); break; + // @formatter:on + } + return result; + } finally { + if (traceEnabled()) { + traceDownCallReturn(nativeCallInfo.name, result); + } + } + } + + @Override + @TruffleBoundary + public synchronized void invokeVoidCall(NativeCallInfo nativeCallInfo, Object[] args) { + if (traceEnabled()) { + traceDownCall(nativeCallInfo.name, args); + } + long address = nativeCallInfo.address.asAddress(); + try { + switch (args.length) { + case 0: + callVoid0(address); + break; + case 1: + callVoid1(address, args[0]); + break; + default: + throw RInternalError.shouldNotReachHere(); + } + } finally { + if (traceEnabled()) { + traceDownCallReturn(nativeCallInfo.name, null); + } + } + } + + @Override + public synchronized void setTempDir(String tempDir) { + if (traceEnabled()) { + traceDownCall("setTempDir", tempDir); + } + RFFIVariables.setTempDir(tempDir); + nativeSetTempDir(tempDir); + if (traceEnabled()) { + traceDownCallReturn("setTempDir", null); + } + } + + @Override + public synchronized void setInteractive(boolean interactive) { + if (traceEnabled()) { + traceDownCall("setInteractive", interactive); + } + nativeSetInteractive(interactive); + if (traceEnabled()) { + traceDownCallReturn("setInteractive", null); + } + } + } private static final boolean ForceRTLDGlobal = false; + protected JNI_Call() { + loadLibrary(); + } + /** * Load the {@code libR} library. N.B. this library defines some non-JNI global symbols that are * referenced by C code in R packages. Unfortunately, {@link System#load(String)} uses @@ -91,39 +176,6 @@ public class JNI_Call implements CallRFFI { } } - @Override - @TruffleBoundary - public synchronized Object invokeCall(NativeCallInfo nativeCallInfo, Object[] args) { - long address = nativeCallInfo.address.asAddress(); - Object result = null; - if (traceEnabled()) { - traceDownCall(nativeCallInfo.name, args); - } - try { - switch (args.length) { - // @formatter:off - case 0: result = call0(address); break; - case 1: result = call1(address, args[0]); break; - case 2: result = call2(address, args[0], args[1]); break; - case 3: result = call3(address, args[0], args[1], args[2]); break; - case 4: result = call4(address, args[0], args[1], args[2], args[3]); break; - case 5: result = call5(address, args[0], args[1], args[2], args[3], args[4]); break; - case 6: result = call6(address, args[0], args[1], args[2], args[3], args[4], args[5]); break; - case 7: result = call7(address, args[0], args[1], args[2], args[3], args[4], args[5], args[6]); break; - case 8: result = call8(address, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]); break; - case 9: result = call9(address, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]); break; - default: - result = call(address, args); break; - // @formatter:on - } - return result; - } finally { - if (traceEnabled()) { - traceDownCallReturn(nativeCallInfo.name, result); - } - } - } - private static native void initialize(UpCallsRFFI upCallRFFI, RFFIVariables[] variables); private static native void nativeSetTempDir(String tempDir); @@ -152,56 +204,13 @@ public class JNI_Call implements CallRFFI { private static native Object call9(long address, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, Object arg8, Object arg9); - @Override - @TruffleBoundary - public synchronized void invokeVoidCall(NativeCallInfo nativeCallInfo, Object[] args) { - if (traceEnabled()) { - traceDownCall(nativeCallInfo.name, args); - } - long address = nativeCallInfo.address.asAddress(); - try { - switch (args.length) { - case 0: - callVoid0(address); - break; - case 1: - callVoid1(address, args[0]); - break; - default: - throw RInternalError.shouldNotReachHere(); - } - } finally { - if (traceEnabled()) { - traceDownCallReturn(nativeCallInfo.name, null); - } - } - } - private static native void callVoid0(long address); private static native void callVoid1(long address, Object arg1); @Override - public synchronized void setTempDir(String tempDir) { - if (traceEnabled()) { - traceDownCall("setTempDir", tempDir); - } - RFFIVariables.setTempDir(tempDir); - nativeSetTempDir(tempDir); - if (traceEnabled()) { - traceDownCallReturn("setTempDir", null); - } - } - - @Override - public synchronized void setInteractive(boolean interactive) { - if (traceEnabled()) { - traceDownCall("setInteractive", interactive); - } - nativeSetInteractive(interactive); - if (traceEnabled()) { - traceDownCallReturn("setInteractive", null); - } + public CallRFFINode callRFFINode() { + return new JNI_CallRFFINode(); } } diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Stats.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Stats.java index 1f0564d90b..9d9c6e1867 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Stats.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Stats.java @@ -29,42 +29,52 @@ 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.StatsRFFI; -// Checkstyle: stop method name public class JNI_Stats implements StatsRFFI { - @Override - @TruffleBoundary - public void fft_factor(int n, int[] pmaxf, int[] pmaxp) { - native_fft_factor(fft_factor_address().asAddress(), n, pmaxf, pmaxp); - } - @Override - @TruffleBoundary - public int fft_work(double[] a, int nseg, int n, int nspn, int isn, double[] work, int[] iwork) { - return native_fft_work(fft_work_address().asAddress(), a, nseg, n, nspn, isn, work, iwork); - } + public static class JNI_FFTNode extends FFTNode { + private SymbolHandle fftWorkAddress; + private SymbolHandle fftFactorAddress; - private SymbolHandle fft_factor_address; - private SymbolHandle fft_work_address; + @Override + @TruffleBoundary + public int executeWork(double[] a, int nseg, int n, int nspn, int isn, double[] work, int[] iwork) { + initialize(); + return native_fft_work(fftWorkAddress.asAddress(), a, nseg, n, nspn, isn, work, iwork); + } + + @Override + @TruffleBoundary + public void executeFactor(int n, int[] pmaxf, int[] pmaxp) { + initialize(); + native_fft_factor(fftFactorAddress.asAddress(), n, pmaxf, pmaxp); - private SymbolHandle fft_factor_address() { - if (fft_factor_address == null) { - DLLInfo dllInfo = DLL.findLibrary("stats"); - fft_factor_address = RFFIFactory.getRFFI().getDLLRFFI().dlsym(dllInfo.handle, "fft_factor"); - assert fft_factor_address != DLL.SYMBOL_NOT_FOUND; } - return fft_factor_address; - } - private SymbolHandle fft_work_address() { - if (fft_work_address == null) { + private void initialize() { + if (fftWorkAddress == null) { + fftWorkAddress = fftAddress("fft_work"); + fftFactorAddress = fftAddress("fft_factor"); + } + } + + private static SymbolHandle fftAddress(String symbol) { + SymbolHandle fftAddress; DLLInfo dllInfo = DLL.findLibrary("stats"); - fft_work_address = RFFIFactory.getRFFI().getDLLRFFI().dlsym(dllInfo.handle, "fft_work"); - assert fft_work_address != DLL.SYMBOL_NOT_FOUND; + fftAddress = RFFIFactory.getRFFI().getDLLRFFI().dlsym(dllInfo.handle, symbol); + assert fftAddress != DLL.SYMBOL_NOT_FOUND; + return fftAddress; } - return fft_work_address; + } + @Override + public FFTNode fftNode() { + return new JNI_FFTNode(); + } + + // Checkstyle: stop method name private static native void native_fft_factor(long address, int n, int[] pmaxf, int[] pmaxp); private static native int native_fft_work(long address, double[] a, int nseg, int n, int nspn, int isn, double[] work, int[] iwork); + } diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/TraceUpCallsAdapter.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/TraceUpCallsAdapter.java index 461863208e..1b6d8aab81 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/TraceUpCallsAdapter.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/TraceUpCallsAdapter.java @@ -298,7 +298,7 @@ public class TraceUpCallsAdapter implements UpCallsRFFI { } @Override - public byte[] RAW(Object x) { + public Object RAW(Object x) { if (RFFIUtils.traceEnabled()) { RFFIUtils.traceUpCall("RAW", x); } @@ -306,7 +306,7 @@ public class TraceUpCallsAdapter implements UpCallsRFFI { } @Override - public byte[] LOGICAL(Object x) { + public Object LOGICAL(Object x) { if (RFFIUtils.traceEnabled()) { RFFIUtils.traceUpCall("LOGICAL", x); } @@ -314,7 +314,7 @@ public class TraceUpCallsAdapter implements UpCallsRFFI { } @Override - public int[] INTEGER(Object x) { + public Object INTEGER(Object x) { if (RFFIUtils.traceEnabled()) { RFFIUtils.traceUpCall("INTEGER", x); } @@ -322,7 +322,7 @@ public class TraceUpCallsAdapter implements UpCallsRFFI { } @Override - public double[] REAL(Object x) { + public Object REAL(Object x) { if (RFFIUtils.traceEnabled()) { RFFIUtils.traceUpCall("REAL", x); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/TempPathName.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/TempPathName.java index 050047c15b..cfea6f2476 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/TempPathName.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/TempPathName.java @@ -68,7 +68,7 @@ public class TempPathName { } else { Utils.rSuicide("cannot create 'R_TempDir'"); } - RFFIFactory.getRFFI().getCallRFFI().setTempDir(tempDirPath); + RFFIFactory.getRFFI().getCallRFFI().callRFFINode().setTempDir(tempDirPath); } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java index 63b0cf0575..1f60bc3c9a 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java @@ -547,7 +547,7 @@ public final class RContext extends ExecutionContext implements TruffleObject { this.methodTableDispatchOn = info.getParent().methodTableDispatchOn; } if (initial && !embedded) { - RFFIFactory.getRFFI().getCallRFFI().setInteractive(isInteractive()); + RFFIFactory.getRFFI().getCallRFFI().callRFFINode().setInteractive(isInteractive()); initialContextInitialized = true; } return this; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java index 3029ffce07..5930f8d17e 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java @@ -22,32 +22,38 @@ */ package com.oracle.truffle.r.runtime.ffi; +import com.oracle.truffle.api.nodes.Node; + /** * Support for the {.Call} and {.External} calls. */ public interface CallRFFI { - /** - * Invoke the native function identified by {@code symbolInfo} passing it the arguments in - * {@code args}. The values in {@code args} can be any of the types used to represent {@code R} - * values in the implementation. - */ - Object invokeCall(NativeCallInfo nativeCallInfo, Object[] args); + public abstract static class CallRFFINode extends Node { + /** + * Invoke the native function identified by {@code symbolInfo} passing it the arguments in + * {@code args}. The values in {@code args} can be any of the types used to represent + * {@code R} values in the implementation. + */ + public abstract Object invokeCall(NativeCallInfo nativeCallInfo, Object[] args); + + /** + * Variant that does not return a result (primarily for library "init" methods). + */ + public abstract void invokeVoidCall(NativeCallInfo nativeCallInfo, Object[] args); - /** - * Variant that does not return a result (primarily for library "init" methods). - */ - void invokeVoidCall(NativeCallInfo nativeCallInfo, Object[] args); + /** + * This interface is instantiated very early and sets the FFI global variables as part of + * that process. However, at that stage {@code tempDir} is not established so this call + * exists to set the value later. + */ + public abstract void setTempDir(String tempDir); - /** - * This interface is instantiated very early and sets the FFI global variables as part of that - * process. However, at that stage {@code tempDir} is not established so this call exists to set - * the value later. - */ - void setTempDir(String tempDir); + /** + * Sets the {@code R_Interactive} FFI variable. Similar rationale to {#link setTmpDir}. + */ + public abstract void setInteractive(boolean interactive); + } - /** - * Sets the {@code R_Interactive} FFI variable. Similar rationale to {#link setTmpDir}. - */ - void setInteractive(boolean interactive); + CallRFFINode callRFFINode(); } 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 bceaacfbd4..f776c52e0e 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 @@ -34,6 +34,7 @@ import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.RTruffleObject; +import com.oracle.truffle.r.runtime.ffi.CallRFFI.CallRFFINode; /** * Support for Dynamically Loaded Libraries. @@ -345,6 +346,7 @@ public class DLL { } private static final String R_INIT_PREFIX = "R_init_"; + private static CallRFFINode callRFFINode; @TruffleBoundary public static DLLInfo loadPackageDLL(String path, boolean local, boolean now) throws DLLException { @@ -355,7 +357,10 @@ public class DLL { if (initFunc != SYMBOL_NOT_FOUND) { synchronized (DLL.class) { try { - RFFIFactory.getRFFI().getCallRFFI().invokeVoidCall(new NativeCallInfo(pkgInit, initFunc, dllInfo), new Object[]{dllInfo}); + if (callRFFINode == null) { + callRFFINode = RFFIFactory.getRFFI().getCallRFFI().callRFFINode(); + } + callRFFINode.invokeVoidCall(new NativeCallInfo(pkgInit, initFunc, dllInfo), new Object[]{dllInfo}); } catch (ReturnException ex) { // An error call can, due to condition handling, throw this which we must // propogate diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StatsRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StatsRFFI.java index a796d4fb61..a6940fbd86 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StatsRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StatsRFFI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,13 +22,20 @@ */ package com.oracle.truffle.r.runtime.ffi; +import com.oracle.truffle.api.nodes.Node; + /** - * Interface to native (C) methods provided by the {@code stats} package. + * Interface to native (C) methods provided by the {@code stats} package that are used to implement + * {@code.Call(C_fft)}. The implementation is split into a Java part which calls the + * {@code fft_factor} and {@code fft_work}. functions from the GNU R C code. */ public interface StatsRFFI { - // Checkstyle: stop method name - void fft_factor(int n, int[] pmaxf, int[] pmaxp); + public abstract static class FFTNode extends Node { + public abstract void executeFactor(int n, int[] pmaxf, int[] pmaxp); + + public abstract int executeWork(double[] a, int nseg, int n, int nspn, int isn, double[] work, int[] iwork); + } - int fft_work(double[] a, int nseg, int n, int nspn, int isn, double[] work, int[] iwork); + FFTNode fftNode(); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/UpCallsRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/UpCallsRFFI.java index d643ba908f..ccfb5fa901 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/UpCallsRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/UpCallsRFFI.java @@ -116,13 +116,13 @@ public interface UpCallsRFFI { void SET_VECTOR_ELT(Object x, int i, Object v); - byte[] RAW(Object x); + Object RAW(Object x); - byte[] LOGICAL(Object x); + Object LOGICAL(Object x); - int[] INTEGER(Object x); + Object INTEGER(Object x); - double[] REAL(Object x); + Object REAL(Object x); Object STRING_ELT(Object x, int i); -- GitLab