Use returns_twice attribute to preserve regs in nlrthumb nlr_push() #7368
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This program crashed on SAMD51 when compiled with
DEBUG=1
:The stack variable
fastn
inmp_execute_bytecode()
inpy/vm.c
was getting smashed. It was a Heisenbug because adding print statements caused it to work.After narrowing down the point of smashing, I looked at the assembly code and saw that a call to
nlr_push()
inmp_execute_bytecode
assumed that registerr3
was preserved, when it was not.nlr_push()
is a "naked
" function that does not have the usual prologue and postlogue.This all seemed more and more familiar as I progressed, and it turns out I fixed this problem already, about five years ago, in #506! However, the fix got undone during an upstream MicroPython merge in 2021. The problem manifested differently and we didn't see this problem again for a while.
My #506 fix involved adding "don't clobber these registers" indicators to
nlr_push()
. There is a long discussion in the related issue, #500. A MicroPython developer discovered the same problem in a different context, but it never really got fixed in MicroPython, because it occurs due to LTO, and they rarely use LTO. See micropython#3889 (which was closed and not merged).The fix proposed in micropython#3889 is to declare
nlr_push()
with the attributereturns_twice
. That is simpler than my #506 fix, so I tried that this time, and lo and behold, it works.Note that this does not solve #7279 (-O2 not working on SAMx5x).