[Tizen] Unify dnetmemoryenumlib terms to match the codebase (#291)
[platform/upstream/coreclr.git] / src / vm / methoddescbackpatchinfo.h
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.
4
5 #pragma once
6
7 #include "debugmacrosext.h"
8 #include "crossloaderallocatorhash.h"
9
10 #ifndef CROSSGEN_COMPILE
11
12 #define DISABLE_COPY(T) \
13     T(const T &) = delete; \
14     T &operator =(const T &) = delete
15
16 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
17 // EntryPointSlots
18
19 class EntryPointSlots
20 {
21 public:
22     enum SlotType : UINT8
23     {
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
28
29         SlotType_Count,
30         SlotType_Mask = SlotType_Vtable | SlotType_Executable | SlotType_ExecutableRel32
31     };
32
33 #ifndef DACCESS_COMPILE
34 private:
35     static SIZE_T GetRequiredSlotAlignment(SlotType slotType)
36     {
37         LIMITED_METHOD_CONTRACT;
38         _ASSERTE(slotType >= SlotType_Normal);
39         _ASSERTE(slotType < SlotType_Count);
40
41         return slotType == SlotType_ExecutableRel32 ? sizeof(INT32) : sizeof(void *);
42     }
43
44 public:
45     static UINT_PTR ConvertSlotAndTypePairToUINT_PTR(TADDR slot, SlotType slotType)
46     {
47         slot |= (TADDR)slotType;
48         return (UINT_PTR)slot;
49     }
50
51     static void ConvertUINT_PTRToSlotAndTypePair(UINT_PTR storedData, TADDR *pSlot, SlotType *pSlotType)
52     {
53         *pSlot = storedData;
54         *pSlotType = (SlotType)(*pSlot & SlotType_Mask);
55         *pSlot ^= *pSlotType;
56     }
57
58     static void Backpatch_Locked(TADDR slot, SlotType slotType, PCODE entryPoint);
59 #endif
60 };
61
62 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
63 // MethodDescBackpatchInfoTracker
64
65 class MethodDescBackpatchInfoTracker
66 {
67 private:
68     static CrstStatic s_lock;
69     static bool s_isLocked;
70
71     class BackpatchInfoTrackerHashTraits : public NoRemoveDefaultCrossLoaderAllocatorHashTraits<MethodDesc *, UINT_PTR>
72     {
73     };
74
75     typedef CrossLoaderAllocatorHash<BackpatchInfoTrackerHashTraits> BackpatchInfoTrackerHash;
76
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;
80
81 #ifndef DACCESS_COMPILE
82 public:
83     static void StaticInitialize();
84 #endif
85
86     void Initialize(LoaderAllocator *pLoaderAllocator)
87     {
88         WRAPPER_NO_CONTRACT;
89         m_backpatchInfoHash.Init(pLoaderAllocator);
90     }
91
92 #ifdef _DEBUG
93 public:
94     static bool IsLockedByCurrentThread();
95 #endif
96
97 #ifndef DACCESS_COMPILE
98 public:
99     static bool IsLockedByAnyThread()
100     {
101         LIMITED_METHOD_CONTRACT;
102         return VolatileLoadWithoutBarrier(&s_isLocked);
103     }
104
105     static void PollForDebuggerSuspension();
106 #endif
107
108 public:
109     class ConditionalLockHolder : CrstHolderWithState
110     {
111     private:
112         bool m_isLocked;
113
114     public:
115         ConditionalLockHolder(bool acquireLock = true)
116             : CrstHolderWithState(
117 #ifndef DACCESS_COMPILE
118                 acquireLock ? &MethodDescBackpatchInfoTracker::s_lock : nullptr
119 #else
120                 nullptr
121 #endif
122                 ),
123             m_isLocked(false)
124         {
125             WRAPPER_NO_CONTRACT;
126
127         #ifndef DACCESS_COMPILE
128             if (acquireLock)
129             {
130                 _ASSERTE(IsLockedByCurrentThread());
131                 _ASSERTE(!s_isLocked);
132                 m_isLocked = true;
133                 s_isLocked = true;
134             }
135         #endif
136         }
137
138         ~ConditionalLockHolder()
139         {
140             WRAPPER_NO_CONTRACT;
141
142         #ifndef DACCESS_COMPILE
143             if (m_isLocked)
144             {
145                 _ASSERTE(IsLockedByCurrentThread());
146                 _ASSERTE(s_isLocked);
147                 s_isLocked = false;
148             }
149         #endif
150         }
151     };
152
153 public:
154     MethodDescBackpatchInfoTracker()
155     {
156         LIMITED_METHOD_CONTRACT;
157     }
158
159 #ifdef _DEBUG
160 public:
161     static bool MayHaveEntryPointSlotsToBackpatch(PTR_MethodDesc methodDesc);
162 #endif
163
164 #ifndef DACCESS_COMPILE
165 public:
166     void Backpatch_Locked(MethodDesc *pMethodDesc, PCODE entryPoint);
167     void AddSlotAndPatch_Locked(MethodDesc *pMethodDesc, LoaderAllocator *pLoaderAllocatorOfSlot, TADDR slot, EntryPointSlots::SlotType slotType, PCODE currentEntryPoint);
168 public:
169 #endif
170
171     friend class ConditionalLockHolder;
172
173     DISABLE_COPY(MethodDescBackpatchInfoTracker);
174 };
175
176 #undef DISABLE_COPY
177
178 #endif // !CROSSGEN_COMPILE