diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallArgumentsNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallArgumentsNode.java index a6b47df08fbe1e6680aceccc60eb82e8b5dbc14e..2175be7d030ab6664ce01b7a2e5ab52691aa31f8 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallArgumentsNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallArgumentsNode.java @@ -164,35 +164,33 @@ public final class CallArgumentsNode extends RBaseNode implements UnmatchedArgum } @ExplodeLoop - public RArgsValuesAndNames evaluateFlatten(VirtualFrame frame, RArgsValuesAndNames varArgs) { - int size = arguments.length; - ArgumentsSignature resultSignature = null; + public ArgumentsSignature flattenNames(RArgsValuesAndNames varArgs) { String[] names = null; - if (containsVarArgsSymbol()) { - size += (varArgs.getLength() - 1) * varArgsSymbolIndices.length; - names = new String[size]; - } else { - resultSignature = signature; + if (!containsVarArgsSymbol()) { + return signature; } - Object[] values = new Object[size]; + int size = arguments.length + (varArgs.getLength() - 1) * varArgsSymbolIndices.length; + names = new String[size]; int vargsSymbolsIndex = 0; int index = 0; for (int i = 0; i < arguments.length; i++) { if (vargsSymbolsIndex < varArgsSymbolIndices.length && varArgsSymbolIndices[vargsSymbolsIndex] == i) { - index = flattenVarArgs(frame, varArgs, names, values, index); + index = flattenVarArgNames(varArgs, names, index); vargsSymbolsIndex++; } else { - values[index] = arguments[i] == null ? RMissing.instance : arguments[i].execute(frame); - if (names != null) { - names[index] = signature.getName(i); - } - index++; + names[index++] = signature.getName(i); } } - if (resultSignature == null) { - resultSignature = ArgumentsSignature.get(names); + return ArgumentsSignature.get(names); + } + + private static int flattenVarArgNames(RArgsValuesAndNames varArgInfo, String[] names, int startIndex) { + int index = startIndex; + for (int j = 0; j < varArgInfo.getLength(); j++) { + names[index] = varArgInfo.getSignature().getName(j); + index++; } - return new RArgsValuesAndNames(values, resultSignature); + return index; } @ExplodeLoop @@ -216,7 +214,7 @@ public final class CallArgumentsNode extends RBaseNode implements UnmatchedArgum return values; } - private int flattenVarArgs(VirtualFrame frame, RArgsValuesAndNames varArgInfo, String[] names, Object[] values, int startIndex) { + private int flattenVarArgsObject(VirtualFrame frame, RArgsValuesAndNames varArgInfo, Object[] values, int startIndex) { int index = startIndex; for (int j = 0; j < varArgInfo.getLength(); j++) { if (promiseHelper == null) { @@ -224,7 +222,6 @@ public final class CallArgumentsNode extends RBaseNode implements UnmatchedArgum promiseHelper = insert(new PromiseCheckHelperNode()); } values[index] = promiseHelper.checkEvaluate(frame, varArgInfo.getArgument(j)); - names[index] = varArgInfo.getSignature().getName(j); index++; } return index; @@ -265,17 +262,4 @@ public final class CallArgumentsNode extends RBaseNode implements UnmatchedArgum } return result; } - - private int flattenVarArgsObject(VirtualFrame frame, RArgsValuesAndNames varArgInfo, Object[] values, int startIndex) { - int index = startIndex; - for (int j = 0; j < varArgInfo.getLength(); j++) { - if (promiseHelper == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - promiseHelper = insert(new PromiseCheckHelperNode()); - } - values[index] = promiseHelper.checkEvaluate(frame, varArgInfo.getArgument(j)); - index++; - } - return index; - } } 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 2f927add9f63457dbc41c674363a543a23317eca..3fd1262d5da9de9454e1510cf9bebcd44c0eb255 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 @@ -129,6 +129,7 @@ public final class FunctionDefinitionNode extends RRootNode implements RSyntaxNo * Profiling for catching {@link ReturnException}s. */ private final BranchProfile returnProfile = BranchProfile.create(); + private final ConditionProfile returnTopLevelProfile = ConditionProfile.createBinaryProfile(); private final ConditionProfile returnHereProfile = ConditionProfile.createBinaryProfile(); public static FunctionDefinitionNode create(SourceSection src, FrameDescriptor frameDesc, SourceSection[] argSourceSections, SaveArgumentsNode saveArguments, RSyntaxNode body, @@ -262,7 +263,7 @@ public final class FunctionDefinitionNode extends RRootNode implements RSyntaxNo } catch (ReturnException ex) { returnProfile.enter(); int depth = ex.getDepth(); - if (returnHereProfile.profile(depth != -1 && RArguments.getDepth(frame) != depth)) { + if (returnTopLevelProfile.profile(depth != -1) && returnHereProfile.profile(RArguments.getDepth(frame) != depth)) { throw ex; } else { return ex.getResult(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseHelperNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseHelperNode.java index e117aeaedcbcc941d2f6a5c5e2af6f7673d4fdfd..5f38938b8713280ce8c5e9e997d92d557178e2d4 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseHelperNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseHelperNode.java @@ -138,6 +138,7 @@ public class PromiseHelperNode extends RBaseNode { private final ValueProfile multiVarArgsOptTypeProfile = ValueProfile.createIdentityProfile(); private final ValueProfile promiseFrameProfile = ValueProfile.createClassProfile(); private final BranchProfile varArgProfile = BranchProfile.create(); + private final ConditionProfile chckPromiseMismatch = ConditionProfile.createBinaryProfile(); /** * Guarded by {@link #isInOriginFrame(VirtualFrame,RPromise)}. @@ -236,13 +237,20 @@ public class PromiseHelperNode extends RBaseNode { * can occur so we don't need the {@link PromiseEvalFrame} (even if the frames are different). * */ - private static Frame checkCreatePromiseEvalFrame(Frame frame, Frame promiseFrame, RPromise promise) { - if (frame != null && RArguments.getDepth(frame) != RArguments.getDepth(promiseFrame)) { + private Frame checkCreatePromiseEvalFrame(Frame frame, Frame promiseFrame, RPromise promise) { + if (frame != null && chckPromiseMismatch.profile(RArguments.getDepth(frame) != RArguments.getDepth(promiseFrame))) { return PromiseEvalFrame.create(frame, promiseFrame.materialize(), promise); } else { return promiseFrame; } + } + private static Frame checkCreatePromiseEvalFrameSlowPath(Frame frame, Frame promiseFrame, RPromise promise) { + if (frame != null && RArguments.getDepth(frame) != RArguments.getDepth(promiseFrame)) { + return PromiseEvalFrame.create(frame, promiseFrame.materialize(), promise); + } else { + return promiseFrame; + } } private Object generateValueEager(VirtualFrame frame, OptType optType, EagerPromise promise) { @@ -313,7 +321,7 @@ public class PromiseHelperNode extends RBaseNode { Frame promiseFrame = promise.getFrame(); assert promiseFrame != null; try { - Frame promiseEvalFrame = checkCreatePromiseEvalFrame(frame, promiseFrame, promise); + Frame promiseEvalFrame = checkCreatePromiseEvalFrameSlowPath(frame, promiseFrame, promise); if (PromiseEvalFrameDebug.enabled) { PromiseEvalFrameDebug.doPromiseEval(true, frame, promiseFrame, promise); } 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 7117b9d93ec754301f8f7e949ca6323419441b4a..944d1f1fb24625ea734dbefbbfa81d8b06ec6bc5 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 @@ -68,7 +68,6 @@ 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.PrepareArguments; -import com.oracle.truffle.r.nodes.function.signature.RArgumentsNode; import com.oracle.truffle.r.nodes.profile.TruffleBoundaryNode; import com.oracle.truffle.r.nodes.unary.CastNode; import com.oracle.truffle.r.runtime.Arguments; @@ -409,12 +408,12 @@ public abstract class RCallNode extends RNode implements RSyntaxNode, RSyntaxCal @Cached("createPromiseHelper()") PromiseCheckHelperNode promiseHelperNode, // @Cached("createUninitializedExplicitCall()") FunctionDispatch call) { - RArgsValuesAndNames argAndNames = explicitArgs != null ? (RArgsValuesAndNames) explicitArgs.execute(frame) : callArguments.evaluateFlatten(frame, lookupVarArgs(frame)); + Object[] args = explicitArgs != null ? ((RArgsValuesAndNames) explicitArgs.execute(frame)).getArguments() : callArguments.evaluateFlattenObjects(frame, lookupVarArgs(frame)); RBuiltinDescriptor builtin = builtinProfile.profile(function.getRBuiltin()); RDispatch dispatch = builtin.getDispatch(); - RStringVector typeX = classHierarchyNodeX.execute(promiseHelperNode.checkEvaluate(frame, argAndNames.getArgument(0))); + RStringVector typeX = classHierarchyNodeX.execute(promiseHelperNode.checkEvaluate(frame, args[0])); Result resultX = null; if (implicitTypeProfileX.profile(typeX != null)) { try { @@ -424,8 +423,8 @@ public abstract class RCallNode extends RNode implements RSyntaxNode, RSyntaxCal } } Result resultY = null; - if (argAndNames.getLength() > 1 && dispatch == RDispatch.OPS_GROUP_GENERIC) { - RStringVector typeY = classHierarchyNodeY.execute(promiseHelperNode.checkEvaluate(frame, argAndNames.getArgument(1))); + if (args.length > 1 && dispatch == RDispatch.OPS_GROUP_GENERIC) { + RStringVector typeY = classHierarchyNodeY.execute(promiseHelperNode.checkEvaluate(frame, args[1])); if (implicitTypeProfileY.profile(typeY != null)) { try { resultY = dispatchLookupY.execute(frame, builtin.getName(), typeY, dispatch.getGroupGenericName(), frame.materialize(), null); @@ -460,20 +459,24 @@ public abstract class RCallNode extends RNode implements RSyntaxNode, RSyntaxCal } } } - S3Args s3Args; - RFunction resultFunction; + final S3Args s3Args; + final RFunction resultFunction; + final ArgumentsSignature argsSignature; if (result == null) { s3Args = null; resultFunction = function; + argsSignature = ArgumentsSignature.empty(args.length); } else { if (resultIsBuiltinProfile.profile(result.function.isBuiltin())) { s3Args = null; + argsSignature = ArgumentsSignature.empty(args.length); } else { s3Args = new S3Args(builtin.getName(), result.clazz, dotMethod, frame.materialize(), null, result.groupMatch ? dispatch.getGroupGenericName() : null); + argsSignature = explicitArgs != null ? ((RArgsValuesAndNames) explicitArgs.execute(frame)).getSignature() : callArguments.flattenNames(lookupVarArgs(frame)); } resultFunction = result.function; } - return call.execute(frame, resultFunction, argAndNames, s3Args); + return call.execute(frame, resultFunction, new RArgsValuesAndNames(args, argsSignature), s3Args); } protected class ForeignCall extends Node { @@ -964,7 +967,6 @@ public abstract class RCallNode extends RNode implements RSyntaxNode, RSyntaxCal private static final class DispatchedCallNode extends LeafCallNode { @Child private DirectCallNode call; - @Child private RArgumentsNode argsNode; @Child private RFastPathNode fastPath; private final ArgumentsSignature signature; @@ -989,17 +991,16 @@ public abstract class RCallNode extends RNode implements RSyntaxNode, RSyntaxCal fastPath = null; } - if (argsNode == null) { + if (call == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - argsNode = insert(RArgumentsNode.create()); call = insert(Truffle.getRuntime().createDirectCallNode(cachedFunction.getTarget())); if (needsSplitting(cachedFunction)) { call.cloneCallTarget(); } } - MaterializedFrame callerFrame = CompilerDirectives.inInterpreter() || originalCall.needsCallerFrame ? frame.materialize() : null; - Object[] argsObject = argsNode.execute(cachedFunction, originalCall.createCaller(frame, cachedFunction), callerFrame, RArguments.getDepth(frame) + 1, RArguments.getPromiseFrame(frame), - orderedArguments, signature, s3Args); + MaterializedFrame callerFrame = /* CompilerDirectives.inInterpreter() || */originalCall.needsCallerFrame ? frame.materialize() : null; + Object[] argsObject = RArguments.create(cachedFunction, originalCall.createCaller(frame, cachedFunction), callerFrame, RArguments.getDepth(frame) + 1, RArguments.getPromiseFrame(frame), + orderedArguments, signature, cachedFunction.getEnclosingFrame(), s3Args); return call.call(frame, argsObject); } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/OptVariablePromiseBaseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/OptVariablePromiseBaseNode.java index 9de276c9d04a3b1133b0e61060d795002058e336..721826a0a6a8c6e36ef3a5b5a0f19530873f0698 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/OptVariablePromiseBaseNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/OptVariablePromiseBaseNode.java @@ -28,6 +28,7 @@ import com.oracle.truffle.api.frame.FrameSlot; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.InvalidAssumptionException; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.api.profiles.ValueProfile; 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; @@ -51,6 +52,7 @@ public abstract class OptVariablePromiseBaseNode extends PromiseNode implements private final int wrapIndex; private final ConditionProfile promiseEvalFrameProfile = ConditionProfile.createBinaryProfile(); + private final ValueProfile frameProfile = ValueProfile.createClassProfile(); public OptVariablePromiseBaseNode(RPromiseFactory factory, ReadVariableNode rvn, int wrapIndex) { super(factory); @@ -71,7 +73,7 @@ public abstract class OptVariablePromiseBaseNode extends PromiseNode implements public Object execute(VirtualFrame initialFrame) { VirtualFrame frame; if (promiseEvalFrameProfile.profile(initialFrame instanceof PromiseEvalFrame)) { - frame = SubstituteVirtualFrame.create(((PromiseEvalFrame) initialFrame).getOriginalFrame()); + frame = frameProfile.profile(SubstituteVirtualFrame.create(((PromiseEvalFrame) initialFrame).getOriginalFrame())); } else { frame = initialFrame; } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/NSBaseMaterializedFrame.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/NSBaseMaterializedFrame.java index 69da8f799bce1ea6f825880c4359a1292fceeb39..af7d7af6ec7e74c8c527523e9c58216cd6736c29 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/NSBaseMaterializedFrame.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/NSBaseMaterializedFrame.java @@ -29,6 +29,7 @@ import com.oracle.truffle.api.frame.FrameDescriptor; 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.profiles.ValueProfile; import com.oracle.truffle.r.runtime.RArguments; /** @@ -38,6 +39,8 @@ import com.oracle.truffle.r.runtime.RArguments; */ public final class NSBaseMaterializedFrame implements MaterializedFrame { + private static final ValueProfile frameProfile = ValueProfile.createClassProfile(); + private final MaterializedFrame packageBaseFrame; @CompilationFinal private final Object[] arguments; @@ -52,6 +55,10 @@ public final class NSBaseMaterializedFrame implements MaterializedFrame { RArguments.initializeEnclosingFrame(this, globalFrame); } + private MaterializedFrame getPackageBaseFrame() { + return frameProfile.profile(packageBaseFrame); + } + public void updateGlobalFrame(MaterializedFrame globalFrame) { RArguments.setEnclosingFrame(this, globalFrame); } @@ -62,7 +69,7 @@ public final class NSBaseMaterializedFrame implements MaterializedFrame { @Override public FrameDescriptor getFrameDescriptor() { - return packageBaseFrame.getFrameDescriptor(); + return getPackageBaseFrame().getFrameDescriptor(); } @Override @@ -81,111 +88,111 @@ public final class NSBaseMaterializedFrame implements MaterializedFrame { @Override public Object getObject(FrameSlot slot) throws FrameSlotTypeException { - return packageBaseFrame.getObject(slot); + return getPackageBaseFrame().getObject(slot); } @Override public void setObject(FrameSlot slot, Object value) { - packageBaseFrame.setObject(slot, value); + getPackageBaseFrame().setObject(slot, value); } @Override public byte getByte(FrameSlot slot) throws FrameSlotTypeException { - return packageBaseFrame.getByte(slot); + return getPackageBaseFrame().getByte(slot); } @Override public void setByte(FrameSlot slot, byte value) { - packageBaseFrame.setByte(slot, value); + getPackageBaseFrame().setByte(slot, value); } @Override public boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException { - return packageBaseFrame.getBoolean(slot); + return getPackageBaseFrame().getBoolean(slot); } @Override public void setBoolean(FrameSlot slot, boolean value) { - packageBaseFrame.setBoolean(slot, value); + getPackageBaseFrame().setBoolean(slot, value); } @Override public int getInt(FrameSlot slot) throws FrameSlotTypeException { - return packageBaseFrame.getInt(slot); + return getPackageBaseFrame().getInt(slot); } @Override public void setInt(FrameSlot slot, int value) { - packageBaseFrame.setInt(slot, value); + getPackageBaseFrame().setInt(slot, value); } @Override public long getLong(FrameSlot slot) throws FrameSlotTypeException { - return packageBaseFrame.getLong(slot); + return getPackageBaseFrame().getLong(slot); } @Override public void setLong(FrameSlot slot, long value) { - packageBaseFrame.setLong(slot, value); + getPackageBaseFrame().setLong(slot, value); } @Override public float getFloat(FrameSlot slot) throws FrameSlotTypeException { - return packageBaseFrame.getFloat(slot); + return getPackageBaseFrame().getFloat(slot); } @Override public void setFloat(FrameSlot slot, float value) { - packageBaseFrame.setFloat(slot, value); + getPackageBaseFrame().setFloat(slot, value); } @Override public double getDouble(FrameSlot slot) throws FrameSlotTypeException { - return packageBaseFrame.getDouble(slot); + return getPackageBaseFrame().getDouble(slot); } @Override public void setDouble(FrameSlot slot, double value) { - packageBaseFrame.setDouble(slot, value); + getPackageBaseFrame().setDouble(slot, value); } @Override public Object getValue(FrameSlot slot) { - return packageBaseFrame.getValue(slot); + return getPackageBaseFrame().getValue(slot); } @Override public boolean isObject(FrameSlot slot) { - return packageBaseFrame.isObject(slot); + return getPackageBaseFrame().isObject(slot); } @Override public boolean isByte(FrameSlot slot) { - return packageBaseFrame.isByte(slot); + return getPackageBaseFrame().isByte(slot); } @Override public boolean isBoolean(FrameSlot slot) { - return packageBaseFrame.isBoolean(slot); + return getPackageBaseFrame().isBoolean(slot); } @Override public boolean isInt(FrameSlot slot) { - return packageBaseFrame.isInt(slot); + return getPackageBaseFrame().isInt(slot); } @Override public boolean isLong(FrameSlot slot) { - return packageBaseFrame.isLong(slot); + return getPackageBaseFrame().isLong(slot); } @Override public boolean isFloat(FrameSlot slot) { - return packageBaseFrame.isFloat(slot); + return getPackageBaseFrame().isFloat(slot); } @Override public boolean isDouble(FrameSlot slot) { - return packageBaseFrame.isDouble(slot); + return getPackageBaseFrame().isDouble(slot); } }