diff options
author | Jan Vorlicek <janvorli@microsoft.com> | 2016-12-10 10:52:34 +0300 |
---|---|---|
committer | Jan Vorlicek <janvorli@microsoft.com> | 2016-12-10 10:52:34 +0300 |
commit | 5c3855f690cb5cae7c7877e350814792fc55eb10 (patch) | |
tree | 9d068c46a48448570a4dc64ddf9c1a7449777e93 /src/Native/Runtime/arm | |
parent | 7f209e8c88359a4e8e756aa385ed71e950569154 (diff) |
This change fixes interface dispatch on ARM and x86 in case the RhpCastableObjectDispatchHelper is jumped-to from RhpInterfaceDispatchX functions. The RhpInterfaceDispatchX were not preserving r12 on ARM / eax on x86 that contain the address of the indirection cell, which lead to failures.
The fix is to let RhpCastableObjectDispatchHelper accept the cache entry pointer in r12 / eax instead.
I have also updated the CastableObject.cs based on Fadi Hanna's suggestion so that it can catch the issue this change fixes.
[tfs-changeset: 1641040]
Diffstat (limited to 'src/Native/Runtime/arm')
-rw-r--r-- | src/Native/Runtime/arm/StubDispatch.asm | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/src/Native/Runtime/arm/StubDispatch.asm b/src/Native/Runtime/arm/StubDispatch.asm index c1f766a4a..4254be83f 100644 --- a/src/Native/Runtime/arm/StubDispatch.asm +++ b/src/Native/Runtime/arm/StubDispatch.asm @@ -50,12 +50,12 @@ ;; Check a single entry in the cache. ;; R1 : Instance EEType* ;; R12: Cache data structure - ;; R2 : Trashed + ;; R2 : Trashed. On succesful check, set to the target address to jump to. ldr r2, [r12, #(OFFSETOF__InterfaceDispatchCache__m_rgEntries + ($entry * 8))] cmp r1, r2 bne %ft0 - ldr r12, [r12, #(OFFSETOF__InterfaceDispatchCache__m_rgEntries + ($entry * 8) + 4)] + ldr r2, [r12, #(OFFSETOF__InterfaceDispatchCache__m_rgEntries + ($entry * 8) + 4)] b %fa99 0 MEND @@ -91,11 +91,16 @@ SECTIONREL_t_TLS_DispatchCell LEAF_ENTRY RhpCastableObjectDispatchHelper_TailCalled ;; Load the dispatch cell out of the TLS variable GET_TLS_DISPATCH_CELL - b RhpCastableObjectDispatchHelper + b RhpCastableObjectDispatchHelper2 LEAF_END RhpCastableObjectDispatchHelper_TailCalled LEAF_ENTRY RhpCastableObjectDispatchHelper - ;; r12 has the interface dispatch cell address in it. + + ;; r12 contains address of the cache block. We need to point it to + ;; the indirection cell using the back pointer in the cache block + ldr r12, [r12, #OFFSETOF__InterfaceDispatchCache__m_pCell] + + ALTERNATE_ENTRY RhpCastableObjectDispatchHelper2 ;; The calling convention of the universal thunk is that the parameter ;; for the universal thunk target is to be placed in sp-8 ;; and the universal thunk target address is to be placed in sp-4 @@ -118,7 +123,7 @@ StubName SETS "RhpInterfaceDispatch$entries" NESTED_ENTRY $StubName ;; On input we have the indirection cell data structure in r12. But we need more scratch registers and ;; we may A/V on a null this. Both of these suggest we need a real prolog and epilog. - PROLOG_PUSH {r1-r2} + PROLOG_PUSH {r1-r2, r12} ;; r12 currently holds the indirection cell address. We need to update it to point to the cache ;; structure instead. @@ -134,18 +139,22 @@ CurrentEntry SETA 0 CurrentEntry SETA CurrentEntry + 1 WEND - ;; r12 currently contains the cache block. We need to point it back to the - ;; indirection cell using the back pointer in the cache block - ldr r12, [r12, #OFFSETOF__InterfaceDispatchCache__m_pCell] - - EPILOG_POP {r1-r2} + EPILOG_POP {r1-r2, r12} EPILOG_BRANCH RhpInterfaceDispatchSlow ;; Common epilog for cache hits. Have to out of line it here due to limitation on the number of ;; epilogs imposed by the unwind code macros. 99 + ;; r12 contains the cache block address. + ;; r2 contains the target address. Store it to the location where r12 was pushed + ;; at the entry. The EPILOG_LDRPC_POSTINC will load it into the pc, which will results + ;; in jump to the target with all registers except r12 in the same state as when + ;; the current function was entered. R12 will point to the cache block address, + ;; which is a contract with the RhpCastableObjectDispatchHelper. + str r2, [sp, #8] + EPILOG_POP {r1-r2} - EPILOG_BRANCH_REG r12 + EPILOG_LDRPC_POSTINC 4 NESTED_END $StubName |