Remove obsolete platforms ifdefs from PAL (#8971)
[platform/upstream/coreclr.git] / src / pal / src / include / pal / virtual.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 /*++
6
7
8
9 Module Name:
10
11     include/pal/virtual.h
12
13 Abstract:
14     Header file for virtual memory management.
15
16
17
18 --*/
19
20 #ifndef _PAL_VIRTUAL_H_
21 #define _PAL_VIRTUAL_H_
22
23 #ifdef __cplusplus
24 extern "C"
25 {
26 #endif // __cplusplus
27
28 typedef struct _CMI {
29
30     struct _CMI * pNext;        /* Link to the next entry. */
31     struct _CMI * pPrevious;    /* Link to the previous entry. */
32
33     UINT_PTR startBoundary;     /* Starting location of the region. */
34     SIZE_T   memSize;           /* Size of the entire region.. */
35
36     DWORD  accessProtection;    /* Initial allocation access protection. */
37     DWORD  allocationType;      /* Initial allocation type. */
38
39     BYTE * pAllocState;         /* Individual allocation type tracking for each */
40                                 /* page in the region. */
41
42     BYTE * pProtectionState;    /* Individual allocation type tracking for each */
43                                 /* page in the region. */
44
45 } CMI, * PCMI;
46
47 enum VIRTUAL_CONSTANTS
48 {
49     /* Allocation type. */
50     VIRTUAL_COMMIT_ALL_BITS     = 0xFF,
51     VIRTUAL_RESERVE_ALL_BITS    = 0x0,
52     
53     /* Protection Type. */
54     VIRTUAL_READONLY,
55     VIRTUAL_READWRITE,
56     VIRTUAL_EXECUTE_READWRITE,
57     VIRTUAL_NOACCESS,
58     VIRTUAL_EXECUTE,
59     VIRTUAL_EXECUTE_READ,
60     
61     VIRTUAL_PAGE_SIZE       = 0x1000,
62     VIRTUAL_PAGE_MASK       = VIRTUAL_PAGE_SIZE - 1,
63     BOUNDARY_64K    = 0xffff
64 };
65
66 /*++
67 Function :
68     VIRTUALInitialize
69
70     Initialize the critical sections.
71
72 Return value:
73     TRUE  if initialization succeeded
74     FALSE otherwise.        
75 --*/
76 BOOL VIRTUALInitialize(bool initializeExecutableMemoryAllocator);
77
78 /*++
79 Function :
80     VIRTUALCleanup
81
82     Deletes the critical sections.
83
84 --*/
85 void VIRTUALCleanup( void );
86
87 #ifdef __cplusplus
88 }
89
90 /*++
91 Class:
92     ExecutableMemoryAllocator
93
94     This class implements a virtual memory allocator for JIT'ed code.
95     The purpose of this allocator is to opportunistically reserve a chunk of virtual memory
96     that is located near the coreclr library (within 2GB range) that can be later used by
97     JIT. Having executable memory close to the coreclr library allows JIT to generate more
98     efficient code (by avoiding usage of jump stubs) and thus it can significantly improve
99     performance of the application.
100
101     This allocator is integrated with the VirtualAlloc/Reserve code. If VirtualAlloc has been
102     called with the MEM_RESERVE_EXECUTABLE flag then it will first try to obtain the requested size
103     of virtual memory from ExecutableMemoryAllocator. If ExecutableMemoryAllocator runs out of
104     the reserved memory (or fails to allocate it during initialization) then VirtualAlloc/Reserve code
105     will simply fall back to reserving memory using OS APIs.
106
107     Notes:
108         - the memory allocated by this class is NOT committed by default. It is responsibility
109           of the caller to commit the virtual memory before accessing it.
110         - in addition, this class does not provide ability to free the reserved memory. The caller
111           has full control of the memory it got from this allocator (i.e. the caller becomes
112           the owner of the allocated memory), so it is caller's responsibility to free the memory
113           if it is no longer needed.
114 --*/
115 class ExecutableMemoryAllocator
116 {
117 public:
118     /*++
119     Function:
120         Initialize
121
122         This function initializes the allocator. It should be called early during process startup
123         (when process address space is pretty much empty) in order to have a chance to reserve
124         sufficient amount of memory that is close to the coreclr library.
125     --*/
126     void Initialize();
127
128     /*++
129     Function:
130         AllocateMemory
131
132         This function attempts to allocate the requested amount of memory from its reserved virtual
133         address space. The function will return NULL if the allocation request cannot
134         be satisfied by the memory that is currently available in the allocator.
135     --*/
136     void* AllocateMemory(SIZE_T allocationSize);
137
138 private:
139     /*++
140     Function:
141         TryReserveInitialMemory
142
143         This function is called during initialization. It opportunistically tries to reserve
144         a large chunk of virtual memory that can be later used to store JIT'ed code.
145     --*/
146     void TryReserveInitialMemory();
147
148     /*++
149     Function:
150         GenerateRandomStartOffset
151
152         This function returns a random offset (in multiples of the virtual page size)
153         at which the allocator should start allocating memory from its reserved memory range.
154     --*/
155     int32_t GenerateRandomStartOffset();
156
157 private:
158     // There does not seem to be an easy way find the size of a library on Unix.
159     // So this constant represents an approximation of the libcoreclr size (on debug build)
160     // that can be used to calculate an approximate location of the memory that
161     // is in 2GB range from the coreclr library. In addition, having precise size of libcoreclr
162     // is not necessary for the calculations.
163     const int32_t CoreClrLibrarySize = 100 * 1024 * 1024;
164
165     // This constant represent the max size of the virtual memory that this allocator
166     // will try to reserve during initialization. We want all JIT-ed code and the
167     // entire libcoreclr to be located in a 2GB range.
168     const int32_t MaxExecutableMemorySize = 0x7FFF0000 - CoreClrLibrarySize;
169
170     // Start address of the reserved virtual address space
171     void* m_startAddress;
172
173     // Next available address in the reserved address space
174     void* m_nextFreeAddress;
175
176     // Total size of the virtual memory that the allocator has been able to
177     // reserve during its initialization.
178     int32_t m_totalSizeOfReservedMemory;
179
180     // Remaining size of the reserved virtual memory that can be used to satisfy allocation requests.
181     int32_t m_remainingReservedMemory;
182 };
183
184 #endif // __cplusplus
185
186 /*++
187 Function :
188     ReserveMemoryFromExecutableAllocator
189
190     This function is used to reserve a region of virual memory (not commited)
191     that is located close to the coreclr library. The memory comes from the virtual
192     address range that is managed by ExecutableMemoryAllocator.
193 --*/
194 void* ReserveMemoryFromExecutableAllocator(CorUnix::CPalThread* pthrCurrent, SIZE_T allocationSize);
195
196 #endif /* _PAL_VIRTUAL_H_ */
197
198
199
200
201
202
203