Skip to content

Commit 7266538

Browse files
committed
Cache Sytem.RuntimeMethodInfoStub instances created in the VM in the MethodDesc's owning LoaderAllocator.
1 parent 48aeae7 commit 7266538

File tree

5 files changed

+84
-47
lines changed

5 files changed

+84
-47
lines changed

src/inc/CrstTypes.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,3 +709,7 @@ Crst MethodDescBackpatchInfoTracker
709709
AcquiredBefore FuncPtrStubs ThreadStore SystemDomain
710710
AcquiredAfter ReJITGlobalRequest
711711
End
712+
713+
Crst StubMethodInfoCache
714+
AcquiredBefore AppDomainHandleTable
715+
End

src/inc/crsttypes.h

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -144,32 +144,33 @@ enum CrstType
144144
CrstStrongName = 125,
145145
CrstStubCache = 126,
146146
CrstStubDispatchCache = 127,
147-
CrstStubUnwindInfoHeapSegments = 128,
148-
CrstSyncBlockCache = 129,
149-
CrstSyncHashLock = 130,
150-
CrstSystemBaseDomain = 131,
151-
CrstSystemDomain = 132,
152-
CrstSystemDomainDelayedUnloadList = 133,
153-
CrstThreadIdDispenser = 134,
154-
CrstThreadpoolEventCache = 135,
155-
CrstThreadpoolTimerQueue = 136,
156-
CrstThreadpoolWaitThreads = 137,
157-
CrstThreadpoolWorker = 138,
158-
CrstThreadStaticDataHashTable = 139,
159-
CrstThreadStore = 140,
160-
CrstTieredCompilation = 141,
161-
CrstTPMethodTable = 142,
162-
CrstTypeEquivalenceMap = 143,
163-
CrstTypeIDMap = 144,
164-
CrstUMEntryThunkCache = 145,
165-
CrstUMThunkHash = 146,
166-
CrstUniqueStack = 147,
167-
CrstUnresolvedClassLock = 148,
168-
CrstUnwindInfoTableLock = 149,
169-
CrstVSDIndirectionCellLock = 150,
170-
CrstWinRTFactoryCache = 151,
171-
CrstWrapperTemplate = 152,
172-
kNumberOfCrstTypes = 153
147+
CrstStubMethodInfoCache = 128,
148+
CrstStubUnwindInfoHeapSegments = 129,
149+
CrstSyncBlockCache = 130,
150+
CrstSyncHashLock = 131,
151+
CrstSystemBaseDomain = 132,
152+
CrstSystemDomain = 133,
153+
CrstSystemDomainDelayedUnloadList = 134,
154+
CrstThreadIdDispenser = 135,
155+
CrstThreadpoolEventCache = 136,
156+
CrstThreadpoolTimerQueue = 137,
157+
CrstThreadpoolWaitThreads = 138,
158+
CrstThreadpoolWorker = 139,
159+
CrstThreadStaticDataHashTable = 140,
160+
CrstThreadStore = 141,
161+
CrstTieredCompilation = 142,
162+
CrstTPMethodTable = 143,
163+
CrstTypeEquivalenceMap = 144,
164+
CrstTypeIDMap = 145,
165+
CrstUMEntryThunkCache = 146,
166+
CrstUMThunkHash = 147,
167+
CrstUniqueStack = 148,
168+
CrstUnresolvedClassLock = 149,
169+
CrstUnwindInfoTableLock = 150,
170+
CrstVSDIndirectionCellLock = 151,
171+
CrstWinRTFactoryCache = 152,
172+
CrstWrapperTemplate = 153,
173+
kNumberOfCrstTypes = 154
173174
};
174175

175176
#endif // __CRST_TYPES_INCLUDED
@@ -308,6 +309,7 @@ int g_rgCrstLevelMap[] =
308309
0, // CrstStrongName
309310
5, // CrstStubCache
310311
0, // CrstStubDispatchCache
312+
14, // CrstStubMethodInfoCache
311313
4, // CrstStubUnwindInfoHeapSegments
312314
3, // CrstSyncBlockCache
313315
0, // CrstSyncHashLock
@@ -466,6 +468,7 @@ LPCSTR g_rgCrstNameMap[] =
466468
"CrstStrongName",
467469
"CrstStubCache",
468470
"CrstStubDispatchCache",
471+
"CrstStubMethodInfoCache",
469472
"CrstStubUnwindInfoHeapSegments",
470473
"CrstSyncBlockCache",
471474
"CrstSyncHashLock",

