From 8fefaad74cb76331675798170cbb0898c80b1299 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 26 Aug 2019 15:43:28 -0700 Subject: [PATCH] Cache Sytem.RuntimeMethodInfoStub instances created in the VM in the MethodDesc's owning LoaderAllocator. --- src/inc/CrstTypes.def | 4 +++ src/inc/crsttypes.h | 55 ++++++++++++++++++++------------------ src/vm/loaderallocator.cpp | 43 +++++++++++++++++++++++++++++ src/vm/loaderallocator.hpp | 6 +++++ src/vm/method.cpp | 23 ++-------------- 5 files changed, 84 insertions(+), 47 deletions(-) diff --git a/src/inc/CrstTypes.def b/src/inc/CrstTypes.def index a41382d62e41..f2f4b746c046 100644 --- a/src/inc/CrstTypes.def +++ b/src/inc/CrstTypes.def @@ -709,3 +709,7 @@ Crst MethodDescBackpatchInfoTracker AcquiredBefore FuncPtrStubs ThreadStore SystemDomain AcquiredAfter ReJITGlobalRequest End + +Crst StubMethodInfoCache + AcquiredBefore AppDomainHandleTable LoaderAllocator +End diff --git a/src/inc/crsttypes.h b/src/inc/crsttypes.h index 6df4adea6141..20b6b7034b8f 100644 --- a/src/inc/crsttypes.h +++ b/src/inc/crsttypes.h @@ -144,32 +144,33 @@ enum CrstType CrstStrongName = 125, CrstStubCache = 126, CrstStubDispatchCache = 127, - CrstStubUnwindInfoHeapSegments = 128, - CrstSyncBlockCache = 129, - CrstSyncHashLock = 130, - CrstSystemBaseDomain = 131, - CrstSystemDomain = 132, - CrstSystemDomainDelayedUnloadList = 133, - CrstThreadIdDispenser = 134, - CrstThreadpoolEventCache = 135, - CrstThreadpoolTimerQueue = 136, - CrstThreadpoolWaitThreads = 137, - CrstThreadpoolWorker = 138, - CrstThreadStaticDataHashTable = 139, - CrstThreadStore = 140, - CrstTieredCompilation = 141, - CrstTPMethodTable = 142, - CrstTypeEquivalenceMap = 143, - CrstTypeIDMap = 144, - CrstUMEntryThunkCache = 145, - CrstUMThunkHash = 146, - CrstUniqueStack = 147, - CrstUnresolvedClassLock = 148, - CrstUnwindInfoTableLock = 149, - CrstVSDIndirectionCellLock = 150, - CrstWinRTFactoryCache = 151, - CrstWrapperTemplate = 152, - kNumberOfCrstTypes = 153 + CrstStubMethodInfoCache = 128, + CrstStubUnwindInfoHeapSegments = 129, + CrstSyncBlockCache = 130, + CrstSyncHashLock = 131, + CrstSystemBaseDomain = 132, + CrstSystemDomain = 133, + CrstSystemDomainDelayedUnloadList = 134, + CrstThreadIdDispenser = 135, + CrstThreadpoolEventCache = 136, + CrstThreadpoolTimerQueue = 137, + CrstThreadpoolWaitThreads = 138, + CrstThreadpoolWorker = 139, + CrstThreadStaticDataHashTable = 140, + CrstThreadStore = 141, + CrstTieredCompilation = 142, + CrstTPMethodTable = 143, + CrstTypeEquivalenceMap = 144, + CrstTypeIDMap = 145, + CrstUMEntryThunkCache = 146, + CrstUMThunkHash = 147, + CrstUniqueStack = 148, + CrstUnresolvedClassLock = 149, + CrstUnwindInfoTableLock = 150, + CrstVSDIndirectionCellLock = 151, + CrstWinRTFactoryCache = 152, + CrstWrapperTemplate = 153, + kNumberOfCrstTypes = 154 }; #endif // __CRST_TYPES_INCLUDED @@ -308,6 +309,7 @@ int g_rgCrstLevelMap[] = 0, // CrstStrongName 5, // CrstStubCache 0, // CrstStubDispatchCache + 15, // CrstStubMethodInfoCache 4, // CrstStubUnwindInfoHeapSegments 3, // CrstSyncBlockCache 0, // CrstSyncHashLock @@ -466,6 +468,7 @@ LPCSTR g_rgCrstNameMap[] = "CrstStrongName", "CrstStubCache", "CrstStubDispatchCache", + "CrstStubMethodInfoCache", "CrstStubUnwindInfoHeapSegments", "CrstSyncBlockCache", "CrstSyncHashLock", diff --git a/src/vm/loaderallocator.cpp b/src/vm/loaderallocator.cpp index 12e14bdd41f0..7f92c162ac15 100644 --- a/src/vm/loaderallocator.cpp +++ b/src/vm/loaderallocator.cpp @@ -1042,6 +1042,41 @@ void LoaderAllocator::ActivateManagedTracking() LOADERALLOCATORREF loaderAllocator = (LOADERALLOCATORREF)ObjectFromHandle(m_hLoaderAllocatorObjectHandle); loaderAllocator->SetNativeLoaderAllocator(this); } + +REFLECTMETHODREF LoaderAllocator::GetStubMethodInfoForMethodDesc(MethodDesc* pMT) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + INJECT_FAULT(COMPlusThrowOM()); + MODE_COOPERATIVE; + } + CONTRACTL_END; + + CrstHolder holder(&m_stubMethodInfoCacheCrst); + + UPTR value = m_stubMethodInfoCache.Gethash((UPTR)pMT); + + if (value != INVALIDENTRY) + { + return (REFLECTMETHODREF)GetHandleValue((LOADERHANDLE)value); + } + + REFLECTMETHODREF retVal; + REFLECTMETHODREF methodRef = (REFLECTMETHODREF)AllocateObject(MscorlibBinder::GetClass(CLASS__STUBMETHODINFO)); + GCPROTECT_BEGIN(methodRef); + + methodRef->SetMethod(pMT); + if (IsCollectible()) + methodRef->SetKeepAlive(GetExposedObject()); + + m_stubMethodInfoCache.InsertValue((UPTR)pMT, (UPTR)AllocateHandle(methodRef)); + retVal = methodRef; + GCPROTECT_END(); + + return retVal; +} #endif // !CROSSGEN_COMPILE @@ -1061,6 +1096,7 @@ void LoaderAllocator::Init(BaseDomain *pDomain, BYTE *pExecutableHeapMemory) m_crstLoaderAllocator.Init(CrstLoaderAllocator, (CrstFlags)CRST_UNSAFE_COOPGC); m_InteropDataCrst.Init(CrstInteropData, CRST_REENTRANCY); + m_stubMethodInfoCacheCrst.Init(CrstStubMethodInfoCache); #ifdef FEATURE_COMINTEROP m_ComCallWrapperCrst.Init(CrstCOMCallWrapper); #endif @@ -1219,6 +1255,12 @@ void LoaderAllocator::Init(BaseDomain *pDomain, BYTE *pExecutableHeapMemory) m_interopDataHash.Init(0, NULL, false, &lock); } #endif // FEATURE_COMINTEROP + + // Init the StubMethodInfo Cache + { + LockOwner lock = { &m_stubMethodInfoCacheCrst, IsOwnerOfCrst }; + m_stubMethodInfoCache.Init(0, (CompareFnPtr)nullptr, false, &lock); + } } @@ -1330,6 +1372,7 @@ void LoaderAllocator::Terminate() m_ComCallWrapperCrst.Destroy(); m_InteropDataCrst.Destroy(); #endif + m_stubMethodInfoCacheCrst.Destroy(); m_LoaderAllocatorReferences.RemoveAll(); // In collectible types we merge the low frequency and high frequency heaps diff --git a/src/vm/loaderallocator.hpp b/src/vm/loaderallocator.hpp index 5681f5abd608..034692cff47a 100644 --- a/src/vm/loaderallocator.hpp +++ b/src/vm/loaderallocator.hpp @@ -273,6 +273,10 @@ class LoaderAllocator CrstExplicitInit m_InteropDataCrst; EEMarshalingData* m_pMarshalingData; + // Used for synchronizing access to m_stubMethodInfoCache. + CrstExplicitInit m_stubMethodInfoCacheCrst; + HashMap m_stubMethodInfoCache; + #ifdef FEATURE_TIERED_COMPILATION CallCounter m_callCounter; #endif @@ -492,6 +496,8 @@ class LoaderAllocator OBJECTREF GetHandleValue(LOADERHANDLE handle); + REFLECTMETHODREF GetStubMethodInfoForMethodDesc(MethodDesc* pMD); + LoaderAllocator(); virtual ~LoaderAllocator(); BaseDomain *GetDomain() { LIMITED_METHOD_CONTRACT; return m_pDomain; } diff --git a/src/vm/method.cpp b/src/vm/method.cpp index fd0d13f13814..e9796ee827e5 100644 --- a/src/vm/method.cpp +++ b/src/vm/method.cpp @@ -5574,28 +5574,9 @@ PTR_LoaderAllocator MethodDesc::GetLoaderAllocator() #if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE) REFLECTMETHODREF MethodDesc::GetStubMethodInfo() { - CONTRACTL - { - THROWS; - GC_TRIGGERS; - INJECT_FAULT(COMPlusThrowOM()); - MODE_COOPERATIVE; - } - CONTRACTL_END; - - REFLECTMETHODREF retVal; - REFLECTMETHODREF methodRef = (REFLECTMETHODREF)AllocateObject(MscorlibBinder::GetClass(CLASS__STUBMETHODINFO)); - GCPROTECT_BEGIN(methodRef); - - methodRef->SetMethod(this); - LoaderAllocator *pLoaderAllocatorOfMethod = this->GetLoaderAllocator(); - if (pLoaderAllocatorOfMethod->IsCollectible()) - methodRef->SetKeepAlive(pLoaderAllocatorOfMethod->GetExposedObject()); - - retVal = methodRef; - GCPROTECT_END(); + WRAPPER_NO_CONTRACT; - return retVal; + return GetLoaderAllocator()->GetStubMethodInfoForMethodDesc(this); } #endif // !DACCESS_COMPILE && CROSSGEN_COMPILE