Fix Linux/x86 call alignment calculation and insertion (dotnet/coreclr#10266)
authorBruce Forstall <brucefo@microsoft.com>
Tue, 21 Mar 2017 22:27:07 +0000 (15:27 -0700)
committerJan Vorlicek <janvorli@microsoft.com>
Tue, 21 Mar 2017 22:27:07 +0000 (23:27 +0100)
commit03e0c746aa86adbf2ccf40d3ab3630dd4de55c1e
tree8ac7b4245bcdce83e61ee54a7e715f082415a878
parent3b4f0f3b1b0c665345be9a2db294099cbbc2b762
Fix Linux/x86 call alignment calculation and insertion (dotnet/coreclr#10266)

* Fix Linux/x86 call alignment calculation and insertion

The existing system of calculating per-call alignment adjustments
did not consider the possibility of nested calls. On x86, some
arguments for a call might be pushed on the stack before a
nested call's arguments start being pushed. Thus, a call can't
consider only its own arguments when determining the stack level.

Instead, use the existing genStackLevel variable, updated
dynamically during code generation, to determine the baseline
stack alignment when a call first needs to push something on
the stack, or if it has no stack arguments, whether it needs to
align the stack before a call.

One wrinkle here is that the fgAddCodeRef() function for adding
throw blocks for array bounds checks, and other similar helpers,
need to know the stack level on entry, and this stack level is
computed during argument morphing. There is a tough phase ordering
problem here. So, we bail out and force an EBP frame if there are
any such throw helpers in the function. When using an EBP frame,
the helper block doesn't need to know the stack level -- it is
only needed for ESP frames, needed for unwinding. Note that this
bail out already existed if the same helper needed multiple different
stack levels on entry. We could do slightly better without too much
work by not bailing out for top-level calls with no stack arguments.

* Track max alignment added for nested calls during codegen

This information is needed by Linux/x86 for an assert about
maximum emitter stack depth.

* Make max stack align tracking available in release as well

The assert these are used in is a noway_assert.

* Formatting

Commit migrated from https://github.com/dotnet/coreclr/commit/68012bf209f37ab5b5b11a02b203f2949d1ef8dc
src/coreclr/src/jit/codegencommon.cpp
src/coreclr/src/jit/codegenlinear.h
src/coreclr/src/jit/codegenxarch.cpp
src/coreclr/src/jit/compiler.h
src/coreclr/src/jit/flowgraph.cpp
src/coreclr/src/jit/gentree.h
src/coreclr/src/jit/lower.cpp
src/coreclr/src/jit/morph.cpp