378813889746029ce8515ccb834917f7f73673df
[platform/upstream/coreclr.git] / src / zap / zapmetadata.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 // ZapMetadata.h
6 //
7
8 //
9 // Metadata zapping
10 // 
11 // ======================================================================================
12
13 #ifndef __ZAPMETADATA_H__
14 #define __ZAPMETADATA_H__
15
16 //-----------------------------------------------------------------------------
17 //
18 // ZapMetaData is the barebone ZapNode to save metadata scope
19 //
20
21 class ZapMetaData : public ZapNode
22 {
23     DWORD m_dwSize;
24
25 protected:
26     IMetaDataEmit * m_pEmit;
27
28 public:
29     ZapMetaData()
30     {
31     }
32
33     ~ZapMetaData()
34     {
35         SAFERELEASE(m_pEmit);
36     }
37
38     void SetMetaData(IUnknown * pEmit);
39
40     virtual DWORD GetSize();
41
42     virtual UINT GetAlignment()
43     {
44         return sizeof(DWORD);
45     }
46
47     virtual ZapNodeType GetType()
48     {
49         return ZapNodeType_MetaData;
50     }
51
52     virtual void Save(ZapWriter * pZapWriter);
53 };
54
55 //-----------------------------------------------------------------------------
56 //
57 // Helper node to copy RVA data to from IL to the NGEN image.
58 //
59
60 class ZapRVADataNode : public ZapNode
61 {
62     PVOID m_pData;
63     DWORD m_dwSize;
64     DWORD m_dwAlignment;
65
66 public:
67     ZapRVADataNode(PVOID pData)
68     {
69         m_pData = pData;
70         m_dwSize = 0;
71         m_dwAlignment = 1;
72     }
73
74     void UpdateSizeAndAlignment(DWORD dwSize, DWORD dwAlignment)
75     {
76         if (dwSize > m_dwSize)
77             m_dwSize = dwSize;
78
79         if (dwAlignment > m_dwAlignment)
80             m_dwAlignment = dwAlignment;
81     }
82
83     PVOID GetData()
84     {
85         return m_pData;
86     }
87
88     virtual DWORD GetSize()
89     {
90         return m_dwSize;
91     }
92
93     virtual UINT GetAlignment()
94     {
95         return m_dwAlignment;
96     }
97
98     virtual ZapNodeType GetType()
99     {
100         return ZapNodeType_RVAFieldData;
101     }
102
103     virtual void Save(ZapWriter * pZapWriter)
104     {
105         pZapWriter->Write(m_pData, m_dwSize);
106     }
107 };
108
109
110 //-----------------------------------------------------------------------------
111 //
112 // ZapILMetaData copies both the metadata and IL to the NGEN image.
113 //
114
115 class ZapILMetaData : public ZapMetaData
116 {
117     ZapImage * m_pImage;
118
119     class ILBlob : public ZapBlobPtr
120     {
121     public:
122         ILBlob(PVOID pData, SIZE_T cbSize)
123             : ZapBlobPtr(pData, cbSize)
124         {
125         }
126
127         virtual UINT GetAlignment()
128         {
129             // The tiny header does not have any alignment requirements
130             return ((COR_ILMETHOD_TINY *)GetData())->IsTiny() ? sizeof(BYTE) : sizeof(DWORD);
131         }
132     };
133
134     // Hashtable with all IL method blobs. If two methods have same IL code
135     // we store it just once.
136     SHash< NoRemoveSHashTraits < ZapBlob::SHashTraits > >  m_blobs;
137
138     struct ILMethod
139     {
140         mdMethodDef m_md;
141         ZapBlob * m_pIL;
142     };
143
144     class ILMethodTraits : public NoRemoveSHashTraits< DefaultSHashTraits<ILMethod> >
145     {
146     public:
147         typedef const mdMethodDef key_t;
148
149         static key_t GetKey(element_t e)
150         {
151             LIMITED_METHOD_CONTRACT;
152             return e.m_md;
153         }
154         static BOOL Equals(key_t k1, key_t k2)
155         {
156             LIMITED_METHOD_CONTRACT;
157             return k1 == k2;
158         }
159         static count_t Hash(key_t k) 
160         {
161             LIMITED_METHOD_CONTRACT;
162             return k;
163         }
164
165         static const element_t Null() { LIMITED_METHOD_CONTRACT; ILMethod e; e.m_md = 0; e.m_pIL = NULL; return e; }
166         static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e.m_md == 0; }
167     };
168
169     SHash< ILMethodTraits > m_ILMethods;
170
171 public:
172     ZapILMetaData(ZapImage * pImage)
173         : m_pImage(pImage)
174     {
175     }
176
177     void Preallocate(COUNT_T cbILImage)
178     {
179         PREALLOCATE_HASHTABLE(ZapILMetaData::m_blobs, 0.0040, cbILImage);
180         PREALLOCATE_HASHTABLE(ZapILMetaData::m_ILMethods, 0.0044, cbILImage);
181     }
182
183     void EmitMethodIL(mdMethodDef md);
184
185     void CopyIL();
186     void CopyMetaData();
187     void CopyRVAFields();
188
189     virtual void Save(ZapWriter * pZapWriter);
190
191     ZapRVADataNode * GetRVAField(void * pData);
192
193 private:
194     class RVADataTraits : public NoRemoveSHashTraits< DefaultSHashTraits<ZapRVADataNode *> >
195     {
196     public:
197         typedef PVOID key_t;
198
199         static key_t GetKey(element_t e)
200         {
201             LIMITED_METHOD_CONTRACT;
202             return e->GetData();
203         }
204         static BOOL Equals(key_t k1, key_t k2)
205         {
206             LIMITED_METHOD_CONTRACT;
207             return k1 == k2;
208         }
209         static count_t Hash(key_t k) 
210         {
211             LIMITED_METHOD_CONTRACT;
212             return (count_t)k;
213         }
214
215         static const element_t Null() { LIMITED_METHOD_CONTRACT; return NULL; }
216         static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e == NULL; }
217     };
218
219     SHash< RVADataTraits > m_rvaData;
220 };
221
222 #endif // __ZAPMETADATA_H__