| 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 | |