diff options
author | dotnet-bot <dotnet-bot@microsoft.com> | 2015-01-30 14:14:42 -0800 |
---|---|---|
committer | dotnet-bot <dotnet-bot@microsoft.com> | 2015-01-30 14:14:42 -0800 |
commit | ef1e2ab328087c61a6878c1e84f4fc5d710aebce (patch) | |
tree | dee1bbb89e9d722e16b0d1485e3cdd1b6c8e2cfa /src/vm/amd64/virtualcallstubamd64.S | |
download | coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.tar.gz coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.tar.bz2 coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.zip |
Initial commit to populate CoreCLR repo
[tfs-changeset: 1407945]
Diffstat (limited to 'src/vm/amd64/virtualcallstubamd64.S')
-rw-r--r-- | src/vm/amd64/virtualcallstubamd64.S | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/src/vm/amd64/virtualcallstubamd64.S b/src/vm/amd64/virtualcallstubamd64.S new file mode 100644 index 0000000000..025e165c17 --- /dev/null +++ b/src/vm/amd64/virtualcallstubamd64.S @@ -0,0 +1,90 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license 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; +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 + + PROLOG_WITH_TRANSITION_BLOCK 0, 8, rdx + + // 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 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: +// rsi 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 rsi, [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, rsi + sub qword ptr [rsi],1 // decrement success counter + jl Promote_RWCLAS + mov rax, [rax+10h] // get the ImplTarget + pop rsi + 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 [rsi], INITIAL_SUCCESS_COUNT + or r11, PROMOTE_CHAIN_FLAG + mov r10, rax // We pass the ResolveCacheElem to ResolveWorkerAsmStub instead of the DispatchToken +Fail_RWCLAS: + pop rsi // Restore the original saved rdx value + push r10 // pass the DispatchToken or ResolveCacheElem to promote to ResolveWorkerAsmStub + + jmp ResolveWorkerAsmStub + +LEAF_END ResolveWorkerChainLookupAsmStub, _TEXT |