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 | // File: methodimpl.h |
6 | // |
7 | |
8 | |
9 | // |
10 | |
11 | // |
12 | // ============================================================================ |
13 | |
14 | #ifndef _METHODIMPL_H |
15 | #define _METHODIMPL_H |
16 | |
17 | class MethodDesc; |
18 | |
19 | // <TODO>@TODO: This is very bloated. We need to trim this down alot. However, |
20 | // we need to keep it on a 8 byte boundary.</TODO> |
21 | class MethodImpl |
22 | { |
23 | #ifdef DACCESS_COMPILE |
24 | friend class NativeImageDumper; |
25 | #endif |
26 | |
27 | RelativePointer<PTR_DWORD> pdwSlots; // Maintains the slots and tokens in sorted order, the first entry is the size |
28 | RelativePointer<DPTR( RelativePointer<PTR_MethodDesc> )> pImplementedMD; |
29 | |
30 | public: |
31 | |
32 | #ifndef DACCESS_COMPILE |
33 | /////////////////////////////////////////////////////////////////////////////////////// |
34 | class Iterator |
35 | { |
36 | private: |
37 | MethodDesc *m_pMD; |
38 | MethodImpl *m_pImpl; |
39 | DWORD m_iCur; |
40 | |
41 | public: |
42 | Iterator(MethodDesc *pMD); |
43 | inline BOOL IsValid() |
44 | { WRAPPER_NO_CONTRACT; return ((m_pImpl != NULL)&& (m_iCur < m_pImpl->GetSize())); } |
45 | inline void Next() |
46 | { WRAPPER_NO_CONTRACT; if (IsValid()) m_iCur++; } |
47 | inline WORD GetSlot() |
48 | { WRAPPER_NO_CONTRACT; CONSISTENCY_CHECK(IsValid()); _ASSERTE(FitsIn<WORD>(m_pImpl->GetSlots()[m_iCur])); return static_cast<WORD>(m_pImpl->GetSlots()[m_iCur]); } |
49 | inline mdToken GetToken() |
50 | { WRAPPER_NO_CONTRACT; CONSISTENCY_CHECK(IsValid()); return m_pImpl->GetTokens()[m_iCur]; } |
51 | inline MethodDesc *GetMethodDesc() |
52 | { WRAPPER_NO_CONTRACT; return m_pImpl->GetMethodDesc(m_iCur, (PTR_MethodDesc) m_pMD); } |
53 | }; |
54 | #endif // !DACCESS_COMPILE |
55 | |
56 | inline DPTR(RelativePointer<PTR_MethodDesc>) GetImpMDs() |
57 | { |
58 | LIMITED_METHOD_DAC_CONTRACT; |
59 | return RelativePointer<DPTR(RelativePointer<PTR_MethodDesc>)>::GetValueMaybeNullAtPtr(PTR_HOST_MEMBER_TADDR(MethodImpl, this, pImplementedMD)); |
60 | } |
61 | |
62 | inline DPTR(RelativePointer<PTR_MethodDesc>) GetImpMDsNonNull() |
63 | { |
64 | LIMITED_METHOD_DAC_CONTRACT; |
65 | return RelativePointer<DPTR(RelativePointer<PTR_MethodDesc>)>::GetValueAtPtr(PTR_HOST_MEMBER_TADDR(MethodImpl, this, pImplementedMD)); |
66 | } |
67 | |
68 | /////////////////////////////////////////////////////////////////////////////////////// |
69 | inline DWORD GetSize() |
70 | { |
71 | CONTRACTL { |
72 | NOTHROW; |
73 | GC_NOTRIGGER; |
74 | PRECONDITION(CheckPointer(this)); |
75 | } CONTRACTL_END; |
76 | |
77 | if(pdwSlots.IsNull()) |
78 | return 0; |
79 | else |
80 | return *GetSlotsRawNonNull(); |
81 | } |
82 | |
83 | /////////////////////////////////////////////////////////////////////////////////////// |
84 | inline PTR_DWORD GetSlots() |
85 | { |
86 | CONTRACTL { |
87 | NOTHROW; |
88 | GC_NOTRIGGER; |
89 | PRECONDITION(CheckPointer(this)); |
90 | SUPPORTS_DAC; |
91 | } CONTRACTL_END; |
92 | |
93 | if(pdwSlots.IsNull()) |
94 | return NULL; |
95 | else |
96 | return GetSlotsRawNonNull() + 1; |
97 | } |
98 | |
99 | inline PTR_DWORD GetSlotsRaw() |
100 | { |
101 | LIMITED_METHOD_DAC_CONTRACT; |
102 | return RelativePointer<PTR_DWORD>::GetValueMaybeNullAtPtr(PTR_HOST_MEMBER_TADDR(MethodImpl, this, pdwSlots)); |
103 | } |
104 | |
105 | inline PTR_DWORD GetSlotsRawNonNull() |
106 | { |
107 | LIMITED_METHOD_DAC_CONTRACT; |
108 | return RelativePointer<PTR_DWORD>::GetValueAtPtr(PTR_HOST_MEMBER_TADDR(MethodImpl, this, pdwSlots)); |
109 | } |
110 | |
111 | #ifndef DACCESS_COMPILE |
112 | |
113 | /////////////////////////////////////////////////////////////////////////////////////// |
114 | inline mdToken* GetTokens() |
115 | { |
116 | CONTRACTL{ |
117 | NOTHROW; |
118 | GC_NOTRIGGER; |
119 | PRECONDITION(CheckPointer(this)); |
120 | SUPPORTS_DAC; |
121 | } CONTRACTL_END; |
122 | |
123 | if (pdwSlots.IsNull()) |
124 | return NULL; |
125 | else |
126 | return (mdToken*)(GetSlotsRawNonNull() + 1 + *GetSlotsRawNonNull()); |
127 | } |
128 | |
129 | /////////////////////////////////////////////////////////////////////////////////////// |
130 | void SetSize(LoaderHeap *pHeap, AllocMemTracker *pamTracker, DWORD size); |
131 | |
132 | /////////////////////////////////////////////////////////////////////////////////////// |
133 | void SetData(DWORD* slots, mdToken* tokens, RelativePointer<MethodDesc*> * md); |
134 | |
135 | #endif // !DACCESS_COMPILE |
136 | |
137 | #ifdef DACCESS_COMPILE |
138 | void EnumMemoryRegions(CLRDataEnumMemoryFlags flags); |
139 | #endif |
140 | |
141 | #ifdef FEATURE_PREJIT |
142 | void Save(DataImage *image); |
143 | void Fixup(DataImage *image, PVOID p, SSIZE_T offset); |
144 | #endif // FEATURE_PREJIT |
145 | |
146 | |
147 | // Returns the method desc for the replaced slot; |
148 | PTR_MethodDesc FindMethodDesc(DWORD slot, PTR_MethodDesc defaultReturn); |
149 | |
150 | // Returns the method desc for the slot index; |
151 | PTR_MethodDesc GetMethodDesc(DWORD slotIndex, PTR_MethodDesc defaultReturn); |
152 | |
153 | private: |
154 | static const DWORD INVALID_INDEX = (DWORD)(-1); |
155 | DWORD FindSlotIndex(DWORD slot); |
156 | #ifndef DACCESS_COMPILE |
157 | MethodDesc* RestoreSlot(DWORD slotIndex, MethodTable *pMT); |
158 | #endif |
159 | |
160 | }; |
161 | |
162 | #endif // !_METHODIMPL_H |
163 | |