diff options
author | Jiyoung Yun <jy910.yun@samsung.com> | 2016-11-23 19:09:09 +0900 |
---|---|---|
committer | Jiyoung Yun <jy910.yun@samsung.com> | 2016-11-23 19:09:09 +0900 |
commit | 4b4aad7217d3292650e77eec2cf4c198ea9c3b4b (patch) | |
tree | 98110734c91668dfdbb126fcc0e15ddbd93738ca /src/vm/amd64/virtualcallstubamd64.S | |
parent | fa45f57ed55137c75ac870356a1b8f76c84b229c (diff) | |
download | coreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.tar.gz coreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.tar.bz2 coreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.zip |
Imported Upstream version 1.1.0upstream/1.1.0
Diffstat (limited to 'src/vm/amd64/virtualcallstubamd64.S')
-rw-r--r-- | src/vm/amd64/virtualcallstubamd64.S | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/src/vm/amd64/virtualcallstubamd64.S b/src/vm/amd64/virtualcallstubamd64.S new file mode 100644 index 0000000000..59b5b77dba --- /dev/null +++ b/src/vm/amd64/virtualcallstubamd64.S @@ -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. + +.intel_syntax noprefix +#include "unixasmmacros.inc" + +// This is the number of times a successful chain lookup will occur before the +// entry is promoted to the front of the chain. This is declared as extern because +// the default value (CALL_STUB_CACHE_INITIAL_SUCCESS_COUNT) is defined in the header. +// extern size_t g_dispatch_cache_chain_success_counter; +#define CHAIN_SUCCESS_COUNTER g_dispatch_cache_chain_success_counter + +// The reason for not using .equ or '=' here is that otherwise the assembler compiles e.g. +// mov rax, BACKPATCH_FLAG as mov rax, [BACKPATCH_FLAG] +#define BACKPATCH_FLAG 1 // Also known as SDF_ResolveBackPatch in the EE +#define PROMOTE_CHAIN_FLAG 2 // Also known as SDF_ResolvePromoteChain in the EE +#define INITIAL_SUCCESS_COUNT 0x100 + +// 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, NoHandler + + PROLOG_WITH_TRANSITION_BLOCK 0, 8, rdx, 0, 0 + + // token stored in rdx by prolog + + lea rdi, [rsp + __PWTB_TransitionBlock] // pTransitionBlock + mov rsi, r11 // indirection cell + flags + mov rcx, rsi + and rcx, 7 // flags + sub rsi, rcx // indirection cell + + call C_FUNC(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 rsi +// [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_RWCLAS // If the BACKPATCH_FLAGS is set we will go directly to the ResolveWorkerAsmStub + +MainLoop_RWCLAS: + 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_RWCLAS + + cmp rdx, [rax+00h] // compare our MT with the one in the ResolveCacheElem + jne MainLoop_RWCLAS + cmp r10, [rax+08h] // compare our DispatchToken with one in the ResolveCacheElem + jne MainLoop_RWCLAS +Success_RWCLAS: + PREPARE_EXTERNAL_VAR CHAIN_SUCCESS_COUNTER, rdx + sub qword ptr [rdx],1 // decrement success counter + jl Promote_RWCLAS + mov rax, [rax+10h] // get the ImplTarget + pop rdx + jmp rax + +Promote_RWCLAS: // 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 qword ptr [rdx], INITIAL_SUCCESS_COUNT + or r11, PROMOTE_CHAIN_FLAG + mov r10, rax // We pass the ResolveCacheElem to ResolveWorkerAsmStub instead of the DispatchToken +Fail_RWCLAS: + pop rdx // Restore the original saved rdx value + push r10 // pass the DispatchToken or ResolveCacheElem to promote to ResolveWorkerAsmStub + + jmp C_FUNC(ResolveWorkerAsmStub) + +LEAF_END ResolveWorkerChainLookupAsmStub, _TEXT + +#ifdef FEATURE_PREJIT +NESTED_ENTRY StubDispatchFixupStub, _TEXT, NoHandler + + PROLOG_WITH_TRANSITION_BLOCK 0, 0, 0, 0, 0 + + lea rdi, [rsp + __PWTB_TransitionBlock] // pTransitionBlock + mov rsi, r11 // indirection cell address + + mov rdx,0 // sectionIndex + mov rcx,0 // pModule + + call C_FUNC(StubDispatchFixupWorker) + + EPILOG_WITH_TRANSITION_BLOCK_TAILCALL +PATCH_LABEL StubDispatchFixupPatchLabel + TAILJMP_RAX + +NESTED_END StubDispatchFixupStub, _TEXT +#endif |