Revamps drreg's state restoration logic (again) to obviate the need to observe non-drreg spills and restores.
The previous strategy of tracking the app value across spills and restores required drreg to be aware of non-drreg spilling mechanisms like spilling to mcontext, to stack, or any other possible methods. This made it non-ideal.
Implements a new strategy for state restoration that does not need to be aware of non-drreg spills, and also handles the various tricky drreg cases like multi-phase use. The key observation behind this is that it is easier to find the matching spill for a given restore, than to find the matching restore for a given spill. This is because there may be other restores besides the final restore (e.g. restores for app read, user prompted restores, etc.). This makes it hard to find exactly where the spill region for a reg/aflags ends. Additional complexities include the fact that aflags re-spills may not use the same slot, which makes differentiating spills from multiple phases difficult. Now we walk the ilist backwards from the last instr to the faulting instr. The first restore (or last restore in the list) found is expected to be an app value restore. We find the matching spill for that restore which uses the same slot which has to be an app value spill too. We continue doing this until we reach the faulting instr and if there's a spill-restore pair where the spill is before the faulting instr, we use that slot to restore the reg/aflags. This way we see only app value spills/restores and skip over tool value spills/restores.
Also makes a small fix in instr_is_reg_spill_or_restore_ex
to not return true
for mcontext base loads to regs, which is not strictly a reg restore operation.
Adds multiple new test cases that use non-drreg spilling mechanisms: spilling to mcontext, clean call instrumentation. Also modifies some previous tests so that the interesting part of the test happens after the faulting instr; this is required because we now walk backwards in the ilist, not forwards.
Verified on a GA runner that the original burst_threads failure didn't occur in 500 runs.
Issue: #3823 (closed) Fixes: #4963 (closed)