-
-
Notifications
You must be signed in to change notification settings - Fork 30.7k
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
test_compiler_recursion_limit fails on wasm32-wasi #95335
Comments
|
To reproduce a similar problem before #95107, add
|
This reminds me of #30855 (comment) Fiddling with the code to keep the stack use below some arbitrary limit imposed by the compiler and platform is not the way to fix this or other bugs of the sort. The proper fix is use some sort of C stack check: #91079 For now, I would recommend reducing the recursion limit in the compiler. TBH, we shouldn't care if some really weird code The only thing we need to handle is long chains of |
Until we implement #91079 we should use the standard recursion limit counter in the compiler, otherwise we can crash on this code:
As we consume most of the stack in f, then crash in the compiler. |
I’m not actually sure my PR added function calls that get repeated in a recursion. I don’t really know what I’m my PR would have caused this. |
It was probably passing locations by value, instead of by pointer, that increased the stack consumption. We need to reduce the recursion by using iterative approaches, not fiddle with the code. |
Converting recursion into iteration is a pain. So, I'd just reduce the depth for everything but |
@pablogsal might have thoughts on converting |
I’m not sure the locations are passed down deep recursions though. |
Probably, not. But they still need stack space to be passed into the |
It is very well possible that your commit change some unrelated properties of the code that results in different optimizations. I asked the wasmtime developers about stack limits in my ticket bytecodealliance/wasmtime#4214 .
The stack limit also depends on the WASM runtime and possible other parameters. So far we have been testing with wasmtime only. |
I personally not very enthusiastic but also don't mind much if we are going to make our life easier as that's an allowed change we can make but also will break everyone analyzing ASTs. |
Let's not break everyone. Can the parser produce the tree without being recursive? |
I will look into it, but the parser is an RDP so it's very nature is to recurse. We have a prototype with a stack machine but it was a pain to debug, a bit slower and it was not really better so we never used it. I am slightly confused, why do you want the parser not to recurse? The parser is not reaching any limits here, no? |
Not yet, no, but if we change the the compiler to not recurse, then the parser will be the limiting factor. This is really only an issue for What about a grammar change, so that the parser iterates? |
It depends on what do you mean by "iterating". If you are referring to make the If you want the parser to fully not recurse we need to bring back the prototype we had to make the parser work as a bytecode interpreter. That would be the best solution, but that's not without downsides, though. In any case, there are even more limiting factors: the ast constructors, optimizers, visitors and validators will recurse and they will become the limiting factor because they currently use the C stack to go down. So even if you have a tree created without recursion, the fact that the tree is very deep will crash these other parts unless you also redesign them. |
I think the best change here is to bite the bullet and change the ast so clauses are in a list instead of a nested tree. That would break everyone but it won't put a lot of crazy redesign burden on the interpreter. Another alternative is just the status quo, which is suboptimal but it is not that bad. In my machine the parser handles a conditional with less than 10000 |
I meant changing the grammar, not the parser.
We could then post-process to convert back to the deeper tree the AST currently has.
On linux, sure. But we want portability, which means controlling recursion. |
Ah, I see what you mean. 👍
I would be ok with that if the parser is the one doing the transformation (no-post processing needed). I argued before why is important that the parser produces the final AST with no post-processing needed. The key would be here how to avoid consuming C stack during the processing which I think should not be a problem. Something like (pseudocode):
This will consume double memory for the elif chain because all nodes need to be alive at the same time.
I suppose it depends on how slower this gets, but we should be aware that the tradeoff may not be worth it. In any case, I think is going to be much much much better for everyone in the long run if we do something like you propose ( In any case, this problem exists for more things, for example:
also creates a tree that will exhaust the stack in the compiler, the parser and every single piece in the middle. |
Since the tests are all passing on WASI at this point, I'm closing this as fixed. |
The problem showed up after we merged #95107
and a couple of test were disabled for WASI in #95296
With the patch in iritkatriel@4ce85e8 we get:
Here is a full WASM stack trace generated with
wasi_stacktrace.txt
Originally posted by @tiran in #93678 (comment)
The text was updated successfully, but these errors were encountered: