diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java index bf2b03c42fab7464c866090374df12bf96fc89ae..025454ff93fa734c34e557a28831e9277ea022df 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java @@ -56,6 +56,9 @@ import com.oracle.truffle.r.nodes.control.BreakException; import com.oracle.truffle.r.nodes.control.NextException; import com.oracle.truffle.r.nodes.function.CallMatcherNode.CallMatcherGenericNode; import com.oracle.truffle.r.nodes.function.PromiseHelperNode; +import com.oracle.truffle.r.nodes.function.call.CallRFunctionNode; +import com.oracle.truffle.r.nodes.function.visibility.GetVisibilityNode; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.nodes.instrumentation.RInstrumentation; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.ExitException; @@ -344,6 +347,7 @@ final class REngine implements Engine, Engine.Timings { } @Override + @TruffleBoundary public Object eval(RExpression exprs, REnvironment envir, RCaller caller) { Object result = RNull.instance; for (int i = 0; i < exprs.getLength(); i++) { @@ -358,6 +362,7 @@ final class REngine implements Engine, Engine.Timings { } @Override + @TruffleBoundary public Object eval(RLanguage expr, REnvironment envir, RCaller caller) { return evalNode(expr.getRep().asRSyntaxNode(), envir, caller); } @@ -410,8 +415,7 @@ final class REngine implements Engine, Engine.Timings { newArgs[i] = PromiseHelperNode.evaluateSlowPath(null, (RPromise) arg); } } - Object[] rArgs = RArguments.create(func, caller == null ? RArguments.getCall(actualFrame) : caller, actualFrame, newArgs, null); - return func.getTarget().call(rArgs); + return CallRFunctionNode.executeSlowpath(func, caller == null ? RArguments.getCall(actualFrame) : caller, actualFrame, newArgs, null); } private Object evalNode(RSyntaxElement exprRep, REnvironment envir, RCaller caller) { @@ -472,6 +476,8 @@ final class REngine implements Engine, Engine.Timings { private final boolean topLevel; @Child private RNode body; + @Child private GetVisibilityNode visibility = GetVisibilityNode.create(); + @Child private SetVisibilityNode setVisibility = SetVisibilityNode.create(); protected AnonymousRootNode(RNode body, String description, boolean printResult, boolean topLevel) { super(TruffleRLanguage.class, null, new FrameDescriptor()); @@ -502,13 +508,14 @@ final class REngine implements Engine, Engine.Timings { assert checkResult(result); if (printResult && result != null) { assert topLevel; - if (context.isVisible()) { + if (visibility.execute(vf, context)) { printResult(result); } } if (topLevel) { RErrorHandling.printWarnings(suppressWarnings); } + setVisibility.executeEndOfFunction(vf); } catch (RError e) { CompilerDirectives.transferToInterpreter(); throw e; @@ -572,7 +579,7 @@ final class REngine implements Engine, Engine.Timings { ((RShareable) resultValue).incRefCount(); } MaterializedFrame callingFrame = REnvironment.globalEnv().getFrame(); - function.getTarget().call(RArguments.create(function, RCaller.createInvalid(callingFrame), callingFrame, new Object[]{resultValue, RMissing.instance}, null)); + CallRFunctionNode.executeSlowpath(function, RCaller.createInvalid(callingFrame), callingFrame, new Object[]{resultValue, RMissing.instance}, null); if (resultValue instanceof RShareable && !((RShareable) resultValue).isSharedPermanent()) { ((RShareable) resultValue).decRefCount(); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java index eedbc00f40bdc250d7b202b9bd51637dafde34c0..4b958b6752fedded1a7364ead804883088535605 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java @@ -22,6 +22,8 @@ */ package com.oracle.truffle.r.nodes.builtin.base; +import java.util.function.Supplier; + import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.r.nodes.RRootNode; import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; @@ -78,6 +80,7 @@ import com.oracle.truffle.r.nodes.builtin.fastr.FastrDqrls; import com.oracle.truffle.r.nodes.builtin.fastr.FastrDqrlsNodeGen; import com.oracle.truffle.r.nodes.unary.UnaryNotNode; import com.oracle.truffle.r.nodes.unary.UnaryNotNodeGen; +import com.oracle.truffle.r.runtime.RVisibility; import com.oracle.truffle.r.runtime.builtins.FastPathFactory; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RFunction; @@ -640,7 +643,11 @@ public class BasePackage extends RBuiltinPackage { ((RRootNode) function.getRootNode()).setFastPath(factory); } - private static void addFastPath(MaterializedFrame baseFrame, String name, java.util.function.Supplier<RFastPathNode> factory, Class<?> builtinNodeClass) { + private static void addFastPath(MaterializedFrame baseFrame, String name, Supplier<RFastPathNode> factory, RVisibility visibility) { + addFastPath(baseFrame, name, FastPathFactory.fromVisibility(visibility, factory)); + } + + private static void addFastPath(MaterializedFrame baseFrame, String name, Supplier<RFastPathNode> factory, Class<?> builtinNodeClass) { RBuiltin builtin = builtinNodeClass.getAnnotation(RBuiltin.class); addFastPath(baseFrame, name, FastPathFactory.fromRBuiltin(builtin, factory)); } @@ -648,16 +655,16 @@ public class BasePackage extends RBuiltinPackage { @Override public void loadOverrides(MaterializedFrame baseFrame) { super.loadOverrides(baseFrame); - addFastPath(baseFrame, "matrix", () -> MatrixFastPathNodeGen.create(null), Matrix.class); - addFastPath(baseFrame, "setdiff", () -> SetDiffFastPathNodeGen.create(null)); - addFastPath(baseFrame, "get", () -> GetFastPathNodeGen.create(null)); - addFastPath(baseFrame, "exists", () -> ExistsFastPathNodeGen.create(null), Exists.class); - addFastPath(baseFrame, "assign", () -> AssignFastPathNodeGen.create(null), Assign.class); - addFastPath(baseFrame, "is.element", () -> IsElementFastPathNodeGen.create(null)); - addFastPath(baseFrame, "integer", () -> IntegerFastPathNodeGen.create(null)); - addFastPath(baseFrame, "numeric", () -> DoubleFastPathNodeGen.create(null)); - addFastPath(baseFrame, "double", () -> DoubleFastPathNodeGen.create(null)); - addFastPath(baseFrame, "intersect", () -> IntersectFastPathNodeGen.create(null)); + addFastPath(baseFrame, "matrix", MatrixFastPathNodeGen::create, Matrix.class); + addFastPath(baseFrame, "setdiff", SetDiffFastPathNodeGen::create, RVisibility.ON); + addFastPath(baseFrame, "get", GetFastPathNodeGen::create, RVisibility.ON); + addFastPath(baseFrame, "exists", ExistsFastPathNodeGen::create, Exists.class); + addFastPath(baseFrame, "assign", AssignFastPathNodeGen::create, Assign.class); + addFastPath(baseFrame, "is.element", IsElementFastPathNodeGen::create, RVisibility.ON); + addFastPath(baseFrame, "integer", IntegerFastPathNodeGen::create, RVisibility.ON); + addFastPath(baseFrame, "numeric", DoubleFastPathNodeGen::create, RVisibility.ON); + addFastPath(baseFrame, "double", DoubleFastPathNodeGen::create, RVisibility.ON); + addFastPath(baseFrame, "intersect", IntersectFastPathNodeGen::create, RVisibility.ON); addFastPath(baseFrame, "pmax", FastPathFactory.EVALUATE_ARGS); addFastPath(baseFrame, "pmin", FastPathFactory.EVALUATE_ARGS); addFastPath(baseFrame, "cbind", FastPathFactory.FORCED_EAGER_ARGS); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BrowserFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BrowserFunctions.java index 8909bff42e888192b915661115b3544a08e45672..5fc17758347b2e04013ac321b5451e25c7bd67ec 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BrowserFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BrowserFunctions.java @@ -82,7 +82,6 @@ public class BrowserFunctions { browserState.pop(); } } - RContext.getInstance().setVisible(false); return RNull.instance; } @@ -144,7 +143,6 @@ public class BrowserFunctions { @TruffleBoundary protected RNull browserSetDebug(@SuppressWarnings("unused") int n) { // TODO implement - RContext.getInstance().setVisible(false); return RNull.instance; } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConditionFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConditionFunctions.java index 802a42cd7055631bf3f1da0e136bb82228ef228a..9e46e7859168825951c07469d325a4a38143e518 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConditionFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConditionFunctions.java @@ -11,7 +11,10 @@ */ package com.oracle.truffle.r.nodes.builtin.base; -import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.size; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue; import static com.oracle.truffle.r.runtime.RErrorHandling.getHandlerStack; import static com.oracle.truffle.r.runtime.RVisibility.OFF; import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX; @@ -27,7 +30,6 @@ import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RErrorHandling; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; @@ -82,7 +84,6 @@ public class ConditionFunctions { @SuppressWarnings("unused") @Specialization protected RNull resetCondHands(Object stack) { - RContext.getInstance().setVisible(false); // TODO throw RInternalError.unimplemented(); } @@ -177,7 +178,6 @@ public class ConditionFunctions { @Specialization protected RNull seterrmessage(String msg) { - RContext.getInstance().setVisible(false); RErrorHandling.seterrmessage(msg); return RNull.instance; } @@ -216,7 +216,6 @@ public class ConditionFunctions { @Specialization @TruffleBoundary protected RNull printDeferredWarnings() { - RContext.getInstance().setVisible(false); RErrorHandling.printDeferredWarnings(); return RNull.instance; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConnectionFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConnectionFunctions.java index f8874611fb802b6b6ff3752e363234c4a9952960..9d17ab954c923876b3a775662c9e13017684985c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConnectionFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConnectionFunctions.java @@ -22,8 +22,17 @@ */ package com.oracle.truffle.r.nodes.builtin.base; -import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*; -import static com.oracle.truffle.r.runtime.RVisibility.CUSTOM; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.equalTo; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.gte; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.lte; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.notEmpty; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.scalarStringValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.singleElement; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.trueValue; import static com.oracle.truffle.r.runtime.RVisibility.OFF; import static com.oracle.truffle.r.runtime.builtins.RBehavior.IO; import static com.oracle.truffle.r.runtime.builtins.RBehavior.READS_STATE; @@ -403,7 +412,6 @@ public abstract class ConnectionFunctions { @Specialization @TruffleBoundary protected Object open(RConnection con, String open, @SuppressWarnings("unused") boolean blocking) { - RContext.getInstance().setVisible(false); try { BaseRConnection baseConn = getBaseConnection(con); if (baseConn.isClosed()) { @@ -536,7 +544,6 @@ public abstract class ConnectionFunctions { } catch (IOException x) { throw RError.error(this, RError.Message.ERROR_WRITING_CONNECTION, x.getMessage()); } - RContext.getInstance().setVisible(false); return RNull.instance; } @@ -647,7 +654,7 @@ public abstract class ConnectionFunctions { } - @RBuiltin(name = "writeChar", visibility = CUSTOM, kind = INTERNAL, parameterNames = {"object", "con", "nchars", "sep", "useBytes"}, behavior = IO) + @RBuiltin(name = "writeChar", visibility = OFF, kind = INTERNAL, parameterNames = {"object", "con", "nchars", "sep", "useBytes"}, behavior = IO) public abstract static class WriteChar extends InternalCloseHelper { @Override protected void createCasts(CastBuilder casts) { @@ -675,7 +682,6 @@ public abstract class ConnectionFunctions { } catch (IOException x) { throw RError.error(this, RError.Message.ERROR_WRITING_CONNECTION, x.getMessage()); } - RContext.getInstance().setVisible(false); return RNull.instance; } @@ -986,7 +992,7 @@ public abstract class ConnectionFunctions { } - @RBuiltin(name = "writeBin", visibility = CUSTOM, kind = INTERNAL, parameterNames = {"object", "con", "size", "swap", "useBytes"}, behavior = IO) + @RBuiltin(name = "writeBin", visibility = OFF, kind = INTERNAL, parameterNames = {"object", "con", "size", "swap", "useBytes"}, behavior = IO) public abstract static class WriteBin extends BinRBuiltinNode { @Override @@ -1018,7 +1024,6 @@ public abstract class ConnectionFunctions { throw RError.error(this, RError.Message.ERROR_WRITING_CONNECTION, x.getMessage()); } } - RContext.getInstance().setVisible(false); return RNull.instance; } @@ -1029,7 +1034,6 @@ public abstract class ConnectionFunctions { boolean useBytes = RRuntime.fromLogical(useBytesArg); ByteBuffer buffer = writeData.execute(object, size, swap, useBytes); buffer.flip(); - RContext.getInstance().setVisible(false); return RDataFactory.createRawVector(buffer.array()); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DebugFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DebugFunctions.java index 73c025a65417598cd818d7b63951dbffee56b5a3..a4ed591f4a180e85358173bb53b0c57a4346d00d 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DebugFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DebugFunctions.java @@ -36,7 +36,6 @@ import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RNull; @@ -101,7 +100,6 @@ public class DebugFunctions { @Specialization @TruffleBoundary protected byte isDebugged(RFunction func) { - RContext.getInstance().setVisible(true); return RRuntime.asLogical(DebugHandling.isDebugged(func)); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EvalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EvalFunctions.java index 2175b5841baeaa0313282dd7634809a4bafb0ff8..d0566c15a27fa135ed742987b7967b291f9e1cc9 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EvalFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EvalFunctions.java @@ -26,6 +26,8 @@ import static com.oracle.truffle.r.runtime.RVisibility.CUSTOM; import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; +import java.beans.Visibility; + import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; @@ -34,6 +36,7 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.base.EvalFunctionsFactory.EvalEnvCastNodeGen; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.runtime.RCaller; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.builtins.RBuiltin; @@ -119,25 +122,33 @@ public class EvalFunctions { @RBuiltin(name = "eval", visibility = CUSTOM, kind = INTERNAL, parameterNames = {"expr", "envir", "enclos"}, behavior = COMPLEX) public abstract static class Eval extends RBuiltinNode { - @TruffleBoundary - protected Object doEvalBody(RCaller rCaller, Object exprArg, REnvironment envir) { - Object expr = RASTUtils.checkForRSymbol(exprArg); - - if (expr instanceof RExpression) { - return RContext.getEngine().eval((RExpression) expr, envir, rCaller); - } else if (expr instanceof RLanguage) { - return RContext.getEngine().eval((RLanguage) expr, envir, rCaller); - } else { - // just return value - return expr; - } - } + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); @Specialization protected Object doEval(VirtualFrame frame, Object expr, Object envir, Object enclos, // @Cached("createCast()") EvalEnvCast envCast) { // Note: fallback for invalid combinations of envir and enclos is in EvalEnvCastNode - return doEvalBody(RCaller.create(frame, getOriginalCall()), expr, envCast.execute(envir, enclos)); + RCaller rCaller = RCaller.create(frame, getOriginalCall()); + REnvironment envir1 = envCast.execute(envir, enclos); + Object expr1 = RASTUtils.checkForRSymbol(expr); + + if (expr1 instanceof RExpression) { + try { + return RContext.getEngine().eval((RExpression) expr1, envir1, rCaller); + } finally { + visibility.executeAfterCall(frame); + } + } else if (expr1 instanceof RLanguage) { + try { + return RContext.getEngine().eval((RLanguage) expr1, envir1, rCaller); + } finally { + visibility.executeAfterCall(frame); + } + } else { + // just return value + visibility.execute(frame, true); + return expr1; + } } protected EvalEnvCast createCast() { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetFunctions.java index 1898de31ae2fd9d3eda061feeecdc2c30566c106..932d169e1beb658373a7a3e03bf2c4c9ab47b98f 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetFunctions.java @@ -35,8 +35,6 @@ import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.ValueProfile; -import com.oracle.truffle.r.nodes.CallInlineCacheNode; -import com.oracle.truffle.r.nodes.CallInlineCacheNodeGen; import com.oracle.truffle.r.nodes.RRootNode; import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; import com.oracle.truffle.r.nodes.attributes.TypeFromModeNode; @@ -46,7 +44,8 @@ import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.function.FormalArguments; import com.oracle.truffle.r.nodes.function.PromiseHelperNode; import com.oracle.truffle.r.nodes.function.RCallerHelper; -import com.oracle.truffle.r.nodes.function.signature.RArgumentsNode; +import com.oracle.truffle.r.nodes.function.call.CallRFunctionCachedNode; +import com.oracle.truffle.r.nodes.function.call.CallRFunctionCachedNodeGen; import com.oracle.truffle.r.nodes.objects.GetS4DataSlot; import com.oracle.truffle.r.nodes.objects.GetS4DataSlotNodeGen; import com.oracle.truffle.r.runtime.ArgumentsSignature; @@ -224,8 +223,7 @@ public class GetFunctions { private final BranchProfile wrongLengthErrorProfile = BranchProfile.create(); @Child private TypeFromModeNode typeFromMode = TypeFromModeNodeGen.create(); - @Child private CallInlineCacheNode callCache = CallInlineCacheNodeGen.create(); - @Child private RArgumentsNode argsNode; + @Child private CallRFunctionCachedNode callCache = CallRFunctionCachedNodeGen.create(2); @CompilationFinal private boolean needsCallerFrame; @@ -337,15 +335,11 @@ public class GetFunctions { CompilerDirectives.transferToInterpreterAndInvalidate(); needsCallerFrame = true; } - if (argsNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - argsNode = insert(RArgumentsNode.create()); - } MaterializedFrame callerFrame = needsCallerFrame ? frame.materialize() : null; FormalArguments formals = ((RRootNode) ifnFunc.getRootNode()).getFormalArguments(); RArgsValuesAndNames args = new RArgsValuesAndNames(new Object[]{x}, ArgumentsSignature.empty(1)); - Object[] callArgs = argsNode.execute(ifnFunc, RCaller.create(frame, RCallerHelper.createFromArguments(ifnFunc, args)), callerFrame, new Object[]{x}, formals.getSignature(), null); - return callCache.execute(frame, ifnFunc.getTarget(), callArgs); + return callCache.execute(frame, ifnFunc, RCaller.create(frame, RCallerHelper.createFromArguments(ifnFunc, args)), callerFrame, new Object[]{x}, formals.getSignature(), + ifnFunc.getEnclosingFrame(), null); } } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java index 0de9b7a77ce26cbf755439f550204af27a035556..4359d6faa7feb74f933cf8ebfb413b8c95a84535 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java @@ -11,7 +11,9 @@ */ package com.oracle.truffle.r.nodes.builtin.base; -import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue; import static com.oracle.truffle.r.runtime.RVisibility.OFF; import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX; import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; @@ -31,8 +33,6 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.LoopNode; -import com.oracle.truffle.r.nodes.CallInlineCacheNode; -import com.oracle.truffle.r.nodes.CallInlineCacheNodeGen; import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.access.ConstantNode; import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; @@ -41,7 +41,8 @@ import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.base.EvalFunctions.Eval; import com.oracle.truffle.r.nodes.function.PromiseHelperNode; import com.oracle.truffle.r.nodes.function.RCallNode; -import com.oracle.truffle.r.runtime.RArguments; +import com.oracle.truffle.r.nodes.function.call.CallRFunctionCachedNode; +import com.oracle.truffle.r.nodes.function.call.CallRFunctionCachedNodeGen; import com.oracle.truffle.r.runtime.RCaller; import com.oracle.truffle.r.runtime.RCompression; import com.oracle.truffle.r.runtime.RDeparse; @@ -187,7 +188,7 @@ public class HiddenInternalFunctions { @RBuiltin(name = "lazyLoadDBfetch", kind = PRIMITIVE, parameterNames = {"key", "datafile", "compressed", "envhook"}, behavior = PURE) public abstract static class LazyLoadDBFetch extends RBuiltinNode { - @Child private CallInlineCacheNode callCache = CallInlineCacheNodeGen.create(); + @Child private CallRFunctionCachedNode callCache = CallRFunctionCachedNodeGen.create(2); @Override protected void createCasts(CastBuilder casts) { @@ -254,8 +255,7 @@ public class HiddenInternalFunctions { RSerialize.CallHook callHook = new RSerialize.CallHook() { @Override public Object eval(Object arg) { - Object[] callArgs = RArguments.create(envhook, RCaller.create(frame, getOriginalCall()), null, new Object[]{arg}, null); - return callCache.execute(SubstituteVirtualFrame.create(frame), envhook.getTarget(), callArgs); + return callCache.execute(SubstituteVirtualFrame.create(frame), envhook, RCaller.create(frame, getOriginalCall()), null, new Object[]{arg}, null); } }; String functionName = ReadVariableNode.getSlowPathEvaluationName(); @@ -356,7 +356,7 @@ public class HiddenInternalFunctions { @RBuiltin(name = "lazyLoadDBinsertValue", kind = INTERNAL, parameterNames = {"value", "file", "ascii", "compsxp", "hook"}, behavior = COMPLEX) public abstract static class LazyLoadDBinsertValue extends RBuiltinNode { - @Child private CallInlineCacheNode callCache = CallInlineCacheNodeGen.create(); + @Child private CallRFunctionCachedNode callCache = CallRFunctionCachedNodeGen.create(2); @Override protected void createCasts(CastBuilder casts) { @@ -378,8 +378,7 @@ public class HiddenInternalFunctions { RSerialize.CallHook callHook = new RSerialize.CallHook() { @Override public Object eval(Object arg) { - Object[] callArgs = RArguments.create(hook, RCaller.create(frame, getOriginalCall()), null, new Object[]{arg}, null); - return callCache.execute(SubstituteVirtualFrame.create(frame), hook.getTarget(), callArgs); + return callCache.execute(SubstituteVirtualFrame.create(frame), hook, RCaller.create(frame, getOriginalCall()), null, new Object[]{arg}, null); } }; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/OptionsFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/OptionsFunctions.java index 3a6bc80e944456c0f3c0a92a392589bb391cdd28..e07c62fc6864be8d98a9b1f85987947533f8dcfc 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/OptionsFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/OptionsFunctions.java @@ -34,9 +34,11 @@ import java.util.Set; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; 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.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; @@ -62,6 +64,8 @@ public class OptionsFunctions { @RBuiltin(name = "options", visibility = CUSTOM, kind = INTERNAL, parameterNames = {"..."}, behavior = MODIFIES_STATE) public abstract static class Options extends RBuiltinNode { + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); + private final ConditionProfile argNameNull = ConditionProfile.createBinaryProfile(); private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); @@ -85,81 +89,104 @@ public class OptionsFunctions { return options(RMissing.instance); } + private static final class InvisibleResult extends Throwable { + private static final long serialVersionUID = 5767688593421435507L; + + private final RList value; + + protected InvisibleResult(RList value) { + this.value = value; + } + } + @Specialization(guards = "!isMissing(args)") - @TruffleBoundary - protected Object options(RArgsValuesAndNames args) { + protected Object options(VirtualFrame frame, RArgsValuesAndNames args) { try { - ROptions.ContextStateImpl options = RContext.getInstance().stateROptions; - Object[] values = args.getArguments(); - ArgumentsSignature signature = args.getSignature(); - Object[] data = new Object[values.length]; - String[] names = new String[values.length]; - for (int i = 0; i < values.length; i++) { - String argName = signature.getName(i); - Object value = values[i]; - if (argNameNull.profile(argName == null)) { - // getting - String optionName = null; - if (value instanceof RStringVector) { - // ignore rest (cf GnuR) - optionName = ((RStringVector) value).getDataAt(0); - } else if (value instanceof String) { - optionName = (String) value; - } else if (value instanceof RList) { - // setting - RList list = (RList) value; - RStringVector thisListnames = null; - Object nn = list.getNames(attrProfiles); - if (nn instanceof RStringVector) { - thisListnames = (RStringVector) nn; - } else { - throw RInternalError.shouldNotReachHere(); - } - Object[] listData = new Object[list.getLength()]; - String[] listNames = new String[listData.length]; - for (int j = 0; j < listData.length; j++) { - String name = thisListnames.getDataAt(j); - Object previousVal = options.getValue(name); - listData[j] = previousVal == null ? RNull.instance : previousVal; - listNames[j] = name; - options.setValue(name, list.getDataAtAsObject(j)); - } - // if this is the only argument, no need to copy, can just return - if (values.length == 1) { - data = listData; - names = listNames; - break; - } else { - // resize and copy - int newSize = values.length - 1 + listData.length; - Object[] newData = new Object[newSize]; - String[] newNames = new String[newSize]; - System.arraycopy(data, 0, newData, 0, i); - System.arraycopy(names, 0, newNames, 0, i); - System.arraycopy(listData, 0, newData, i, listData.length); - System.arraycopy(listNames, 0, newNames, i, listNames.length); - data = newData; - names = newNames; - } + return optionsInternal(args); + } catch (OptionsException ex) { + throw RError.error(this, ex); + } catch (InvisibleResult ex) { + visibility.execute(frame, false); + return ex.value; + } + } + + @TruffleBoundary + private Object optionsInternal(RArgsValuesAndNames args) throws OptionsException, InvisibleResult { + boolean invisible = false; + ROptions.ContextStateImpl options = RContext.getInstance().stateROptions; + Object[] values = args.getArguments(); + ArgumentsSignature signature = args.getSignature(); + Object[] data = new Object[values.length]; + String[] names = new String[values.length]; + for (int i = 0; i < values.length; i++) { + String argName = signature.getName(i); + Object value = values[i]; + if (argNameNull.profile(argName == null)) { + // getting + String optionName = null; + if (value instanceof RStringVector) { + // ignore rest (cf GnuR) + optionName = ((RStringVector) value).getDataAt(0); + } else if (value instanceof String) { + optionName = (String) value; + } else if (value instanceof RList) { + // setting + RList list = (RList) value; + RStringVector thisListnames = null; + Object nn = list.getNames(attrProfiles); + if (nn instanceof RStringVector) { + thisListnames = (RStringVector) nn; } else { - throw RError.error(this, Message.INVALID_UNNAMED_ARGUMENT); + throw RInternalError.shouldNotReachHere(); + } + Object[] listData = new Object[list.getLength()]; + String[] listNames = new String[listData.length]; + for (int j = 0; j < listData.length; j++) { + String name = thisListnames.getDataAt(j); + Object previousVal = options.getValue(name); + listData[j] = previousVal == null ? RNull.instance : previousVal; + listNames[j] = name; + options.setValue(name, list.getDataAtAsObject(j)); + } + // if this is the only argument, no need to copy, can just return + if (values.length == 1) { + data = listData; + names = listNames; + break; + } else { + // resize and copy + int newSize = values.length - 1 + listData.length; + Object[] newData = new Object[newSize]; + String[] newNames = new String[newSize]; + System.arraycopy(data, 0, newData, 0, i); + System.arraycopy(names, 0, newNames, 0, i); + System.arraycopy(listData, 0, newData, i, listData.length); + System.arraycopy(listNames, 0, newNames, i, listNames.length); + data = newData; + names = newNames; } - Object optionVal = options.getValue(optionName); - data[i] = optionVal == null ? RNull.instance : optionVal; - names[i] = optionName; } else { - // setting - Object previousVal = options.getValue(argName); - data[i] = previousVal == null ? RNull.instance : previousVal; - names[i] = argName; - options.setValue(argName, value); - // any settings means result is invisible - RContext.getInstance().setVisible(false); + throw RError.error(this, Message.INVALID_UNNAMED_ARGUMENT); } + Object optionVal = options.getValue(optionName); + data[i] = optionVal == null ? RNull.instance : optionVal; + names[i] = optionName; + } else { + // setting + Object previousVal = options.getValue(argName); + data[i] = previousVal == null ? RNull.instance : previousVal; + names[i] = argName; + options.setValue(argName, value); + // any settings means result is invisible + invisible = true; } - return RDataFactory.createList(data, RDataFactory.createStringVector(names, RDataFactory.COMPLETE_VECTOR)); - } catch (OptionsException ex) { - throw RError.error(this, ex); + } + RList result = RDataFactory.createList(data, RDataFactory.createStringVector(names, RDataFactory.COMPLETE_VECTOR)); + if (invisible) { + throw new InvisibleResult(result); + } else { + return result; } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Switch.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Switch.java index a787025f2617d7a6391e07ee7ebdecd662bc5ad3..c41df4be78fcdfafbb4cb032d0a9a36ee8effe05 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Switch.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Switch.java @@ -23,13 +23,13 @@ import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.function.PromiseHelperNode.PromiseCheckHelperNode; import com.oracle.truffle.r.nodes.function.RMissingHelper; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.nodes.unary.CastIntegerNode; import com.oracle.truffle.r.nodes.unary.CastIntegerNodeGen; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RDeparse; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.RNull; @@ -46,8 +46,10 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; */ @RBuiltin(name = "switch", visibility = CUSTOM, kind = PRIMITIVE, parameterNames = {"EXPR", "..."}, nonEvalArgs = 1, behavior = COMPLEX) public abstract class Switch extends RBuiltinNode { + @Child private CastIntegerNode castIntNode; @Child private PromiseCheckHelperNode promiseHelper = new PromiseCheckHelperNode(); + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); private final BranchProfile suppliedArgNameIsEmpty = BranchProfile.create(); private final BranchProfile suppliedArgNameIsNull = BranchProfile.create(); @@ -61,7 +63,7 @@ public abstract class Switch extends RBuiltinNode { if (x.getLength() != 1) { throw RError.error(this, RError.Message.EXPR_NOT_LENGTH_ONE); } - return prepareResult(doSwitchString(frame, x, optionalArgs)); + return prepareResult(frame, doSwitchString(frame, x, optionalArgs)); } private Object doSwitchString(VirtualFrame frame, RAbstractStringVector x, RArgsValuesAndNames optionalArgs) { @@ -130,7 +132,7 @@ public abstract class Switch extends RBuiltinNode { @Specialization protected Object doSwitch(VirtualFrame frame, int x, RArgsValuesAndNames optionalArgs) { - return prepareResult(doSwitchInt(frame, x, optionalArgs)); + return prepareResult(frame, doSwitchInt(frame, x, optionalArgs)); } @Specialization @@ -144,7 +146,7 @@ public abstract class Switch extends RBuiltinNode { notIntType.enter(); return null; } - return prepareResult(doSwitchInt(frame, (int) objIndex, optionalArgs)); + return prepareResult(frame, doSwitchInt(frame, (int) objIndex, optionalArgs)); } @SuppressWarnings("unused") @@ -166,12 +168,12 @@ public abstract class Switch extends RBuiltinNode { return null; } - private Object prepareResult(Object value) { + private Object prepareResult(VirtualFrame frame, Object value) { if (returnValueProfile.profile(value != null)) { - RContext.getInstance().setVisible(true); + visibility.execute(frame, true); return value; } else { - RContext.getInstance().setVisible(false); + visibility.execute(frame, false); return RNull.instance; } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TraceFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TraceFunctions.java index 2e5c2fa33b531583efbed165f3775d95bc0f21ad..3d86ab3e90c3fa99372e58729130d0555f52e82c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TraceFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TraceFunctions.java @@ -45,6 +45,7 @@ import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.base.GetFunctionsFactory.GetNodeGen; import com.oracle.truffle.r.nodes.builtin.helpers.TraceHandling; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.runtime.RArguments; import com.oracle.truffle.r.runtime.RCaller; import com.oracle.truffle.r.runtime.RError; @@ -227,25 +228,28 @@ public class TraceFunctions { */ @RBuiltin(name = "retracemem", kind = PRIMITIVE, visibility = CUSTOM, parameterNames = {"x", "previous"}, behavior = COMPLEX) public abstract static class Retracemem extends TracememBase { + + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); + @Override protected void createCasts(CastBuilder casts) { casts.arg("previous").defaultError(Message.INVALID_ARGUMENT, "previous").mustBe(stringValue().or(missingValue())); } @Specialization - protected Object execute(Object x, @SuppressWarnings("unused") RNull previous) { - return getResult(x); + protected Object execute(VirtualFrame frame, Object x, @SuppressWarnings("unused") RNull previous) { + return getResult(frame, x); } @Specialization - protected Object execute(Object x, @SuppressWarnings("unused") RMissing previous) { - return getResult(x); + protected Object execute(VirtualFrame frame, Object x, @SuppressWarnings("unused") RMissing previous) { + return getResult(frame, x); } @Specialization - @TruffleBoundary - protected Object execute(Object x, String previous) { - Object result = getResult(x); + protected Object execute(VirtualFrame frame, Object x, String previous) { + CompilerDirectives.transferToInterpreter(); + Object result = getResult(frame, x); if (x != null && x != RNull.instance) { startTracing(x); printToStdout(String.format("tracemem[%s -> 0x%x]: %s", previous, x.hashCode(), getStackTrace())); @@ -253,13 +257,12 @@ public class TraceFunctions { return result; } - @TruffleBoundary - private static Object getResult(Object x) { + private Object getResult(VirtualFrame frame, Object x) { if (!isRNull(x) && getTracedObjects().contains(x)) { - RContext.getInstance().setVisible(true); + visibility.execute(frame, true); return formatHashCode(x); } else { - RContext.getInstance().setVisible(false); + visibility.execute(frame, false); return RNull.instance; } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateSlot.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateSlot.java index b549fede5a4879ec25b1cc2f1f3c9e40dea1a39e..e6364e915a043a587e286376cb0922cc22152526 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateSlot.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateSlot.java @@ -18,11 +18,9 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.DirectCallNode; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.access.ConstantNode; import com.oracle.truffle.r.nodes.access.UpdateSlotNode; @@ -33,7 +31,7 @@ import com.oracle.truffle.r.nodes.function.ClassHierarchyNode; import com.oracle.truffle.r.nodes.function.ClassHierarchyNodeGen; import com.oracle.truffle.r.nodes.function.RCallNode; import com.oracle.truffle.r.nodes.function.WrapArgumentNode; -import com.oracle.truffle.r.nodes.function.signature.RArgumentsNode; +import com.oracle.truffle.r.nodes.function.call.CallRFunctionNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RCaller; import com.oracle.truffle.r.runtime.RError; @@ -55,8 +53,7 @@ public abstract class UpdateSlot extends RBuiltinNode { @Child private ClassHierarchyNode valClassHierarchy; @Child private UpdateSlotNode updateSlotNode = com.oracle.truffle.r.nodes.access.UpdateSlotNodeGen.create(null, null, null); @Child private ReadVariableNode checkAtAssignmentFind = ReadVariableNode.createFunctionLookup(RSyntaxNode.INTERNAL, "checkAtAssignment"); - @Child private DirectCallNode checkAtAssignmentCall; - @Child private RArgumentsNode argsNode = RArgumentsNode.create(); + @Child private CallRFunctionNode checkAtAssignmentCall; private final ConditionProfile cached = ConditionProfile.createBinaryProfile(); @Override @@ -93,7 +90,7 @@ public abstract class UpdateSlot extends RBuiltinNode { if (checkSlotAssignFunction == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); checkSlotAssignFunction = (RFunction) checkAtAssignmentFind.execute(frame); - checkAtAssignmentCall = insert(Truffle.getRuntime().createDirectCallNode(checkSlotAssignFunction.getTarget())); + checkAtAssignmentCall = insert(CallRFunctionNode.create(checkSlotAssignFunction.getTarget())); assert objClassHierarchy == null && valClassHierarchy == null; objClassHierarchy = insert(ClassHierarchyNodeGen.create(true, false)); valClassHierarchy = insert(ClassHierarchyNodeGen.create(true, false)); @@ -105,8 +102,8 @@ public abstract class UpdateSlot extends RBuiltinNode { if (cached.profile(currentFunction == checkSlotAssignFunction)) { // TODO: technically, someone could override checkAtAssignment function and access the // caller, but it's rather unlikely - Object[] args = argsNode.execute(checkSlotAssignFunction, RCaller.create(frame, getOriginalCall()), null, new Object[]{objClass, name, valClass}, SIGNATURE, null); - checkAtAssignmentCall.call(frame, args); + checkAtAssignmentCall.execute(frame, checkSlotAssignFunction, RCaller.create(frame, getOriginalCall()), null, new Object[]{objClass, name, valClass}, SIGNATURE, + checkSlotAssignFunction.getEnclosingFrame(), null); } else { // slow path RContext.getEngine().evalFunction(currentFunction, frame.materialize(), RCaller.create(frame, getOriginalCall()), null, objClass, name, valClass); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/WithVisible.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/WithVisible.java index ac1c17063144512e320092bfa7a4193bdf381e4f..8146e8d738e69121fe5a4f05d33c88a5bd2534ab 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/WithVisible.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/WithVisible.java @@ -22,18 +22,20 @@ */ package com.oracle.truffle.r.nodes.builtin.base; -import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.missingValue; import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; +import com.oracle.truffle.r.nodes.function.visibility.GetVisibilityNode; import com.oracle.truffle.r.runtime.FastROptions; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RStringVector; @@ -44,7 +46,8 @@ import com.oracle.truffle.r.runtime.data.RStringVector; // set noEvalArgs and evaluate the argument here and set the visibility explicitly. @RBuiltin(name = "withVisible", kind = PRIMITIVE, parameterNames = "x", behavior = COMPLEX) public abstract class WithVisible extends RBuiltinNode { - private static final RStringVector LISTNAMES = RDataFactory.createStringVector(new String[]{"value", "visible"}, RDataFactory.COMPLETE_VECTOR); + + private static final RStringVector LISTNAMES = (RStringVector) RDataFactory.createStringVector(new String[]{"value", "visible"}, RDataFactory.COMPLETE_VECTOR).makeSharedPermanent(); @Override protected void createCasts(CastBuilder casts) { @@ -52,13 +55,13 @@ public abstract class WithVisible extends RBuiltinNode { } @Specialization - protected RList withVisible(Object x) { + protected RList withVisible(VirtualFrame frame, Object x, + @Cached("create()") GetVisibilityNode visibility) { if (FastROptions.IgnoreVisibility.getBooleanValue()) { RError.warning(this, RError.Message.GENERIC, "using withVisible with IgnoreVisibility"); } - Object[] data = new Object[]{x, RRuntime.asLogical(RContext.getInstance().isVisible())}; + Object[] data = new Object[]{x, RRuntime.asLogical(visibility.execute(frame))}; return RDataFactory.createList(data, LISTNAMES); } - } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/fastpaths/IntersectFastPath.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/fastpaths/IntersectFastPath.java index 266a77c09afda2c9ae1f0b2bbc0f60061aec8be8..e0f1161c1d5415edda8156fef193ab9269f7bafa 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/fastpaths/IntersectFastPath.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/fastpaths/IntersectFastPath.java @@ -32,6 +32,7 @@ import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.nodes.RFastPathNode; +import com.oracle.truffle.r.runtime.nodes.RNode; public abstract class IntersectFastPath extends RFastPathNode { @@ -44,7 +45,7 @@ public abstract class IntersectFastPath extends RFastPathNode { @Cached("createBinaryProfile()") ConditionProfile resultLengthMatchProfile) { int xLength = x.getLength(); int yLength = y.getLength(); - reportWork(xLength + yLength); + RNode.reportWork(this, xLength + yLength); int count = 0; int[] result = EMPTY_INT_ARRAY; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/fastpaths/IsElementFastPath.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/fastpaths/IsElementFastPath.java index 19e6b1b609cf8b61fd8bb25aaa6198178b6a180b..63a1876788b7fe1d3456d3f6d7febe0c2bf550f5 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/fastpaths/IsElementFastPath.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/fastpaths/IsElementFastPath.java @@ -28,7 +28,6 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RIntSequence; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; @@ -42,7 +41,6 @@ public abstract class IsElementFastPath extends RFastPathNode { protected Byte iselementOne(RAbstractStringVector el, RAbstractStringVector set, // @Cached("create()") BranchProfile trueProfile, // @Cached("create()") BranchProfile falseProfile) { - RContext.getInstance().setVisible(true); String element = el.getDataAt(0); int length = set.getLength(); for (int i = 0; i < length; i++) { @@ -57,7 +55,6 @@ public abstract class IsElementFastPath extends RFastPathNode { @Specialization protected Byte iselementOne(double el, double set) { - RContext.getInstance().setVisible(true); return RRuntime.asLogical(el == set); } @@ -65,7 +62,6 @@ public abstract class IsElementFastPath extends RFastPathNode { protected Byte iselementOne(RAbstractDoubleVector el, RAbstractDoubleVector set, // @Cached("create()") BranchProfile trueProfile, // @Cached("create()") BranchProfile falseProfile) { - RContext.getInstance().setVisible(true); double element = el.getDataAt(0); int length = set.getLength(); for (int i = 0; i < length; i++) { @@ -81,7 +77,6 @@ public abstract class IsElementFastPath extends RFastPathNode { @Specialization(guards = "el.getLength() == 1") protected Byte isElementOneSequence(RAbstractDoubleVector el, RIntSequence set, // @Cached("createBinaryProfile()") ConditionProfile profile) { - RContext.getInstance().setVisible(true); double element = el.getDataAt(0); return RRuntime.asLogical(profile.profile(element >= set.getStart() && element <= set.getEnd())); } @@ -91,7 +86,6 @@ public abstract class IsElementFastPath extends RFastPathNode { @Cached("create()") NACheck na, // @Cached("create()") BranchProfile trueProfile, // @Cached("create()") BranchProfile falseProfile) { - RContext.getInstance().setVisible(true); double element = el.getDataAt(0); int length = set.getLength(); na.enable(set); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/system/ProcessSystemFunctionFactory.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/system/ProcessSystemFunctionFactory.java index 9be9ca380beaadf2f9c20a535849aadaeeb19a91..d0812bf2d2bd663a8aee3497d2693f17540faeac 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/system/ProcessSystemFunctionFactory.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/system/ProcessSystemFunctionFactory.java @@ -88,7 +88,6 @@ public class ProcessSystemFunctionFactory extends SystemFunctionFactory { } catch (InterruptedException | IOException ex) { result = 127; } - RContext.getInstance().setVisible(false); return result; } @@ -103,5 +102,4 @@ public class ProcessSystemFunctionFactory extends SystemFunctionFactory { } } } - } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/system/SystemFunction.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/system/SystemFunction.java index 2b4d464807199ebf0eaf6898ce640aea8f900333..237680183ca9549ace6ee66251443453c425c694 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/system/SystemFunction.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/system/SystemFunction.java @@ -24,7 +24,7 @@ package com.oracle.truffle.r.nodes.builtin.base.system; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean; -import static com.oracle.truffle.r.runtime.RVisibility.CUSTOM; +import static com.oracle.truffle.r.runtime.RVisibility.OFF; import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; @@ -35,7 +35,7 @@ import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -@RBuiltin(name = "system", visibility = CUSTOM, kind = INTERNAL, parameterNames = {"command", "intern"}, behavior = COMPLEX) +@RBuiltin(name = "system", visibility = OFF, kind = INTERNAL, parameterNames = {"command", "intern"}, behavior = COMPLEX) public abstract class SystemFunction extends RBuiltinNode { @Override protected void createCasts(CastBuilder casts) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRTrace.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRTrace.java index 470f42fd0914c3dffa37ffd4c107dbf93857b17c..09ce4a2d89bc135a7f791928fabeda2656693483 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRTrace.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRTrace.java @@ -43,6 +43,7 @@ import com.oracle.truffle.r.nodes.builtin.base.TraceFunctions; import com.oracle.truffle.r.nodes.builtin.base.TraceFunctionsFactory.PrimTraceNodeGen; import com.oracle.truffle.r.nodes.builtin.base.TraceFunctionsFactory.PrimUnTraceNodeGen; import com.oracle.truffle.r.nodes.builtin.helpers.TraceHandling; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.nodes.unary.CastLogicalNode; import com.oracle.truffle.r.nodes.unary.CastLogicalNodeGen; import com.oracle.truffle.r.runtime.ArgumentsSignature; @@ -50,7 +51,6 @@ import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RLanguage; @@ -114,6 +114,7 @@ public class FastRTrace { @Child private TraceFunctions.PrimTrace primTrace; @Child private CastLogicalNode castLogical; + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); @Specialization protected Object trace(VirtualFrame frame, Object whatObj, Object tracer, Object exit, Object at, Object printObj, Object signature, Object whereObj) { @@ -137,7 +138,7 @@ public class FastRTrace { } Object result = primTrace.execute(frame, func); - RContext.getInstance().setVisible(false); + visibility.execute(frame, false); return result; } @@ -153,7 +154,7 @@ public class FastRTrace { print = RRuntime.fromLogical((byte) castLogical.execute(printObj)); } complexCase(func, tracer, exit, at, print, signature); - RContext.getInstance().setVisible(true); + visibility.execute(frame, true); return func.toString(); } @@ -181,7 +182,6 @@ public class FastRTrace { @Specialization protected Object untrace(VirtualFrame frame, Object whatObj, Object signature, Object whereObj) { - RContext.getInstance().setVisible(false); Object what = whatObj; checkWhat(what); Object where = whereObj; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/CallInlineCacheNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/CallInlineCacheNode.java deleted file mode 100644 index 6bffe4ce0c9fc7181d61d8afcdc0ff94efbab026..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/CallInlineCacheNode.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2014, 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.nodes; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.DirectCallNode; -import com.oracle.truffle.api.nodes.IndirectCallNode; -import com.oracle.truffle.r.runtime.nodes.RBaseNode; - -/** - * This node reifies a runtime object into the AST by creating nodes for frequently encountered - * values. This can be used to bridge the gap between code as runtime data and executed code. - */ -public abstract class CallInlineCacheNode extends RBaseNode { - - protected static final int CACHE_LIMIT = 2; - - public abstract Object execute(VirtualFrame frame, CallTarget target, Object[] arguments); - - protected static DirectCallNode createDirectCallNode(CallTarget target) { - return Truffle.getRuntime().createDirectCallNode(target); - } - - @Specialization(guards = "target == callNode.getCallTarget()", limit = "CACHE_LIMIT") - protected Object call(VirtualFrame frame, @SuppressWarnings("unused") CallTarget target, Object[] arguments, @Cached("createDirectCallNode(target)") DirectCallNode callNode) { - return callNode.call(frame, arguments); - } - - protected static IndirectCallNode createIndirectCallNode() { - return Truffle.getRuntime().createIndirectCallNode(); - } - - @Specialization - protected Object call(VirtualFrame frame, CallTarget target, Object[] arguments, @Cached("createIndirectCallNode()") IndirectCallNode callNode) { - return callNode.call(frame, target, arguments); - } -} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java index 9c7b5454cdc538f3551c5189d26152b33ec2b7cb..deb90eb6641880a7f0b5834f9f7ebd219453608d 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java @@ -50,9 +50,10 @@ public abstract class AccessSlotNode extends RNode { public abstract Object executeAccess(Object o, String name); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); @Child private ClassHierarchyNode classHierarchy; @Child private TypeofNode typeofNode; + + private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); private final BranchProfile noSlot = BranchProfile.create(); private final BranchProfile symbolValue = BranchProfile.create(); private final boolean asOperator; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/ConstantNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/ConstantNode.java index e7b17317c98683c229cd58afcb8d281a9b34f8c7..d9d3c1c69ac25b7d6d66ef876a35b4a37152f71c 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/ConstantNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/ConstantNode.java @@ -25,9 +25,9 @@ package com.oracle.truffle.r.nodes.access; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RSerialize; -import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.RPromise; @@ -40,6 +40,8 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; public abstract class ConstantNode extends RSourceSectionNode implements RSyntaxNode, RSyntaxConstant { + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); + private ConstantNode(SourceSection sourceSection) { super(sourceSection); } @@ -59,9 +61,13 @@ public abstract class ConstantNode extends RSourceSectionNode implements RSyntax @Override public abstract Object getValue(); + protected final void handleVisibility(VirtualFrame frame) { + visibility.execute(frame, true); + } + @Override public final Object execute(VirtualFrame frame) { - RContext.getInstance().setVisible(true); + handleVisibility(frame); return getValue(); } @@ -113,7 +119,7 @@ public abstract class ConstantNode extends RSourceSectionNode implements RSyntax @Override public double executeDouble(VirtualFrame frame) { - RContext.getInstance().setVisible(true); + handleVisibility(frame); return doubleValue; } } @@ -136,7 +142,7 @@ public abstract class ConstantNode extends RSourceSectionNode implements RSyntax @Override public byte executeByte(VirtualFrame frame) { - RContext.getInstance().setVisible(true); + handleVisibility(frame); return logicalValue; } } @@ -159,7 +165,7 @@ public abstract class ConstantNode extends RSourceSectionNode implements RSyntax @Override public int executeInteger(VirtualFrame frame) { - RContext.getInstance().setVisible(true); + handleVisibility(frame); return intValue; } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/ReadVariadicComponentNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/ReadVariadicComponentNode.java index 363ba30ac7b19966a77b9d45ae642540e4b737a4..d8702da5ed28f7c372df37b4deae5bf59fd615fe 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/ReadVariadicComponentNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/ReadVariadicComponentNode.java @@ -22,20 +22,20 @@ */ package com.oracle.truffle.r.nodes.access; -import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; -import com.oracle.truffle.r.nodes.function.PromiseHelperNode; +import com.oracle.truffle.r.nodes.function.PromiseHelperNode.PromiseCheckHelperNode; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RSerialize.State; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.Utils; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RMissing; -import com.oracle.truffle.r.runtime.data.RPromise; import com.oracle.truffle.r.runtime.nodes.RNode; import com.oracle.truffle.r.runtime.nodes.RSourceSectionNode; import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup; @@ -47,21 +47,23 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; public class ReadVariadicComponentNode extends RSourceSectionNode implements RSyntaxNode, RSyntaxLookup { @Child private ReadVariableNode lookup = ReadVariableNode.createSilent(ArgumentsSignature.VARARG_NAME, RType.Any); - @Child private PromiseHelperNode promiseHelper; + @Child private PromiseCheckHelperNode promiseHelper = new PromiseCheckHelperNode(); + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); private final int index; + private final String name; private final BranchProfile errorBranch = BranchProfile.create(); - private final BranchProfile promiseBranch = BranchProfile.create(); public ReadVariadicComponentNode(SourceSection src, int index) { super(src); this.index = index; + this.name = Utils.intern(".." + Integer.toString(index + 1)); } @Override public Object execute(VirtualFrame frame) { - RContext.getInstance().setVisible(true); + visibility.execute(frame, true); Object args = lookup.execute(frame); if (args == null) { @@ -73,37 +75,26 @@ public class ReadVariadicComponentNode extends RSourceSectionNode implements RSy errorBranch.enter(); throw RError.error(this, RError.Message.NO_LIST_FOR_CDR); } - if (argsValuesAndNames.getLength() <= index) { errorBranch.enter(); throw RError.error(this, RError.Message.DOT_DOT_SHORT, index + 1); } Object ret = argsValuesAndNames.getArgument(index); - if (ret instanceof RPromise) { - promiseBranch.enter(); - // This might be the case, as lookup only checks for "..." to be a promise and forces it - // eventually, NOT (all) of its content - if (promiseHelper == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - promiseHelper = insert(new PromiseHelperNode()); - } - ret = promiseHelper.evaluate(frame, (RPromise) ret); - } - return ret == null ? RMissing.instance : ret; + return ret == null ? RMissing.instance : promiseHelper.checkEvaluate(frame, ret); } public String getPrintForm() { - return ".." + Integer.toString(index + 1); + return name; } @Override - public void serializeImpl(com.oracle.truffle.r.runtime.RSerialize.State state) { + public void serializeImpl(State state) { state.setCarAsSymbol(getPrintForm()); } @Override public String getIdentifier() { - return Utils.intern(getPrintForm()); + return name; } @Override diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/RemoveAndAnswerNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/RemoveAndAnswerNode.java index 28c07e510dce1781491d79502e3aefa728faa032..3a66dc1427fa8880bbf7e228ca667b1631edbb14 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/RemoveAndAnswerNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/RemoveAndAnswerNode.java @@ -31,7 +31,6 @@ import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.r.nodes.access.RemoveAndAnswerNodeFactory.RemoveAndAnswerResolvedNodeGen; 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.env.frame.FrameSlotChangeMonitor; import com.oracle.truffle.r.runtime.nodes.RNode; @@ -103,7 +102,6 @@ public abstract class RemoveAndAnswerNode extends RNode { @Specialization(guards = "isObject(frame)") protected Object doObject(VirtualFrame frame) { - RContext.getInstance().setVisible(false); Object result; try { result = frame.getObject(slot); @@ -118,7 +116,6 @@ public abstract class RemoveAndAnswerNode extends RNode { @Specialization(guards = "isInt(frame)") protected int doInt(VirtualFrame frame) { - RContext.getInstance().setVisible(false); int result; try { result = frame.getInt(slot); @@ -133,7 +130,6 @@ public abstract class RemoveAndAnswerNode extends RNode { @Specialization(guards = "isDouble(frame)") protected double doDouble(VirtualFrame frame) { - RContext.getInstance().setVisible(false); double result; try { result = frame.getDouble(slot); @@ -148,7 +144,6 @@ public abstract class RemoveAndAnswerNode extends RNode { @Specialization(guards = "isByte(frame)") protected byte doByte(VirtualFrame frame) { - RContext.getInstance().setVisible(false); byte result; try { result = frame.getByte(slot); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteCurrentVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteCurrentVariableNode.java index f7dbb258511d99587e6636f7fad2ab9f7a927dc2..f8998f171c9ad1e5399f7365b06e8260ccb8753c 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteCurrentVariableNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteCurrentVariableNode.java @@ -26,9 +26,9 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.NodeCost; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RSerialize; -import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.nodes.RNode; import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; @@ -40,16 +40,17 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; */ @NodeInfo(cost = NodeCost.NONE) public class WriteCurrentVariableNode extends WriteVariableNodeSyntaxHelper implements RSyntaxNode, RSyntaxCall { + @Child private WriteLocalFrameVariableNode writeLocalFrameVariableNode; + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); - protected WriteCurrentVariableNode(SourceSection src) { + protected WriteCurrentVariableNode(SourceSection src, String name, RNode rhs) { super(src); + writeLocalFrameVariableNode = WriteLocalFrameVariableNode.create(name, rhs, Mode.REGULAR); } static WriteCurrentVariableNode create(SourceSection src, String name, RNode rhs) { - WriteCurrentVariableNode result = new WriteCurrentVariableNode(src); - result.writeLocalFrameVariableNode = result.insert(WriteLocalFrameVariableNode.create(name, rhs, Mode.REGULAR)); - return result; + return new WriteCurrentVariableNode(src, name, rhs); } @Override @@ -65,7 +66,7 @@ public class WriteCurrentVariableNode extends WriteVariableNodeSyntaxHelper impl @Override public Object execute(VirtualFrame frame) { Object result = writeLocalFrameVariableNode.execute(frame); - RContext.getInstance().setVisible(false); + visibility.execute(frame, false); return result; } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperVariableNode.java index d79875a674117af26fed7c4b062dd65b1bc197bb..a916a6ac23092e1446c26bca9ddf9592ebc02d76 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperVariableNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperVariableNode.java @@ -26,9 +26,9 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.NodeCost; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RSerialize; -import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.nodes.RNode; import com.oracle.truffle.r.runtime.nodes.RSourceSectionNode; import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; @@ -47,15 +47,15 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; public class WriteSuperVariableNode extends WriteVariableNodeSyntaxHelper implements RSyntaxNode, RSyntaxCall { @Child private WriteVariableNode writeSuperFrameVariableNode; + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); - protected WriteSuperVariableNode(SourceSection src) { + protected WriteSuperVariableNode(SourceSection src, String name, RNode rhs) { super(src); + writeSuperFrameVariableNode = WriteSuperFrameVariableNode.create(name, rhs, Mode.REGULAR); } static WriteSuperVariableNode create(SourceSection src, String name, RNode rhs) { - WriteSuperVariableNode result = new WriteSuperVariableNode(src); - result.writeSuperFrameVariableNode = result.insert(WriteSuperFrameVariableNode.create(name, rhs, Mode.REGULAR)); - return result; + return new WriteSuperVariableNode(src, name, rhs); } @Override @@ -71,7 +71,7 @@ public class WriteSuperVariableNode extends WriteVariableNodeSyntaxHelper implem @Override public Object execute(VirtualFrame frame) { Object result = writeSuperFrameVariableNode.execute(frame); - RContext.getInstance().setVisible(false); + visibility.execute(frame, false); return result; } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/ReadVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/ReadVariableNode.java index d13c16f36760f10aa59843d2e091ff4c679dddc8..0482836c0119317f7a47d9ff631e6ffc8a3058d8 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/ReadVariableNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/ReadVariableNode.java @@ -48,6 +48,7 @@ import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.r.nodes.function.PromiseHelperNode; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.FastROptions; import com.oracle.truffle.r.runtime.RArguments; @@ -57,7 +58,6 @@ import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RSerialize; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.StableValue; -import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RMissing; @@ -130,6 +130,8 @@ public final class ReadVariableNode extends RSourceSectionNode implements RSynta @Child private PromiseHelperNode promiseHelper; @Child private CheckTypeNode checkTypeNode; + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); + @CompilationFinal private FrameLevel read; @CompilationFinal private boolean needsCopying; @@ -187,7 +189,7 @@ public final class ReadVariableNode extends RSourceSectionNode implements RSynta private Object executeInternal(VirtualFrame frame, Frame variableFrame) { if (kind != ReadKind.Silent) { - RContext.getInstance().setVisible(true); + visibility.execute(frame, true); } Object result; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinRootNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinRootNode.java index 12b61f2bc13a85ee86ec411a2b0316c59d33656b..a4f5ca52693fb66098def049f9e8d548f3c5b092 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinRootNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinRootNode.java @@ -31,8 +31,9 @@ import com.oracle.truffle.r.nodes.RRootNode; import com.oracle.truffle.r.nodes.function.FormalArguments; import com.oracle.truffle.r.runtime.RDispatch; import com.oracle.truffle.r.runtime.RError; -import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RError.Message; +import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.RVisibility; import com.oracle.truffle.r.runtime.builtins.FastPathFactory; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor; @@ -40,6 +41,7 @@ import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor; public final class RBuiltinRootNode extends RRootNode { @Child private RBuiltinNode builtin; + private final RBuiltinFactory factory; RBuiltinRootNode(RBuiltinFactory factory, RBuiltinNode builtin, FormalArguments formalArguments, FrameDescriptor frameDescriptor, FastPathFactory fastPath) { @@ -74,8 +76,12 @@ public final class RBuiltinRootNode extends RRootNode { CompilerDirectives.transferToInterpreter(); throw new RInternalError(e, "internal error"); } + if (factory.getVisibility() == RVisibility.OFF) { + RContext.getInstance().setVisible(false); + } else if (factory.getVisibility() == RVisibility.ON) { + RContext.getInstance().setVisible(true); + } - RContext.getInstance().setVisible(factory.getVisibility()); return result; } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/BlockNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/BlockNode.java index 0adccc729521bcd0f6769db5810f256da7bc444d..9d9cee87c0faf3c20802d0c936175490f9a4d542 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/BlockNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/BlockNode.java @@ -26,9 +26,9 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.ExplodeLoop; import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.r.nodes.RASTUtils; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RSerialize; -import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.gnur.SEXPTYPE; import com.oracle.truffle.r.runtime.nodes.RNode; @@ -46,6 +46,7 @@ public final class BlockNode extends RSourceSectionNode implements RSyntaxNode, public static final RNode[] EMPTY_BLOCK = new RNode[0]; @Children protected final RNode[] sequence; + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); public BlockNode(SourceSection src, RNode[] sequence) { super(src); @@ -59,7 +60,7 @@ public final class BlockNode extends RSourceSectionNode implements RSyntaxNode, @Override @ExplodeLoop public Object execute(VirtualFrame frame) { - RContext.getInstance().setVisible(true); + visibility.execute(frame, true); Object lastResult = RNull.instance; for (int i = 0; i < sequence.length; i++) { lastResult = sequence[i].execute(frame); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/BreakNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/BreakNode.java index 3479f87c3a917a82fd38fe3e6c2a241d83e2f004..e7a5887847ac23025ef88700b03bfb62d1fbda2c 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/BreakNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/BreakNode.java @@ -24,9 +24,9 @@ package com.oracle.truffle.r.nodes.control; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RSerialize; -import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.nodes.RSourceSectionNode; import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; @@ -35,6 +35,8 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; public final class BreakNode extends RSourceSectionNode implements RSyntaxNode, RSyntaxCall { + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); + public BreakNode(SourceSection src) { super(src); } @@ -46,7 +48,7 @@ public final class BreakNode extends RSourceSectionNode implements RSyntaxNode, @Override public Object execute(VirtualFrame frame) { - RContext.getInstance().setVisible(false); + visibility.execute(frame, false); throw BreakException.instance; } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ForNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ForNode.java index 2e29ed124561413cd7eadf5761589219c76e92d5..6f91c950265a89b5b3fbd3c5c5604365e55e8ce3 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ForNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ForNode.java @@ -36,10 +36,10 @@ import com.oracle.truffle.r.nodes.RRootNode; import com.oracle.truffle.r.nodes.access.WriteVariableNode; import com.oracle.truffle.r.nodes.access.WriteVariableNode.Mode; import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.runtime.AnonymousFrameVariable; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RSerialize; -import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.gnur.SEXPTYPE; import com.oracle.truffle.r.runtime.nodes.RBaseNode; @@ -55,6 +55,7 @@ public final class ForNode extends AbstractLoopNode implements RSyntaxNode, RSyn @Child private WriteVariableNode writeIndexNode; @Child private WriteVariableNode writeRangeNode; @Child private LoopNode loopNode; + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); private ForNode(SourceSection src, WriteVariableNode cvar, RNode range, RNode body) { super(src); @@ -79,7 +80,7 @@ public final class ForNode extends AbstractLoopNode implements RSyntaxNode, RSyn writeRangeNode.execute(frame); writeLengthNode.execute(frame); loopNode.executeLoop(frame); - RContext.getInstance().setVisible(false); + visibility.execute(frame, false); return RNull.instance; } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/IfNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/IfNode.java index 25ece0e792df83744f8a0bd50af5943889eb1767..e36b1924649d90ee8945aefa5c7ab144a70f3201 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/IfNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/IfNode.java @@ -26,12 +26,12 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.nodes.unary.ConvertBooleanNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RSerialize; -import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.gnur.SEXPTYPE; import com.oracle.truffle.r.runtime.nodes.RNode; @@ -46,6 +46,7 @@ public final class IfNode extends RSourceSectionNode implements RSyntaxNode, RSy @Child private ConvertBooleanNode condition; @Child private RNode thenPart; @Child private RNode elsePart; + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); private final ConditionProfile conditionProfile = ConditionProfile.createCountingProfile(); @@ -72,7 +73,7 @@ public final class IfNode extends RSourceSectionNode implements RSyntaxNode, RSy @Override public Object execute(VirtualFrame frame) { byte cond = condition.executeByte(frame); - RContext.getInstance().setVisible(elsePart != null || cond == RRuntime.LOGICAL_TRUE); + visibility.execute(frame, elsePart != null || cond == RRuntime.LOGICAL_TRUE); if (cond == RRuntime.LOGICAL_NA) { // NA is the only remaining option diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/NextNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/NextNode.java index dab24867943b464f7f4603239998327ab405f308..514cd84e6dd25dead708e071771d3a2cfdb1097b 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/NextNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/NextNode.java @@ -24,9 +24,9 @@ package com.oracle.truffle.r.nodes.control; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RSerialize; -import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.nodes.RSourceSectionNode; import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; @@ -35,13 +35,15 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; public final class NextNode extends RSourceSectionNode implements RSyntaxNode, RSyntaxCall { + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); + public NextNode(SourceSection src) { super(src); } @Override public Object execute(VirtualFrame frame) { - RContext.getInstance().setVisible(false); + visibility.execute(frame, false); throw NextException.instance; } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java index ab03b7d5e149f22fc2389975ac654331a7eac10e..abc79605a78c6c09ef9077e944af446251f487b7 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java @@ -29,6 +29,7 @@ import com.oracle.truffle.api.nodes.ExplodeLoop; import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.r.nodes.access.RemoveAndAnswerNode; import com.oracle.truffle.r.nodes.access.WriteVariableNode; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RSerialize; import com.oracle.truffle.r.runtime.gnur.SEXPTYPE; @@ -61,6 +62,7 @@ public final class ReplacementNode extends RSourceSectionNode implements RSyntax @Children private final RNode[] updates; @Child private RemoveAndAnswerNode removeTemp; @Child private RemoveAndAnswerNode removeRhs; + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); public ReplacementNode(SourceSection src, String operator, RSyntaxNode syntaxLhs, RSyntaxNode rhs, String rhsSymbol, RNode v, String tmpSymbol, List<RNode> updates) { super(src); @@ -98,7 +100,11 @@ public final class ReplacementNode extends RSourceSectionNode implements RSyntax update.execute(frame); } removeTemp.execute(frame); - return removeRhs.execute(frame); + try { + return removeRhs.execute(frame); + } finally { + visibility.execute(frame, false); + } } @Override diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/WhileNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/WhileNode.java index 170a10ae5d85d3398f91ec1054ba4bc4b2daa325..cc1a415e0193c8e2b7fe627ced2227bd6bbbe37b 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/WhileNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/WhileNode.java @@ -31,11 +31,11 @@ import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.r.nodes.RRootNode; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.nodes.unary.ConvertBooleanNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RSerialize; -import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.gnur.SEXPTYPE; import com.oracle.truffle.r.runtime.nodes.RBaseNode; @@ -48,6 +48,7 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; public final class WhileNode extends AbstractLoopNode implements RSyntaxNode, RSyntaxCall { @Child private LoopNode loop; + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); /** * Also used for {@code repeat}, with a {@code TRUE} condition. @@ -68,7 +69,7 @@ public final class WhileNode extends AbstractLoopNode implements RSyntaxNode, RS @Override public Object execute(VirtualFrame frame) { loop.executeLoop(frame); - RContext.getInstance().setVisible(false); + visibility.execute(frame, false); return RNull.instance; } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java index a28e67e0ffcdb8844f13e333bb4defb6d1bc4c9d..58f248caeb3d1c4aaeb7c70d9492d6b4f16ff260 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java @@ -16,26 +16,25 @@ import java.util.function.Supplier; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.DirectCallNode; import com.oracle.truffle.api.nodes.ExplodeLoop; -import com.oracle.truffle.api.nodes.IndirectCallNode; import com.oracle.truffle.api.nodes.NodeCost; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.RRootNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.function.ArgumentMatcher.MatchPermutation; -import com.oracle.truffle.r.nodes.function.signature.RArgumentsNode; +import com.oracle.truffle.r.nodes.function.call.CallRFunctionCachedNode; +import com.oracle.truffle.r.nodes.function.call.CallRFunctionCachedNodeGen; +import com.oracle.truffle.r.nodes.function.call.CallRFunctionNode; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.nodes.unary.CastNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RArguments; import com.oracle.truffle.r.runtime.RArguments.DispatchArgs; -import com.oracle.truffle.r.runtime.builtins.RBuiltinDescriptor; import com.oracle.truffle.r.runtime.RCaller; import com.oracle.truffle.r.runtime.RInternalError; -import com.oracle.truffle.r.runtime.context.RContext; +import com.oracle.truffle.r.runtime.builtins.RBuiltinDescriptor; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.REmpty; import com.oracle.truffle.r.runtime.data.RFunction; @@ -50,7 +49,6 @@ public abstract class CallMatcherNode extends RBaseNode { protected final boolean argsAreEvaluated; @Child private PromiseHelperNode promiseHelper; - @Child private RArgumentsNode argsNode = RArgumentsNode.create(); protected final ConditionProfile missingArgProfile = ConditionProfile.createBinaryProfile(); protected final ConditionProfile emptyArgProfile = ConditionProfile.createBinaryProfile(); @@ -128,10 +126,6 @@ public abstract class CallMatcherNode extends RBaseNode { return new CallMatcherCachedNode(suppliedSignature, varArgSignatures, function, preparePermutation, permutation, forNextMethod, argsAreEvaluated, next); } - protected Object[] prepareArguments(Object[] reorderedArgs, ArgumentsSignature reorderedSignature, RFunction function, DispatchArgs dispatchArgs, RCaller caller) { - return argsNode.execute(function, caller, null, reorderedArgs, reorderedSignature, dispatchArgs); - } - protected final void evaluatePromises(VirtualFrame frame, RFunction function, Object[] args, int varArgIndex) { if (function.isBuiltin()) { if (!argsAreEvaluated) { @@ -185,7 +179,7 @@ public abstract class CallMatcherNode extends RBaseNode { CallMatcherCachedNode cachedNode = replace(specialize(suppliedSignature, suppliedArguments, function, this)); // for splitting if necessary if (cachedNode.call != null && RCallNode.needsSplitting(function.getTarget())) { - cachedNode.call.cloneCallTarget(); + cachedNode.call.getCallNode().cloneCallTarget(); } return cachedNode.execute(frame, suppliedSignature, suppliedArguments, function, functionName, dispatchArgs); } @@ -200,11 +194,10 @@ public abstract class CallMatcherNode extends RBaseNode { private static final class CallMatcherCachedNode extends CallMatcherNode { @Child private CallMatcherNode next; - - @Child private DirectCallNode call; - + @Child private CallRFunctionNode call; @Child private RBuiltinNode builtin; @Children private final CastNode[] builtinArgumentCasts; + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); private final RBuiltinDescriptor builtinDescriptor; private final ArgumentsSignature cachedSuppliedSignature; @@ -233,7 +226,7 @@ public abstract class CallMatcherNode extends RBaseNode { this.builtin = RBuiltinNode.inline(builtinDescriptor, null); this.builtinArgumentCasts = builtin.getCasts(); } else { - this.call = Truffle.getRuntime().createDirectCallNode(function.getTarget()); + this.call = CallRFunctionNode.create(function.getTarget()); this.builtinArgumentCasts = null; this.builtinDescriptor = null; } @@ -259,12 +252,11 @@ public abstract class CallMatcherNode extends RBaseNode { String genFunctionName = functionName == null ? function.getName() : functionName; Supplier<RSyntaxNode> argsSupplier = RCallerHelper.createFromArguments(genFunctionName, preparePermutation, suppliedArguments, suppliedSignature); RCaller caller = genFunctionName == null ? RCaller.createInvalid(frame, parent) : RCaller.create(frame, parent, argsSupplier); - Object[] arguments = prepareArguments(reorderedArgs, matchedArgs.getSignature(), cachedFunction, dispatchArgs, caller); - return call.call(frame, arguments); + return call.execute(frame, cachedFunction, caller, null, reorderedArgs, matchedArgs.getSignature(), cachedFunction.getEnclosingFrame(), dispatchArgs); } else { applyCasts(reorderedArgs); Object result = builtin.execute(frame, reorderedArgs); - RContext.getInstance().setVisible(builtinDescriptor.getVisibility()); + visibility.execute(frame, builtinDescriptor.getVisibility()); return result; } } else { @@ -334,7 +326,7 @@ public abstract class CallMatcherNode extends RBaseNode { super(forNextMethod, argsAreEvaluated); } - @Child private IndirectCallNode call = Truffle.getRuntime().createIndirectCallNode(); + @Child private CallRFunctionCachedNode call = CallRFunctionCachedNodeGen.create(0); @Override public Object execute(VirtualFrame frame, ArgumentsSignature suppliedSignature, Object[] suppliedArguments, RFunction function, String functionName, DispatchArgs dispatchArgs) { @@ -346,8 +338,7 @@ public abstract class CallMatcherNode extends RBaseNode { RCaller caller = genFunctionName == null ? RCaller.createInvalid(frame, parent) : RCaller.create(frame, RCallerHelper.createFromArguments(genFunctionName, new RArgsValuesAndNames(reorderedArgs.getArguments(), ArgumentsSignature.empty(reorderedArgs.getLength())))); - Object[] arguments = prepareArguments(reorderedArgs.getArguments(), reorderedArgs.getSignature(), function, dispatchArgs, caller); - return call.call(frame, function.getTarget(), arguments); + return call.execute(frame, function, caller, null, reorderedArgs.getArguments(), reorderedArgs.getSignature(), function.getEnclosingFrame(), dispatchArgs); } @Override diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionDefinitionNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionDefinitionNode.java index 260ee359b51c6c32724245f659bf10cf8ca94ada..e68431c47f78428f966a191498ac10db4d28b657 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionDefinitionNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionDefinitionNode.java @@ -47,6 +47,7 @@ import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinFactory; import com.oracle.truffle.r.nodes.control.BreakException; import com.oracle.truffle.r.nodes.control.NextException; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.JumpToTopLevelException; import com.oracle.truffle.r.runtime.ExitException; @@ -116,6 +117,8 @@ public final class FunctionDefinitionNode extends RRootNode implements RSyntaxNo @Child private FrameSlotNode dotTargetSlot; @Child private FrameSlotNode dotMethodsSlot; + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); + @Child private PostProcessArgumentsNode argPostProcess; private final boolean needsSplitting; @@ -287,6 +290,7 @@ public final class FunctionDefinitionNode extends RRootNode implements RSyntaxNo * has no exit handlers (by fiat), so any exceptions from onExits handlers will be * caught above. */ + visibility.executeEndOfFunction(frame); if (argPostProcess != null) { resetArgs.enter(); argPostProcess.execute(frame); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java index 98b20bc722767e8679064d0389a8431800d80ad0..ee4d814f981084f26fe209474fdbb1a721e4da9b 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java @@ -30,7 +30,6 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.RootCallTarget; -import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.NodeChild; @@ -42,7 +41,6 @@ import com.oracle.truffle.api.frame.VirtualFrame; 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.nodes.DirectCallNode; import com.oracle.truffle.api.nodes.ExplodeLoop; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeCost; @@ -67,7 +65,9 @@ import com.oracle.truffle.r.nodes.function.PromiseHelperNode.PromiseCheckHelperN import com.oracle.truffle.r.nodes.function.RCallNodeGen.FunctionDispatchNodeGen; import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode.NoGenericMethodException; import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode.Result; +import com.oracle.truffle.r.nodes.function.call.CallRFunctionNode; import com.oracle.truffle.r.nodes.function.call.PrepareArguments; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.nodes.profile.TruffleBoundaryNode; import com.oracle.truffle.r.nodes.unary.CastNode; import com.oracle.truffle.r.runtime.Arguments; @@ -75,9 +75,6 @@ import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RArguments; import com.oracle.truffle.r.runtime.RArguments.S3Args; import com.oracle.truffle.r.runtime.RArguments.S3DefaultArguments; -import com.oracle.truffle.r.runtime.builtins.FastPathFactory; -import com.oracle.truffle.r.runtime.builtins.RBuiltinDescriptor; -import com.oracle.truffle.r.runtime.builtins.RBuiltinKind; import com.oracle.truffle.r.runtime.RCaller; import com.oracle.truffle.r.runtime.RDeparse; import com.oracle.truffle.r.runtime.RDispatch; @@ -88,7 +85,9 @@ import com.oracle.truffle.r.runtime.RSerialize; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.RVisibility; import com.oracle.truffle.r.runtime.SubstituteVirtualFrame; -import com.oracle.truffle.r.runtime.context.RContext; +import com.oracle.truffle.r.runtime.builtins.FastPathFactory; +import com.oracle.truffle.r.runtime.builtins.RBuiltinDescriptor; +import com.oracle.truffle.r.runtime.builtins.RBuiltinKind; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.REmpty; @@ -295,14 +294,15 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS } @Specialization(limit = "5", guards = {"isSpecialDispatch(function)", "cachedBuiltin == function.getRBuiltin()"}) - public Object callSpecial(VirtualFrame frame, @SuppressWarnings("unused") RFunction function, // - @Cached("function.getRBuiltin()") RBuiltinDescriptor cachedBuiltin, // - @Cached("createSpecial(cachedBuiltin)") RBuiltinNode call) { + public Object callSpecial(VirtualFrame frame, @SuppressWarnings("unused") RFunction function, + @Cached("function.getRBuiltin()") RBuiltinDescriptor cachedBuiltin, + @Cached("createSpecial(cachedBuiltin)") RBuiltinNode call, + @Cached("create()") SetVisibilityNode visibility) { if (explicitArgs != null) { CompilerDirectives.transferToInterpreter(); throw RError.error(this, RError.Message.INVALID_USE, cachedBuiltin.getName()); } - RContext.getInstance().setVisible(cachedBuiltin.getVisibility()); + visibility.execute(frame, cachedBuiltin.getVisibility()); return call.execute(frame); } @@ -930,6 +930,7 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS @Child private RBuiltinNode builtin; @Child private PromiseCheckHelperNode promiseHelper; @Children private final CastNode[] casts; + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); private final BranchProfile emptyProfile = BranchProfile.create(); private final BranchProfile varArgsProfile = BranchProfile.create(); @@ -1018,15 +1019,16 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS @Override public Object execute(VirtualFrame frame, RFunction currentFunction, RArgsValuesAndNames orderedArguments, S3Args s3Args) { Object result = builtin.execute(frame, castArguments(frame, orderedArguments.getArguments())); - RContext.getInstance().setVisible(builtinDescriptor.getVisibility()); + visibility.execute(frame, builtinDescriptor.getVisibility()); return result; } } private static final class DispatchedCallNode extends LeafCallNode { - @Child private DirectCallNode call; + @Child private CallRFunctionNode call; @Child private RFastPathNode fastPath; + @Child private SetVisibilityNode visibility; private final RootCallTarget cachedTarget; private final FastPathFactory fastPathFactory; @@ -1039,6 +1041,7 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS this.fastPathFactory = root.getFastPath(); this.fastPath = fastPathFactory == null ? null : fastPathFactory.create(); this.fastPathVisibility = fastPathFactory == null ? null : fastPathFactory.getVisibility(); + this.visibility = fastPathFactory == null ? null : SetVisibilityNode.create(); originalCall.needsCallerFrame |= root.containsDispatch(); } @@ -1047,25 +1050,26 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS if (fastPath != null) { Object result = fastPath.execute(frame, orderedArguments.getArguments()); if (result != null) { - RContext.getInstance().setVisible(this.fastPathVisibility); + assert fastPathVisibility != null; + visibility.execute(frame, fastPathVisibility); return result; } CompilerDirectives.transferToInterpreterAndInvalidate(); fastPath = null; + visibility = null; } if (call == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - call = insert(Truffle.getRuntime().createDirectCallNode(cachedTarget)); + call = insert(CallRFunctionNode.create(cachedTarget)); if (needsSplitting(cachedTarget)) { - call.cloneCallTarget(); + call.getCallNode().cloneCallTarget(); } } MaterializedFrame callerFrame = /* CompilerDirectives.inInterpreter() || */originalCall.needsCallerFrame ? frame.materialize() : null; - Object[] argsObject = RArguments.create(function, originalCall.createCaller(frame, function), callerFrame, orderedArguments.getArguments(), orderedArguments.getSignature(), + return call.execute(frame, function, originalCall.createCaller(frame, function), callerFrame, orderedArguments.getArguments(), orderedArguments.getSignature(), function.getEnclosingFrame(), s3Args); - return call.call(frame, argsObject); } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/UseMethodInternalNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/UseMethodInternalNode.java index da4f5715c1e4add5da9d72ea7b84b4e1766f5275..284b6b0c0825045733416846ed73b1ab1641f761 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/UseMethodInternalNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/UseMethodInternalNode.java @@ -17,7 +17,6 @@ import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.FastROptions; import com.oracle.truffle.r.runtime.RArguments.S3Args; import com.oracle.truffle.r.runtime.RInternalError; -import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.nodes.RNode; @@ -39,7 +38,6 @@ public final class UseMethodInternalNode extends RNode { } public Object execute(VirtualFrame frame, RStringVector type, Object[] arguments) { - RContext.getInstance().setVisible(true); Result lookupResult = lookup.execute(frame, generic, type, null, frame.materialize(), null); if (wrap) { assert arguments != null; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/CallRFunctionCachedNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/CallRFunctionCachedNode.java new file mode 100644 index 0000000000000000000000000000000000000000..1c8b0fce0bb4616a854b24566febd93c88265a63 --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/CallRFunctionCachedNode.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2014, 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.nodes.function.call; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.MaterializedFrame; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.DirectCallNode; +import com.oracle.truffle.api.nodes.IndirectCallNode; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.NodeCost; +import com.oracle.truffle.api.nodes.NodeInfo; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; +import com.oracle.truffle.r.runtime.ArgumentsSignature; +import com.oracle.truffle.r.runtime.RArguments; +import com.oracle.truffle.r.runtime.RArguments.DispatchArgs; +import com.oracle.truffle.r.runtime.RCaller; +import com.oracle.truffle.r.runtime.data.RFunction; + +@NodeInfo(cost = NodeCost.NONE) +public abstract class CallRFunctionCachedNode extends Node { + + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); + + protected final int cacheLimit; + + protected CallRFunctionCachedNode(int cacheLimit) { + this.cacheLimit = cacheLimit; + } + + public final Object execute(VirtualFrame frame, RFunction function, RCaller call, MaterializedFrame callerFrame, Object[] evaluatedArgs, DispatchArgs dispatchArgs) { + Object[] callArgs = RArguments.create(function, call, callerFrame, evaluatedArgs, dispatchArgs); + return execute(frame, function.getTarget(), callArgs); + } + + public final Object execute(VirtualFrame frame, RFunction function, RCaller call, MaterializedFrame callerFrame, Object[] evaluatedArgs, + ArgumentsSignature suppliedSignature, MaterializedFrame enclosingFrame, DispatchArgs dispatchArgs) { + Object[] callArgs = RArguments.create(function, call, callerFrame, evaluatedArgs, suppliedSignature, enclosingFrame, dispatchArgs); + return execute(frame, function.getTarget(), callArgs); + } + + protected abstract Object execute(VirtualFrame frame, CallTarget target, Object[] arguments); + + protected static DirectCallNode createDirectCallNode(CallTarget target) { + return Truffle.getRuntime().createDirectCallNode(target); + } + + @Specialization(guards = "target == callNode.getCallTarget()", limit = "cacheLimit") + protected Object call(VirtualFrame frame, @SuppressWarnings("unused") CallTarget target, Object[] arguments, + @Cached("createDirectCallNode(target)") DirectCallNode callNode) { + try { + return callNode.call(frame, arguments); + } finally { + visibility.executeAfterCall(frame); + } + } + + protected static IndirectCallNode createIndirectCallNode() { + return Truffle.getRuntime().createIndirectCallNode(); + } + + @Specialization + protected Object call(VirtualFrame frame, CallTarget target, Object[] arguments, + @Cached("createIndirectCallNode()") IndirectCallNode callNode) { + try { + return callNode.call(frame, target, arguments); + } finally { + visibility.executeAfterCall(frame); + } + } +} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/CallRFunctionNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/CallRFunctionNode.java new file mode 100644 index 0000000000000000000000000000000000000000..6cdf8d25967db8c12a98fa7d5df2dd0d25f5420c --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/CallRFunctionNode.java @@ -0,0 +1,76 @@ +/* + * 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.nodes.function.call; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.frame.MaterializedFrame; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.DirectCallNode; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.NodeCost; +import com.oracle.truffle.api.nodes.NodeInfo; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; +import com.oracle.truffle.r.runtime.ArgumentsSignature; +import com.oracle.truffle.r.runtime.RArguments; +import com.oracle.truffle.r.runtime.RArguments.DispatchArgs; +import com.oracle.truffle.r.runtime.RCaller; +import com.oracle.truffle.r.runtime.data.RFunction; + +@NodeInfo(cost = NodeCost.NONE) +public final class CallRFunctionNode extends Node { + + @Child private DirectCallNode callNode; + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); + + private CallRFunctionNode(CallTarget callTarget) { + this.callNode = Truffle.getRuntime().createDirectCallNode(callTarget); + } + + public static CallRFunctionNode create(CallTarget callTarget) { + return new CallRFunctionNode(callTarget); + } + + public Object execute(VirtualFrame frame, RFunction function, RCaller call, MaterializedFrame callerFrame, Object[] evaluatedArgs, ArgumentsSignature suppliedSignature, + MaterializedFrame enclosingFrame, DispatchArgs dispatchArgs) { + Object[] callArgs = RArguments.create(function, call, callerFrame, evaluatedArgs, suppliedSignature, enclosingFrame, dispatchArgs); + try { + return callNode.call(frame, callArgs); + } finally { + visibility.executeAfterCall(frame); + } + } + + public DirectCallNode getCallNode() { + return callNode; + } + + public static Object executeSlowpath(RFunction function, RCaller call, MaterializedFrame callerFrame, Object[] evaluatedArgs, DispatchArgs dispatchArgs) { + Object[] callArgs = RArguments.create(function, call, callerFrame, evaluatedArgs, dispatchArgs); + try { + return function.getTarget().call(callArgs); + } finally { + SetVisibilityNode.executeAfterCallSlowPath(callerFrame); + } + } +} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/signature/RArgumentsNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/signature/RArgumentsNode.java deleted file mode 100644 index 244c55359e7f6bc046ae731e45ff3fea0e17a9ee..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/signature/RArgumentsNode.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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 - * 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.nodes.function.signature; - -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.frame.MaterializedFrame; -import com.oracle.truffle.api.nodes.NodeCost; -import com.oracle.truffle.r.runtime.ArgumentsSignature; -import com.oracle.truffle.r.runtime.RArguments; -import com.oracle.truffle.r.runtime.RArguments.DispatchArgs; -import com.oracle.truffle.r.runtime.RCaller; -import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.nodes.RBaseNode; - -public abstract class RArgumentsNode extends RBaseNode { - - /* - * This inline cache is not implemented using Truffle DSL because of null values provided for - * certain parameters, on which Truffle DSL cannot specialize. - */ - - public abstract Object[] execute(RFunction function, RCaller caller, MaterializedFrame callerFrame, Object[] evaluatedArgs, ArgumentsSignature signature, DispatchArgs dispatchArgs); - - public static RArgumentsNode create() { - return new RArgumentsUninitializedNode(); - } - - @Override - public NodeCost getCost() { - return NodeCost.NONE; - } - - private static final class RArgumentsUninitializedNode extends RArgumentsNode { - @Override - public Object[] execute(RFunction function, RCaller caller, MaterializedFrame callerFrame, Object[] evaluatedArgs, ArgumentsSignature signature, DispatchArgs dispatchArgs) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - return replace(new RArgumentsCachedNode(function)).execute(function, caller, callerFrame, evaluatedArgs, signature, dispatchArgs); - } - } - - private static final class RArgumentsCachedNode extends RArgumentsNode { - private final RFunction cachedFunction; - - RArgumentsCachedNode(RFunction cachedFunction) { - this.cachedFunction = cachedFunction; - } - - @Override - public Object[] execute(RFunction function, RCaller caller, MaterializedFrame callerFrame, Object[] evaluatedArgs, ArgumentsSignature signature, DispatchArgs dispatchArgs) { - if (function == cachedFunction) { - return RArguments.create(cachedFunction, caller, callerFrame, evaluatedArgs, cachedFunction.getEnclosingFrame(), dispatchArgs); - } else { - CompilerDirectives.transferToInterpreterAndInvalidate(); - return replace(new RArgumentsGenericNode()).execute(function, caller, callerFrame, evaluatedArgs, signature, dispatchArgs); - } - } - } - - private static final class RArgumentsGenericNode extends RArgumentsNode { - @Override - public Object[] execute(RFunction function, RCaller caller, MaterializedFrame callerFrame, Object[] evaluatedArgs, ArgumentsSignature signature, DispatchArgs dispatchArgs) { - return RArguments.create(function, caller, callerFrame, evaluatedArgs, function.getEnclosingFrame(), dispatchArgs); - } - } -} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/visibility/GetVisibilityNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/visibility/GetVisibilityNode.java new file mode 100644 index 0000000000000000000000000000000000000000..4a53a3de85217f25b066dd15d6c15f4bffe71ef5 --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/visibility/GetVisibilityNode.java @@ -0,0 +1,117 @@ +/* + * 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.nodes.function.visibility; + +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +import com.oracle.truffle.api.frame.Frame; +import com.oracle.truffle.api.frame.FrameSlot; +import com.oracle.truffle.api.frame.FrameSlotKind; +import com.oracle.truffle.api.frame.FrameSlotTypeException; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.NodeCost; +import com.oracle.truffle.api.nodes.NodeInfo; +import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.runtime.FastROptions; +import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.context.RContext; +import com.oracle.truffle.r.runtime.env.frame.RFrameSlot; + +@NodeInfo(cost = NodeCost.NONE) +public abstract class GetVisibilityNode extends Node { + + public abstract boolean execute(Frame frame); + + public abstract boolean execute(Frame frame, RContext context); + + private GetVisibilityNode() { + } + + public static GetVisibilityNode create() { + if (FastROptions.IgnoreVisibility.getBooleanValue()) { + return new GetVisibilityNoopNode(); + } else if (FastROptions.OptimizeVisibility.getBooleanValue()) { + return new GetVisibilityOptimizedNode(); + } else { + return new GetVisibilityDefaultNode(); + } + } + + private static final class GetVisibilityNoopNode extends GetVisibilityNode { + + @Override + public boolean execute(Frame frame) { + return false; + } + + @Override + public boolean execute(Frame frame, RContext context) { + return false; + } + } + + private static final class GetVisibilityDefaultNode extends GetVisibilityNode { + + @Override + public boolean execute(Frame frame) { + return execute(frame, RContext.getInstance()); + } + + @Override + public boolean execute(Frame frame, RContext context) { + return context.isVisible(); + } + } + + /** + * See {@link RFrameSlot#Visibility}. + */ + private static final class GetVisibilityOptimizedNode extends GetVisibilityNode { + + @CompilationFinal private FrameSlot frameSlot; + private final ConditionProfile isCustomProfile = ConditionProfile.createBinaryProfile(); + + @Override + public boolean execute(Frame frame) { + if (frameSlot == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + frameSlot = frame.getFrameDescriptor().findOrAddFrameSlot(RFrameSlot.Visibility, FrameSlotKind.Object); + } + try { + Object visibility = frame.getObject(frameSlot); + if (isCustomProfile.profile(visibility == null)) { + return RContext.getInstance().isVisible(); + } else { + return visibility == Boolean.TRUE; + } + } catch (FrameSlotTypeException e) { + throw RInternalError.shouldNotReachHere(e); + } + } + + @Override + public boolean execute(Frame frame, RContext context) { + return execute(frame); + } + } +} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/visibility/SetVisibilityNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/visibility/SetVisibilityNode.java new file mode 100644 index 0000000000000000000000000000000000000000..e6347e24fff03b405cba20e6da3c414638977aaf --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/visibility/SetVisibilityNode.java @@ -0,0 +1,169 @@ +/* + * 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.nodes.function.visibility; + +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +import com.oracle.truffle.api.frame.Frame; +import com.oracle.truffle.api.frame.FrameSlot; +import com.oracle.truffle.api.frame.FrameSlotKind; +import com.oracle.truffle.api.frame.FrameSlotTypeException; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.NodeCost; +import com.oracle.truffle.api.nodes.NodeInfo; +import com.oracle.truffle.r.runtime.FastROptions; +import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.RVisibility; +import com.oracle.truffle.r.runtime.context.RContext; +import com.oracle.truffle.r.runtime.env.frame.RFrameSlot; + +@NodeInfo(cost = NodeCost.NONE) +public abstract class SetVisibilityNode extends Node { + + public abstract void execute(Frame frame, boolean value); + + public abstract void execute(VirtualFrame frame, RVisibility visibility); + + public abstract void executeAfterCall(VirtualFrame frame); + + public abstract void executeEndOfFunction(VirtualFrame frame); + + private SetVisibilityNode() { + } + + public static SetVisibilityNode create() { + if (FastROptions.IgnoreVisibility.getBooleanValue()) { + return new SetVisibilityNoopNode(); + } else if (FastROptions.OptimizeVisibility.getBooleanValue()) { + return new SetVisibilityOptimizedNode(); + } else { + return new SetVisibilityDefaultNode(); + } + } + + private static final class SetVisibilityNoopNode extends SetVisibilityNode { + + @Override + public void execute(Frame frame, boolean value) { + // nothing to do + } + + @Override + public void execute(VirtualFrame frame, RVisibility visibility) { + // nothing to do + } + + @Override + public void executeAfterCall(VirtualFrame frame) { + // nothing to do + } + + @Override + public void executeEndOfFunction(VirtualFrame frame) { + // nothing to do + } + } + + private static final class SetVisibilityDefaultNode extends SetVisibilityNode { + + @Override + public void execute(Frame frame, boolean value) { + RContext.getInstance().setVisible(value); + } + + @Override + public void execute(VirtualFrame frame, RVisibility visibility) { + if (visibility == RVisibility.ON) { + execute(frame, true); + } else if (visibility == RVisibility.OFF) { + execute(frame, false); + } + } + + @Override + public void executeAfterCall(VirtualFrame frame) { + // nothing to do + } + + @Override + public void executeEndOfFunction(VirtualFrame frame) { + // nothing to do + } + } + + /** + * See {@link RFrameSlot#Visibility}. + */ + private static final class SetVisibilityOptimizedNode extends SetVisibilityNode { + + @CompilationFinal private FrameSlot frameSlot; + + @Override + public void execute(Frame frame, boolean value) { + if (frameSlot == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + frameSlot = frame.getFrameDescriptor().findOrAddFrameSlot(RFrameSlot.Visibility, FrameSlotKind.Object); + } + frame.setObject(frameSlot, value); + } + + @Override + public void execute(VirtualFrame frame, RVisibility visibility) { + if (visibility == RVisibility.ON) { + execute(frame, true); + } else if (visibility == RVisibility.OFF) { + execute(frame, false); + } + } + + @Override + public void executeAfterCall(VirtualFrame frame) { + if (frameSlot == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + frameSlot = frame.getFrameDescriptor().findOrAddFrameSlot(RFrameSlot.Visibility, FrameSlotKind.Object); + } + frame.setObject(frameSlot, null); + } + + @Override + public void executeEndOfFunction(VirtualFrame frame) { + if (frameSlot == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + frameSlot = frame.getFrameDescriptor().findOrAddFrameSlot(RFrameSlot.Visibility, FrameSlotKind.Object); + } + try { + Object visibility = frame.getObject(frameSlot); + if (visibility != null) { + RContext.getInstance().setVisible(visibility == Boolean.TRUE); + } + } catch (FrameSlotTypeException e) { + throw RInternalError.shouldNotReachHere(e); + } + } + } + + public static void executeAfterCallSlowPath(Frame frame) { + frame.setObject(frame.getFrameDescriptor().findOrAddFrameSlot(RFrameSlot.Visibility, FrameSlotKind.Object), null); + } +} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/DispatchGeneric.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/DispatchGeneric.java index 7863264c41c0e4d51d6e4b53920933e67a4e983e..733648fbaea8f503607b1b735e07275a000315ab 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/DispatchGeneric.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/DispatchGeneric.java @@ -23,7 +23,6 @@ import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.access.variables.LocalReadVariableNode; import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; -import com.oracle.truffle.r.nodes.function.signature.RArgumentsNode; import com.oracle.truffle.r.runtime.RCaller; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RFunction; @@ -37,7 +36,6 @@ public abstract class DispatchGeneric extends RBaseNode { private final ConditionProfile singleStringProfile = ConditionProfile.createBinaryProfile(); private final BranchProfile equalsMethodRequired = BranchProfile.create(); - @Child private RArgumentsNode argsNode = RArgumentsNode.create(); @Child private LoadMethod loadMethod = LoadMethodNodeGen.create(); @Child private ExecuteMethod executeMethod = new ExecuteMethod(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/LoadMethod.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/LoadMethod.java index 72a4c84ab2dcfdc2f42b28b3d0a4a3ed09b55855..64bb9faef97b5e45e360939675c1bacd95455be1 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/LoadMethod.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/LoadMethod.java @@ -14,11 +14,9 @@ package com.oracle.truffle.r.nodes.objects; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.DirectCallNode; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.ValueProfile; @@ -29,7 +27,7 @@ import com.oracle.truffle.r.nodes.access.variables.LocalReadVariableNode; import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; import com.oracle.truffle.r.nodes.attributes.AttributeAccess; import com.oracle.truffle.r.nodes.attributes.AttributeAccessNodeGen; -import com.oracle.truffle.r.nodes.function.signature.RArgumentsNode; +import com.oracle.truffle.r.nodes.function.call.CallRFunctionNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RCaller; import com.oracle.truffle.r.runtime.RError; @@ -58,9 +56,8 @@ abstract class LoadMethod extends RBaseNode { @Child private WriteLocalFrameVariableNode writeRMethod = WriteLocalFrameVariableNode.create(RRuntime.R_DOT_METHOD, null, WriteVariableNode.Mode.REGULAR); @Child private LocalReadVariableNode methodsEnvRead = LocalReadVariableNode.create("methods", true); @Child private ReadVariableNode loadMethodFind; - @Child private DirectCallNode loadMethodCall; + @Child private CallRFunctionNode loadMethodCall; @CompilationFinal private RFunction loadMethodFunction; - @Child private RArgumentsNode argsNode = RArgumentsNode.create(); private final ConditionProfile cached = ConditionProfile.createBinaryProfile(); private final ConditionProfile moreAttributes = ConditionProfile.createBinaryProfile(); private final ConditionProfile noNextMethodAttr = ConditionProfile.createBinaryProfile(); @@ -119,7 +116,7 @@ abstract class LoadMethod extends RBaseNode { loadMethodFind = insert(ReadVariableNode.createFunctionLookup(RSyntaxNode.INTERNAL, RRuntime.R_LOAD_METHOD_NAME)); currentFunction = (RFunction) loadMethodFind.execute(frame, methodsEnv.getFrame()); loadMethodFunction = currentFunction; - loadMethodCall = insert(Truffle.getRuntime().createDirectCallNode(loadMethodFunction.getTarget())); + loadMethodCall = insert(CallRFunctionNode.create(loadMethodFunction.getTarget())); RError.performanceWarning("loadMethod executing slow path"); } else { currentFunction = (RFunction) loadMethodFind.execute(frame, methodsEnv.getFrame(methodsFrameAccessProfile)); @@ -129,10 +126,8 @@ abstract class LoadMethod extends RBaseNode { if (cached.profile(currentFunction == loadMethodFunction)) { // TODO: technically, someone could override loadMethod function and access the // caller, but it's rather unlikely - Object[] args = argsNode.execute(loadMethodFunction, caller, null, - new Object[]{fdef, fname, REnvironment.frameToEnvironment(frame.materialize())}, SIGNATURE, - null); - ret = (RFunction) loadMethodCall.call(frame, args); + ret = (RFunction) loadMethodCall.execute(frame, loadMethodFunction, caller, null, new Object[]{fdef, fname, REnvironment.frameToEnvironment(frame.materialize())}, SIGNATURE, + loadMethodFunction.getEnclosingFrame(), null); } else { // slow path ret = (RFunction) RContext.getEngine().evalFunction(currentFunction, frame.materialize(), caller, null, fdef, fname, REnvironment.frameToEnvironment(frame.materialize())); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/FastROptions.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/FastROptions.java index dca4160352aa4e20ce5b12f61385cdae22a23066..ab173296f67a787a4afe0c45d295986c5e14b7e4 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/FastROptions.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/FastROptions.java @@ -27,6 +27,7 @@ import java.util.Map.Entry; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +import com.oracle.truffle.r.runtime.env.frame.RFrameSlot; /** * Options to control the behavior of the FastR system, that relate to the implementation, i.e., are @@ -49,6 +50,10 @@ public enum FastROptions { LoadBase("Load base package", true), PrintComplexLookups("Print a message for each non-trivial variable lookup", false), IgnoreVisibility("Ignore setting of the visibility flag", false), + /** + * See {@link RFrameSlot#Visibility}. + */ + OptimizeVisibility("optimized setting of the visibility flag", true), LoadPkgSourcesIndex("Load R package sources index", true), InvisibleArgs("Argument writes do not trigger state transitions", true), RefCountIncrementOnly("Disable reference count decrements for experimental state transition implementation", false), diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RArguments.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RArguments.java index 35ebce4aa43a83817be26942121d23bc3a2fbe36..6fe38d5db1bb7f8b3abb758119d0cefe9e471198 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RArguments.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RArguments.java @@ -169,18 +169,10 @@ public final class RArguments { return frame.getArguments().length - INDEX_ARGUMENTS; } - public static Object[] create(RFunction functionObj, RCaller call, MaterializedFrame callerFrame, Object[] evaluatedArgs, DispatchArgs dispatchArgs) { - ArgumentsSignature formalSignature = ((HasSignature) functionObj.getRootNode()).getSignature(); - return create(functionObj, call, callerFrame, evaluatedArgs, ArgumentsSignature.empty(formalSignature.getLength()), dispatchArgs); - } - - public static Object[] create(RFunction functionObj, RCaller call, MaterializedFrame callerFrame, Object[] evaluatedArgs, ArgumentsSignature suppliedSignature, DispatchArgs dispatchArgs) { + public static Object[] create(RFunction function, RCaller call, MaterializedFrame callerFrame, Object[] evaluatedArgs, DispatchArgs dispatchArgs) { + ArgumentsSignature formalSignature = ((HasSignature) function.getRootNode()).getSignature(); CompilerAsserts.neverPartOfCompilation(); - return create(functionObj, call, callerFrame, evaluatedArgs, suppliedSignature, functionObj.getEnclosingFrame(), dispatchArgs); - } - - public static Object[] create(RFunction functionObj, RCaller call, MaterializedFrame callerFrame, Object[] evaluatedArgs, MaterializedFrame enclosingFrame, DispatchArgs dispatchArgs) { - return create(functionObj, call, callerFrame, evaluatedArgs, ArgumentsSignature.empty(evaluatedArgs.length), enclosingFrame, dispatchArgs); + return create(function, call, callerFrame, evaluatedArgs, ArgumentsSignature.empty(formalSignature.getLength()), function.getEnclosingFrame(), dispatchArgs); } /** @@ -194,7 +186,7 @@ public final class RArguments { * function as well as additional information like the parent frame or supplied * signature. */ - public static Object[] create(RFunction functionObj, RCaller call, MaterializedFrame callerFrame, Object[] evaluatedArgs, + public static Object[] create(RFunction function, RCaller call, MaterializedFrame callerFrame, Object[] evaluatedArgs, ArgumentsSignature suppliedSignature, MaterializedFrame enclosingFrame, DispatchArgs dispatchArgs) { assert suppliedSignature.getLength() == evaluatedArgs.length : "suppliedSignature should match the evaluatedArgs (see Java docs)."; assert evaluatedArgs != null : "RArguments.create evaluatedArgs is null"; @@ -204,7 +196,7 @@ public final class RArguments { Object[] a = new Object[MINIMAL_ARRAY_LENGTH + evaluatedArgs.length]; a[INDEX_ENVIRONMENT] = null; - a[INDEX_FUNCTION] = functionObj; + a[INDEX_FUNCTION] = function; a[INDEX_CALL] = call; a[INDEX_CALLER_FRAME] = callerFrame; a[INDEX_ENCLOSING_FRAME] = enclosingFrame; @@ -308,11 +300,6 @@ public final class RArguments { frame.getArguments()[INDEX_IS_IRREGULAR] = isIrregularFrame; } - public static void setIsIrregular(Object[] arguments, boolean isIrregularFrame) { - assert arguments.length >= INDEX_ARGUMENTS; - arguments[INDEX_IS_IRREGULAR] = isIrregularFrame; - } - public static void setEnclosingFrame(Frame frame, MaterializedFrame newEnclosingFrame) { CompilerAsserts.neverPartOfCompilation(); Object[] arguments = frame.getArguments(); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/builtins/FastPathFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/builtins/FastPathFactory.java index 59271ee152afc1d898158e4c11f9195f983d8785..494ef0ba2c953fbfcb6e0b3d757ee2e8f75429b8 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/builtins/FastPathFactory.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/builtins/FastPathFactory.java @@ -38,10 +38,30 @@ import com.oracle.truffle.r.runtime.nodes.RFastPathNode; * the function is invoked, the fast path is invoked first and only if it returns {@code null}, then * the original implementation is invoked. */ -@FunctionalInterface public interface FastPathFactory { - FastPathFactory EVALUATE_ARGS = () -> null; + FastPathFactory EVALUATE_ARGS = new FastPathFactory() { + + @Override + public RFastPathNode create() { + return null; + } + + @Override + public RVisibility getVisibility() { + return null; + } + + @Override + public boolean evaluatesArgument(int index) { + return true; + } + + @Override + public boolean forcedEagerPromise(int index) { + return false; + } + }; FastPathFactory FORCED_EAGER_ARGS = new FastPathFactory() { @@ -50,6 +70,11 @@ public interface FastPathFactory { return null; } + @Override + public RVisibility getVisibility() { + return null; + } + @Override public boolean evaluatesArgument(int index) { return false; @@ -83,23 +108,46 @@ public interface FastPathFactory { } return true; } + + @Override + public boolean forcedEagerPromise(int index) { + return false; + } }; } - RFastPathNode create(); + static FastPathFactory fromVisibility(RVisibility visibility, Supplier<RFastPathNode> factory) { + return new FastPathFactory() { + @Override + public RFastPathNode create() { + return factory.get(); + } - default boolean evaluatesArgument(@SuppressWarnings("unused") int index) { - return true; - } + @Override + public RVisibility getVisibility() { + return visibility; + } + + @Override + public boolean evaluatesArgument(int index) { + return true; + } - default boolean forcedEagerPromise(@SuppressWarnings("unused") int index) { - return false; + @Override + public boolean forcedEagerPromise(int index) { + return false; + } + }; } + RFastPathNode create(); + + boolean evaluatesArgument(int index); + + boolean forcedEagerPromise(int index); + /** * Visibility of the output. This corresponds to {@link RBuiltin#visibility()} */ - default RVisibility getVisibility() { - return RVisibility.ON; - } + RVisibility getVisibility(); } 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 3c89158ada69e37d6ad29a517fbdf2f73f29581a..1184323bbc096d7d44bf14011f5f44f38d0b75f3 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 @@ -51,19 +51,18 @@ import com.oracle.truffle.r.runtime.REnvVars; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RErrorHandling; import com.oracle.truffle.r.runtime.RInternalCode.ContextStateImpl; -import com.oracle.truffle.r.runtime.builtins.RBuiltinDescriptor; -import com.oracle.truffle.r.runtime.builtins.RBuiltinKind; -import com.oracle.truffle.r.runtime.builtins.RBuiltinLookup; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.ROptions; import com.oracle.truffle.r.runtime.RProfile; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RRuntimeASTAccess; import com.oracle.truffle.r.runtime.RSerialize; -import com.oracle.truffle.r.runtime.RStartParams; import com.oracle.truffle.r.runtime.RSource; -import com.oracle.truffle.r.runtime.RVisibility; +import com.oracle.truffle.r.runtime.RStartParams; import com.oracle.truffle.r.runtime.Utils; +import com.oracle.truffle.r.runtime.builtins.RBuiltinDescriptor; +import com.oracle.truffle.r.runtime.builtins.RBuiltinKind; +import com.oracle.truffle.r.runtime.builtins.RBuiltinLookup; import com.oracle.truffle.r.runtime.conn.ConnectionSupport; import com.oracle.truffle.r.runtime.conn.StdConnections; import com.oracle.truffle.r.runtime.context.Engine.ParseException; @@ -603,10 +602,18 @@ public final class RContext extends ExecutionContext implements TruffleObject { return engine; } + /** + * This method should only be used under exceptional circumstances; the visibility can be + * derived with {@code GetVisibilityNode}. + */ public boolean isVisible() { return resultVisible; } + /** + * This method should only be used under exceptional circumstances; the visibility can be + * changed with {@code SetVisibilityNode}. + */ public void setVisible(boolean v) { if (!FastROptions.IgnoreVisibility.getBooleanValue()) { /* @@ -618,14 +625,6 @@ public final class RContext extends ExecutionContext implements TruffleObject { } } - public void setVisible(RVisibility visibility) { - if (visibility == RVisibility.ON) { - setVisible(true); - } else if (visibility == RVisibility.OFF) { - setVisible(false); - } - } - public boolean isMethodTableDispatchOn() { return methodTableDispatchOn; } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/RFrameSlot.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/RFrameSlot.java index af64e0c2b744533d75fc7e44b8116cb713bb40e5..cfec997297a6e845e13761bc762f462d23bf5d22 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/RFrameSlot.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/RFrameSlot.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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,6 +22,37 @@ */ package com.oracle.truffle.r.runtime.env.frame; +import java.util.ArrayList; + +import com.oracle.truffle.r.runtime.FastROptions; +import com.oracle.truffle.r.runtime.context.RContext; +import com.oracle.truffle.r.runtime.nodes.RNode; + +/** + * Description of different internal frame slots used by FastR. This enum is used as an identifier, + * so that these internal frame slots have non-string names. + */ public enum RFrameSlot { - OnExit; + /** + * This frame slot is used to store expressions installed as function exit handlers via on.exit. + * It contains an {@link ArrayList} with {@link RNode} elements. + */ + OnExit, + /** + * This frame slot is used to track result visibility when + * {@link FastROptions#OptimizeVisibility} is enabled. It can contain one of three values: + * <ul> + * <li>{@link Boolean#TRUE} if the result is currently visible</li> + * <li>{@link Boolean#FALSE} if the result is currently not visible</li> + * <li>{@code null} if the visibility needs to be determined via{@link RContext#isVisible()} + * </li> + * </ul> + * + * Whenever an {@RBuiltinNode} is called via {@code RCallNode}, the resulting visibility is + * stored in the current frame. At the end of a {@code FunctionDefinitionNode}, the current + * state is stored into {@link RContext#setVisible(boolean)} if it is non-{@code null}. + * Additionally, the frame-local state stored in this frame slot is set to {@code null} after + * each call to a non-builtin function. + */ + Visibility; } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/EvaluatedArgumentsFastPath.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/EvaluatedArgumentsFastPath.java index 7485df6bc517b694b0b08604f64d936c11506bed..82cbd61526bc10abcd5f907a17fba9583a856e24 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/EvaluatedArgumentsFastPath.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/EvaluatedArgumentsFastPath.java @@ -26,6 +26,7 @@ import java.util.Arrays; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.FastROptions; +import com.oracle.truffle.r.runtime.RVisibility; import com.oracle.truffle.r.runtime.builtins.FastPathFactory; final class EvaluatedArgumentsFastPath implements FastPathFactory { @@ -41,6 +42,11 @@ final class EvaluatedArgumentsFastPath implements FastPathFactory { return null; } + @Override + public RVisibility getVisibility() { + return null; + } + @Override public boolean evaluatesArgument(int index) { return false; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RFastPathNode.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RFastPathNode.java index af5a762ce0ded699f73451fffdb63bb5a5084f59..859d2c670d46d5646566adc7fb7c65c2811465cd 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RFastPathNode.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RFastPathNode.java @@ -22,11 +22,9 @@ */ package com.oracle.truffle.r.runtime.nodes; -import com.oracle.truffle.api.dsl.NodeChild; import com.oracle.truffle.api.frame.VirtualFrame; -@NodeChild(value = "arguments", type = RNode[].class) -public abstract class RFastPathNode extends RNode { +public abstract class RFastPathNode extends RBaseNode { public abstract Object execute(VirtualFrame frame, Object... args); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/tck/FastRDebugTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/tck/FastRDebugTest.java index 318c667e9affa52073115f643799afd861e7c6d8..e86035f0b5d6a2565caa9adb7120f1fd45cae09a 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/tck/FastRDebugTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/tck/FastRDebugTest.java @@ -265,7 +265,7 @@ public class FastRDebugTest { Assert.assertEquals(code, actualCode); final MaterializedFrame frame = suspendedEvent.getFrame(); - Assert.assertEquals(expectedFrame.length / 2, frame.getFrameDescriptor().getSize()); + Assert.assertEquals(expectedFrame.length / 2, frameSize(frame)); for (int i = 0; i < expectedFrame.length; i = i + 2) { final String expectedIdentifier = (String) expectedFrame[i]; @@ -277,6 +277,16 @@ public class FastRDebugTest { } run.removeFirst().run(); } + + private int frameSize(MaterializedFrame frame) { + int cnt = 0; + for (FrameSlot slot : frame.getFrameDescriptor().getSlots()) { + if (slot.getIdentifier() instanceof String) { + cnt++; + } + } + return cnt; + } }); } diff --git a/mx.fastr/mx_fastr_pkgs.py b/mx.fastr/mx_fastr_pkgs.py index acde4d86b1b9fd5e027b1502cef15f4d20494bb9..f5771fbc8b29c1146c5725547a3d42d2e71d1415 100644 --- a/mx.fastr/mx_fastr_pkgs.py +++ b/mx.fastr/mx_fastr_pkgs.py @@ -77,7 +77,7 @@ def _installpkgs(args, **kwargs): ''' script = _installpkgs_script() if _is_graalvm(): - rscript = join(_graalvm(), 'bin', 'rscript') + rscript = join(_graalvm(), 'bin', 'Rscript') return mx.run([rscript, script] + args, **kwargs) else: return mx_fastr.rscript([script] + args, **kwargs)