ARM64: Enable End-To-End ReadyToRun (R2R) Crossgen
authorKyungwoo Lee <kyulee@microsoft.com>
Sat, 14 May 2016 20:06:57 +0000 (13:06 -0700)
committerKyungwoo Lee <kyulee@microsoft.com>
Wed, 18 May 2016 21:23:58 +0000 (14:23 -0700)
commitf7ff1244fdcd8c795ea50abf8b89f4ef7adfe366
tree8337ed7a378a7679d30958936884f9da0f7dc5b0
parent286c1be3edc5d1e4796c58cc51a0f25b0244b375
ARM64: Enable End-To-End ReadyToRun (R2R) Crossgen

Fixes https://github.com/dotnet/coreclr/issues/4649
The immediate issues was NYI on genEmitHelperCalls. The initial
implementation for the missing part was enough to just crossgen System.dll.
But running tests revealed various issues in crossgened binaries (R2R).
Most common user/helper calls in R2R are represented as indirect calls
similar to interface call using virtual stub dispatch cell --
thunk/helper needs a indirect cell address to update the final target
address on the data location. `IsDelayLoadHelper` and `IsLazyHelper` belong to
this case.
Instead of passing such parameter, x64/x86 uses an encoding trick -- it
assumes the call is dispatched like `call [addr]`. So from the return
address, runtime could extract indirect cell address. Unfortunately this is not
an option for arm64 (actually arm as well but I haven't fixed it in this
change) where indirect call on memory is not encodable.
So, I made the following changes:

1. For the call requiring that needs to pass indirect cell address, I
tagged the call tree via `setR2RRelativeIndir`. Tried to be comprehensive,
but I may miss something. Currently, it includes a regular call and
various helpers for (virtual) load function pointer/static data access, etc.
Hopely we change JIT/EE interface somehow that gives us such explicit information.

2. Use the X11 to record indirect cell address for such call tree in
lower similar to VSD.

3. Fixed encodings `ZapIndirectHelperThunk`. In particular the immediate
value/offset for `ldr` should be scaled down 4 times since HW will scale
it 4 times.

4. Implement `genEmitHelperCalls` for indirect case. This is not the case requiring indirect
cell address. This is the case we inlined the indirect helper thunk for
the speed. I'm seeing the case for size opt helper call, we invoke a
direct call to such thunk which actually uses x12 to dispatch the final
target. Likewise, I used x12 for this expansion which seems a trash register that is not
overlapped with arugments with jit helpers like writer barriers.

With this change, I've tested various cases/scenraios locally.
Also I've verified all tests are passed against mscorlib.ni.dll and System.ni.dll.

Commit migrated from https://github.com/dotnet/coreclr/commit/3165d8e5bfddd78028c9eb2b5ea3ec995c71a849
src/coreclr/src/jit/codegenarm64.cpp
src/coreclr/src/jit/flowgraph.cpp
src/coreclr/src/jit/gentree.cpp
src/coreclr/src/jit/gentree.h
src/coreclr/src/jit/importer.cpp
src/coreclr/src/jit/lower.cpp
src/coreclr/src/jit/target.h
src/coreclr/src/zap/zapimport.cpp