summaryrefslogtreecommitdiff
path: root/src/vm/amd64/VirtualCallStubAMD64.asm
blob: fc032dd204625cc487a5ac00647394779a587da3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
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