From d2cd0df600cfa697d30cf7ef5a7cf1c3c33b9959 Mon Sep 17 00:00:00 2001 From: Fadi Hanna Date: Tue, 13 Nov 2018 12:44:49 -0800 Subject: Optimize vtable calls (#20696) * Implementation of R2R vtable call thunks. These thunks will fetch the target code pointer from the vtable of the input thisPtr, and jump to that address. This is especially helpful with generics, since we can avoid a generic dictionary lookup cost for a simple vtable call. Overall, these thunks cause the CPU to have less branch mispredictions, and give a small performance boost to vtable calls. These stubs are under VirtualCallStubManager so that the managed debugger can handle stepping through them. --- src/vm/prestub.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'src/vm/prestub.cpp') diff --git a/src/vm/prestub.cpp b/src/vm/prestub.cpp index b614e341a2..78e9f22e17 100644 --- a/src/vm/prestub.cpp +++ b/src/vm/prestub.cpp @@ -2286,20 +2286,24 @@ EXTERN_C PCODE STDCALL ExternalMethodFixupWorker(TransitionBlock * pTransitionBl // Get the stub manager for this module VirtualCallStubManager *pMgr = pModule->GetLoaderAllocator()->GetVirtualCallStubManager(); - DispatchToken token; - if (pMT->IsInterface()) - token = pMT->GetLoaderAllocator()->GetDispatchToken(pMT->GetTypeID(), slot); - else - token = DispatchToken::CreateDispatchToken(slot); - OBJECTREF *protectedObj = pEMFrame->GetThisPtr(); _ASSERTE(protectedObj != NULL); if (*protectedObj == NULL) { COMPlusThrow(kNullReferenceException); } - - StubCallSite callSite(pIndirection, pEMFrame->GetReturnAddress()); - pCode = pMgr->ResolveWorker(&callSite, protectedObj, token, VirtualCallStubManager::SK_LOOKUP); + + DispatchToken token; + if (pMT->IsInterface() || MethodTable::VTableIndir_t::isRelative) + { + token = pMT->GetLoaderAllocator()->GetDispatchToken(pMT->GetTypeID(), slot); + StubCallSite callSite(pIndirection, pEMFrame->GetReturnAddress()); + pCode = pMgr->ResolveWorker(&callSite, protectedObj, token, VirtualCallStubManager::SK_LOOKUP); + } + else + { + pCode = pMgr->GetVTableCallStub(slot); + *EnsureWritableExecutablePages((TADDR *)pIndirection) = pCode; + } _ASSERTE(pCode != NULL); } else -- cgit v1.2.3