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
Simplify memory setup / remove special JS allocation modes? #7795
Comments
I regret that I have but one +1 to give for this proposal.... |
@juj, any thoughts/concerns here before I start to look into this? |
How do you see the extent of this to go:
The The Although I think there may still be a need to have a |
Yes, JS would no longer manage any memory allocation. It would just call into wasm/asm.js for stackAlloc or malloc. (should be a nice shrinking of our JS glue)
Yes.
Yes.
Yes. Still sbrk() as normal, but done all in compiled code (it already mostly is, just the initial location came from JS).
Note that But yes, as you said in the second part of your comment, statically handling JS static allocations may be useful here, and may end up replacing some allocate()s (the static and perhaps dynamic ones).
Yes, this may end up the hard part here - it may need to be asynchronous if it is to be in JS. Other options are to statically compute JS static allocations, as just mentioned. Another option is for me to move some things into compiled code. I hope to avoid any async messiness with both of those, but I can't be sure til I try. |
Will it still be possible to call malloc / free from the JS / host code? Sometimes host functions need to return dynamically allocated memory to the hosted code.
Edit: nevermind above question, after re-reading your proposal I'm fairly certain you're taking that into account. Big +1 from me.
|
I am in favor of removing If instead |
Yes, it allows the optimizer to pre-execute code at compile time. Say if the program starts with a few mallocs, those can be done at compile time, improving startup and download times.
How many does it allocate? If it's just a few, then statically allocating them at compile time seems ok?
That is async anyhow, and so it seems like it could use malloc - so it just waits for the wasm to be ready to run? |
First part of #7795: this removes the ability to do static allocations in JS when the app starts. That means no more staticAlloc, ALLOC_STATIC, and the staticSealed logic to handle it. Instead, static allocations are done at compile time, using makeStaticAlloc. The JS compiler informs emscripten.py of those static allocations, and then they are added after static allocations from LLVM, basically. Benefits: * Remove a bunch of complexity (no more staticSealed), etc. See apply_memory in emscripten.py for how simple memory layout is after this: we run the C compiler, then the JS compiler, then in that python code we can lay out static memory completely at compile time. * Saves code size and startup work by replacing x = staticAlloc(size) to x = ptr (hardcoded ptr numbers, computed at compile time). On hello world (with closure/-Os) this saves around 1%, more than I thought actually. Downsides: * The current model is very simple: JS library files do {{{ makeStaticAlloc(size) }}} which does the allocation and returns a ptr, at compile time. However, when JS did the call at runtime, if the code was not reached the allocation was not done. In this model, if the JS library is parsed and preprocessed, we allocate - which means the library_pthreads.js ones are not done by default, but the library.js ones are. As a result, we are wasting in some cases a little static space that is actually unused (maybe 100 bytes?). This is probably pretty negligible, but we could optimize it out later, at the cost of more complexity in the JS compiler - not sure if that would be worth it. Possible followups / stuff not done in this PR: * No changes to dynamic allocation in JS when the app starts. Only static allocation is changed here. We could hardcode DYNAMICTOP_PTR's location in the wasm (but not its value, not without changes to dynamic allocation, see previous point), say as a param to wasm-emscripten-finalize etc. This would save passing it at runtime into the wasm. PR also contains a few minor test fixes, like the stack-overflow test had an incorrect part, but we never noticed til now where the new memory layout happens to make it actually cause a problem.
Part of #7795. Depends on WebAssembly/binaryen#1870 (has a hardcoded binaryen port value for testing, before landing needs to be a new tag there) This is the emscripten side of that PR: * For asm2wasm, define STACKTOP/STACK_MAX in the asm.js code with the hardcoded value directly. * For wasm-emscripten-finalize, send it using --initial-stack-pointer. This saves 1 or 2 imports in the wasm, and JS to send it there. Not a huge savings in code size (16 bytes in hello world), but it is simpler and also simpler in the compiler code too. * bump abi * fix test_stack_varargs - in the wasm backend, 2K is not enough for the single printf, it overflows. double the stack and double the stack uses * update binaryen port
ping @juj - see comments above. |
sgtm |
This issue has been automatically marked as stale because there has been no activity in the past year. It will be closed automatically if no further activity occurs in the next 7 days. Feel free to re-open at any time if this issue is still relevant. |
I still think this is worth doing. |
This issue has been automatically marked as stale because there has been no activity in the past year. It will be closed automatically if no further activity occurs in the next 30 days. Feel free to re-open at any time if this issue is still relevant. |
I believe this has been done. |
I'd like to simplify our memory setup code by removing the ability to do "special" allocations in JS. That is, right now you can do these allocations from JS:
stackAlloc
in compiled code)malloc
in compiled code)I propose keeping the first two (which we can't remove, they are the absolute minimum) and removing the latter two.
The benefits of removing them:
The downsides:
malloc/stackAlloc
, we must wait for compiled code to be ready first.The text was updated successfully, but these errors were encountered: