diff options
author | David Wrighton <davidwr@microsoft.com> | 2019-02-14 17:07:14 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-14 17:07:14 -0800 |
commit | 423d2a3b91feea18ab361da04d5cc24bdff157d0 (patch) | |
tree | e59d54a5c48322a09ef1a4c5325378c9f60171dd /src/vm/methoddescbackpatchinfo.cpp | |
parent | 89e78f42ba11beaa81635a75cf593a3713dba176 (diff) | |
download | coreclr-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.cpp | 153 |
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 - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |