Skip to content

Commit

Permalink
Fix indirect primitiveNode dispatch
Browse files Browse the repository at this point in the history
  • Loading branch information
fniephaus committed Jan 28, 2025
1 parent e9e5291 commit dc36b28
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -53,8 +54,7 @@ public final class CompiledCodeObject extends AbstractSqueakObjectWithClassAndHa
private static final String SOURCE_UNAVAILABLE_NAME = "<unavailable>";
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;
Expand All @@ -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;

Expand Down Expand Up @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
Loading

0 comments on commit dc36b28

Please sign in to comment.