diff --git a/src/trufflesom/interpreter/nodes/dispatch/GenericBlockDispatchNode.java b/src/trufflesom/interpreter/nodes/dispatch/GenericBlockDispatchNode.java deleted file mode 100644 index 588fea2e1..000000000 --- a/src/trufflesom/interpreter/nodes/dispatch/GenericBlockDispatchNode.java +++ /dev/null @@ -1,24 +0,0 @@ -package trufflesom.interpreter.nodes.dispatch; - -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.IndirectCallNode; - -import trufflesom.vmobjects.SBlock; - - -public final class GenericBlockDispatchNode extends AbstractDispatchNode { - @Child private IndirectCallNode call = Truffle.getRuntime().createIndirectCallNode(); - - @Override - public Object executeDispatch(final VirtualFrame frame, - final Object[] arguments) { - SBlock rcvr = (SBlock) arguments[0]; - return call.call(rcvr.getMethod().getCallTarget(), arguments); - } - - @Override - public int lengthOfDispatchChain() { - return 1000; - } -} diff --git a/src/trufflesom/interpreter/nodes/dispatch/InvokeOnCache.java b/src/trufflesom/interpreter/nodes/dispatch/InvokeOnCache.java deleted file mode 100644 index dc49227fb..000000000 --- a/src/trufflesom/interpreter/nodes/dispatch/InvokeOnCache.java +++ /dev/null @@ -1,120 +0,0 @@ -package trufflesom.interpreter.nodes.dispatch; - -import static trufflesom.interpreter.TruffleCompiler.transferToInterpreterAndInvalidate; - -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.IndirectCallNode; -import com.oracle.truffle.api.nodes.Node; - -import trufflesom.vmobjects.SInvokable; - - -public abstract class InvokeOnCache extends Node implements DispatchChain { - public static final int INLINE_CACHE_SIZE = 6; - - public static InvokeOnCache create() { - return new UninitializedDispatchNode(0); - } - - protected final int depth; - - public InvokeOnCache(final int depth) { - this.depth = depth; - } - - public abstract Object executeDispatch(VirtualFrame frame, - SInvokable invokable, Object[] arguments); - - private static final class UninitializedDispatchNode extends InvokeOnCache { - - UninitializedDispatchNode(final int depth) { - super(depth); - } - - private InvokeOnCache specialize(final SInvokable invokable) { - transferToInterpreterAndInvalidate("Initialize a dispatch node."); - - if (depth < INLINE_CACHE_SIZE) { - CachedDispatchNode specialized = new CachedDispatchNode(invokable, - new UninitializedDispatchNode(depth + 1), - depth); - return replace(specialized); - } - - InvokeOnCache headNode = determineChainHead(); - GenericDispatchNode generic = new GenericDispatchNode(); - return headNode.replace(generic); - } - - @Override - public Object executeDispatch(final VirtualFrame frame, - final SInvokable invokable, final Object[] arguments) { - return specialize(invokable).executeDispatch(frame, invokable, arguments); - } - - private InvokeOnCache determineChainHead() { - Node i = this; - while (i.getParent() instanceof InvokeOnCache) { - i = i.getParent(); - } - return (InvokeOnCache) i; - } - - @Override - public int lengthOfDispatchChain() { - return 0; - } - } - - private static final class CachedDispatchNode extends InvokeOnCache { - private final SInvokable invokable; - @Child private DirectCallNode callNode; - @Child private InvokeOnCache nextInCache; - - CachedDispatchNode(final SInvokable invokable, - final InvokeOnCache nextInCache, final int depth) { - super(depth); - this.invokable = invokable; - this.nextInCache = nextInCache; - callNode = Truffle.getRuntime().createDirectCallNode(invokable.getCallTarget()); - } - - @Override - public Object executeDispatch(final VirtualFrame frame, - final SInvokable invokable, final Object[] arguments) { - if (this.invokable == invokable) { - return callNode.call(arguments); - } else { - return nextInCache.executeDispatch(frame, invokable, arguments); - } - } - - @Override - public int lengthOfDispatchChain() { - return 1 + nextInCache.lengthOfDispatchChain(); - } - } - - private static final class GenericDispatchNode extends InvokeOnCache { - - @Child private IndirectCallNode callNode; - - GenericDispatchNode() { - super(0); - callNode = Truffle.getRuntime().createIndirectCallNode(); - } - - @Override - public Object executeDispatch(final VirtualFrame frame, - final SInvokable invokable, final Object[] arguments) { - return callNode.call(invokable.getCallTarget(), arguments); - } - - @Override - public int lengthOfDispatchChain() { - return 1000; - } - } -} diff --git a/src/trufflesom/primitives/reflection/MethodPrims.java b/src/trufflesom/primitives/reflection/MethodPrims.java index b0981ab02..f4a30eb36 100644 --- a/src/trufflesom/primitives/reflection/MethodPrims.java +++ b/src/trufflesom/primitives/reflection/MethodPrims.java @@ -1,13 +1,18 @@ package trufflesom.primitives.reflection; +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.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeChild; 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 bd.primitives.Primitive; import trufflesom.interpreter.nodes.ExpressionNode; -import trufflesom.interpreter.nodes.dispatch.InvokeOnCache; +import trufflesom.interpreter.nodes.dispatch.AbstractDispatchNode; import trufflesom.interpreter.nodes.nary.EagerlySpecializableNode; import trufflesom.interpreter.nodes.nary.UnaryExpressionNode; import trufflesom.primitives.arrays.ToArgumentsArrayNode; @@ -51,22 +56,40 @@ public final SAbstractObject doSMethod(final SInvokable receiver) { executeWith = {"somArr", "target"}) @Primitive(selector = "invokeOn:with:", extraChild = ToArgumentsArrayNodeFactory.class) public abstract static class InvokeOnPrim extends EagerlySpecializableNode { - @Child private InvokeOnCache callNode = InvokeOnCache.create(); public abstract Object executeEvaluated(VirtualFrame frame, SInvokable receiver, Object target, SArray somArr); + public static DirectCallNode create(final CallTarget ct) { + return Truffle.getRuntime().createDirectCallNode(ct); + } + + public static IndirectCallNode createIndirect() { + return Truffle.getRuntime().createIndirectCallNode(); + } + @Override public final Object doPreEvaluated(final VirtualFrame frame, final Object[] args) { return executeEvaluated(frame, (SInvokable) args[0], args[1], (SArray) args[2]); } - @Specialization - public final Object doInvoke(final VirtualFrame frame, + @Specialization(guards = "receiver == cachedReceiver", + limit = "" + AbstractDispatchNode.INLINE_CACHE_SIZE) + public final Object doCached( + final SInvokable receiver, final Object target, final SArray somArr, + final Object[] argArr, + @Cached("receiver") final SInvokable cachedReceiver, + @Cached("create(receiver.getCallTarget())") final DirectCallNode callNode) { + return callNode.call(argArr); + } + + @Specialization(replaces = "doCached") + public final Object doUncached( final SInvokable receiver, final Object target, final SArray somArr, - final Object[] argArr) { - return callNode.executeDispatch(frame, receiver, argArr); + final Object[] argArr, + @Cached("createIndirect()") final IndirectCallNode callNode) { + return callNode.call(receiver.getCallTarget(), argArr); } } }