1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
7 #include "debugmacrosext.h"
8 #include "crossloaderallocatorhash.h"
10 #ifndef CROSSGEN_COMPILE
12 #define DISABLE_COPY(T) \
13 T(const T &) = delete; \
14 T &operator =(const T &) = delete
16 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
24 SlotType_Normal, // pointer-sized value not in executable code
25 SlotType_Vtable, // pointer-sized value not in executable code, may be relative based on MethodTable::VTableIndir2_t
26 SlotType_Executable, // pointer-sized value in executable code
27 SlotType_ExecutableRel32, // 32-bit value relative to the end of the slot, in executable code
30 SlotType_Mask = SlotType_Vtable | SlotType_Executable | SlotType_ExecutableRel32
33 #ifndef DACCESS_COMPILE
35 static SIZE_T GetRequiredSlotAlignment(SlotType slotType)
37 LIMITED_METHOD_CONTRACT;
38 _ASSERTE(slotType >= SlotType_Normal);
39 _ASSERTE(slotType < SlotType_Count);
41 return slotType == SlotType_ExecutableRel32 ? sizeof(INT32) : sizeof(void *);
45 static UINT_PTR ConvertSlotAndTypePairToUINT_PTR(TADDR slot, SlotType slotType)
47 slot |= (TADDR)slotType;
48 return (UINT_PTR)slot;
51 static void ConvertUINT_PTRToSlotAndTypePair(UINT_PTR storedData, TADDR *pSlot, SlotType *pSlotType)
54 *pSlotType = (SlotType)(*pSlot & SlotType_Mask);
58 static void Backpatch_Locked(TADDR slot, SlotType slotType, PCODE entryPoint);
62 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
63 // MethodDescBackpatchInfoTracker
65 class MethodDescBackpatchInfoTracker
68 static CrstStatic s_lock;
69 static bool s_isLocked;
71 class BackpatchInfoTrackerHashTraits : public NoRemoveDefaultCrossLoaderAllocatorHashTraits<MethodDesc *, UINT_PTR>
75 typedef CrossLoaderAllocatorHash<BackpatchInfoTrackerHashTraits> BackpatchInfoTrackerHash;
77 // Contains information about slots associated with the MethodDesc that were recorded for backpatching. This field and its
78 // data is protected by s_lock.
79 BackpatchInfoTrackerHash m_backpatchInfoHash;
81 #ifndef DACCESS_COMPILE
83 static void StaticInitialize();
86 void Initialize(LoaderAllocator *pLoaderAllocator)
89 m_backpatchInfoHash.Init(pLoaderAllocator);
94 static bool IsLockedByCurrentThread();
97 #ifndef DACCESS_COMPILE
99 static bool IsLockedByAnyThread()
101 LIMITED_METHOD_CONTRACT;
102 return VolatileLoadWithoutBarrier(&s_isLocked);
105 static void PollForDebuggerSuspension();
109 class ConditionalLockHolder : CrstHolderWithState
115 ConditionalLockHolder(bool acquireLock = true)
116 : CrstHolderWithState(
117 #ifndef DACCESS_COMPILE
118 acquireLock ? &MethodDescBackpatchInfoTracker::s_lock : nullptr
127 #ifndef DACCESS_COMPILE
130 _ASSERTE(IsLockedByCurrentThread());
131 _ASSERTE(!s_isLocked);
138 ~ConditionalLockHolder()
142 #ifndef DACCESS_COMPILE
145 _ASSERTE(IsLockedByCurrentThread());
146 _ASSERTE(s_isLocked);
154 MethodDescBackpatchInfoTracker()
156 LIMITED_METHOD_CONTRACT;
161 static bool MayHaveEntryPointSlotsToBackpatch(PTR_MethodDesc methodDesc);
164 #ifndef DACCESS_COMPILE
166 void Backpatch_Locked(MethodDesc *pMethodDesc, PCODE entryPoint);
167 void AddSlotAndPatch_Locked(MethodDesc *pMethodDesc, LoaderAllocator *pLoaderAllocatorOfSlot, TADDR slot, EntryPointSlots::SlotType slotType, PCODE currentEntryPoint);
171 friend class ConditionalLockHolder;
173 DISABLE_COPY(MethodDescBackpatchInfoTracker);
178 #endif // !CROSSGEN_COMPILE