Fix #11273 by adjusting the fix for VSO 406163.
authorPat Gavlin <pagavlin@microsoft.com>
Fri, 28 Apr 2017 23:31:25 +0000 (16:31 -0700)
committerPat Gavlin <pagavlin@microsoft.com>
Sat, 29 Apr 2017 00:02:34 +0000 (17:02 -0700)
commitcf0e382bd7b235d6cae0204d3a11850d4d95df44
tree4b9cfa5a9434c04157beaeb7fc950e45583324de
parentb38113c80d04c39890207d149bf0359a86711d62
Fix #11273 by adjusting the fix for VSO 406163.

Issue #11273 revealed an issue with the fix for VSO 406163: as of today,
the compiler models the incoming exception object in a handler by
looking for `GT_CATCH_ARG` in the first block of a handler and if found
marking the register that contains the exception object as holding a GC
pointer. Unfortunately, this breaks down under the transform that the
original fix (#11134) was performing for single-block filters. That
transformation was from this:

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

to this:

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

After this transform, `BBN` still contains the `GT_CATCH_ARG`, but the
register containing the exception object must be live through `BBN + 1`
as well as live in to `BBN`.

There are a number of possible solutions to this problem (e.g. modeling
the liveness of the exception object in some fashion or splitting the
single-block filter either after the catch arg or before the filter
ret), but many of them are complicated by the fact that this
transformation needs to operate on both HIR and LIR and must be be able
to run in a variety of locations, including after registers have been
allocated. Instead, this change takes the approach of ensuring that no
single-block filter regions exist on platforms that target the JIT32 GC
encoder by inserting a spill of the exception object to a local var in
its own block at the start of a filter.
src/jit/compiler.h
src/jit/flowgraph.cpp
src/jit/importer.cpp