From dd852367b3fd02015b9583445c99a158d3911db4 Mon Sep 17 00:00:00 2001 From: Florian Angerer <florian.angerer@oracle.com> Date: Thu, 21 Sep 2017 19:01:00 +0200 Subject: [PATCH] Materializing containers for '.Call'. --- .../foreign/CallAndExternalFunctions.java | 30 ++++++++++------ .../r/nodes/helpers/MaterializeNode.java | 36 +++++++++++++++++++ 2 files changed, 56 insertions(+), 10 deletions(-) create mode 100644 com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/helpers/MaterializeNode.java diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java index dd8bc94b7a..bdef66450b 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java @@ -71,6 +71,7 @@ import com.oracle.truffle.r.library.utils.TypeConvertNodeGen; import com.oracle.truffle.r.library.utils.UnzipNodeGen; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.nodes.builtin.RInternalCodeBuiltinNode; +import com.oracle.truffle.r.nodes.helpers.MaterializeNode; import com.oracle.truffle.r.nodes.objects.GetPrimNameNodeGen; import com.oracle.truffle.r.nodes.objects.NewObjectNodeGen; import com.oracle.truffle.r.runtime.FastROptions; @@ -223,6 +224,7 @@ public class CallAndExternalFunctions { public abstract static class DotCall extends LookupAdapter { @Child CallRFFI.InvokeCallNode callRFFINode = RFFIFactory.getCallRFFI().createInvokeCallNode(); + @Child MaterializeNode materializeNode = MaterializeNode.create(); static { Casts.noCasts(DotCall.class); @@ -233,6 +235,14 @@ public class CallAndExternalFunctions { return new Object[]{RMissing.instance, RArgsValuesAndNames.EMPTY, RMissing.instance}; } + private Object[] materializeArgs(VirtualFrame frame, Object[] args) { + Object[] materializedArgs = new Object[args.length]; + for (int i = 0; i < args.length; i++) { + materializedArgs[i] = materializeNode.execute(frame, args[i]); + } + return materializedArgs; + } + @Override @TruffleBoundary public RExternalBuiltinNode lookupBuiltin(RList symbol) { @@ -655,12 +665,12 @@ public class CallAndExternalFunctions { */ @SuppressWarnings("unused") @Specialization(limit = "2", guards = {"cached == symbol", "builtin == null"}) - protected Object callNamedFunction(RList symbol, RArgsValuesAndNames args, Object packageName, + protected Object callNamedFunction(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, Object packageName, @Cached("symbol") RList cached, @Cached("lookupBuiltin(symbol)") RExternalBuiltinNode builtin, @Cached("new()") ExtractNativeCallInfoNode extractSymbolInfo, @Cached("extractSymbolInfo.execute(symbol)") NativeCallInfo nativeCallInfo) { - return callRFFINode.dispatch(nativeCallInfo, args.getArguments()); + return callRFFINode.dispatch(nativeCallInfo, materializeArgs(frame, args.getArguments())); } /** @@ -669,24 +679,24 @@ public class CallAndExternalFunctions { */ @SuppressWarnings("unused") @Specialization(replaces = {"callNamedFunction", "doExternal"}) - protected Object callNamedFunctionGeneric(RList symbol, RArgsValuesAndNames args, Object packageName, + protected Object callNamedFunctionGeneric(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, Object packageName, @Cached("new()") ExtractNativeCallInfoNode extractSymbolInfo) { RExternalBuiltinNode builtin = lookupBuiltin(symbol); if (builtin != null) { throw RInternalError.shouldNotReachHere("Cache for .Calls with FastR reimplementation (lookupBuiltin(...) != null) exceeded the limit"); } NativeCallInfo nativeCallInfo = extractSymbolInfo.execute(symbol); - return callRFFINode.dispatch(nativeCallInfo, args.getArguments()); + return callRFFINode.dispatch(nativeCallInfo, materializeArgs(frame, args.getArguments())); } /** * {@code .NAME = string}, no package specified. */ @Specialization - protected Object callNamedFunction(String symbol, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName, + protected Object callNamedFunction(VirtualFrame frame, String symbol, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName, @Cached("createRegisteredNativeSymbol(CallNST)") DLL.RegisteredNativeSymbol rns, @Cached("create()") DLL.RFindSymbolNode findSymbolNode) { - return callNamedFunctionWithPackage(symbol, args, null, rns, findSymbolNode); + return callNamedFunctionWithPackage(frame, symbol, args, null, rns, findSymbolNode); } /** @@ -694,19 +704,19 @@ public class CallAndExternalFunctions { * define that symbol. */ @Specialization - protected Object callNamedFunctionWithPackage(String symbol, RArgsValuesAndNames args, String packageName, + protected Object callNamedFunctionWithPackage(VirtualFrame frame, String symbol, RArgsValuesAndNames args, String packageName, @Cached("createRegisteredNativeSymbol(CallNST)") DLL.RegisteredNativeSymbol rns, @Cached("create()") DLL.RFindSymbolNode findSymbolNode) { DLL.SymbolHandle func = findSymbolNode.execute(symbol, packageName, rns); if (func == DLL.SYMBOL_NOT_FOUND) { throw error(RError.Message.SYMBOL_NOT_IN_TABLE, symbol, "Call", packageName); } - return callRFFINode.dispatch(new NativeCallInfo(symbol, func, rns.getDllInfo()), args.getArguments()); + return callRFFINode.dispatch(new NativeCallInfo(symbol, func, rns.getDllInfo()), materializeArgs(frame, args.getArguments())); } @Specialization - protected Object callNamedFunctionWithPackage(RExternalPtr symbol, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { - return callRFFINode.dispatch(new NativeCallInfo("", symbol.getAddr(), null), args.getArguments()); + protected Object callNamedFunctionWithPackage(VirtualFrame frame, RExternalPtr symbol, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { + return callRFFINode.dispatch(new NativeCallInfo("", symbol.getAddr(), null), materializeArgs(frame, args.getArguments())); } @SuppressWarnings("unused") diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/helpers/MaterializeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/helpers/MaterializeNode.java new file mode 100644 index 0000000000..ec7c9da1e4 --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/helpers/MaterializeNode.java @@ -0,0 +1,36 @@ +package com.oracle.truffle.r.nodes.helpers; + +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; + +public abstract class MaterializeNode extends Node { + + protected static final int LIMIT = 10; + + public abstract Object execute(VirtualFrame frame, Object arg); + + @Specialization(limit = "LIMIT", guards = {"vec.getClass() == cachedClass"}) + protected RAbstractContainer doAbstractContainerCached(RAbstractContainer vec, + @SuppressWarnings("unused") @Cached("vec.getClass()") Class<?> cachedClass) { + return vec.materialize(); + } + + @Specialization(replaces = "doAbstractContainerCached") + protected RAbstractContainer doAbstractContainer(RAbstractContainer vec) { + return vec.materialize(); + } + + @Fallback + protected Object doGeneric(Object o) { + return o; + } + + public static MaterializeNode create() { + return MaterializeNodeGen.create(); + } + +} -- GitLab