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 d381b5e
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 57 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 @@ -41,6 +41,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,7 +385,7 @@ 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);
} else {
Expand All @@ -393,9 +394,9 @@ protected static final Object doUncached(final VirtualFrame frame, final Compile
}

@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 @@ -41,6 +41,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,7 +385,7 @@ 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);
} else {
Expand All @@ -393,10 +394,10 @@ protected static final Object doUncached(final VirtualFrame frame, final Compile
}

@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 @@ -41,6 +41,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,7 +387,7 @@ 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);
} else {
Expand All @@ -395,10 +396,10 @@ protected static final Object doUncached(final VirtualFrame frame, final Compile
}

@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 @@ -41,6 +41,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,7 +391,7 @@ 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);
} else {
Expand All @@ -399,10 +400,10 @@ protected static final Object doUncached(final VirtualFrame frame, final Compile
}

@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 @@ -41,6 +41,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,7 +396,7 @@ 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);
} else {
Expand All @@ -404,10 +405,10 @@ protected static final Object doUncached(final VirtualFrame frame, final Compile
}

@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
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,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;
Expand Down Expand Up @@ -399,7 +400,7 @@ 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);
} else {
Expand All @@ -408,10 +409,10 @@ protected static final Object doUncached(final VirtualFrame frame, final Compile
}

@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;
Expand Down
Loading

1 comment on commit d381b5e

@TruffleSqueak-Bot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Performance Report (d381b5e)

Benchmarks ran on 23.0.2-graal.

Steady (after 100 iterations)

Benchmark Name Min Geomean Median Mean Max Total (ms) Total (min)
Bounce 514 548 517.92 515 517.88 103583 1.73
CD 638 660 644.21 639 644.17 128841 2.15
DeltaBlue 283 388 363.03 364 362.73 72605 1.21
Havlak 1259 1320 1292.6 1294 1292.55 258520 4.31
Json 365 392 377.58 374 377.53 75516 1.26
List 368 466 370.48 369 370.4 74096 1.23
Mandelbrot 130 153 131.01 130 130.97 26202 0.44
NBody 245 263 249.12 246 249.07 49824 0.83
Permute 234 248 236.66 234 236.62 47332 0.79
Queens 219 258 222.47 221 222.4 44493 0.74
Richards 1066 1090 1074.51 1076 1074.49 214902 3.58
Sieve 176 204 177.11 176 177.07 35421 0.59
Storage 191 205 195.26 192 195.19 39051 0.65
Towers 224 260 225.69 224 225.64 45138 0.75
5912 6455 6077.62 6054 6076.71 1215524 20.26

d381b5e-2-steady.svg

Warmup (first 100 iterations)

d381b5e-3-warmup.svg

Please sign in to comment.