Skip to content

Conversation

frank-emrich
Copy link
Contributor

@frank-emrich frank-emrich commented Mar 13, 2024

This PR is part of a series that adds basic support for the typed continuations/wasmfx proposal.

This particular PR adds support for the suspend instruction for suspending with a given tag, documented here.
These instructions are of the form (suspend $tag). Assuming that $tag is defined with n param types t_1 to t_n, the instruction consumes n arguments of types t_1 to t_n. Its result type is the same as the result type of the tag.
Thus, the folded textual representation looks like (suspend $tag arg1 ... argn).

Support for the instruction is implemented in both the old and the new wat parser.

Note that this PR does not implement validation of the new instruction.

This PR also fixes finalization of cont.new, cont.bind and resume nodes in those cases where any of their children are unreachable.

@frank-emrich
Copy link
Contributor Author

I haven't been able to run the fuzzer on this, because it immediately reports a fault even on the main branch. Is that a known issue? I've seen that there's been quite a few changes to the fuzzer lately, so I was wondering if it's supposed to be usable at the moment?

@tlively
Copy link
Member

tlively commented Mar 13, 2024

Hmm, no, I think it's surprising that the fuzzer is failing on the main branch.

@kripken
Copy link
Member

kripken commented Mar 13, 2024

Is that with latest V8? Then that is a known issue due to the br_if situation. The following is the safe V8 revision to use, which is one before that: 5748834cc5813a8acda0aa378b42b242a186b07e

@frank-emrich
Copy link
Contributor Author

The following is the safe V8 revision to use, which is one before that: 5748834cc5813a8acda0aa378b42b242a186b07e

Thanks, using that fixed the problem! 👍

Copy link
Member

@tlively tlively left a comment

Choose a reason for hiding this comment

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

LGTM besides checking for unreachable types in finalize.

src/ir/cost.h Outdated
return 12 + visit(curr->cont);
}
CostType visitSuspend(Suspend* curr) {
// Cheaper than resume, since payloads cannot be partially applied.
Copy link
Member

Choose a reason for hiding this comment

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

Can you explain this more? What does it mean that resume can partially apply payloads?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is definitely my most dreaded file now 😅

What I meant in the original comment here is the following: If you call resume on a continuation, it may have been produced with cont.bind, meaning that we have partially applied some arguments to the continuation, and resume only needs to provide the remaining ones. That means that we need to perform some runtime check that determines how to handle payloads in resume.
In contrast, suspend always sees all the payloads statically: When you call suspend, you provide all the payloads at once.

But there are more considerations when talking about the performance of suspend and resume, so mentioning only partial applications in my comment was a bit misleading: resume may have to check if you are initiating execution for the first time vs continuing after a suspension, suspend may need to forward to an outer handler, etc.

Given that suspend works in tandem with resume (i.e., whenever you call suspend you continue execution at another resume) and they both do stack switching, I'm now feeling more inclined to just give suspend the same cost as resume and delete my comment on suspend. Does that sound okay?

Copy link
Member

Choose a reason for hiding this comment

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

Thanks, makes sense.

Yes, giving them the same cost without comment seems fine. Trying to be too precise in the reasoning here doesn't make sense given how imprecise all the numbers actually are :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great, I've updated the function for suspend accordingly. I've also realized that I forgot to include the cost of the operands when calculating the cost of resume, so I fixed that in one go.

Comment on lines 1416 to 1422
void Suspend::finalize(Module* wasm) {
if (wasm) {
auto tag = wasm->getTag(this->tag);
type = tag->sig.results;
}
}

Copy link
Member

Choose a reason for hiding this comment

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

This needs to set the type to Type::unreachable if any of the operands are unreachable, regardless of whether wasm is present or not.

(We should do this for the other instructions as well if we forgot to do this before)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added these checks now, here and for the earlier WasmFX instructions. If that's what you had in mind I'll update the description of the PR to mention that it also fixes finalization of the other instructions.

@tlively
Copy link
Member

tlively commented Mar 18, 2024

Yep, that last change looks good 👍 Let me know when you've updated the description and I'll merge this.

@frank-emrich
Copy link
Contributor Author

Great, I've updated the description now. Any thoughts on the question in cost.h?

@tlively
Copy link
Member

tlively commented Mar 19, 2024

Oops, sorry, I had missed that.

@tlively tlively merged commit 84cc9fa into WebAssembly:main Mar 19, 2024
@gkdn gkdn mentioned this pull request Aug 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants