Skip to content
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

Expose intrinsics to set/get the pointer to the simulated stack. #200

Open
lachlansneff opened this issue Jun 20, 2018 · 7 comments
Open

Comments

@lachlansneff
Copy link

LLVM currently creates a mutable global that points to a location in memory that acts as a local stack from webassembly. This is akin to the stack pointer register on most cpus. Currently, there is no way to figure out where that points or to set it to a new location.

In nebulet, this is required to implement different simulated stacks for each user-level thread.

I propose implementing two intrinsics:

  1. get_stack
  2. set_stack
@lachlansneff
Copy link
Author

On further explorations, it looks like llvm exports intrinsics for this: llvm.stacksave and llvm.stackrestore. I've confirmed these as working in wasm. Nevertheless, it would be good to have these exposed in std::arch.

@pepyakin
Copy link
Member

pepyakin commented Jun 27, 2018

hey hey @lachlansneff ! Why did you close the issue? Maybe it is a good idea to leave it for tracking/discussing about exposing this intrinsics in std::arch?

@lachlansneff
Copy link
Author

It turns out that the llvm.stackrestore intrinsic actually is not useful for this use-case. It has to be used with a matching llvm.stacksave, and thus is not the same as being able to set the stack pointer. I'm all for exposing intrinsics to set/get the stack pointer, but it'll be more complicated than just binding to those.

@pepyakin
Copy link
Member

So let's then reopen this issue.

My use-case is to avoid stack-overflows and dynamically grow the stack in wasm runtime. Maybe something similar to @alexcrichton 's stacker!

@pepyakin pepyakin reopened this Jun 27, 2018
@lachlansneff
Copy link
Author

@pepyakin Have you had any luck with this?

@pepyakin
Copy link
Member

pepyakin commented Aug 8, 2018

Unfortunately, no, haven't tried to do something about it. Thankfully, it doesn't press me, yet : )

@bitwalker
Copy link

I just came across this issue, but something to be aware of is that the shadow stack used by LLVM is separate from the host stack (i.e. the "real" stack), so it cannot be relied upon as a way to prevent stack overflows. Even if you only ever allocate on the shadow stack, the host may allocate on its own stack, e.g. activation records, function arguments, etc. So with deep enough recursion you can still overflow the host stack, and cause a crash - currently there seems to be no way to avoid this.

I brought this up to the WebAssembly CG recently, in the context of continuations, and requested primitives for being able to query the host stack size and position in the stack (in relative terms, not actual pointers, to avoid raising security concerns). This would allow one to check both the shadow stack and host stack, and if overflow is imminent, reclaim stack space by jumping or returning to a trampoline (ala Cheney on the MTA). In my use case, this would perform much better than trampolining for every call, and enable garbage collection schemes that leverage the Cheney on the MTA-style approach of using the stack as a young generation in a generational collector. More generally though, it would enable a variety of use cases where stack management is necessary. I have not yet created an issue with a formal proposal, but it is on my TODO list.

Based on the use case in the OP, some form of continuations or coroutines may be useful for you as well. There is also some discussion around extending the base exception handling proposal with "resumable" exceptions, which may be able to act as a foundation for delimited continuations/coroutines, but I don't believe that is part of the proposal today, so if that kind of functionality is important for things you are building, I would definitely suggestion dropping by the WebAssembly design repository and make sure your voice gets heard!

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

No branches or pull requests

3 participants