summaryrefslogtreecommitdiff
path: root/src/vm/prestub.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/prestub.cpp')
-rw-r--r--src/vm/prestub.cpp22
1 files changed, 13 insertions, 9 deletions
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