diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lapply.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lapply.java index 54ecf0b6dc9db4eaf3fcfd74062c55e6372bb18c..4cd34ed9f441d06c369bdfc1c72c98880a2d1d24 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lapply.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lapply.java @@ -17,7 +17,6 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; @@ -89,21 +88,18 @@ public abstract class Lapply extends RBuiltinNode { private static final class ExtractElementInternal extends RSourceSectionNode implements RSyntaxCall { - protected ExtractElementInternal() { + @Child private ExtractVectorNode extractElementNode = ExtractVectorNodeGen.create(ElementAccessMode.SUBSCRIPT, false); + private final FrameSlot vectorSlot; + private final FrameSlot indexSlot; + + protected ExtractElementInternal(FrameSlot vectorSlot, FrameSlot indexSlot) { super(RSyntaxNode.LAZY_DEPARSE); + this.vectorSlot = vectorSlot; + this.indexSlot = indexSlot; } - @Child private ExtractVectorNode extractElementNode = ExtractVectorNodeGen.create(ElementAccessMode.SUBSCRIPT, false); - @CompilationFinal private FrameSlot vectorSlot; - @CompilationFinal private FrameSlot indexSlot; - @Override public Object execute(VirtualFrame frame) { - if (vectorSlot == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - vectorSlot = frame.getFrameDescriptor().findFrameSlot("X"); - indexSlot = frame.getFrameDescriptor().findFrameSlot("i"); - } try { return extractElementNode.apply(frame, frame.getObject(vectorSlot), new Object[]{frame.getInt(indexSlot)}, RRuntime.LOGICAL_TRUE, RRuntime.LOGICAL_TRUE); } catch (FrameSlotTypeException e) { @@ -149,8 +145,8 @@ public abstract class Lapply extends RBuiltinNode { @Cached("createVectorSlot(frame)") FrameSlot vectorSlot, // @Cached("create()") RLengthNode lengthNode, // @Cached("createCountingProfile()") LoopConditionProfile loop, // - @Cached("createCallNode()") RCallNode firstCallNode, // - @Cached("createCallNode()") RCallNode callNode) { + @Cached("createCallNode(vectorSlot, indexSlot)") RCallNode firstCallNode, // + @Cached("createCallNode(vectorSlot, indexSlot)") RCallNode callNode) { // TODO: R switches to double if x.getLength() is greater than 2^31-1 frame.setObject(vectorSlot, vector); int length = lengthNode.executeInteger(frame, vector); @@ -171,10 +167,10 @@ public abstract class Lapply extends RBuiltinNode { /** * Creates the {@link RCallNode} for this target and {@code varArgs}. */ - protected RCallNode createCallNode() { + protected RCallNode createCallNode(FrameSlot vectorSlot, FrameSlot indexSlot) { CompilerAsserts.neverPartOfCompilation(); - ExtractElementInternal element = new ExtractElementInternal(); + ExtractElementInternal element = new ExtractElementInternal(vectorSlot, indexSlot); ReadVariableNode readArgs = ReadVariableNode.createSilent(ArgumentsSignature.VARARG_NAME, RType.Any); return RCallNode.createCall(createCallSourceSection(), ReadVariableNode.create("FUN"), ArgumentsSignature.get(null, "..."), element, readArgs); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanScalarNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanScalarNode.java index 00fd37061cd9548111df37b17ddf621dea0401ca..3a3f0fe6d7477ce2aa7426dd4c7ae506f7867b8e 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanScalarNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanScalarNode.java @@ -23,7 +23,6 @@ package com.oracle.truffle.r.nodes.binary; import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; @@ -65,26 +64,19 @@ public abstract class BinaryBooleanScalarNode extends RBuiltinNode { BinaryBooleanScalarNode(BooleanOperationFactory factory) { this.booleanLogic = factory.createOperation(); + logic = new BinaryMapBooleanFunctionNode(booleanLogic); + leftCast = LogicalScalarCastNodeGen.create(booleanLogic.opName(), "x", logic.getLeftNACheck()); + leftBox = BoxPrimitiveNodeGen.create(); + rightCast = LogicalScalarCastNodeGen.create(booleanLogic.opName(), "y", logic.getRightNACheck()); + rightBox = BoxPrimitiveNodeGen.create(); + promiseHelper = new PromiseCheckHelperNode(); } @Specialization protected byte binary(VirtualFrame frame, Object leftValue, Object rightValue) { - if (leftCast == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - logic = insert(new BinaryMapBooleanFunctionNode(booleanLogic)); - leftCast = insert(LogicalScalarCastNodeGen.create(booleanLogic.opName(), "x", logic.getLeftNACheck())); - leftBox = insert(BoxPrimitiveNodeGen.create()); - } byte left = leftCast.executeCast(leftBox.execute(leftValue)); if (profile.profile(logic.requiresRightOperand(left))) { - if (rightCast == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - rightCast = insert(LogicalScalarCastNodeGen.create(booleanLogic.opName(), "y", logic.getRightNACheck())); - rightBox = insert(BoxPrimitiveNodeGen.create()); - promiseHelper = insert(new PromiseCheckHelperNode()); - } - byte right = rightCast.executeCast(rightBox.execute(promiseHelper.checkEvaluate(frame, rightValue))); - return logic.applyLogical(left, right); + return logic.applyLogical(left, rightCast.executeCast(rightBox.execute(promiseHelper.checkEvaluate(frame, rightValue)))); } return left; } 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 4a2c89ad48a62fc5debd7c6be8f4bb3ca2864f8e..2e3030709b306ecc445d7a5bdf376c11bf1ea4f5 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 @@ -30,6 +30,7 @@ import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.frame.FrameDescriptor; 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; @@ -101,24 +102,13 @@ public final class FunctionDefinitionNode extends RRootNode implements RSyntaxNo private final BranchProfile breakProfile = BranchProfile.create(); private final BranchProfile nextProfile = BranchProfile.create(); - @CompilationFinal private BranchProfile invalidateFrameSlotProfile; - // S3/S4 slots - @Child private FrameSlotNode dotGenericSlot; - @Child private FrameSlotNode dotMethodSlot; - // S3 slots - @Child private FrameSlotNode dotClassSlot; - @Child private FrameSlotNode dotGenericCallEnvSlot; - @Child private FrameSlotNode dotGenericCallDefSlot; - @Child private FrameSlotNode dotGroupSlot; - // S4 slots - @Child private FrameSlotNode dotDefinedSlot; - @Child private FrameSlotNode dotTargetSlot; - @Child private FrameSlotNode dotMethodsSlot; - @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); @Child private PostProcessArgumentsNode argPostProcess; + @Child private SetupS3ArgsNode setupS3Args; + @Child private SetupS4ArgsNode setupS4Args; + private final boolean needsSplitting; @CompilationFinal private boolean containsDispatch; @@ -317,55 +307,88 @@ public final class FunctionDefinitionNode extends RRootNode implements RSyntaxNo } } + private abstract static class SetupDispatchNode extends Node { + // S3/S4 slots + private final FrameSlot dotGenericSlot; + private final FrameSlot dotMethodSlot; + + final BranchProfile invalidateFrameSlotProfile = BranchProfile.create(); + + SetupDispatchNode(FrameDescriptor frameDescriptor) { + dotGenericSlot = FrameSlotChangeMonitor.findOrAddFrameSlot(frameDescriptor, RRuntime.R_DOT_GENERIC, FrameSlotKind.Object); + dotMethodSlot = FrameSlotChangeMonitor.findOrAddFrameSlot(frameDescriptor, RRuntime.R_DOT_METHOD, FrameSlotKind.Object); + } + + void execute(VirtualFrame frame, DispatchArgs args) { + FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGenericSlot, args.generic, false, invalidateFrameSlotProfile); + FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotMethodSlot, args.method, false, invalidateFrameSlotProfile); + } + } + + private static final class SetupS3ArgsNode extends SetupDispatchNode { + // S3 slots + private final FrameSlot dotClassSlot; + private final FrameSlot dotGenericCallEnvSlot; + private final FrameSlot dotGenericCallDefSlot; + private final FrameSlot dotGroupSlot; + + SetupS3ArgsNode(FrameDescriptor frameDescriptor) { + super(frameDescriptor); + dotClassSlot = FrameSlotChangeMonitor.findOrAddFrameSlot(frameDescriptor, RRuntime.R_DOT_CLASS, FrameSlotKind.Object); + dotGenericCallEnvSlot = FrameSlotChangeMonitor.findOrAddFrameSlot(frameDescriptor, RRuntime.R_DOT_GENERIC_CALL_ENV, FrameSlotKind.Object); + dotGenericCallDefSlot = FrameSlotChangeMonitor.findOrAddFrameSlot(frameDescriptor, RRuntime.R_DOT_GENERIC_DEF_ENV, FrameSlotKind.Object); + dotGroupSlot = FrameSlotChangeMonitor.findOrAddFrameSlot(frameDescriptor, RRuntime.R_DOT_GROUP, FrameSlotKind.Object); + } + + void execute(VirtualFrame frame, S3Args args) { + super.execute(frame, args); + FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotClassSlot, args.clazz, false, invalidateFrameSlotProfile); + FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGenericCallEnvSlot, args.callEnv, false, invalidateFrameSlotProfile); + FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGenericCallDefSlot, args.defEnv, false, invalidateFrameSlotProfile); + FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGroupSlot, args.group, false, invalidateFrameSlotProfile); + } + } + + private static final class SetupS4ArgsNode extends SetupDispatchNode { + // S4 slots + private final FrameSlot dotDefinedSlot; + private final FrameSlot dotTargetSlot; + private final FrameSlot dotMethodsSlot; + + SetupS4ArgsNode(FrameDescriptor frameDescriptor) { + super(frameDescriptor); + dotDefinedSlot = FrameSlotChangeMonitor.findOrAddFrameSlot(frameDescriptor, RRuntime.R_DOT_DEFINED, FrameSlotKind.Object); + dotTargetSlot = FrameSlotChangeMonitor.findOrAddFrameSlot(frameDescriptor, RRuntime.R_DOT_TARGET, FrameSlotKind.Object); + dotMethodsSlot = FrameSlotChangeMonitor.findOrAddFrameSlot(frameDescriptor, RRuntime.R_DOT_METHODS, FrameSlotKind.Object); + } + + void execute(VirtualFrame frame, S4Args args) { + super.execute(frame, args); + FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotDefinedSlot, args.defined, false, invalidateFrameSlotProfile); + FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotTargetSlot, args.target, false, invalidateFrameSlotProfile); + FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotMethodsSlot, args.methods, false, invalidateFrameSlotProfile); + } + } + private void setupDispatchSlots(VirtualFrame frame) { DispatchArgs dispatchArgs = RArguments.getDispatchArgs(frame); if (dispatchArgs == null) { return; } - if (dotGenericSlot == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - assert invalidateFrameSlotProfile == null && dotMethodSlot == null; - invalidateFrameSlotProfile = BranchProfile.create(); - FrameDescriptor frameDescriptor = frame.getFrameDescriptor(); - - dotGenericSlot = insert(FrameSlotNode.createInitialized(frameDescriptor, RRuntime.R_DOT_GENERIC, true)); - dotMethodSlot = insert(FrameSlotNode.createInitialized(frameDescriptor, RRuntime.R_DOT_METHOD, true)); - } - FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGenericSlot.executeFrameSlot(frame), dispatchArgs.generic, false, invalidateFrameSlotProfile); - FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotMethodSlot.executeFrameSlot(frame), dispatchArgs.method, false, invalidateFrameSlotProfile); - if (dispatchArgs instanceof S3Args) { S3Args s3Args = (S3Args) dispatchArgs; - if (dotClassSlot == null) { + if (setupS3Args == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - assert dotGenericCallEnvSlot == null && dotGenericCallDefSlot == null && dotGroupSlot == null; - invalidateFrameSlotProfile = BranchProfile.create(); - FrameDescriptor frameDescriptor = frame.getFrameDescriptor(); - - dotClassSlot = insert(FrameSlotNode.createInitialized(frameDescriptor, RRuntime.R_DOT_CLASS, true)); - dotGenericCallEnvSlot = insert(FrameSlotNode.createInitialized(frameDescriptor, RRuntime.R_DOT_GENERIC_CALL_ENV, true)); - dotGenericCallDefSlot = insert(FrameSlotNode.createInitialized(frameDescriptor, RRuntime.R_DOT_GENERIC_DEF_ENV, true)); - dotGroupSlot = insert(FrameSlotNode.createInitialized(frameDescriptor, RRuntime.R_DOT_GROUP, true)); + setupS3Args = insert(new SetupS3ArgsNode(frame.getFrameDescriptor())); } - FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotClassSlot.executeFrameSlot(frame), s3Args.clazz, false, invalidateFrameSlotProfile); - FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGenericCallEnvSlot.executeFrameSlot(frame), s3Args.callEnv, false, invalidateFrameSlotProfile); - FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGenericCallDefSlot.executeFrameSlot(frame), s3Args.defEnv, false, invalidateFrameSlotProfile); - FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGroupSlot.executeFrameSlot(frame), s3Args.group, false, invalidateFrameSlotProfile); + setupS3Args.execute(frame, s3Args); } else { S4Args s4Args = (S4Args) dispatchArgs; - if (dotDefinedSlot == null) { + if (setupS4Args == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - assert dotTargetSlot == null && dotMethodsSlot == null; - invalidateFrameSlotProfile = BranchProfile.create(); - FrameDescriptor frameDescriptor = frame.getFrameDescriptor(); - - dotDefinedSlot = insert(FrameSlotNode.createInitialized(frameDescriptor, RRuntime.R_DOT_DEFINED, true)); - dotTargetSlot = insert(FrameSlotNode.createInitialized(frameDescriptor, RRuntime.R_DOT_TARGET, true)); - dotMethodsSlot = insert(FrameSlotNode.createInitialized(frameDescriptor, RRuntime.R_DOT_METHODS, true)); + setupS4Args = insert(new SetupS4ArgsNode(frame.getFrameDescriptor())); } - FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotDefinedSlot.executeFrameSlot(frame), s4Args.defined, false, invalidateFrameSlotProfile); - FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotTargetSlot.executeFrameSlot(frame), s4Args.target, false, invalidateFrameSlotProfile); - FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotMethodsSlot.executeFrameSlot(frame), s4Args.methods, false, invalidateFrameSlotProfile); + setupS4Args.execute(frame, s4Args); } }