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// ZapWrapper.h
6//
7
8//
9// ZapNode that wraps EE datastructure for zapping
10//
11// ======================================================================================
12
13#ifndef __ZAPWRAPPER_H__
14#define __ZAPWRAPPER_H__
15
16//
17// When generating compiled code for IL, the compiler will need to embed
18// handles, which are pointers to various data structures. The data
19// structures may either not exist, or we may not have some information
20// we need for optimal code gen.
21//
22// In such cases, we use placeholders. Compiled code embed pointers
23// to placeholders, which then have rich information about the
24// referenced data structure.
25//
26// Once information is finally available for the exact code required,
27// ZapWrapper::Resolve makes the place holder to point to the intended target.
28//
29
30class ZapWrapper : public ZapNode
31{
32 PVOID m_handle;
33
34public:
35 ZapWrapper(PVOID handle)
36 : m_handle(handle)
37 {
38 }
39
40 ZapWrapper()
41 {
42 }
43
44 void SetHandle(PVOID handle)
45 {
46 _ASSERTE(m_handle == NULL);
47 _ASSERTE(handle != NULL);
48 m_handle = handle;
49 }
50
51 PVOID GetHandle()
52 {
53 return m_handle;
54 }
55
56 virtual ZapNode * GetBase()
57 {
58 return this;
59 }
60
61 virtual void Resolve(ZapImage * pImage)
62 {
63 }
64};
65
66class ZapWrapperTable
67{
68 class WrapperTraits : public NoRemoveSHashTraits< DefaultSHashTraits<ZapWrapper *> >
69 {
70 public:
71 typedef PVOID key_t;
72
73 static key_t GetKey(element_t e)
74 {
75 LIMITED_METHOD_CONTRACT;
76 return e->GetHandle();
77 }
78 static BOOL Equals(key_t k1, key_t k2)
79 {
80 LIMITED_METHOD_CONTRACT;
81 return k1 == k2;
82 }
83 static count_t Hash(key_t k)
84 {
85 LIMITED_METHOD_CONTRACT;
86 return (count_t)(size_t)k;
87 }
88
89 static element_t Null() { LIMITED_METHOD_CONTRACT; return NULL; }
90 static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e == NULL; }
91 };
92
93 typedef SHash< WrapperTraits > WrapperTable;
94
95 WrapperTable m_entries;
96 ZapImage * m_pImage;
97
98 //
99 // Helper for inserting actual implementations of placeholders into hashtable
100 //
101 template < typename impl, ZapNodeType type >
102 ZapNode * GetPlaceHolder(PVOID handle)
103 {
104 ZapWrapper * pPlaceHolder = m_entries.Lookup(handle);
105
106 if (pPlaceHolder != NULL)
107 {
108 _ASSERTE(pPlaceHolder->GetType() == type);
109 return pPlaceHolder;
110 }
111
112 pPlaceHolder = new (m_pImage->GetHeap()) impl();
113 _ASSERTE(pPlaceHolder->GetType() == type);
114 pPlaceHolder->SetHandle(handle);
115 m_entries.Add(pPlaceHolder);
116 return pPlaceHolder;
117 }
118
119public:
120 ZapWrapperTable(ZapImage * pImage)
121 : m_pImage(pImage)
122 {
123 }
124
125 void Preallocate(COUNT_T cbILImage)
126 {
127 PREALLOCATE_HASHTABLE(ZapWrapperTable::m_entries, 0.0013, cbILImage);
128 }
129
130 ZapNode * GetMethodHandle(CORINFO_METHOD_HANDLE handle);
131 ZapNode * GetClassHandle(CORINFO_CLASS_HANDLE handle);
132 ZapNode * GetFieldHandle(CORINFO_FIELD_HANDLE handle);
133 ZapNode * GetAddrOfPInvokeFixup(CORINFO_METHOD_HANDLE handle);
134 ZapNode * GetGenericHandle(CORINFO_GENERIC_HANDLE handle);
135 ZapNode * GetModuleIDHandle(CORINFO_MODULE_HANDLE handle);
136
137 ZapNode * GetStub(void * pStub);
138
139 void Resolve();
140};
141
142#endif // __ZAPWRAPPER_H__
143