diff options
Diffstat (limited to 'src/vm/amd64/VirtualCallStubAMD64.asm')
-rw-r--r-- | src/vm/amd64/VirtualCallStubAMD64.asm | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/src/vm/amd64/VirtualCallStubAMD64.asm b/src/vm/amd64/VirtualCallStubAMD64.asm new file mode 100644 index 0000000000..fc032dd204 --- /dev/null +++ b/src/vm/amd64/VirtualCallStubAMD64.asm @@ -0,0 +1,109 @@ +; Licensed to the .NET Foundation under one or more agreements. +; The .NET Foundation licenses this file to you under the MIT license. +; See the LICENSE file in the project root for more information. + +include <AsmMacros.inc> +include AsmConstants.inc + +CHAIN_SUCCESS_COUNTER equ ?g_dispatch_cache_chain_success_counter@@3_KA + + extern VSD_ResolveWorker:proc + extern CHAIN_SUCCESS_COUNTER:dword + + extern StubDispatchFixupWorker:proc + extern ProcessCLRException:proc + +BACKPATCH_FLAG equ 1 ;; Also known as SDF_ResolveBackPatch in the EE +PROMOTE_CHAIN_FLAG equ 2 ;; Also known as SDF_ResolvePromoteChain in the EE +INITIAL_SUCCESS_COUNT equ 100h + +;; On Input: +;; r11 contains the address of the indirection cell (with the flags in the low bits) +;; [rsp+0] m_Datum: contains the dispatch token (slot number or MethodDesc) for the target +;; or the ResolveCacheElem when r11 has the PROMOTE_CHAIN_FLAG set +;; [rsp+8] m_ReturnAddress: contains the return address of caller to stub + +NESTED_ENTRY ResolveWorkerAsmStub, _TEXT + + PROLOG_WITH_TRANSITION_BLOCK 0, 8, r8 + + ; token stored in r8 by prolog + + lea rcx, [rsp + __PWTB_TransitionBlock] ; pTransitionBlock + mov rdx, r11 ; indirection cell + flags + mov r9, rdx + and r9, 7 ; flags + sub rdx, r9 ; indirection cell + + call VSD_ResolveWorker + + EPILOG_WITH_TRANSITION_BLOCK_TAILCALL + TAILJMP_RAX + +NESTED_END ResolveWorkerAsmStub, _TEXT + +;; extern void ResolveWorkerChainLookupAsmStub() +LEAF_ENTRY ResolveWorkerChainLookupAsmStub, _TEXT +;; This will perform a quick chained lookup of the entry if the initial cache lookup fails +;; On Input: +;; rdx contains our type (MethodTable) +;; r10 contains our contract (DispatchToken) +;; r11 contains the address of the indirection (and the flags in the low two bits) +;; [rsp+0x00] contains the pointer to the ResolveCacheElem +;; [rsp+0x08] contains the saved value of rdx +;; [rsp+0x10] contains the return address of caller to stub +;; + mov rax, BACKPATCH_FLAG ;; First we check if r11 has the BACKPATCH_FLAG set + and rax, r11 ;; Set the flags based on (BACKPATCH_FLAG and r11) + pop rax ;; pop the pointer to the ResolveCacheElem from the top of stack (leaving the flags unchanged) + jnz Fail ;; If the BACKPATCH_FLAGS is set we will go directly to the ResolveWorkerAsmStub + +MainLoop: + mov rax, [rax+18h] ;; get the next entry in the chain (don't bother checking the first entry again) + test rax,rax ;; test if we hit a terminating NULL + jz Fail + + cmp rdx, [rax+00h] ;; compare our MT with the one in the ResolveCacheElem + jne MainLoop + cmp r10, [rax+08h] ;; compare our DispatchToken with one in the ResolveCacheElem + jne MainLoop +Success: + sub [CHAIN_SUCCESS_COUNTER],1 ;; decrement success counter + jl Promote + mov rax, [rax+10h] ;; get the ImplTarget + pop rdx + jmp rax + +Promote: ;; Move this entry to head postion of the chain + ;; be quick to reset the counter so we don't get a bunch of contending threads + mov [CHAIN_SUCCESS_COUNTER], INITIAL_SUCCESS_COUNT + or r11, PROMOTE_CHAIN_FLAG + mov r10, rax ;; We pass the ResolveCacheElem to ResolveWorkerAsmStub instead of the DispatchToken +Fail: + pop rdx ;; Restore the original saved rdx value + push r10 ;; pass the DispatchToken or ResolveCacheElem to promote to ResolveWorkerAsmStub + + jmp ResolveWorkerAsmStub + +LEAF_END ResolveWorkerChainLookupAsmStub, _TEXT + + +NESTED_ENTRY StubDispatchFixupStub, _TEXT, ProcessCLRException + + PROLOG_WITH_TRANSITION_BLOCK + + lea rcx, [rsp + __PWTB_TransitionBlock] ; pTransitionBlock + mov rdx, r11 ; indirection cell address + + mov r8,0 ; sectionIndex + mov r9,0 ; pModule + + call StubDispatchFixupWorker + + EPILOG_WITH_TRANSITION_BLOCK_TAILCALL +PATCH_LABEL StubDispatchFixupPatchLabel + TAILJMP_RAX + +NESTED_END StubDispatchFixupStub, _TEXT + + end |