src/vm/loaderallocator.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,41 @@ void LoaderAllocator::ActivateManagedTracking()
10421042
LOADERALLOCATORREF loaderAllocator = (LOADERALLOCATORREF)ObjectFromHandle(m_hLoaderAllocatorObjectHandle);
10431043
loaderAllocator->SetNativeLoaderAllocator(this);
10441044
}
1045+
1046+
REFLECTMETHODREF LoaderAllocator::GetStubMethodInfoForMethodDesc(MethodDesc* pMT)
1047+
{
1048+
CONTRACTL
1049+
{
1050+
THROWS;
1051+
GC_TRIGGERS;
1052+
INJECT_FAULT(COMPlusThrowOM());
1053+
MODE_COOPERATIVE;
1054+
}
1055+
CONTRACTL_END;
1056+
1057+
CrstHolder holder(&m_stubMethodInfoCacheCrst);
1058+
1059+
UPTR value = m_stubMethodInfoCache.Gethash((UPTR)pMT);
1060+
1061+
if (value != INVALIDENTRY)
1062+
{
1063+
return (REFLECTMETHODREF)GetHandleValue((LOADERHANDLE)value);
1064+
}
1065+
1066+
REFLECTMETHODREF retVal;
1067+
REFLECTMETHODREF methodRef = (REFLECTMETHODREF)AllocateObject(MscorlibBinder::GetClass(CLASS__STUBMETHODINFO));
1068+
GCPROTECT_BEGIN(methodRef);
1069+
1070+
methodRef->SetMethod(pMT);
1071+
if (IsCollectible())
1072+
methodRef->SetKeepAlive(GetExposedObject());
1073+
1074+
m_stubMethodInfoCache.InsertValue((UPTR)pMT, (UPTR)AllocateHandle(methodRef));
1075+
retVal = methodRef;
1076+
GCPROTECT_END();
1077+
1078+
return retVal;
1079+
}
10451080
#endif // !CROSSGEN_COMPILE
10461081

10471082

@@ -1061,6 +1096,7 @@ void LoaderAllocator::Init(BaseDomain *pDomain, BYTE *pExecutableHeapMemory)
10611096

10621097
m_crstLoaderAllocator.Init(CrstLoaderAllocator, (CrstFlags)CRST_UNSAFE_COOPGC);
10631098
m_InteropDataCrst.Init(CrstInteropData, CRST_REENTRANCY);
1099+
m_stubMethodInfoCacheCrst.Init(CrstStubMethodInfoCache);
10641100
#ifdef FEATURE_COMINTEROP
10651101
m_ComCallWrapperCrst.Init(CrstCOMCallWrapper);
10661102
#endif
@@ -1219,6 +1255,12 @@ void LoaderAllocator::Init(BaseDomain *pDomain, BYTE *pExecutableHeapMemory)
12191255
m_interopDataHash.Init(0, NULL, false, &lock);
12201256
}
12211257
#endif // FEATURE_COMINTEROP
1258+
1259+
// Init the StubMethodInfo Cache
1260+
{
1261+
LockOwner lock = {};
1262+
m_stubMethodInfoCache.Init(0, (CompareFnPtr)nullptr, false, &lock);
1263+
}
12221264
}
12231265

12241266

@@ -1330,6 +1372,7 @@ void LoaderAllocator::Terminate()
13301372
m_ComCallWrapperCrst.Destroy();
13311373
m_InteropDataCrst.Destroy();
13321374
#endif
1375+
m_stubMethodInfoCacheCrst.Destroy();
13331376
m_LoaderAllocatorReferences.RemoveAll();
13341377

13351378
// In collectible types we merge the low frequency and high frequency heaps

src/vm/loaderallocator.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,10 @@ class LoaderAllocator
273273
CrstExplicitInit m_InteropDataCrst;
274274
EEMarshalingData* m_pMarshalingData;
275275

276+
// Used for synchronizing access to m_stubMethodInfoCache.
277+
CrstExplicitInit m_stubMethodInfoCacheCrst;
278+
HashMap m_stubMethodInfoCache;
279+
276280
#ifdef FEATURE_TIERED_COMPILATION
277281
CallCounter m_callCounter;
278282
#endif
@@ -497,6 +501,8 @@ class LoaderAllocator
497501

498502
OBJECTREF GetHandleValue(LOADERHANDLE handle);
499503

504+
REFLECTMETHODREF GetStubMethodInfoForMethodDesc(MethodDesc* pMD);
505+
500506
LoaderAllocator();
501507
virtual ~LoaderAllocator();
502508
BaseDomain *GetDomain() { LIMITED_METHOD_CONTRACT; return m_pDomain; }

src/vm/method.cpp

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5589,28 +5589,9 @@ PTR_LoaderAllocator MethodDesc::GetLoaderAllocator()
55895589
#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
55905590
REFLECTMETHODREF MethodDesc::GetStubMethodInfo()
55915591
{
5592-
CONTRACTL
5593-
{
5594-
THROWS;
5595-
GC_TRIGGERS;
5596-
INJECT_FAULT(COMPlusThrowOM());
5597-
MODE_COOPERATIVE;
5598-
}
5599-
CONTRACTL_END;
5600-
5601-
REFLECTMETHODREF retVal;
5602-
REFLECTMETHODREF methodRef = (REFLECTMETHODREF)AllocateObject(MscorlibBinder::GetClass(CLASS__STUBMETHODINFO));
5603-
GCPROTECT_BEGIN(methodRef);
5604-
5605-
methodRef->SetMethod(this);
5606-
LoaderAllocator *pLoaderAllocatorOfMethod = this->GetLoaderAllocator();
5607-
if (pLoaderAllocatorOfMethod->IsCollectible())
5608-
methodRef->SetKeepAlive(pLoaderAllocatorOfMethod->GetExposedObject());
5609-
5610-
retVal = methodRef;
5611-
GCPROTECT_END();
5592+
WRAPPER_NO_CONTRACT;
56125593

5613-
return retVal;
5594+
return GetLoaderAllocator()->GetStubMethodInfoForMethodDesc(this);
56145595
}
56155596
#endif // !DACCESS_COMPILE && CROSSGEN_COMPILE
56165597

0 commit comments

Comments
 (0)