summaryrefslogtreecommitdiff
path: root/src/vm/arm/asmhelpers.asm
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/arm/asmhelpers.asm')
-rw-r--r--src/vm/arm/asmhelpers.asm524
1 files changed, 4 insertions, 520 deletions
diff --git a/src/vm/arm/asmhelpers.asm b/src/vm/arm/asmhelpers.asm
index 796c1d14c5..542bdc65cc 100644
--- a/src/vm/arm/asmhelpers.asm
+++ b/src/vm/arm/asmhelpers.asm
@@ -40,12 +40,6 @@
#endif // WRITE_BARRIER_CHECK
-#ifdef FEATURE_REMOTING
- IMPORT $CTPMethodTable__s_pThunkTable
- IMPORT VSD_GetTargetForTPWorker
- IMPORT VSD_GetTargetForTPWorkerQuick
- IMPORT TransparentProxyStubWorker
-#endif
#ifdef FEATURE_COMINTEROP
IMPORT CLRToCOMWorker
IMPORT ComPreStubWorker
@@ -64,11 +58,6 @@
IMPORT GetCurrentSavedRedirectContext
-#ifdef FEATURE_MIXEDMODE
- SETALIAS IJWNOADThunk__FindThunkTarget, ?FindThunkTarget@IJWNOADThunk@@QAAPBXXZ
- IMPORT $IJWNOADThunk__FindThunkTarget
-#endif
-
;; Imports to support virtual import fixup for ngen images
IMPORT VirtualMethodFixupWorker
;; Import to support cross-moodule external method invocation in ngen images
@@ -562,41 +551,6 @@ UM2MThunk_WrapperHelper_ArgumentsSetup
NESTED_END
-; ------------------------------------------------------------------
-;
-; IJWNOADThunk::MakeCall
-;
-; On entry:
-; r12 : IJWNOADThunk *
-;
-; On exit:
-; Tail calls to real managed target
-;
-
-#ifdef FEATURE_MIXEDMODE
- NESTED_ENTRY IJWNOADThunk__MakeCall
-
- ; Can't pass C++ mangled names to NESTED_ENTRY and my attempts to use EQU to define an alternate name
- ; for a symbol didn't work. Just define a label for the decorated name of the method and export it
- ; manually.
-|?MakeCall@IJWNOADThunk@@KAXXZ|
- EXPORT |?MakeCall@IJWNOADThunk@@KAXXZ|
-
- PROLOG_PUSH {r0-r4,lr}
- PROLOG_VPUSH {d0-d7}
-
- CHECK_STACK_ALIGNMENT
-
- mov r0, r12 ; IJWNOADThunk * is this pointer for IJWNOADThunk::FindThunkTarget
- bl $IJWNOADThunk__FindThunkTarget
- mov r12, r0 ; Returns real jump target in r0, save this in r12
-
- EPILOG_VPOP {d0-d7}
- EPILOG_POP {r0-r4,lr}
- EPILOG_BRANCH_REG r12
-
- NESTED_END
-#endif
; ------------------------------------------------------------------
@@ -704,7 +658,7 @@ ThePreStubPatchLabel
NESTED_END
-#if defined(FEATURE_REMOTING) || defined(FEATURE_COMINTEROP)
+#if defined(FEATURE_COMINTEROP)
; ------------------------------------------------------------------
; setStubReturnValue
@@ -753,372 +707,10 @@ NoFloatingPointRetVal
LEAF_END
-#endif // FEATURE_REMOTING || FEATURE_COMINTEROP
-
-#ifdef FEATURE_REMOTING
-
-; ------------------------------------------------------------------
-; Remoting stub used to dispatch a method invocation. This is the choke point for all remoting calls; all
-; scenarios where we determine we're not a local or a COM call, regardless of whether the dispatch is
-; interface, virtual or direct will wind up here sooner or later.
-;
-; On entry:
-; r0 : transparent proxy
-; r12 : target MethodDesc or slot number
-; plus user arguments in registers and on the stack
-;
- NESTED_ENTRY TransparentProxyStub_CrossContext
-
- PROLOG_WITH_TRANSITION_BLOCK 0x20
-
- add r0, sp, #__PWTB_TransitionBlock ; pTransitionBlock
- mov r1, r12 ; pMethodDesc
-
- bl TransparentProxyStubWorker
-
- ; r0 = fpRetSize
-
- ; return value is stored before float argument registers
- add r1, sp, #(__PWTB_FloatArgumentRegisters - 0x20)
- bl setStubReturnValue
-
- EPILOG_WITH_TRANSITION_BLOCK_RETURN
-
- NESTED_END
-
-; ------------------------------------------------------------------
-; This method does nothing. It's just a fixed function for the debugger to put a breakpoint on.
- LEAF_ENTRY TransparentProxyStubPatch
- add r0, r1, r2
-TransparentProxyStubPatchLabel
- EXPORT TransparentProxyStubPatchLabel
- bx lr
- LEAF_END
-
-; ------------------------------------------------------------------
-; VSD helper for performing an in-context interface dispatch on a TransparentProxy. This only happens for
-; ContextBoundObjects that are invoked in the correct context, never for general remoting.
-;
-; On entry:
-; r0 : transparent proxy
-; r12 : interface MethodDesc
-; plus user arguments in registers and on the stack
-;
-; On exit:
-; Tail calls to actual target which returns as normal to the caller.
-;
- NESTED_ENTRY InContextTPQuickDispatchAsmStub
-
- ; Spill caller's volatile argument registers and some other state we wish to preserve.
- PROLOG_PUSH {r0-r3,r12,lr}
- PROLOG_VPUSH {d0-d7}
-
- CHECK_STACK_ALIGNMENT
-
- ; Set up arguments for VSD_GetTargetForTPWorkerQuick
- ; mov r0, r0 ; this
- mov r1, r12 ; Interface MethodDesc
-
- bl VSD_GetTargetForTPWorkerQuick
-
- ; If we didn't find a target head for the slow path.
- cbz r0, CacheMiss
-
- ; Save target address since we're about to restore the value of r0. Can't place it directly into r12
- ; since that's about to be restored as well. Instead we overwrite the saved version of r12 on the
- ; stack (we don't need it any more since the lookup succeeded).
- str r0, [sp, #((16 * 4) + (4 * 4))]
-
- ; Restore caller's argument registers.
- EPILOG_VPOP {d0-d7}
- EPILOG_POP {r0-r3,r12,lr}
-
- ; Tail call to the real code using the previously computed target address.
- EPILOG_BRANCH_REG r12
-
-CacheMiss
- ; Restore caller's argument registers.
- EPILOG_VPOP {d0-d7}
- EPILOG_POP {r0-r3,r12,lr}
-
- EPILOG_BRANCH InContextTPDispatchAsmStub
-
- NESTED_END
-
-; ------------------------------------------------------------------
-
- NESTED_ENTRY InContextTPDispatchAsmStub
-
- PROLOG_WITH_TRANSITION_BLOCK
-
- add r0, sp, #__PWTB_TransitionBlock ; pTransitionBlock
- mov r1, r12 ; pMethodDesc / token
-
- bl VSD_GetTargetForTPWorker
-
- mov r12, r0
-
- EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
- EPILOG_BRANCH_REG r12
-
- NESTED_END
-
-; ------------------------------------------------------------------
-; Macro used to compare a MethodTable with that of __TransparentProxy. Sets the Z condition flag to indicate
-; the result (Z=1 for a match, Z=0 for a mismatch).
-;
- MACRO
- TP_TYPE_CHECK $methodTableReg, $scratchReg
-
- ldr $scratchReg, =$CTPMethodTable__s_pThunkTable
- ldr $scratchReg, [$scratchReg]
- cmp $scratchReg, $methodTableReg
- MEND
-
-; ------------------------------------------------------------------
-; Macro used to perform a context check.
-;
-; Calls a user customizable routine that determines whether the current execution context warrants a context
-; transition for the call. Regular remoting (as opposed to context transitioning based on ContextBoundObjects)
-; always returns a context-mismatch from this call.
-;
-; On entry:
-; r0 : this (TranparentProxy object)
-;
-; On exit:
-; r0 : check result (0 == contexts match, non-zero == contexts mismatch)
-; r1-r3,r12,lr: trashed
-;
- MACRO
- TP_CONTEXT_CHECK
-
- ldr r1, [r0, #TransparentProxyObject___stub]
- ldr r0, [r0, #TransparentProxyObject___stubData]
- blx r1
- MEND
-
-; ------------------------------------------------------------------
-; Used by the remoting precode for non-virtual dispatch to instance methods which might be remoted. Performs a
-; context and transparent proxy check and if both of these are negative (or the call has been made on a null
-; 'this') we simply return and the precode will dispatch the call locally as normal. Otherwise we redirect to
-; the remoting system and never return.
-;
-; On entry:
-; r0 : this (may or may not be a TransparentProxy)
-; r1 : trashed
-; lr : return address into RemotingPrecode (RemotingPrecode* + REMOTING_PRECODE_RET_OFFSET)
-; [sp, #0] : caller's saved r1
-; [sp, #4] : caller's saved lr (i.e. return address into caller of RemotingPrecode)
-; plus user arguments in registers and on the stack
-;
- LEAF_ENTRY PrecodeRemotingThunk
-
- ; Send null 'this' case to local dispatch case (else we'd need to handle an A/V from this stub).
- cbz r0, LocalDispatch ; predicted not taken
-
- ; Load MethodTable* in r12.
- ldr r12, [r0]
-
- ; Compare MethodTable in 'this' with that of __TransparentProxy; if they're not equal we dispatch
- ; locally.
- TP_TYPE_CHECK r12, r1 ; r1 is a scratch register
- beq TransparentProxyDispatch ; predicted not taken
-
-LocalDispatch
- ; Recover target MethodDesc pointer from the RemotingPrecode (we have the address of this +
- ; REMOTING_PRECODE_RET_OFFSET in lr). Subtract extra 1 to account for the low-bit being set in LR to
- ; indicate thumb mode.
- ; We do this here because even the local case needs r12 initialized.
- ldr r12, [lr, #(RemotingPrecode__m_pMethodDesc - REMOTING_PRECODE_RET_OFFSET - 1)]
-
- bx lr
-
- LEAF_END
-
-; ------------------------------------------------------------------
-; Handles the atypical path for the remoting precode above (typically the non-local dispatch cases). The
-; regular entry point defined by NESTED_ENTRY below is never called directly; it serves only to generate
-; prolog unwind data matching the pushes of the caller's r1 and lr done in the remoting precode so we can
-; unwind out of this frame. The real entry point is TransparentProxyDispatch called directly from
-; PrecodeRemotingThunk.
-;
- NESTED_ENTRY TransparentProxyDispatch_FakeProlog
-
- ; Match what the remoting precode has pushed.
- PROLOG_PUSH {r1,lr}
-
- ; This is where execution really starts.
-TransparentProxyDispatch
-
- ; We need some temporary registers and to preserve lr.
- PROLOG_PUSH {r0,r2-r5,lr}
-
- CHECK_STACK_ALIGNMENT
-
- ; Recover target MethodDesc pointer from the RemotingPrecode (we have the address of this +
- ; REMOTING_PRECODE_RET_OFFSET in lr). Subtract extra 1 to account for the low-bit being set in LR to
- ; indicate thumb mode. Stash the result in a non-volatile register to preserve it over the call to
- ; TP_CONTEXT_CHECK below.
- ldr r4, [lr, #(RemotingPrecode__m_pMethodDesc - REMOTING_PRECODE_RET_OFFSET - 1)]
-
- ; Check whether the TP is already in the correct context. This can happen for ContextBoundObjects
- ; only. The following macro will trash volatile registers and lr and return the result in r0 (0 ==
- ; context match, non-zero for everything else). All other registers are preserved.
- TP_CONTEXT_CHECK
-
- ; Place MethodDesc* in r12 ready for wherever we dispatch to next.
- mov r12, r4
-
- ; Check the result of TP_CONTEXT_CHECK
- cbnz r0, ContextMismatch1
-
- ; At this point we know we're being called on a transparent proxy but the source and destination
- ; contexts match. This only happens for a ContextBoundObject. For an non-interface dispatch we can
- ; just return to the local dispatch case; the precode will eventually redirect to the jitted code
- ; which knows how to handle a TP-wrapped ContextBoundObject. For interface calls we need to hand off
- ; to VSD so it can resolve to the real target method. The quickest way to determine which of these
- ; cases we need is to look at the classification of the method desc. All interface methods for which a
- ; remoting precode is used are marked as mcComInterop, which though non-intuitive is generally OK
- ; since only COM interop and remoting can dispatch directly on an interface method desc. (Generic
- ; interface methods are not classified as mcComInterop but we use a different mechanism to intercept
- ; those).
- ldrh r0, [r4, #MethodDesc__m_wFlags]
- and r0, #MethodDesc__mdcClassification
- cmp r0, #MethodDesc__mcComInterop
- bne LocalDispatch1
-
- ; Local interface dispatch case. Restore argument registers saved here and in the RemotingPrecode,
- ; discard return address into the RemotingPrecode (we're not going back there) and restore the real
- ; caller's return address to LR before tail calling into the interface dispatch helper.
- EPILOG_POP {r0,r2-r5,lr} ; Restore arg registers saved by this routine and RemotingPrecode lr
- EPILOG_POP {r1,lr} ; Restore r1 saved by RemotingPrecode and real return address
- EPILOG_BRANCH InContextTPQuickDispatchAsmStub
-
-LocalDispatch1
-
- ; Local dispatch case. Restore argument registers saved here and return to the remoting precode.
- EPILOG_POP {r0,r2-r5,pc}
-
-ContextMismatch1
- ; Context-mismatch (remoted) dispatch case. Restore argument registers saved here and in the
- ; RemotingPrecode, discard return address into the RemotingPrecode (we're not going back there) and
- ; restore the real caller's return address to LR before tail calling into the cross-context helper.
- EPILOG_POP {r0,r2-r5,lr} ; Restore arg registers saved by this routine and RemotingPrecode lr
- EPILOG_POP {r1,lr} ; Restore r1 saved by RemotingPrecode and real return address
- EPILOG_BRANCH TransparentProxyStub_CrossContext
-
- NESTED_END
-
-; ------------------------------------------------------------------
-; Used to dispatch an interface call that is possibly be cross-context or remoted. Normally this is handled
-; by the remoting precode stub above but there is an edge case for generic interface methods that falls
-; through the cracks (it is not easy to cover since the precode stub makes use of it as a quick means
-; to differentiate between interface and non-interface calls in the non-cross context case).
-;
-; On entry:
-; r0 : this (TransparentProxy object)
-; r12 : interface MethodDesc
-; plus user arguments in registers and on the stack
-;
-; On exit:
-; Tail calls to the VSD in-context TP dispatcher or remoting system as appropriate.
-;
- NESTED_ENTRY CRemotingServices__DispatchInterfaceCall
-
- PROLOG_PUSH {r0-r3,r12,lr}
-
- CHECK_STACK_ALIGNMENT
-
- ; Check whether the TP is already in the correct context. This can happen for ContextBoundObjects
- ; only. The following macro will trash volatile registers and lr and return the result in r0 (0 ==
- ; context match, non-zero for everything else). All other registers are preserved.
- TP_CONTEXT_CHECK
- cbnz r0, ContextMismatch2
-
- ; Local interface dispatch case. Tail call to VSD helper specifically for the in-context TP dispatch
- ; scenario. Interface MethodDesc is restored to r12.
- EPILOG_POP {r0-r3,r12,lr}
- EPILOG_BRANCH InContextTPQuickDispatchAsmStub
-
-ContextMismatch2
- ; Context-mismatch (remoted) dispatch case. Tail call to the general remoting dispatch code. Interface
- ; MethodDesc is restored to r12.
- EPILOG_POP {r0-r3,r12,lr}
- EPILOG_BRANCH TransparentProxyStub_CrossContext
-
- NESTED_END
-
-; ------------------------------------------------------------------
-; Common stub used for vtable dispatch of remoted methods. A small prestub will load the vtable slot index
-; into r12 and then jump here. This stub determines whether we're already in the correct context (which can
-; only happen for ContextBoundObjects). Depending on the answers we'll either dispatch the call locally or
-; re-direct it to the remoting system (via TransparentProxyStub_CrossContext).
-;
-; On entry:
-; r0 : this (TransparentProxy object)
-; r12 : virtual method slot number
-; plus user arguments in registers and on the stack
-;
-; On exit:
-; Tail calls to the VSD in-context TP dispatcher or remoting system as appropriate.
-;
- NESTED_ENTRY TransparentProxyStub
-
- PROLOG_PUSH {r0-r3,r12,lr}
-
- CHECK_STACK_ALIGNMENT
-
- ; Check whether the TP is already in the correct context. This can happen for ContextBoundObjects
- ; only. The following macro will trash volatile registers and lr and return the result in r0 (0 ==
- ; context match, non-zero for everything else). All other registers are preserved.
- TP_CONTEXT_CHECK
- cbnz r0, ContextMismatch3
-
- ; We need to perform a local vtable dispatch on the ContextBoundObject. Obviously this needs to be on
- ; the real type held in the proxy, not TransparentProxy's MethodTable or we'll just end up back here
- ; recursively.
-
- ; Recover 'this' pointer and slot number.
- ldr r0, [sp]
- ldr r12, [sp, #0x10]
-
- ; Extract real type from the TP.
- ldr r0, [r0, #TransparentProxyObject___pMT]
-
- ; Vtables are no longer a linear array. Instead they use a two-level indirection with the first level
- ; consisting of fixed sized chunks of function pointer arrays. R12 has our slot number.
-
- ; Calculate first level chunk index.
- lsr r1, r12, #ASM__VTABLE_SLOTS_PER_CHUNK_LOG2
-
- ; Load the address of the chunk from the MethodTable (the chunk table immediately follows the
- ; MethodTable structure).
- add r0, #SIZEOF__MethodTable
- ldr r2, [r0, r1, lsl #2]
-
- ; Calculate the slot index within the chunk.
- and r0, r12, #(ASM__VTABLE_SLOTS_PER_CHUNK - 1)
-
- ; Load the target address into r12 (we no longer need the slot number and we're about to restore the
- ; other registers).
- ldr r12, [r2, r0, lsl #2]
-
- ; Restore the stack state and tail call to the local target.
- EPILOG_POP {r0-r3}
- EPILOG_STACK_FREE 4 ; Skip restore of r12 since we've overwritten it
- EPILOG_POP {lr}
- EPILOG_BRANCH_REG r12
-
-ContextMismatch3
- ; Contexts don't match so we have to dispatch through remoting. Clean up the stack and tail call to
- ; the helper.
- EPILOG_POP {r0-r3,r12,lr}
- EPILOG_BRANCH TransparentProxyStub_CrossContext
+#endif // FEATURE_COMINTEROP
- NESTED_END
-#endif // FEATURE_REMOTING
-#if defined(FEATURE_REMOTING) || defined(FEATURE_COMINTEROP)
+#if defined(FEATURE_COMINTEROP)
; ------------------------------------------------------------------
; Function used by remoting/COM interop to get floating point return value (since it's not in the same
; register(s) as non-floating point values).
@@ -1168,116 +760,8 @@ LsetFP8
LEAF_END
-#endif defined(FEATURE_REMOTING) || defined(FEATURE_COMINTEROP)
-#ifdef FEATURE_REMOTING
-
-; ------------------------------------------------------------------
-; Tail call Object.FieldGetter remotely with the given arguments.
-;
-; On entry:
-; r0 : pMD (MethodDesc * of the Object.FieldGetter method)
-; r1 : pThis (the transparent proxy)
-; r2 : pFirst
-; r3 : pSecond
-; [sp, #0] : pThird
-;
-; On exit:
-; Tail calls to the managed method
-;
- LEAF_ENTRY CRemotingServices__CallFieldGetter
-
- mov r12, r0
- mov r0, r1
- mov r1, r2
- mov r2, r3
- ldr r3, [sp, #0]
-
- b TransparentProxyStub_CrossContext
-
- LEAF_END
-
-; ------------------------------------------------------------------
-; Tail call Object.FieldSetter remotely with the given arguments.
-;
-; On entry:
-; r0 : pMD (MethodDesc * of the Object.FieldSetter method)
-; r1 : pThis (the transparent proxy)
-; r2 : pFirst
-; r3 : pSecond
-; [sp, #0] : pThird
-;
-; On exit:
-; Tail calls to the managed method
-;
- LEAF_ENTRY CRemotingServices__CallFieldSetter
-
- mov r12, r0
- mov r0, r1
- mov r1, r2
- mov r2, r3
- ldr r3, [sp, #0]
-
- b TransparentProxyStub_CrossContext
-
- LEAF_END
-
-; ------------------------------------------------------------------
-; General purpose remoting helper used to call given target with two parameters.
-;
-; On entry:
-; r0 : pTarget
-; r1 : pFirst
-; r2 : pSecond
-;
-;
- NESTED_ENTRY CTPMethodTable__CallTargetHelper2,,CallDescrWorkerUnwindFrameChainHandler
-
- PROLOG_PUSH {r11, lr}
-
- mov r12, r0
- mov r0, r1
- mov r1, r2
-
- blx r12
-
- ; Adding a nop so that unwind does not result in the IP being in epilog.
- ; This ensures that the OS unwinder looks up the personality routine for this method.
- nop
-
- EPILOG_POP {r11, pc}
-
- NESTED_END
-
-; ------------------------------------------------------------------
-; General purpose remoting helper used to call given target with three parameters.
-;
-; On entry:
-; r0 : pTarget
-; r1 : pFirst
-; r2 : pSecond
-; r3 : pThird
-;
-;
- NESTED_ENTRY CTPMethodTable__CallTargetHelper3,,CallDescrWorkerUnwindFrameChainHandler
-
- PROLOG_PUSH {r11, lr}
-
- mov r12, r0
- mov r0, r1
- mov r1, r2
- mov r2, r3
-
- blx r12
-
- ; Adding a nop so that unwind does not result in the IP being in epilog.
- ; This ensures that the OS unwinder looks up the personality routine for this method.
- nop
-
- EPILOG_POP {r11, pc}
-
- NESTED_END
+#endif defined(FEATURE_COMINTEROP)
-#endif // FEATURE_REMOTING
#ifdef FEATURE_COMINTEROP
; ------------------------------------------------------------------