JIT: enable inline pinvoke in more cases
authorAndy Ayers <andya@microsoft.com>
Mon, 21 Nov 2016 23:44:21 +0000 (15:44 -0800)
committerAndy Ayers <andya@microsoft.com>
Mon, 5 Dec 2016 21:18:42 +0000 (13:18 -0800)
commit043fe32b7489952a62b2cb0cbe41de86895075a3
tree019a471453c1e1079d99c97c3f9439c85bd721be
parent75a625faaddcd45b5ab396019dc1623dfe3b35c1
JIT: enable inline pinvoke in more cases

An inline pinvoke is a pinvoke where the managed/native transition
overhead is reduced by inlining parts of the transition bookkeeping
around the call site. A normal pinvoke does this bookkeeping in
a stub method that interposes between the managed caller and the
native callee.

Previously the jit would not allow pinvoke calls that came from inlines
to be optimized via inline pinvoke. This sometimes caused performance
surprises for users who wrap DLL imports with managed methods. See for
instance #2373.

This change lifts this limitation. Pinvokes from inlined method bodies
are now given the same treatment as pinvokes in the root method. The
legality check for inline pinvokes has been streamlined slightly to
remove a redundant check. Inline pinvokes introduced by inlining are
handled by accumulating the unmanaged method count with the value from
inlinees, and deferring insertion of the special basic blocks until after
inlining, so that if the only inline pinvokes come from inline instances
they are still properly processed.

Inline pinvokes are still disallowed in try and handler regions
(catches, filters, and finallies).

X87 liveness tracking was updated to handle the implicit inline frame
var references. This was a pre-existing issue that now can show up more
frequently. Added a test case that fails with the stock legacy jit
(and also with the new enhancements to pinvoke). Now both the original
failing case and this case pass.

Inline pinvokes are also now suppressed in rarely executed blocks,
for instance blocks leading up to throws or similar.

The inliner is now also changed to preferentially report inline
reasons as forced instead of always when both are applicable.

This change adds a new test case that shows the variety of
situations that can occur with pinvoke, inlining, and EH.
src/jit/compiler.h
src/jit/flowgraph.cpp
src/jit/importer.cpp
src/jit/inlinepolicy.cpp
src/jit/morph.cpp
src/jit/stackfp.cpp
tests/src/JIT/Directed/pinvoke/pinvoke-examples.cs [new file with mode: 0644]
tests/src/JIT/Directed/pinvoke/pinvoke-examples.csproj [new file with mode: 0644]
tests/src/jit/Directed/pinvoke/pinvoke-bug.cs [new file with mode: 0644]
tests/src/jit/Directed/pinvoke/pinvoke-bug.csproj [new file with mode: 0644]
tests/testsUnsupportedOutsideWindows.txt