summaryrefslogtreecommitdiff
path: root/src/vm/methoddescbackpatchinfo.cpp
diff options
context:
space:
mode:
authorDavid Wrighton <davidwr@microsoft.com>2019-02-14 17:07:14 -0800
committerGitHub <noreply@github.com>2019-02-14 17:07:14 -0800
commit423d2a3b91feea18ab361da04d5cc24bdff157d0 (patch)
treee59d54a5c48322a09ef1a4c5325378c9f60171dd /src/vm/methoddescbackpatchinfo.cpp
parent89e78f42ba11beaa81635a75cf593a3713dba176 (diff)
downloadcoreclr-423d2a3b91feea18ab361da04d5cc24bdff157d0.tar.gz
coreclr-423d2a3b91feea18ab361da04d5cc24bdff157d0.tar.bz2
coreclr-423d2a3b91feea18ab361da04d5cc24bdff157d0.zip
Replace multi-loaderallocator hash implementation in MethodDescBackpatchInfo (#22285)
* GCHeapHash - Hashtable implementation for runtime use - Implementation written in C++ - Data storage in managed heap memory - Based on SHash design, but using managed memory CrossLoaderAllocatorHash - Hash for c++ Pointer to C++ pointer where the lifetimes are controlled by different loader allocators - Support for add/remove/visit all entries of 1 key/visit all entries/ remove all entries of 1 key - Supports holding data which is unmanaged, but data items themselves can be of any size (key/value are templated types) * Swap MethodDescBackpatchInfo to use the CrossLoaderAllocatorHash * The MethodDescBackpatchCrst needs to be around an allocation - Adjust the Crst so that it can safely be used around code which allocates - Required moving its use out from within the EESuspend logic used in rejit
Diffstat (limited to 'src/vm/methoddescbackpatchinfo.cpp')
-rw-r--r--src/vm/methoddescbackpatchinfo.cpp153
1 files changed, 29 insertions, 124 deletions
diff --git a/src/vm/methoddescbackpatchinfo.cpp b/src/vm/methoddescbackpatchinfo.cpp
index 386786c6ba..571007cdfc 100644
--- a/src/vm/methoddescbackpatchinfo.cpp
+++ b/src/vm/methoddescbackpatchinfo.cpp
@@ -17,24 +17,6 @@
#ifndef DACCESS_COMPILE
-void EntryPointSlots::Backpatch_Locked(PCODE entryPoint)
-{
- WRAPPER_NO_CONTRACT;
- static_assert_no_msg(SlotType_Count <= sizeof(INT32));
- _ASSERTE(MethodDescBackpatchInfoTracker::IsLockedByCurrentThread());
- _ASSERTE(entryPoint != NULL);
-
- TADDR *slots = m_slots.GetElements();
- COUNT_T slotCount = m_slots.GetCount();
- for (COUNT_T i = 0; i < slotCount; ++i)
- {
- TADDR slot = slots[i];
- SlotType slotType = (SlotType)(slot & SlotType_Mask);
- slot ^= slotType;
- Backpatch_Locked(slot, slotType, entryPoint);
- }
-}
-
void EntryPointSlots::Backpatch_Locked(TADDR slot, SlotType slotType, PCODE entryPoint)
{
WRAPPER_NO_CONTRACT;
@@ -81,55 +63,50 @@ void EntryPointSlots::Backpatch_Locked(TADDR slot, SlotType slotType, PCODE entr
#endif // !DACCESS_COMPILE
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// MethodDescBackpatchInfo
+// MethodDescBackpatchInfoTracker
+
+CrstStatic MethodDescBackpatchInfoTracker::s_lock;
#ifndef DACCESS_COMPILE
-void MethodDescBackpatchInfo::AddDependentLoaderAllocator_Locked(LoaderAllocator *dependentLoaderAllocator)
+void MethodDescBackpatchInfoTracker::Backpatch_Locked(MethodDesc *pMethodDesc, PCODE entryPoint)
{
WRAPPER_NO_CONTRACT;
- _ASSERTE(MethodDescBackpatchInfoTracker::IsLockedByCurrentThread());
- _ASSERTE(m_methodDesc != nullptr);
- _ASSERTE(dependentLoaderAllocator != nullptr);
- _ASSERTE(dependentLoaderAllocator != m_methodDesc->GetLoaderAllocator());
+ _ASSERTE(IsLockedByCurrentThread());
+ _ASSERTE(pMethodDesc != nullptr);
- LoaderAllocatorSet *set = m_dependentLoaderAllocators;
- if (set != nullptr)
+ GCX_COOP();
+
+ auto lambda = [&entryPoint](OBJECTREF obj, MethodDesc *pMethodDesc, UINT_PTR slotData)
{
- if (set->Lookup(dependentLoaderAllocator) != nullptr)
- {
- return;
- }
- set->Add(dependentLoaderAllocator);
- return;
- }
- NewHolder<LoaderAllocatorSet> setHolder = new LoaderAllocatorSet();
- setHolder->Add(dependentLoaderAllocator);
- m_dependentLoaderAllocators = setHolder.Extract();
-}
+ TADDR slot;
+ EntryPointSlots::SlotType slotType;
-void MethodDescBackpatchInfo::RemoveDependentLoaderAllocator_Locked(LoaderAllocator *dependentLoaderAllocator)
-{
- WRAPPER_NO_CONTRACT;
- _ASSERTE(MethodDescBackpatchInfoTracker::IsLockedByCurrentThread());
- _ASSERTE(m_methodDesc != nullptr);
- _ASSERTE(dependentLoaderAllocator != nullptr);
- _ASSERTE(dependentLoaderAllocator != m_methodDesc->GetLoaderAllocator());
- _ASSERTE(m_dependentLoaderAllocators != nullptr);
- _ASSERTE(m_dependentLoaderAllocators->Lookup(dependentLoaderAllocator) == dependentLoaderAllocator);
+ EntryPointSlots::ConvertUINT_PTRToSlotAndTypePair(slotData, &slot, &slotType);
+ EntryPointSlots::Backpatch_Locked(slot, slotType, entryPoint);
- m_dependentLoaderAllocators->Remove(dependentLoaderAllocator);
+ return true; // Keep walking
+ };
+
+ m_backpatchInfoHash.VisitValuesOfKey(pMethodDesc, lambda);
}
-#endif // !DACCESS_COMPILE
+void MethodDescBackpatchInfoTracker::AddSlotAndPatch_Locked(MethodDesc *pMethodDesc, LoaderAllocator *pLoaderAllocatorOfSlot, TADDR slot, EntryPointSlots::SlotType slotType, PCODE currentEntryPoint)
+{
+ WRAPPER_NO_CONTRACT;
+ _ASSERTE(IsLockedByCurrentThread());
+ _ASSERTE(pMethodDesc != nullptr);
+ _ASSERTE(pMethodDesc->MayHaveEntryPointSlotsToBackpatch());
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// MethodDescBackpatchInfoTracker
+ GCX_COOP();
-CrstStatic MethodDescBackpatchInfoTracker::s_lock;
+ UINT_PTR slotData;
+ slotData = EntryPointSlots::ConvertSlotAndTypePairToUINT_PTR(slot, slotType);
-#ifndef DACCESS_COMPILE
+ m_backpatchInfoHash.Add(pMethodDesc, slotData, pLoaderAllocatorOfSlot);
+ EntryPointSlots::Backpatch_Locked(slot, slotType, currentEntryPoint);
+}
void MethodDescBackpatchInfoTracker::StaticInitialize()
{
@@ -163,76 +140,4 @@ bool MethodDescBackpatchInfoTracker::MayHaveEntryPointSlotsToBackpatch(PTR_Metho
#endif // _DEBUG
-#ifndef DACCESS_COMPILE
-
-MethodDescBackpatchInfo *MethodDescBackpatchInfoTracker::AddBackpatchInfo_Locked(MethodDesc *methodDesc)
-{
- WRAPPER_NO_CONTRACT;
- _ASSERTE(IsLockedByCurrentThread());
- _ASSERTE(methodDesc != nullptr);
- _ASSERTE(methodDesc->MayHaveEntryPointSlotsToBackpatch());
- _ASSERTE(m_backpatchInfoHash.Lookup(methodDesc) == nullptr);
-
- NewHolder<MethodDescBackpatchInfo> backpatchInfoHolder = new MethodDescBackpatchInfo(methodDesc);
- m_backpatchInfoHash.Add(backpatchInfoHolder);
- return backpatchInfoHolder.Extract();
-}
-
-EntryPointSlots *MethodDescBackpatchInfoTracker::GetDependencyMethodDescEntryPointSlots_Locked(MethodDesc *methodDesc)
-{
- WRAPPER_NO_CONTRACT;
- _ASSERTE(IsLockedByCurrentThread());
- _ASSERTE(methodDesc != nullptr);
- _ASSERTE(methodDesc->MayHaveEntryPointSlotsToBackpatch());
-
- MethodDescEntryPointSlots *methodDescSlots =
- m_dependencyMethodDescEntryPointSlotsHash.Lookup(methodDesc);
- return methodDescSlots == nullptr ? nullptr : methodDescSlots->GetSlots();
-}
-
-EntryPointSlots *MethodDescBackpatchInfoTracker::GetOrAddDependencyMethodDescEntryPointSlots_Locked(MethodDesc *methodDesc)
-{
- WRAPPER_NO_CONTRACT;
- _ASSERTE(IsLockedByCurrentThread());
- _ASSERTE(methodDesc != nullptr);
- _ASSERTE(methodDesc->MayHaveEntryPointSlotsToBackpatch());
-
- MethodDescEntryPointSlots *methodDescSlots = m_dependencyMethodDescEntryPointSlotsHash.Lookup(methodDesc);
- if (methodDescSlots != nullptr)
- {
- return methodDescSlots->GetSlots();
- }
-
- NewHolder<MethodDescEntryPointSlots> methodDescSlotsHolder = new MethodDescEntryPointSlots(methodDesc);
- m_dependencyMethodDescEntryPointSlotsHash.Add(methodDescSlotsHolder);
- return methodDescSlotsHolder.Extract()->GetSlots();
-}
-
-void MethodDescBackpatchInfoTracker::ClearDependencyMethodDescEntryPointSlots(LoaderAllocator *loaderAllocator)
-{
- WRAPPER_NO_CONTRACT;
- _ASSERTE(loaderAllocator != nullptr);
- _ASSERTE(loaderAllocator->GetMethodDescBackpatchInfoTracker() == this);
-
- ConditionalLockHolder lockHolder;
-
- for (MethodDescEntryPointSlotsHash::Iterator
- it = m_dependencyMethodDescEntryPointSlotsHash.Begin(),
- itEnd = m_dependencyMethodDescEntryPointSlotsHash.End();
- it != itEnd;
- ++it)
- {
- MethodDesc *methodDesc = (*it)->GetMethodDesc();
- MethodDescBackpatchInfo *backpatchInfo = methodDesc->GetBackpatchInfoTracker()->GetBackpatchInfo_Locked(methodDesc);
- if (backpatchInfo != nullptr)
- {
- backpatchInfo->RemoveDependentLoaderAllocator_Locked(loaderAllocator);
- }
- }
-
- m_dependencyMethodDescEntryPointSlotsHash.RemoveAll();
-}
-
-#endif // DACCESS_COMPILE
-
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////