summaryrefslogtreecommitdiff
path: root/src/zap/zapwrapper.h
blob: bcf10b546fb752de45afaa05d0b32cc394ab8219 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// ZapWrapper.h
//

//
// ZapNode that wraps EE datastructure for zapping
// 
// ======================================================================================

#ifndef __ZAPWRAPPER_H__
#define __ZAPWRAPPER_H__

//
// When generating compiled code for IL, the compiler will need to embed
// handles, which are pointers to various data structures. The data
// structures may either not exist, or we may not have some information
// we need for optimal code gen.
//
// In such cases, we use placeholders. Compiled code embed pointers
// to placeholders, which then have rich information about the
// referenced data structure.
//
// Once information is finally available for the exact code required,
// ZapWrapper::Resolve makes the place holder to point to the intended target.
//

class ZapWrapper : public ZapNode
{
    PVOID m_handle;

public:
    ZapWrapper(PVOID handle)
        : m_handle(handle)
    {
    }

    ZapWrapper()
    {
    }

    void SetHandle(PVOID handle)
    {
        _ASSERTE(m_handle == NULL);
        _ASSERTE(handle != NULL);
        m_handle = handle;
    }

    PVOID GetHandle()
    {
        return m_handle;
    }

    virtual ZapNode * GetBase()
    {
        return this;
    }

    virtual void Resolve(ZapImage * pImage)
    {
    }
};

class ZapWrapperTable
{
    class WrapperTraits : public NoRemoveSHashTraits< DefaultSHashTraits<ZapWrapper *> >
    {
    public:
        typedef PVOID key_t;

        static key_t GetKey(element_t e)
        { 
            LIMITED_METHOD_CONTRACT;
            return e->GetHandle();
        }
        static BOOL Equals(key_t k1, key_t k2) 
        { 
            LIMITED_METHOD_CONTRACT;
            return k1 == k2;
        }
        static count_t Hash(key_t k) 
        {
            LIMITED_METHOD_CONTRACT;
            return (count_t)(size_t)k;
        }

        static const element_t Null() { LIMITED_METHOD_CONTRACT; return NULL; }
        static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e == NULL; }
    };

    typedef SHash< WrapperTraits > WrapperTable;

    WrapperTable m_entries;
    ZapImage * m_pImage;

    //
    // Helper for inserting actual implementations of placeholders into hashtable
    //
    template < typename impl, ZapNodeType type >
    ZapNode * GetPlaceHolder(PVOID handle)
    {
        ZapWrapper * pPlaceHolder = m_entries.Lookup(handle);

        if (pPlaceHolder != NULL)
        {
            _ASSERTE(pPlaceHolder->GetType() == type);
            return pPlaceHolder;
        }

        pPlaceHolder = new (m_pImage->GetHeap()) impl();
        _ASSERTE(pPlaceHolder->GetType() == type);
        pPlaceHolder->SetHandle(handle);
        m_entries.Add(pPlaceHolder);
        return pPlaceHolder;
    }

public:
    ZapWrapperTable(ZapImage * pImage)
        : m_pImage(pImage)
    {
    }

    void Preallocate(COUNT_T cbILImage)
    {
        PREALLOCATE_HASHTABLE(ZapWrapperTable::m_entries, 0.0013, cbILImage);
    }

    ZapNode * GetMethodHandle(CORINFO_METHOD_HANDLE handle);
    ZapNode * GetClassHandle(CORINFO_CLASS_HANDLE handle);
    ZapNode * GetFieldHandle(CORINFO_FIELD_HANDLE handle);
    ZapNode * GetAddrOfPInvokeFixup(CORINFO_METHOD_HANDLE handle);
    ZapNode * GetGenericHandle(CORINFO_GENERIC_HANDLE handle);
    ZapNode * GetModuleIDHandle(CORINFO_MODULE_HANDLE handle);

    ZapNode * GetStub(void * pStub);

    void Resolve();
};

#endif // __ZAPWRAPPER_H__