diff --git a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/AboutToReturnNode.java b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/AboutToReturnNode.java index f16cbaef3..e09996b71 100644 --- a/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/AboutToReturnNode.java +++ b/src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/AboutToReturnNode.java @@ -21,10 +21,12 @@ import de.hpi.swa.trufflesqueak.model.BooleanObject; import de.hpi.swa.trufflesqueak.model.CompiledCodeObject; import de.hpi.swa.trufflesqueak.model.ContextObject; +import de.hpi.swa.trufflesqueak.model.NilObject; import de.hpi.swa.trufflesqueak.nodes.AboutToReturnNodeFactory.AboutToReturnImplNodeGen; -import de.hpi.swa.trufflesqueak.nodes.context.TemporaryWriteMarkContextsNode; import de.hpi.swa.trufflesqueak.nodes.context.frame.FrameStackReadNode; +import de.hpi.swa.trufflesqueak.nodes.context.frame.FrameStackWriteNode; import de.hpi.swa.trufflesqueak.nodes.context.frame.GetContextOrMarkerNode; +import de.hpi.swa.trufflesqueak.nodes.context.frame.GetOrCreateContextNode; import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchClosureNode; import de.hpi.swa.trufflesqueak.util.FrameAccess; @@ -42,6 +44,26 @@ public static AboutToReturnNode create(final CompiledCodeObject code) { @ImportStatic(FrameStackReadNode.class) protected abstract static class AboutToReturnImplNode extends AboutToReturnNode { + @Specialization(guards = {"!hasModifiedSender(frame)"}) + protected final void doAboutToReturnVirtualizedNothing(final VirtualFrame frame, final NonLocalReturn nlr, + @Cached("createTemporaryReadNode(frame, 1)") final FrameStackReadNode completeTempReadNode, + @Cached final DispatchVirtualAboutToReturnNode dispatchVirtualAboutToReturnNode) { + dispatchVirtualAboutToReturnNode.execute(frame, completeTempReadNode.executeRead(frame) == NilObject.SINGLETON); + } + + @Specialization(guards = {"hasModifiedSender(frame)"}) + protected static final void doAboutToReturn(final VirtualFrame frame, final NonLocalReturn nlr, + @Bind("this") final Node node, + @Cached final GetOrCreateContextNode getOrCreateContextNode, + @Cached("createAboutToReturnSend()") final SendSelectorNode sendAboutToReturnNode) { + assert nlr.getTargetContextOrMarker() instanceof ContextObject; + sendAboutToReturnNode.executeSend(frame, new Object[]{getOrCreateContextNode.executeGet(frame, node), nlr.getReturnValue(), nlr.getTargetContextOrMarker()}); + } + } + + protected abstract static class DispatchVirtualAboutToReturnNode extends AbstractNode { + + protected abstract void execute(VirtualFrame frame, boolean completeTempIsNil); /* * Virtualized version of Context>>aboutToReturn:through:, more specifically @@ -50,12 +72,11 @@ protected abstract static class AboutToReturnImplNode extends AboutToReturnNode * handled. Note that this however does not check if the current context isDead nor does it * terminate contexts (this may be a problem). */ - @Specialization(guards = {"!hasModifiedSender(frame)", "isNil(completeTempReadNode.executeRead(frame))"}, limit = "1") - protected static final void doAboutToReturnVirtualized(final VirtualFrame frame, @SuppressWarnings("unused") final NonLocalReturn nlr, + @Specialization(guards = {"completeTempIsNil"}) + protected static final void doVirtualized(final VirtualFrame frame, @SuppressWarnings("unused") final boolean completeTempIsNil, @Bind("this") final Node node, @Cached("createTemporaryReadNode(frame, 0)") final FrameStackReadNode blockArgumentNode, - @SuppressWarnings("unused") @Cached("createTemporaryReadNode(frame, 1)") final FrameStackReadNode completeTempReadNode, - @Cached("create(frame, 1)") final TemporaryWriteMarkContextsNode completeTempWriteNode, + @Cached("create(frame, 1)") final FrameStackWriteNode completeTempWriteNode, @Cached final GetContextOrMarkerNode getContextOrMarkerNode, @Cached final DispatchClosureNode dispatchNode) { completeTempWriteNode.executeWrite(frame, BooleanObject.TRUE); @@ -63,19 +84,10 @@ protected static final void doAboutToReturnVirtualized(final VirtualFrame frame, dispatchNode.execute(node, closure, FrameAccess.newClosureArgumentsTemplate(closure, getContextOrMarkerNode.execute(frame), 0)); } - @SuppressWarnings("unused") - @Specialization(guards = {"!hasModifiedSender(frame)", "!isNil(completeTempReadNode.executeRead(frame))"}, limit = "1") - protected final void doAboutToReturnVirtualizedNothing(final VirtualFrame frame, final NonLocalReturn nlr, - @Cached("createTemporaryReadNode(frame, 1)") final FrameStackReadNode completeTempReadNode) { + @Specialization(guards = {"!completeTempIsNil"}) + protected static final void doAboutToReturnVirtualizedNothing(@SuppressWarnings("unused") final boolean completeTempIsNil) { // Nothing to do. } - - @Specialization(guards = {"hasModifiedSender(frame)"}) - protected static final void doAboutToReturn(final VirtualFrame frame, final NonLocalReturn nlr, - @Cached("createAboutToReturnSend()") final SendSelectorNode sendAboutToReturnNode) { - assert nlr.getTargetContextOrMarker() instanceof ContextObject; - sendAboutToReturnNode.executeSend(frame, new Object[]{FrameAccess.getContext(frame), nlr.getReturnValue(), nlr.getTargetContextOrMarker()}); - } } @DenyReplace