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 d202fe1015cfe2a332ff77da078972284f3fecf1..9d15a921074ee56752d4aeae6f3c7cb48bf0f3e4 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 @@ -35,6 +35,7 @@ import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.NodeChild; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.dsl.TypeSystemReference; +import com.oracle.truffle.api.frame.FrameSlot; import com.oracle.truffle.api.frame.FrameSlotTypeException; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; @@ -55,7 +56,6 @@ import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout; import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.RRootNode; import com.oracle.truffle.r.nodes.access.ConstantNode; -import com.oracle.truffle.r.nodes.access.FrameSlotNode; import com.oracle.truffle.r.nodes.access.variables.LocalReadVariableNode; import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; @@ -234,11 +234,11 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS } protected FunctionDispatch createUninitializedCall() { - return FunctionDispatchNodeGen.create(this, null, explicitArgs == null ? false : true); + return FunctionDispatchNodeGen.create(this, explicitArgs != null, null); } protected FunctionDispatch createUninitializedExplicitCall() { - return FunctionDispatchNodeGen.create(this, null, true); + return FunctionDispatchNodeGen.create(this, true, null); } /** @@ -284,7 +284,7 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS @Cached("createBinaryProfile()") ConditionProfile resultIsBuiltinProfile) { RBuiltinDescriptor builtin = builtinProfile.profile(function.getRBuiltin()); Object dispatchObject = dispatchArgument.execute(frame); - dispatchTempSlot.initialize(frame, dispatchObject, () -> internalDispatchCall = null); + FrameSlot slot = dispatchTempSlot.initialize(frame, dispatchObject); try { RStringVector type = classHierarchyNode.execute(dispatchObject); S3Args s3Args; @@ -301,13 +301,13 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS s3Args = null; resultFunction = function; } - if (internalDispatchCall == null) { + if (internalDispatchCall == null || internalDispatchCall.tempFrameSlot != slot) { CompilerDirectives.transferToInterpreterAndInvalidate(); - internalDispatchCall = insert(FunctionDispatchNodeGen.create(this, new Object[]{dispatchTempSlot.getIdentifier()}, false)); + internalDispatchCall = insert(FunctionDispatchNodeGen.create(this, false, slot)); } return internalDispatchCall.execute(frame, resultFunction, lookupVarArgs(frame), s3Args, null); } finally { - dispatchTempSlot.cleanup(frame, dispatchObject); + TemporarySlotNode.cleanup(frame, dispatchObject, slot); } } @@ -548,11 +548,11 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS return getParentCallNode().getFunctionNode(); } - public CallArgumentsNode createArguments(Object[] dispatchTempIdentifiers, boolean modeChange, boolean modeChangeAppliesToAll) { + public CallArgumentsNode createArguments(FrameSlot tempFrameSlot, boolean modeChange, boolean modeChangeAppliesToAll) { RNode[] args = new RNode[arguments.length]; for (int i = 0; i < arguments.length; i++) { - if (dispatchTempIdentifiers != null && i < dispatchTempIdentifiers.length) { - args[i] = new GetTempNode(dispatchTempIdentifiers[i], arguments[i]); + if (tempFrameSlot != null && i == 0) { + args[i] = new GetTempNode(tempFrameSlot, arguments[i]); } else { args[i] = arguments[i] == null ? null : RASTUtils.cloneNode(arguments[i].asRNode()); } @@ -570,7 +570,7 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS */ public static RNode createInternalCall(RCallNode internalCallArg, RFunction function) { CompilerAsserts.neverPartOfCompilation(); - return new InternalNode(FunctionDispatchNodeGen.create(internalCallArg, null, false), function, internalCallArg.lookupVarArgs != null); + return new InternalNode(FunctionDispatchNodeGen.create(internalCallArg, false, null), function, internalCallArg.lookupVarArgs != null); } @NodeInfo(cost = NodeCost.NONE) @@ -654,11 +654,11 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS private static final class GetTempNode extends RNode { - @Child private FrameSlotNode slot; + private final FrameSlot slot; private final RSyntaxNode arg; - GetTempNode(Object identifier, RSyntaxNode arg) { - slot = FrameSlotNode.createTemp(identifier, false); + GetTempNode(FrameSlot slot, RSyntaxNode arg) { + this.slot = slot; this.arg = arg; } @@ -670,7 +670,7 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS @Override public Object execute(VirtualFrame frame) { try { - return frame.getObject(slot.executeFrameSlot(frame)); + return frame.getObject(slot); } catch (FrameSlotTypeException e) { throw RInternalError.shouldNotReachHere(); } @@ -691,13 +691,14 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS protected static final int CACHE_SIZE = 4; private final RCallNode originalCall; - private final Object[] dispatchTempIdentifiers; private final boolean explicitArgs; - public FunctionDispatch(RCallNode originalCall, Object[] dispatchTempIdentifiers, boolean explicitArgs) { + private final FrameSlot tempFrameSlot; + + public FunctionDispatch(RCallNode originalCall, boolean explicitArgs, FrameSlot tempFrameSlot) { this.originalCall = originalCall; - this.dispatchTempIdentifiers = dispatchTempIdentifiers; this.explicitArgs = explicitArgs; + this.tempFrameSlot = tempFrameSlot; } protected LeafCallNode createCacheNode(RootCallTarget cachedTarget) { @@ -717,7 +718,7 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS if (explicitArgs) { return PrepareArguments.createExplicit(root); } else { - CallArgumentsNode args = originalCall.createArguments(dispatchTempIdentifiers, root.getBuiltin() == null, true); + CallArgumentsNode args = originalCall.createArguments(tempFrameSlot, root.getBuiltin() == null, true); return PrepareArguments.create(root, args, noOpt); } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/TemporarySlotNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/TemporarySlotNode.java index cab3f3c4da90b28fb840338a03006ebcd7bb9b31..03e13b0d068b6a277a8511029d130b4bab6ba20b 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/TemporarySlotNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/TemporarySlotNode.java @@ -37,33 +37,35 @@ public final class TemporarySlotNode extends Node { @CompilationFinal private FrameSlot tempSlot; private int tempIdentifier; - private Object identifier; - public void initialize(VirtualFrame frame, Object value, Runnable invalidate) { + public FrameSlot initialize(VirtualFrame frame, Object value) { if (tempSlot == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - tempSlot = frame.getFrameDescriptor().findOrAddFrameSlot(identifier = defaultTempIdentifiers[0], FrameSlotKind.Object); - invalidate.run(); + tempSlot = frame.getFrameDescriptor().findOrAddFrameSlot(defaultTempIdentifiers[0], FrameSlotKind.Object); } + FrameSlot slot = tempSlot; try { - if (frame.getObject(tempSlot) != null) { + if (frame.getObject(slot) != null) { CompilerDirectives.transferToInterpreterAndInvalidate(); // keep the complete loop in the slow path do { tempIdentifier++; - identifier = tempIdentifier < defaultTempIdentifiers.length ? defaultTempIdentifiers[tempIdentifier] : new Object(); - tempSlot = frame.getFrameDescriptor().findOrAddFrameSlot(identifier, FrameSlotKind.Object); - invalidate.run(); - } while (frame.getObject(tempSlot) != null); + Object identifier = tempIdentifier < defaultTempIdentifiers.length ? defaultTempIdentifiers[tempIdentifier] : new Object(); + tempSlot = slot = frame.getFrameDescriptor().findOrAddFrameSlot(identifier, FrameSlotKind.Object); + if (frame.getObject(slot) == null) { + break; + } + } while (true); } } catch (FrameSlotTypeException e) { CompilerDirectives.transferToInterpreter(); throw RInternalError.shouldNotReachHere(); } - frame.setObject(tempSlot, value); + frame.setObject(slot, value); + return slot; } - public void cleanup(VirtualFrame frame, Object object) { + public static void cleanup(VirtualFrame frame, Object object, FrameSlot tempSlot) { try { assert frame.getObject(tempSlot) == object; } catch (FrameSlotTypeException e) { @@ -71,8 +73,4 @@ public final class TemporarySlotNode extends Node { } frame.setObject(tempSlot, null); } - - public Object getIdentifier() { - return identifier; - } }