Fix fgNewBBinRegion when inserting into filters.
authorPat Gavlin <pagavlin@microsoft.com>
Fri, 21 Apr 2017 17:26:05 +0000 (10:26 -0700)
committerPat Gavlin <pagavlin@microsoft.com>
Tue, 25 Apr 2017 17:10:48 +0000 (10:10 -0700)
commitd07005742f51c8e719e78d566861a0ba1d65d3b1
treef4d4eafe1e3236926a2e68722d574996eec307fb
parenta5cc8aed33c27ed3ad816142aac45d8488abb1e8
Fix fgNewBBinRegion when inserting into filters.

In order to ensure that the GC operates properly when handling
exceptions, the CLR ABI requires that control exits a filter region
throguh its terminal instruction. `fgNewBBinRegion` was violating this
invariant, however, which lead to GC stress failures when the GC was
invoked immediately after a filter finished executing but before control
entered any handlers. This change fixes the behavior of
`fgNewBBinRegion` when inserting new blocks into filter regions.

There are two cases to consider when inserting a new BB into a filter
region:
1. The filter region consists of multiple blocks
2. The filter region consists of a single block

The first case is straightforward: instead of inserting a new BB after
the last block of the filter, insert it before the last block of the
filter. Because the filter contains multiple blocks, the predecessor of
the filter must also be in the filter region.

The latter case requires splitting the single block, as inserting a new
block before the single block would otherwise change control flow (the
filter would begin with the new block rather than the single block). In
order to acheive this with minimal complexity, this change first inserts
a `BBJ_ALWAYS` block that transfers control to the existing single
block, then inserts a second new block immediately before the existing
single block. The second new block is then returned. To put it
visually, the transformation is from this:

```
    filter start: BBN (BBJ_EHFILTERRET)
```

to this:

```
    filter start: BBN + 1 (BBJ_ALWAYS -> BBN)
                  BBN + 2 (jumpKind)
                  BBN     (BBJ_EHFILTERRET)
```

and the function returns `BBN + 2`.

Fixes VSO 406163.

Commit migrated from https://github.com/dotnet/coreclr/commit/c0987857bd44ab415d886094548590c880e12373
docs/coreclr/botr/clr-abi.md
src/coreclr/src/jit/flowgraph.cpp