Skip to content

Lightweight allocation for temporary strings for use with WASI #1706

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
sunfishcode opened this issue Mar 1, 2021 · 7 comments
Open

Lightweight allocation for temporary strings for use with WASI #1706

sunfishcode opened this issue Mar 1, 2021 · 7 comments

Comments

@sunfishcode
Copy link

@dcodeIO Thinking about WebAssembly/WASI#402 (comment), I had an idea for how AssemblyScript might implement a call to a non-AS function which uses a different string representation, using temporary storage that doesn't need a GC or even a malloc heap and that may also avoid interfering with the GC's stack scanning.

The idea is, allocate the temporary string at the end of the shadow stack, but don't adjust the stack pointer. I assume the GC's stack scan stops when it reaches the stack pointer, so it wouldn't scan the temporary string data. Then after the call, there'd be no cleanup to do.

This technique has limitations. It assumes that the callee doesn't capture the pointer. And it assumes that the callee isn't using AS's shadow stack. So it isn't fully general-purpose, but in particular, it would be enough for calling WASI APIs, as no current WASI APIs capture pointers or use the caller's shadow stack.

And of course, this technique doesn't eliminate the conversion overhead. But on one hand, it'd only be temporary, as WebAssembly is already working on a better answer, and (b) it would avoid the code size of either a GC or a malloc.

@dcodeIO
Copy link
Member

dcodeIO commented Mar 1, 2021

That's indeed an idea I've also been thinking about, and involves a couple of interesting twists: Without the GC, there is no managed shadow stack. When there is a managed shadow stack, it is typically quite small, as it only tracks managed pointers but does typically not store structs or buffers, so it may again become necessary to gracefully handle a stack overflow, most likely using the dynamic memory manager we just tried to work around. Quite fascinating how these kind of things often end up in one of those chasing your own tail-like scenarios 🙂

@dcodeIO
Copy link
Member

dcodeIO commented Mar 1, 2021

I guess the safest way to avoid the MM is to use a fixed size buffer exclusive to string re-encoding, and utilize it in a streaming manner if necessary. Say we reserve a few KB for it, then most strings will fit, and if they don't we can still write in chunks. Interestingly, that wouldn't play so well with a logging API anymore, as it typically inserts a newline in between chunks, which is not what one wants then. Could be a solution on top of WASI Filesystem, though.

@sunfishcode
Copy link
Author

it may again become necessary to gracefully handle a stack overflow, most likely using the dynamic memory manager we just tried to work around

You wouldn't need full malloc+free functionality though, which would seem to be the bulk of the code size involved here. Stack overflow checking in concept doesn't need malloc+free, so if they get pulled in, perhaps there's a way to organize the code to avoid that.

The fixed-size buffer technique does indeed sound like a practical approach for streaming data.

@jtenner
Copy link
Contributor

jtenner commented Mar 1, 2021

As someone who is responsible for writing lots of glue code, is a fixed size buffer to stream data a good practice?

I would imagine something like that could even be configured at compile time using a compiler constant.

@dcodeIO
Copy link
Member

dcodeIO commented Mar 1, 2021

It's more a workaround for a very specific use case, that is calling external APIs with some temporary data that may not somehow call back into Wasm, so it is guaranteed that these never interfere with the heavy machinery, plus these APIs have to allow streaming. Thinking about this a little more, it's even a bit risky, because we cannot guarantee that every WASI polyfill in existence doesn't do more than that.

@sunfishcode
Copy link
Author

The WASI spec could easily give you the guarantees you'd need here.

@dcodeIO
Copy link
Member

dcodeIO commented Mar 1, 2021

Hmm, yeah, that may help to some extent. In general I am open to give this a shot, given that getting rid of our custom ABI is generally good to do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants