Fix x86 stack probing (#23881)
authorBruce Forstall <brucefo@microsoft.com>
Fri, 12 Apr 2019 23:54:55 +0000 (16:54 -0700)
committerGitHub <noreply@github.com>
Fri, 12 Apr 2019 23:54:55 +0000 (16:54 -0700)
commitd5865236e7898b730de28a7a6f034e975bb7282e
treed8e17668ab939506d13859ebc1b6060d57db9757
parentecbf6bf4300e770ba786395554cf032a57c50beb
Fix x86 stack probing (#23881)

* Fix x86 stack probing

On x86, structs are passed by value on the stack. We copy structs
to the stack in various ways, but one way is to first subtract the
size of the struct and then use a "rep movsb" instruction. If the
struct we are passing is sufficiently large, this can cause us to
miss the stack guard page.

So, introduce stack probes for these struct copies.

It turns out the stack pointer after prolog probing can be sitting
near the very end of the guard page (one `STACK_ALIGN` slot before
the end, which allows a "call" instruction which pushes its
return address to touch the guard page with the return address push).
We don't want to probe with every argument push, though. So change
the prolog probing to insert an "extra" touch at the final SP location
if the previous touch was "too far" away, leaving at least some
buffer zone for un-probed SP adjustments. I chose this to be the
size of the largest SIMD register, which also can get copied to the
argument stack with a "SUB;MOV" sequence.

Added several test case variations showing different large stack
probe situations.

Fixes #23796

* Increase the argument size probe buffer

* Formatting
src/jit/codegen.h
src/jit/codegenlinear.cpp
src/jit/codegenxarch.cpp
src/jit/target.h
tests/src/JIT/Methodical/largeframes/skip3/skippage3.cs [new file with mode: 0644]
tests/src/JIT/Methodical/largeframes/skip3/skippage3.csproj [new file with mode: 0644]
tests/src/JIT/Methodical/largeframes/skip4/skippage4.cs [new file with mode: 0644]
tests/src/JIT/Methodical/largeframes/skip4/skippage4.csproj [new file with mode: 0644]
tests/src/JIT/Methodical/largeframes/skip4/skippage4_save.cs [new file with mode: 0644]
tests/src/JIT/Methodical/largeframes/skip5/skippage5.cs [new file with mode: 0644]
tests/src/JIT/Methodical/largeframes/skip5/skippage5.csproj [new file with mode: 0644]