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
17class 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>
21class 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
30public:
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
153private:
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