diff --git a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/model/CompiledCodeObject.java b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/model/CompiledCodeObject.java index aaec8b31b..7cb2743cf 100644 --- a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/model/CompiledCodeObject.java +++ b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/model/CompiledCodeObject.java @@ -40,6 +40,7 @@ import de.hpi.swa.trufflesqueak.nodes.bytecodes.AbstractSqueakBytecodeDecoder; import de.hpi.swa.trufflesqueak.nodes.bytecodes.SqueakBytecodeSistaV1Decoder; import de.hpi.swa.trufflesqueak.nodes.bytecodes.SqueakBytecodeV3PlusClosuresDecoder; +import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelectorNaryNode.DispatchPrimitiveNode; import de.hpi.swa.trufflesqueak.nodes.primitives.AbstractPrimitiveNode; import de.hpi.swa.trufflesqueak.nodes.primitives.PrimitiveNodeFactory; import de.hpi.swa.trufflesqueak.shared.SqueakLanguageConfig; @@ -53,8 +54,7 @@ public final class CompiledCodeObject extends AbstractSqueakObjectWithClassAndHa private static final String SOURCE_UNAVAILABLE_NAME = ""; public static final String SOURCE_UNAVAILABLE_CONTENTS = "Source unavailable"; - private static final AbstractPrimitiveNode UNINITIALIZED_PRIMITIVE_NODE = new AbstractPrimitiveNode() { - }; + private static final DispatchPrimitiveNode UNINITIALIZED_PRIMITIVE_NODE = DispatchPrimitiveNode.create(null, 0); // header info and data @CompilationFinal private int header; @@ -66,7 +66,7 @@ public final class CompiledCodeObject extends AbstractSqueakObjectWithClassAndHa @CompilationFinal(dimensions = 1) private Object[] literals; @CompilationFinal(dimensions = 1) private byte[] bytes; - @CompilationFinal private AbstractPrimitiveNode primitiveNodeOrNull = UNINITIALIZED_PRIMITIVE_NODE; + @CompilationFinal private DispatchPrimitiveNode primitiveNodeOrNull = UNINITIALIZED_PRIMITIVE_NODE; @CompilationFinal private ExecutionData executionData; @@ -436,11 +436,16 @@ public int primitiveIndex() { } @Idempotent - public AbstractPrimitiveNode getPrimitiveNodeOrNull() { + public DispatchPrimitiveNode getPrimitiveNodeOrNull() { if (primitiveNodeOrNull == UNINITIALIZED_PRIMITIVE_NODE) { CompilerDirectives.transferToInterpreterAndInvalidate(); if (hasPrimitive()) { - primitiveNodeOrNull = PrimitiveNodeFactory.getOrCreateIndexedOrNamed(this); + final AbstractPrimitiveNode nodeOrNull = PrimitiveNodeFactory.getOrCreateIndexedOrNamed(this); + if (nodeOrNull != null) { + primitiveNodeOrNull = DispatchPrimitiveNode.create(nodeOrNull, getNumArgs()); + } else { + primitiveNodeOrNull = null; + } } else { primitiveNodeOrNull = null; } diff --git a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector0Node.java b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector0Node.java index 320907902..2f25f90ce 100644 --- a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector0Node.java +++ b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector0Node.java @@ -21,6 +21,7 @@ import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.DirectCallNode; +import com.oracle.truffle.api.nodes.EncapsulatingNodeReference; import com.oracle.truffle.api.nodes.IndirectCallNode; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedBranchProfile; @@ -41,6 +42,7 @@ import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelector0NodeFactory.DispatchDirectPrimitiveFallback0NodeGen; import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelector0NodeFactory.DispatchDirectedSuper0NodeFactory.DirectedSuperDispatch0NodeGen; import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelector0NodeFactory.DispatchSuper0NodeGen; +import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelectorNaryNode.DispatchPrimitiveNode; import de.hpi.swa.trufflesqueak.nodes.primitives.AbstractPrimitiveNode; import de.hpi.swa.trufflesqueak.nodes.primitives.Primitive.Primitive0; import de.hpi.swa.trufflesqueak.nodes.primitives.PrimitiveNodeFactory; @@ -384,18 +386,24 @@ protected static final Object doCached(final VirtualFrame frame, @SuppressWarnin @Specialization(replaces = {"doNoPrimitive", "doCached"}) protected static final Object doUncached(final VirtualFrame frame, final CompiledCodeObject method, final Object receiver, @Bind("this") final Node node) { - final AbstractPrimitiveNode primitiveNode = method.getPrimitiveNodeOrNull(); + final DispatchPrimitiveNode primitiveNode = method.getPrimitiveNodeOrNull(); if (primitiveNode != null) { - return tryPrimitive(primitiveNode, frame.materialize(), node, method, receiver); + final EncapsulatingNodeReference encapsulating = EncapsulatingNodeReference.getCurrent(); + final Node encapsulatingNode = encapsulating.set(node); + try { + return tryPrimitive(primitiveNode, frame.materialize(), node, method, receiver); + } finally { + encapsulating.set(encapsulatingNode); + } } else { return null; } } @TruffleBoundary - private static Object tryPrimitive(final AbstractPrimitiveNode primitiveNode, final MaterializedFrame frame, final Node node, final CompiledCodeObject method, final Object receiver) { + private static Object tryPrimitive(final DispatchPrimitiveNode primitiveNode, final MaterializedFrame frame, final Node node, final CompiledCodeObject method, final Object receiver) { try { - return ((Primitive0) primitiveNode).execute(frame, receiver); + return ((DispatchPrimitiveNode.DispatchPrimitive0Node) primitiveNode).execute(frame, receiver); } catch (final PrimitiveFailed pf) { DispatchUtils.handlePrimitiveFailedIndirect(node, method, pf); return null; diff --git a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector1Node.java b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector1Node.java index 3df4729ae..93716cbd3 100644 --- a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector1Node.java +++ b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector1Node.java @@ -21,6 +21,7 @@ import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.DirectCallNode; +import com.oracle.truffle.api.nodes.EncapsulatingNodeReference; import com.oracle.truffle.api.nodes.IndirectCallNode; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedBranchProfile; @@ -41,6 +42,7 @@ import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelector1NodeFactory.DispatchDirectPrimitiveFallback1NodeGen; import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelector1NodeFactory.DispatchDirectedSuper1NodeFactory.DirectedSuperDispatch1NodeGen; import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelector1NodeFactory.DispatchSuper1NodeGen; +import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelectorNaryNode.DispatchPrimitiveNode; import de.hpi.swa.trufflesqueak.nodes.primitives.AbstractPrimitiveNode; import de.hpi.swa.trufflesqueak.nodes.primitives.Primitive.Primitive1; import de.hpi.swa.trufflesqueak.nodes.primitives.PrimitiveNodeFactory; @@ -384,19 +386,25 @@ protected static final Object doCached(final VirtualFrame frame, @SuppressWarnin @Specialization(replaces = {"doNoPrimitive", "doCached"}) protected static final Object doUncached(final VirtualFrame frame, final CompiledCodeObject method, final Object receiver, final Object arg1, @Bind("this") final Node node) { - final AbstractPrimitiveNode primitiveNode = method.getPrimitiveNodeOrNull(); + final DispatchPrimitiveNode primitiveNode = method.getPrimitiveNodeOrNull(); if (primitiveNode != null) { - return tryPrimitive(primitiveNode, frame.materialize(), node, method, receiver, arg1); + final EncapsulatingNodeReference encapsulating = EncapsulatingNodeReference.getCurrent(); + final Node encapsulatingNode = encapsulating.set(node); + try { + return tryPrimitive(primitiveNode, frame.materialize(), node, method, receiver, arg1); + } finally { + encapsulating.set(encapsulatingNode); + } } else { return null; } } @TruffleBoundary - private static Object tryPrimitive(final AbstractPrimitiveNode primitiveNode, final MaterializedFrame frame, final Node node, final CompiledCodeObject method, final Object receiver, + private static Object tryPrimitive(final DispatchPrimitiveNode primitiveNode, final MaterializedFrame frame, final Node node, final CompiledCodeObject method, final Object receiver, final Object arg1) { try { - return ((Primitive1) primitiveNode).execute(frame, receiver, arg1); + return ((DispatchPrimitiveNode.DispatchPrimitive1Node) primitiveNode).execute(frame, receiver, arg1); } catch (final PrimitiveFailed pf) { DispatchUtils.handlePrimitiveFailedIndirect(node, method, pf); return null; diff --git a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector2Node.java b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector2Node.java index 58b38f2cc..25917862f 100644 --- a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector2Node.java +++ b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector2Node.java @@ -21,6 +21,7 @@ import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.DirectCallNode; +import com.oracle.truffle.api.nodes.EncapsulatingNodeReference; import com.oracle.truffle.api.nodes.IndirectCallNode; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedBranchProfile; @@ -41,6 +42,7 @@ import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelector2NodeFactory.DispatchDirectPrimitiveFallback2NodeGen; import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelector2NodeFactory.DispatchDirectedSuper2NodeFactory.DirectedSuperDispatch2NodeGen; import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelector2NodeFactory.DispatchSuper2NodeGen; +import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelectorNaryNode.DispatchPrimitiveNode; import de.hpi.swa.trufflesqueak.nodes.primitives.AbstractPrimitiveNode; import de.hpi.swa.trufflesqueak.nodes.primitives.Primitive.Primitive2; import de.hpi.swa.trufflesqueak.nodes.primitives.PrimitiveNodeFactory; @@ -386,19 +388,25 @@ protected static final Object doCached(final VirtualFrame frame, @SuppressWarnin @Specialization(replaces = {"doNoPrimitive", "doCached"}) protected static final Object doUncached(final VirtualFrame frame, final CompiledCodeObject method, final Object receiver, final Object arg1, final Object arg2, @Bind("this") final Node node) { - final AbstractPrimitiveNode primitiveNode = method.getPrimitiveNodeOrNull(); + final DispatchPrimitiveNode primitiveNode = method.getPrimitiveNodeOrNull(); if (primitiveNode != null) { - return tryPrimitive(primitiveNode, frame.materialize(), node, method, receiver, arg1, arg2); + final EncapsulatingNodeReference encapsulating = EncapsulatingNodeReference.getCurrent(); + final Node encapsulatingNode = encapsulating.set(node); + try { + return tryPrimitive(primitiveNode, frame.materialize(), node, method, receiver, arg1, arg2); + } finally { + encapsulating.set(encapsulatingNode); + } } else { return null; } } @TruffleBoundary - private static Object tryPrimitive(final AbstractPrimitiveNode primitiveNode, final MaterializedFrame frame, final Node node, final CompiledCodeObject method, final Object receiver, + private static Object tryPrimitive(final DispatchPrimitiveNode primitiveNode, final MaterializedFrame frame, final Node node, final CompiledCodeObject method, final Object receiver, final Object arg1, final Object arg2) { try { - return ((Primitive2) primitiveNode).execute(frame, receiver, arg1, arg2); + return ((DispatchPrimitiveNode.DispatchPrimitive2Node) primitiveNode).execute(frame, receiver, arg1, arg2); } catch (final PrimitiveFailed pf) { DispatchUtils.handlePrimitiveFailedIndirect(node, method, pf); return null; diff --git a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector3Node.java b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector3Node.java index 51b7a18a1..adf541956 100644 --- a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector3Node.java +++ b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector3Node.java @@ -21,6 +21,7 @@ import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.DirectCallNode; +import com.oracle.truffle.api.nodes.EncapsulatingNodeReference; import com.oracle.truffle.api.nodes.IndirectCallNode; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedBranchProfile; @@ -41,6 +42,7 @@ import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelector3NodeFactory.DispatchDirectPrimitiveFallback3NodeGen; import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelector3NodeFactory.DispatchDirectedSuper3NodeFactory.DirectedSuperDispatch3NodeGen; import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelector3NodeFactory.DispatchSuper3NodeGen; +import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelectorNaryNode.DispatchPrimitiveNode; import de.hpi.swa.trufflesqueak.nodes.primitives.AbstractPrimitiveNode; import de.hpi.swa.trufflesqueak.nodes.primitives.Primitive.Primitive3; import de.hpi.swa.trufflesqueak.nodes.primitives.PrimitiveNodeFactory; @@ -390,19 +392,25 @@ protected static final Object doCached(final VirtualFrame frame, @SuppressWarnin @Specialization(replaces = {"doNoPrimitive", "doCached"}) protected static final Object doUncached(final VirtualFrame frame, final CompiledCodeObject method, final Object receiver, final Object arg1, final Object arg2, final Object arg3, @Bind("this") final Node node) { - final AbstractPrimitiveNode primitiveNode = method.getPrimitiveNodeOrNull(); + final DispatchPrimitiveNode primitiveNode = method.getPrimitiveNodeOrNull(); if (primitiveNode != null) { - return tryPrimitive(primitiveNode, frame.materialize(), node, method, receiver, arg1, arg2, arg3); + final EncapsulatingNodeReference encapsulating = EncapsulatingNodeReference.getCurrent(); + final Node encapsulatingNode = encapsulating.set(node); + try { + return tryPrimitive(primitiveNode, frame.materialize(), node, method, receiver, arg1, arg2, arg3); + } finally { + encapsulating.set(encapsulatingNode); + } } else { return null; } } @TruffleBoundary - private static Object tryPrimitive(final AbstractPrimitiveNode primitiveNode, final MaterializedFrame frame, final Node node, final CompiledCodeObject method, final Object receiver, + private static Object tryPrimitive(final DispatchPrimitiveNode primitiveNode, final MaterializedFrame frame, final Node node, final CompiledCodeObject method, final Object receiver, final Object arg1, final Object arg2, final Object arg3) { try { - return ((Primitive3) primitiveNode).execute(frame, receiver, arg1, arg2, arg3); + return ((DispatchPrimitiveNode.DispatchPrimitive3Node) primitiveNode).execute(frame, receiver, arg1, arg2, arg3); } catch (final PrimitiveFailed pf) { DispatchUtils.handlePrimitiveFailedIndirect(node, method, pf); return null; diff --git a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector4Node.java b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector4Node.java index 946861714..d865c028e 100644 --- a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector4Node.java +++ b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector4Node.java @@ -21,6 +21,7 @@ import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.DirectCallNode; +import com.oracle.truffle.api.nodes.EncapsulatingNodeReference; import com.oracle.truffle.api.nodes.IndirectCallNode; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedBranchProfile; @@ -41,6 +42,7 @@ import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelector4NodeFactory.DispatchDirectPrimitiveFallback4NodeGen; import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelector4NodeFactory.DispatchDirectedSuper4NodeFactory.DirectedSuperDispatch4NodeGen; import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelector4NodeFactory.DispatchSuper4NodeGen; +import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelectorNaryNode.DispatchPrimitiveNode; import de.hpi.swa.trufflesqueak.nodes.primitives.AbstractPrimitiveNode; import de.hpi.swa.trufflesqueak.nodes.primitives.Primitive.Primitive4; import de.hpi.swa.trufflesqueak.nodes.primitives.PrimitiveNodeFactory; @@ -395,19 +397,25 @@ protected static final Object doCached(final VirtualFrame frame, @SuppressWarnin protected static final Object doUncached(final VirtualFrame frame, final CompiledCodeObject method, final Object receiver, final Object arg1, final Object arg2, final Object arg3, final Object arg4, @Bind("this") final Node node) { - final AbstractPrimitiveNode primitiveNode = method.getPrimitiveNodeOrNull(); + final DispatchPrimitiveNode primitiveNode = method.getPrimitiveNodeOrNull(); if (primitiveNode != null) { - return tryPrimitive(primitiveNode, frame.materialize(), node, method, receiver, arg1, arg2, arg3, arg4); + final EncapsulatingNodeReference encapsulating = EncapsulatingNodeReference.getCurrent(); + final Node encapsulatingNode = encapsulating.set(node); + try { + return tryPrimitive(primitiveNode, frame.materialize(), node, method, receiver, arg1, arg2, arg3, arg4); + } finally { + encapsulating.set(encapsulatingNode); + } } else { return null; } } @TruffleBoundary - private static Object tryPrimitive(final AbstractPrimitiveNode primitiveNode, final MaterializedFrame frame, final Node node, final CompiledCodeObject method, final Object receiver, + private static Object tryPrimitive(final DispatchPrimitiveNode primitiveNode, final MaterializedFrame frame, final Node node, final CompiledCodeObject method, final Object receiver, final Object arg1, final Object arg2, final Object arg3, final Object arg4) { try { - return ((Primitive4) primitiveNode).execute(frame, receiver, arg1, arg2, arg3, arg4); + return ((DispatchPrimitiveNode.DispatchPrimitive4Node) primitiveNode).execute(frame, receiver, arg1, arg2, arg3, arg4); } catch (final PrimitiveFailed pf) { DispatchUtils.handlePrimitiveFailedIndirect(node, method, pf); return null; diff --git a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector5Node.java b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector5Node.java index e1b6841ae..53259c08b 100644 --- a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector5Node.java +++ b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelector5Node.java @@ -21,6 +21,7 @@ import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.DirectCallNode; +import com.oracle.truffle.api.nodes.EncapsulatingNodeReference; import com.oracle.truffle.api.nodes.IndirectCallNode; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedBranchProfile; @@ -41,6 +42,7 @@ import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelector5NodeFactory.DispatchDirectPrimitiveFallback5NodeGen; import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelector5NodeFactory.DispatchDirectedSuper5NodeFactory.DirectedSuperDispatch5NodeGen; import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelector5NodeFactory.DispatchSuper5NodeGen; +import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchSelectorNaryNode.DispatchPrimitiveNode; import de.hpi.swa.trufflesqueak.nodes.primitives.AbstractPrimitiveNode; import de.hpi.swa.trufflesqueak.nodes.primitives.Primitive.Primitive5; import de.hpi.swa.trufflesqueak.nodes.primitives.PrimitiveNodeFactory; @@ -399,19 +401,25 @@ protected static final Object doCached(final VirtualFrame frame, @SuppressWarnin protected static final Object doUncached(final VirtualFrame frame, final CompiledCodeObject method, final Object receiver, final Object arg1, final Object arg2, final Object arg3, final Object arg4, final Object arg5, @Bind("this") final Node node) { - final AbstractPrimitiveNode primitiveNode = method.getPrimitiveNodeOrNull(); + final DispatchPrimitiveNode primitiveNode = method.getPrimitiveNodeOrNull(); if (primitiveNode != null) { - return tryPrimitive(primitiveNode, frame.materialize(), node, method, receiver, arg1, arg2, arg3, arg4, arg5); + final EncapsulatingNodeReference encapsulating = EncapsulatingNodeReference.getCurrent(); + final Node encapsulatingNode = encapsulating.set(node); + try { + return tryPrimitive(primitiveNode, frame.materialize(), node, method, receiver, arg1, arg2, arg3, arg4, arg5); + } finally { + encapsulating.set(encapsulatingNode); + } } else { return null; } } @TruffleBoundary - private static Object tryPrimitive(final AbstractPrimitiveNode primitiveNode, final MaterializedFrame frame, final Node node, final CompiledCodeObject method, final Object receiver, + private static Object tryPrimitive(final DispatchPrimitiveNode primitiveNode, final MaterializedFrame frame, final Node node, final CompiledCodeObject method, final Object receiver, final Object arg1, final Object arg2, final Object arg3, final Object arg4, final Object arg5) { try { - return ((Primitive5) primitiveNode).execute(frame, receiver, arg1, arg2, arg3, arg4, arg5); + return ((DispatchPrimitiveNode.DispatchPrimitive5Node) primitiveNode).execute(frame, receiver, arg1, arg2, arg3, arg4, arg5); } catch (final PrimitiveFailed pf) { DispatchUtils.handlePrimitiveFailedIndirect(node, method, pf); return null; diff --git a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelectorNaryNode.java b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelectorNaryNode.java index 56742fe3e..5aeda6d3b 100644 --- a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelectorNaryNode.java +++ b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/dispatch/DispatchSelectorNaryNode.java @@ -22,9 +22,11 @@ import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.DirectCallNode; +import com.oracle.truffle.api.nodes.EncapsulatingNodeReference; import com.oracle.truffle.api.nodes.ExplodeLoop; import com.oracle.truffle.api.nodes.IndirectCallNode; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.UnadoptableNode; import com.oracle.truffle.api.profiles.InlinedBranchProfile; import de.hpi.swa.trufflesqueak.exceptions.PrimitiveFailed; @@ -274,8 +276,8 @@ public Object execute(final VirtualFrame frame, final Object receiver, final Obj } } - protected abstract static class DispatchPrimitiveNode extends AbstractNode { - protected abstract Object execute(VirtualFrame frame, Object receiver, Object[] arguments); + public abstract static class DispatchPrimitiveNode extends AbstractNode implements UnadoptableNode { + public abstract Object execute(VirtualFrame frame, Object receiver, Object[] arguments); public static DispatchPrimitiveNode create(final AbstractPrimitiveNode primitiveNode, final int numArgs) { return switch (numArgs) { @@ -295,7 +297,7 @@ public static DispatchPrimitiveNode create(final AbstractPrimitiveNode primitive }; } - private static final class DispatchPrimitive0Node extends DispatchPrimitiveNode { + public static final class DispatchPrimitive0Node extends DispatchPrimitiveNode { @Child private Primitive0 primitiveNode; private DispatchPrimitive0Node(final Primitive0 primitiveNode) { @@ -303,12 +305,17 @@ private DispatchPrimitive0Node(final Primitive0 primitiveNode) { } @Override - public Object execute(final VirtualFrame frame, final Object receiver, final Object[] arguments) { + public Object execute(final VirtualFrame frame, final Object receiver, final Object[] args) { + assert args.length == 0; + return primitiveNode.execute(frame, receiver); + } + + public Object execute(final VirtualFrame frame, final Object receiver) { return primitiveNode.execute(frame, receiver); } } - private static final class DispatchPrimitive1Node extends DispatchPrimitiveNode { + public static final class DispatchPrimitive1Node extends DispatchPrimitiveNode { @Child private Primitive1 primitiveNode; private DispatchPrimitive1Node(final Primitive1 primitiveNode) { @@ -316,12 +323,17 @@ private DispatchPrimitive1Node(final Primitive1 primitiveNode) { } @Override - public Object execute(final VirtualFrame frame, final Object receiver, final Object[] arguments) { - return primitiveNode.execute(frame, receiver, arguments[0]); + public Object execute(final VirtualFrame frame, final Object receiver, final Object[] args) { + assert args.length == 1; + return primitiveNode.execute(frame, receiver, args[0]); + } + + public Object execute(final VirtualFrame frame, final Object receiver, final Object arg1) { + return primitiveNode.execute(frame, receiver, arg1); } } - private static final class DispatchPrimitive2Node extends DispatchPrimitiveNode { + public static final class DispatchPrimitive2Node extends DispatchPrimitiveNode { @Child private Primitive2 primitiveNode; private DispatchPrimitive2Node(final Primitive2 primitiveNode) { @@ -330,11 +342,16 @@ private DispatchPrimitive2Node(final Primitive2 primitiveNode) { @Override public Object execute(final VirtualFrame frame, final Object receiver, final Object[] arguments) { + assert arguments.length == 2; return primitiveNode.execute(frame, receiver, arguments[0], arguments[1]); } + + public Object execute(final VirtualFrame frame, final Object receiver, final Object arg1, final Object arg2) { + return primitiveNode.execute(frame, receiver, arg1, arg2); + } } - private static final class DispatchPrimitive3Node extends DispatchPrimitiveNode { + public static final class DispatchPrimitive3Node extends DispatchPrimitiveNode { @Child private Primitive3 primitiveNode; private DispatchPrimitive3Node(final Primitive3 primitiveNode) { @@ -342,12 +359,17 @@ private DispatchPrimitive3Node(final Primitive3 primitiveNode) { } @Override - public Object execute(final VirtualFrame frame, final Object receiver, final Object[] arguments) { - return primitiveNode.execute(frame, receiver, arguments[0], arguments[1], arguments[2]); + public Object execute(final VirtualFrame frame, final Object receiver, final Object[] args) { + assert args.length == 3; + return primitiveNode.execute(frame, receiver, args[0], args[1], args[2]); + } + + public Object execute(final VirtualFrame frame, final Object receiver, final Object arg1, final Object arg2, final Object arg3) { + return primitiveNode.execute(frame, receiver, arg1, arg2, arg3); } } - private static final class DispatchPrimitive4Node extends DispatchPrimitiveNode { + public static final class DispatchPrimitive4Node extends DispatchPrimitiveNode { @Child private Primitive4 primitiveNode; private DispatchPrimitive4Node(final Primitive4 primitiveNode) { @@ -355,12 +377,17 @@ private DispatchPrimitive4Node(final Primitive4 primitiveNode) { } @Override - public Object execute(final VirtualFrame frame, final Object receiver, final Object[] arguments) { - return primitiveNode.execute(frame, receiver, arguments[0], arguments[1], arguments[2], arguments[3]); + public Object execute(final VirtualFrame frame, final Object receiver, final Object[] args) { + assert args.length == 4; + return primitiveNode.execute(frame, receiver, args[0], args[1], args[2], args[3]); + } + + public Object execute(final VirtualFrame frame, final Object receiver, final Object arg1, final Object arg2, final Object arg3, final Object arg4) { + return primitiveNode.execute(frame, receiver, arg1, arg2, arg3, arg4); } } - private static final class DispatchPrimitive5Node extends DispatchPrimitiveNode { + public static final class DispatchPrimitive5Node extends DispatchPrimitiveNode { @Child private Primitive5 primitiveNode; private DispatchPrimitive5Node(final Primitive5 primitiveNode) { @@ -368,8 +395,13 @@ private DispatchPrimitive5Node(final Primitive5 primitiveNode) { } @Override - public Object execute(final VirtualFrame frame, final Object receiver, final Object[] arguments) { - return primitiveNode.execute(frame, receiver, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]); + public Object execute(final VirtualFrame frame, final Object receiver, final Object[] args) { + assert args.length == 5; + return primitiveNode.execute(frame, receiver, args[0], args[1], args[2], args[3], args[4]); + } + + public Object execute(final VirtualFrame frame, final Object receiver, final Object arg1, final Object arg2, final Object arg3, final Object arg4, final Object arg5) { + return primitiveNode.execute(frame, receiver, arg1, arg2, arg3, arg4, arg5); } } @@ -381,8 +413,9 @@ private DispatchPrimitive6Node(final Primitive6 primitiveNode) { } @Override - public Object execute(final VirtualFrame frame, final Object receiver, final Object[] arguments) { - return primitiveNode.execute(frame, receiver, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]); + public Object execute(final VirtualFrame frame, final Object receiver, final Object[] args) { + assert args.length == 6; + return primitiveNode.execute(frame, receiver, args[0], args[1], args[2], args[3], args[4], args[5]); } } @@ -394,8 +427,9 @@ private DispatchPrimitive7Node(final Primitive7 primitiveNode) { } @Override - public Object execute(final VirtualFrame frame, final Object receiver, final Object[] arguments) { - return primitiveNode.execute(frame, receiver, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6]); + public Object execute(final VirtualFrame frame, final Object receiver, final Object[] args) { + assert args.length == 7; + return primitiveNode.execute(frame, receiver, args[0], args[1], args[2], args[3], args[4], args[5], args[6]); } } @@ -407,8 +441,9 @@ private DispatchPrimitive8Node(final Primitive8 primitiveNode) { } @Override - public Object execute(final VirtualFrame frame, final Object receiver, final Object[] arguments) { - return primitiveNode.execute(frame, receiver, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); + public Object execute(final VirtualFrame frame, final Object receiver, final Object[] args) { + assert args.length == 8; + return primitiveNode.execute(frame, receiver, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]); } } @@ -420,8 +455,9 @@ private DispatchPrimitive9Node(final Primitive9 primitiveNode) { } @Override - public Object execute(final VirtualFrame frame, final Object receiver, final Object[] arguments) { - return primitiveNode.execute(frame, receiver, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8]); + public Object execute(final VirtualFrame frame, final Object receiver, final Object[] args) { + assert args.length == 9; + return primitiveNode.execute(frame, receiver, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]); } } @@ -433,9 +469,9 @@ private DispatchPrimitive10Node(final Primitive10 primitiveNode) { } @Override - public Object execute(final VirtualFrame frame, final Object receiver, final Object[] arguments) { - return primitiveNode.execute(frame, receiver, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], - arguments[9]); + public Object execute(final VirtualFrame frame, final Object receiver, final Object[] args) { + assert args.length == 10; + return primitiveNode.execute(frame, receiver, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9]); } } @@ -447,9 +483,9 @@ private DispatchPrimitive11Node(final Primitive11 primitiveNode) { } @Override - public Object execute(final VirtualFrame frame, final Object receiver, final Object[] arguments) { - return primitiveNode.execute(frame, receiver, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], - arguments[9], arguments[10]); + public Object execute(final VirtualFrame frame, final Object receiver, final Object[] args) { + assert args.length == 11; + return primitiveNode.execute(frame, receiver, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10]); } } } @@ -589,19 +625,25 @@ protected static final Object doCached(final VirtualFrame frame, @SuppressWarnin @Specialization(replaces = {"doNoPrimitive", "doCached"}) protected static final Object doUncached(final VirtualFrame frame, final CompiledCodeObject method, final Object receiver, final Object[] arguments, @Bind("this") final Node node) { - final AbstractPrimitiveNode primitiveNode = method.getPrimitiveNodeOrNull(); + final DispatchPrimitiveNode primitiveNode = method.getPrimitiveNodeOrNull(); if (primitiveNode != null) { - return tryPrimitive(primitiveNode, frame.materialize(), node, method, receiver, arguments); + final eReference encapsulating = EncapsulatingNodeReference.getCurrent(); + final Node encapsulatingNode = encapsulating.set(node); + try { + return tryPrimitive(primitiveNode, frame.materialize(), node, method, receiver, arguments); + } finally { + encapsulating.set(encapsulatingNode); + } } else { return null; } } @TruffleBoundary - private static Object tryPrimitive(final AbstractPrimitiveNode primitiveNode, final MaterializedFrame frame, final Node node, final CompiledCodeObject method, final Object receiver, + private static Object tryPrimitive(final DispatchPrimitiveNode primitiveNode, final MaterializedFrame frame, final Node node, final CompiledCodeObject method, final Object receiver, final Object[] arguments) { try { - return primitiveNode.executeWithArguments(frame, receiver, arguments); + return primitiveNode.execute(frame, receiver, arguments); } catch (final PrimitiveFailed pf) { DispatchUtils.handlePrimitiveFailedIndirect(node, method, pf); return null;