From 6416123cf522a80651fa822c3ffe99c678131820 Mon Sep 17 00:00:00 2001 From: Mick Jordan <mick.jordan@oracle.com> Date: Mon, 12 Dec 2016 17:13:01 -0800 Subject: [PATCH] rffi: ensure all rffi nodes are called via RootCallTargets --- .../r/engine/RRuntimeASTAccessImpl.java | 7 +++ .../truffle/r/library/graphics/RGraphics.java | 4 +- .../r/runtime/ffi/generic/Generic_Grid.java | 5 +- .../truffle/r/runtime/ffi/jni/JNI_Call.java | 4 +- .../truffle/r/runtime/RRuntimeASTAccess.java | 7 +++ .../truffle/r/runtime/ffi/FFIRootNode.java | 59 ++++++++++++++++++ .../truffle/r/runtime/rng/user/UserRNG.java | 60 ++++++++++++++++--- mx.fastr/copyrights/overrides | 1 - 8 files changed, 131 insertions(+), 16 deletions(-) create mode 100644 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/FFIRootNode.java diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java index cc2f268bcf..161c25219a 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java @@ -33,6 +33,7 @@ import java.util.List; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.FrameInstance.FrameAccess; import com.oracle.truffle.api.nodes.Node; @@ -719,4 +720,10 @@ class RRuntimeASTAccessImpl implements RRuntimeASTAccess { public void checkDebugRequest(RFunction func) { RInstrumentation.checkDebugRequested(func); } + + @SuppressWarnings("rawtypes") + @Override + public Class<? extends TruffleLanguage> getTruffleRLanguage() { + return TruffleRLanguage.class; + } } 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 6aa3aada26..72fe424293 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 @@ -26,8 +26,8 @@ import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.ffi.DLL; +import com.oracle.truffle.r.runtime.ffi.FFIRootNode; import com.oracle.truffle.r.runtime.ffi.NativeCallInfo; -import com.oracle.truffle.r.runtime.ffi.RFFIFactory; /** * A placeholder to keep {@code REngine} limited to calling the {@link #initialize} method. Two @@ -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().createCallRFFINode().invokeVoidCall(new NativeCallInfo("InitGraphics", func, DLL.findLibrary("graphics")), new Object[0]); + FFIRootNode.createCallTarget().call(new NativeCallInfo("InitGraphics", func, DLL.findLibrary("graphics")), true, new Object[0]); } } } 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 6161b0e4e7..c2f8f6f4e6 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 @@ -26,6 +26,7 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.ffi.CallRFFI; import com.oracle.truffle.r.runtime.ffi.DLL; +import com.oracle.truffle.r.runtime.ffi.FFIRootNode; import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle; import com.oracle.truffle.r.runtime.ffi.GridRFFI; import com.oracle.truffle.r.runtime.ffi.LibPaths; @@ -70,13 +71,13 @@ public class Generic_Grid implements GridRFFI { @Override public Object initGrid(REnvironment gridEvalEnv) { long initGrid = GridProvider.gridProvider().getInitGrid(); - return callRFFINode.invokeCall(new NativeCallInfo("L_initGrid", new SymbolHandle(initGrid), DLL.findLibrary("grid")), new Object[]{gridEvalEnv}); + return FFIRootNode.createCallTarget().call(new NativeCallInfo("L_initGrid", new SymbolHandle(initGrid), DLL.findLibrary("grid")), false, new Object[]{gridEvalEnv}); } @Override public Object killGrid() { long killGrid = GridProvider.gridProvider().getKillGrid(); - return callRFFINode.invokeCall(new NativeCallInfo("L_killGrid", new SymbolHandle(killGrid), DLL.findLibrary("grid")), new Object[0]); + return FFIRootNode.createCallTarget().call(new NativeCallInfo("L_killGrid", new SymbolHandle(killGrid), DLL.findLibrary("grid")), false, new Object[0]); } } 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 c543c998c7..ee4a044a1f 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,7 +49,7 @@ import com.oracle.truffle.r.runtime.ffi.UpCallsRFFIFactory; */ public class JNI_Call implements CallRFFI { - private static class JNI_CallRFFINode extends CallRFFINode { + public static class JNI_CallRFFINode extends CallRFFINode { @Override @TruffleBoundary @@ -136,7 +136,7 @@ public class JNI_Call implements CallRFFI { private static final boolean ForceRTLDGlobal = false; - protected JNI_Call() { + public JNI_Call() { loadLibRLibrary(); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntimeASTAccess.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntimeASTAccess.java index 7a4a01cd50..835b3d36e2 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntimeASTAccess.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntimeASTAccess.java @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.runtime; +import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.r.runtime.context.Engine; @@ -90,6 +91,12 @@ public interface RRuntimeASTAccess { */ RLanguage getSyntaxCaller(RCaller rl); + /** + * Gets {@code TruffleRLanguage} avoiding project circularity. + */ + @SuppressWarnings("rawtypes") + Class<? extends TruffleLanguage> getTruffleRLanguage(); + /** * Returns a string for a call as represented by {@code rl}, returned originally by * {@link #getSyntaxCaller}. diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/FFIRootNode.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/FFIRootNode.java new file mode 100644 index 0000000000..fbc4445e00 --- /dev/null +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/FFIRootNode.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.runtime.ffi; + +import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.r.runtime.context.RContext; +import com.oracle.truffle.r.runtime.data.RNull; + +public final class FFIRootNode extends RootNode { + @Child CallRFFI.CallRFFINode callRFFINode = RFFIFactory.getRFFI().getCallRFFI().createCallRFFINode(); + + public FFIRootNode() { + super(RContext.getRRuntimeASTAccess().getTruffleRLanguage(), null, new FrameDescriptor()); + + } + + @Override + public Object execute(VirtualFrame frame) { + Object[] args = frame.getArguments(); + NativeCallInfo nativeCallInfo = (NativeCallInfo) args[0]; + boolean isVoidCall = (boolean) args[1]; + Object[] callArgs = (Object[]) args[2]; + if (isVoidCall) { + callRFFINode.invokeVoidCall(nativeCallInfo, callArgs); + return RNull.instance; + } else { + return callRFFINode.invokeCall(nativeCallInfo, callArgs); + } + } + + public static RootCallTarget createCallTarget() { + return Truffle.getRuntime().createCallTarget(new FFIRootNode()); + } + +} diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/user/UserRNG.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/user/UserRNG.java index dda0917b27..b8490dfaae 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/user/UserRNG.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/user/UserRNG.java @@ -23,7 +23,15 @@ package com.oracle.truffle.r.runtime.rng.user; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.RootNode; 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.RNull; import com.oracle.truffle.r.runtime.ffi.DLL; import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo; import com.oracle.truffle.r.runtime.ffi.RFFIFactory; @@ -67,19 +75,52 @@ public final class UserRNG implements RandomNumberGenerator { } private int nSeeds = 0; - private UserRngRFFI.UserRngRFFINode userRngRFFINode; - private UserRngRFFI.UserRngRFFINode getUserRngRFFINode() { - if (userRngRFFINode == null) { - userRngRFFINode = RFFIFactory.getRFFI().getUserRngRFFI().createUserRngRFFINode(); + private abstract static class UserRNGRootNodeAdapter extends RootNode { + @Child protected UserRngRFFI.UserRngRFFINode userRngRFFINode = RFFIFactory.getRFFI().getUserRngRFFI().createUserRngRFFINode(); + + protected UserRNGRootNodeAdapter() { + super(RContext.getRRuntimeASTAccess().getTruffleRLanguage(), null, new FrameDescriptor()); + } + } + + private static final class GenericUserRNGRootNode extends UserRNGRootNodeAdapter { + @Override + public Object execute(VirtualFrame frame) { + Object[] args = frame.getArguments(); + Function function = (Function) args[0]; + switch (function) { + case Init: + userRngRFFINode.init((int) args[1]); + return RNull.instance; + case NSeed: + return userRngRFFINode.nSeed(); + case Seedloc: + userRngRFFINode.seeds((int[]) args[1]); + return RNull.instance; + default: + throw RInternalError.shouldNotReachHere(); + } } - return userRngRFFINode; } + private static final class RandUserRNGRootNode extends UserRNGRootNodeAdapter { + + @Override + public Object execute(VirtualFrame frame) { + return userRngRFFINode.rand(); + } + + } + + private RootCallTarget callGeneric; + private RootCallTarget callRand; + @Override @TruffleBoundary public void init(int seed) { DLLInfo dllInfo = DLL.findLibraryContainingSymbol(Function.Rand.symbol); + callGeneric = Truffle.getRuntime().createCallTarget(new GenericUserRNGRootNode()); if (dllInfo == null) { throw RError.error(RError.NO_CALLER, RError.Message.RNG_SYMBOL, Function.Rand.symbol); } @@ -87,13 +128,13 @@ public final class UserRNG implements RandomNumberGenerator { f.setSymbolHandle(dllInfo); } if (Function.Init.isDefined()) { - getUserRngRFFINode().init(seed); + callGeneric.call(Function.Init, seed); } if (Function.Seedloc.isDefined() && !Function.NSeed.isDefined()) { RError.warning(RError.NO_CALLER, RError.Message.RNG_READ_SEEDS); } if (Function.NSeed.isDefined()) { - int ns = getUserRngRFFINode().nSeed(); + int ns = (int) callGeneric.call(Function.NSeed); if (ns < 0 || ns > 625) { RError.warning(RError.NO_CALLER, RError.Message.GENERIC, "seed length must be in 0...625; ignored"); } else { @@ -104,6 +145,7 @@ public final class UserRNG implements RandomNumberGenerator { */ } } + callRand = Truffle.getRuntime().createCallTarget(new RandUserRNGRootNode()); } private static DLL.SymbolHandle findSymbol(String symbol, DLLInfo dllInfo, boolean optional) { @@ -131,7 +173,7 @@ public final class UserRNG implements RandomNumberGenerator { return null; } int[] seeds = new int[nSeeds]; - getUserRngRFFINode().seeds(seeds); + callGeneric.call(Function.Seedloc, seeds); int[] result = new int[nSeeds + 1]; System.arraycopy(seeds, 0, result, 1, seeds.length); return result; @@ -139,7 +181,7 @@ public final class UserRNG implements RandomNumberGenerator { @Override public double genrandDouble() { - return getUserRngRFFINode().rand(); + return (double) callRand.call(); } @Override diff --git a/mx.fastr/copyrights/overrides b/mx.fastr/copyrights/overrides index 475db3491e..5749956835 100644 --- a/mx.fastr/copyrights/overrides +++ b/mx.fastr/copyrights/overrides @@ -152,7 +152,6 @@ com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/D com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EncodeString.java,purdue.copyright com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java,gnu_r.copyright com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CairoProps.java,gnu_r.copyright -com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/DotC.java,gnu_r.copyright com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java,gnu_r.copyright com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java,gnu_r.copyright com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Fft.java,gnu_r.copyright -- GitLab