From 16b6f941ec40dea125ea30d276ba332155d5db9d Mon Sep 17 00:00:00 2001 From: Lukas Stadler <lukas.stadler@oracle.com> Date: Tue, 6 Jun 2017 13:46:26 +0200 Subject: [PATCH] slow path without deop for PrepareArguments --- .../nodes/function/call/PrepareArguments.java | 49 +++++++++++++++++-- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/PrepareArguments.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/PrepareArguments.java index 554d2b2b0e..62c6f044fb 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/PrepareArguments.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/PrepareArguments.java @@ -27,6 +27,7 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; 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.ExplodeLoop; import com.oracle.truffle.api.nodes.Node; @@ -38,11 +39,13 @@ import com.oracle.truffle.r.nodes.function.FormalArguments; import com.oracle.truffle.r.nodes.function.RCallNode; import com.oracle.truffle.r.nodes.function.call.PrepareArgumentsFactory.PrepareArgumentsDefaultNodeGen; import com.oracle.truffle.r.nodes.function.call.PrepareArgumentsFactory.PrepareArgumentsExplicitNodeGen; +import com.oracle.truffle.r.nodes.profile.TruffleBoundaryNode; import com.oracle.truffle.r.runtime.Arguments; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RArguments.S3DefaultArguments; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.SubstituteVirtualFrame; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.nodes.RNode; @@ -111,12 +114,48 @@ public abstract class PrepareArguments extends Node { return executeArgs(arguments.matchedArguments, arguments.matchedSuppliedSignature, frame); } - @Fallback - public RArgsValuesAndNames prepareGeneric(VirtualFrame frame, RArgsValuesAndNames varArgs, S3DefaultArguments s3DefaultArguments, @SuppressWarnings("unused") RCallNode call) { - CompilerDirectives.transferToInterpreter(); + private static final class GenericCallEntry extends Node { + private final ArgumentsSignature cachedVarArgSignature; + private final S3DefaultArguments cachedS3DefaultArguments; + + @Child private ArgumentsAndSignature arguments; + + GenericCallEntry(ArgumentsSignature cachedVarArgSignature, S3DefaultArguments cachedS3DefaultArguments, ArgumentsAndSignature arguments) { + this.cachedVarArgSignature = cachedVarArgSignature; + this.cachedS3DefaultArguments = cachedS3DefaultArguments; + this.arguments = arguments; + } + } + + /* + * Use a TruffleBoundaryNode to be able to switch child nodes without invalidating the whole + * method. + */ + protected final class GenericCall extends TruffleBoundaryNode { + + @Child private GenericCallEntry entry; + + @TruffleBoundary + public RArgsValuesAndNames execute(MaterializedFrame materializedFrame, S3DefaultArguments s3DefaultArguments, ArgumentsSignature varArgSignature, RCallNode call) { + GenericCallEntry e = entry; + if (e == null || e.cachedVarArgSignature != varArgSignature || e.cachedS3DefaultArguments != s3DefaultArguments) { + ArgumentsAndSignature arguments = createArguments(call, varArgSignature, s3DefaultArguments); + entry = e = insert(new GenericCallEntry(varArgSignature, s3DefaultArguments, arguments)); + } + VirtualFrame frame = SubstituteVirtualFrame.create(materializedFrame); + return executeArgs(e.arguments.matchedArguments, e.arguments.matchedSuppliedSignature, frame); + } + } + + protected GenericCall createGenericCall() { + return new GenericCall(); + } + + @Specialization + public RArgsValuesAndNames prepareGeneric(VirtualFrame frame, RArgsValuesAndNames varArgs, S3DefaultArguments s3DefaultArguments, RCallNode call, + @Cached("createGenericCall()") GenericCall generic) { ArgumentsSignature varArgSignature = varArgs == null ? null : varArgs.getSignature(); - Arguments<RNode> matchedArgs = ArgumentMatcher.matchArguments(target, sourceArguments, varArgSignature, s3DefaultArguments, RError.ROOTNODE, true); - return executeArgs(matchedArgs.getArguments(), matchedArgs.getSignature(), frame); + return generic.execute(frame.materialize(), s3DefaultArguments, varArgSignature, call); } } -- GitLab