[HEAP]
[reactos.git] / reactos / lib / rtl / heap.h
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS System Libraries
4 * FILE: lib/rtl/heap.h
5 * PURPOSE: Run-Time Libary Heap Manager header
6 * PROGRAMMER: Aleksey Bragin
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #ifndef RTL_HEAP_H
12 #define RTL_HEAP_H
13
14 /* Core heap definitions */
15 #define HEAP_FREELISTS 128
16 #define HEAP_SEGMENTS 64
17
18 #define HEAP_ENTRY_SIZE ((ULONG)sizeof(HEAP_ENTRY))
19 #ifdef _WIN64
20 #define HEAP_ENTRY_SHIFT 4
21 #else
22 #define HEAP_ENTRY_SHIFT 3
23 #endif
24 #define HEAP_MAX_BLOCK_SIZE ((0x80000 - PAGE_SIZE) >> HEAP_ENTRY_SHIFT)
25
26 #define ARENA_INUSE_FILLER 0xBAADF00D
27 #define ARENA_FREE_FILLER 0xFEEEFEEE
28 #define HEAP_TAIL_FILL 0xab
29
30 // from ntifs.h, should go to another header!
31 #define HEAP_GLOBAL_TAG 0x0800
32 #define HEAP_PSEUDO_TAG_FLAG 0x8000
33 #define HEAP_TAG_MASK (HEAP_MAXIMUM_TAG << HEAP_TAG_SHIFT)
34
35 #define HEAP_EXTRA_FLAGS_MASK (HEAP_CAPTURE_STACK_BACKTRACES | \
36 HEAP_SETTABLE_USER_VALUE | \
37 (HEAP_TAG_MASK ^ (0xFF << HEAP_TAG_SHIFT)))
38
39 /* Heap entry flags */
40 #define HEAP_ENTRY_BUSY 0x01
41 #define HEAP_ENTRY_EXTRA_PRESENT 0x02
42 #define HEAP_ENTRY_FILL_PATTERN 0x04
43 #define HEAP_ENTRY_VIRTUAL_ALLOC 0x08
44 #define HEAP_ENTRY_LAST_ENTRY 0x10
45 #define HEAP_ENTRY_SETTABLE_FLAG1 0x20
46 #define HEAP_ENTRY_SETTABLE_FLAG2 0x40
47 #define HEAP_ENTRY_SETTABLE_FLAG3 0x80
48 #define HEAP_ENTRY_SETTABLE_FLAGS (HEAP_ENTRY_SETTABLE_FLAG1 | HEAP_ENTRY_SETTABLE_FLAG2 | HEAP_ENTRY_SETTABLE_FLAG3)
49
50 /* Signatures */
51 #define HEAP_SIGNATURE 0xeefeeff
52 #define HEAP_SEGMENT_SIGNATURE 0xffeeffee
53
54 /* Segment flags */
55 #define HEAP_USER_ALLOCATED 0x1
56
57 /* Heap structures */
58 struct _HEAP_COMMON_ENTRY
59 {
60 union
61 {
62 struct
63 {
64 USHORT Size;
65 UCHAR Flags;
66 UCHAR SmallTagIndex;
67 };
68 struct
69 {
70 PVOID SubSegmentCode;
71 USHORT PreviousSize;
72 union
73 {
74 UCHAR SegmentOffset;
75 UCHAR LFHFlags;
76 };
77 UCHAR UnusedBytes;
78 };
79 struct
80 {
81 USHORT FunctionIndex;
82 USHORT ContextValue;
83 };
84 struct
85 {
86 ULONG InterceptorValue;
87 USHORT UnusedBytesLength;
88 UCHAR EntryOffset;
89 UCHAR ExtendedBlockSignature;
90 };
91 struct
92 {
93 ULONG Code1;
94 USHORT Code2;
95 UCHAR Code3;
96 UCHAR Code4;
97 };
98 ULONGLONG AgregateCode;
99 };
100 };
101
102 typedef struct _HEAP_FREE_ENTRY
103 {
104 struct _HEAP_COMMON_ENTRY;
105 LIST_ENTRY FreeList;
106 } HEAP_FREE_ENTRY, *PHEAP_FREE_ENTRY;
107
108 typedef struct _HEAP_ENTRY
109 {
110 struct _HEAP_COMMON_ENTRY;
111 } HEAP_ENTRY, *PHEAP_ENTRY;
112
113 #ifdef _WIN64
114 C_ASSERT(sizeof(HEAP_ENTRY) == 16);
115 #else
116 C_ASSERT(sizeof(HEAP_ENTRY) == 8);
117 #endif
118 C_ASSERT((1 << HEAP_ENTRY_SHIFT) == sizeof(HEAP_ENTRY));
119
120 typedef struct _HEAP_TAG_ENTRY
121 {
122 ULONG Allocs;
123 ULONG Frees;
124 ULONG Size;
125 USHORT TagIndex;
126 USHORT CreatorBackTraceIndex;
127 WCHAR TagName[24];
128 } HEAP_TAG_ENTRY, *PHEAP_TAG_ENTRY;
129
130 typedef struct _HEAP_PSEUDO_TAG_ENTRY
131 {
132 ULONG Allocs;
133 ULONG Frees;
134 ULONG Size;
135 } HEAP_PSEUDO_TAG_ENTRY, *PHEAP_PSEUDO_TAG_ENTRY;
136
137 typedef struct _HEAP_COUNTERS
138 {
139 ULONG TotalMemoryReserved;
140 ULONG TotalMemoryCommitted;
141 ULONG TotalMemoryLargeUCR;
142 ULONG TotalSizeInVirtualBlocks;
143 ULONG TotalSegments;
144 ULONG TotalUCRs;
145 ULONG CommittOps;
146 ULONG DeCommitOps;
147 ULONG LockAcquires;
148 ULONG LockCollisions;
149 ULONG CommitRate;
150 ULONG DecommittRate;
151 ULONG CommitFailures;
152 ULONG InBlockCommitFailures;
153 ULONG CompactHeapCalls;
154 ULONG CompactedUCRs;
155 ULONG InBlockDeccommits;
156 ULONG InBlockDeccomitSize;
157 } HEAP_COUNTERS, *PHEAP_COUNTERS;
158
159 typedef struct _HEAP_TUNING_PARAMETERS
160 {
161 ULONG CommittThresholdShift;
162 ULONG MaxPreCommittThreshold;
163 } HEAP_TUNING_PARAMETERS, *PHEAP_TUNING_PARAMETERS;
164
165 typedef struct _HEAP
166 {
167 HEAP_ENTRY Entry;
168 ULONG SegmentSignature;
169 ULONG SegmentFlags;
170 LIST_ENTRY SegmentListEntry;
171 struct _HEAP *Heap;
172 PVOID BaseAddress;
173 ULONG NumberOfPages;
174 PHEAP_ENTRY FirstEntry;
175 PHEAP_ENTRY LastValidEntry;
176 ULONG NumberOfUnCommittedPages;
177 ULONG NumberOfUnCommittedRanges;
178 USHORT SegmentAllocatorBackTraceIndex;
179 USHORT Reserved;
180 LIST_ENTRY UCRSegmentList;
181
182 ULONG Flags;
183 ULONG ForceFlags;
184 ULONG CompatibilityFlags;
185 ULONG EncodeFlagMask;
186 HEAP_ENTRY Encoding;
187 ULONG PointerKey;
188 ULONG Interceptor;
189 ULONG VirtualMemoryThreshold;
190 ULONG Signature;
191 ULONG SegmentReserve;
192 ULONG SegmentCommit;
193 ULONG DeCommitFreeBlockThreshold;
194 ULONG DeCommitTotalFreeThreshold;
195 ULONG TotalFreeSize;
196 ULONG MaximumAllocationSize;
197 USHORT ProcessHeapsListIndex;
198 USHORT HeaderValidateLength;
199 PVOID HeaderValidateCopy;
200 USHORT NextAvailableTagIndex;
201 USHORT MaximumTagIndex;
202 PHEAP_TAG_ENTRY TagEntries;
203 LIST_ENTRY UCRList;
204 LIST_ENTRY UCRSegments; // FIXME: non-Vista
205 ULONG AlignRound;
206 ULONG AlignMask;
207 LIST_ENTRY VirtualAllocdBlocks;
208 LIST_ENTRY SegmentList;
209 struct _HEAP_SEGMENT *Segments[HEAP_SEGMENTS]; //FIXME: non-Vista
210 USHORT AllocatorBackTraceIndex;
211 ULONG NonDedicatedListLength;
212 PVOID BlocksIndex;
213 PVOID UCRIndex;
214 PHEAP_PSEUDO_TAG_ENTRY PseudoTagEntries;
215 LIST_ENTRY FreeLists[HEAP_FREELISTS]; //FIXME: non-Vista
216 union
217 {
218 ULONG FreeListsInUseUlong[HEAP_FREELISTS / (sizeof(ULONG) * 8)]; //FIXME: non-Vista
219 UCHAR FreeListsInUseBytes[HEAP_FREELISTS / (sizeof(UCHAR) * 8)]; //FIXME: non-Vista
220 } u;
221 PHEAP_LOCK LockVariable;
222 PRTL_HEAP_COMMIT_ROUTINE CommitRoutine;
223 PVOID FrontEndHeap;
224 USHORT FrontHeapLockCount;
225 UCHAR FrontEndHeapType;
226 HEAP_COUNTERS Counters;
227 HEAP_TUNING_PARAMETERS TuningParameters;
228 } HEAP, *PHEAP;
229
230 typedef struct _HEAP_SEGMENT
231 {
232 HEAP_ENTRY Entry;
233 ULONG SegmentSignature;
234 ULONG SegmentFlags;
235 LIST_ENTRY SegmentListEntry;
236 PHEAP Heap;
237 PVOID BaseAddress;
238 ULONG NumberOfPages;
239 PHEAP_ENTRY FirstEntry;
240 PHEAP_ENTRY LastValidEntry;
241 ULONG NumberOfUnCommittedPages;
242 ULONG NumberOfUnCommittedRanges;
243 USHORT SegmentAllocatorBackTraceIndex;
244 USHORT Reserved;
245 LIST_ENTRY UCRSegmentList;
246 PHEAP_ENTRY LastEntryInSegment; //FIXME: non-Vista
247 } HEAP_SEGMENT, *PHEAP_SEGMENT;
248
249 typedef struct _HEAP_UCR_DESCRIPTOR
250 {
251 LIST_ENTRY ListEntry;
252 LIST_ENTRY SegmentEntry;
253 PVOID Address;
254 ULONG Size;
255 } HEAP_UCR_DESCRIPTOR, *PHEAP_UCR_DESCRIPTOR;
256
257 typedef struct _HEAP_UCR_SEGMENT
258 {
259 LIST_ENTRY ListEntry;
260 SIZE_T ReservedSize;
261 SIZE_T CommittedSize;
262 } HEAP_UCR_SEGMENT, *PHEAP_UCR_SEGMENT;
263
264 typedef struct _HEAP_ENTRY_EXTRA
265 {
266 union
267 {
268 struct
269 {
270 USHORT AllocatorBackTraceIndex;
271 USHORT TagIndex;
272 ULONG_PTR Settable;
273 };
274 UINT64 ZeroInit;
275 };
276 } HEAP_ENTRY_EXTRA, *PHEAP_ENTRY_EXTRA;
277
278 typedef HEAP_ENTRY_EXTRA HEAP_FREE_ENTRY_EXTRA, *PHEAP_FREE_ENTRY_EXTRA;
279
280 typedef struct _HEAP_VIRTUAL_ALLOC_ENTRY
281 {
282 LIST_ENTRY Entry;
283 HEAP_ENTRY_EXTRA ExtraStuff;
284 ULONG CommitSize;
285 ULONG ReserveSize;
286 HEAP_ENTRY BusyBlock;
287 } HEAP_VIRTUAL_ALLOC_ENTRY, *PHEAP_VIRTUAL_ALLOC_ENTRY;
288
289 /* Global variables */
290 extern HEAP_LOCK RtlpProcessHeapsListLock;
291 extern BOOLEAN RtlpPageHeapEnabled;
292
293 /* Functions declarations */
294
295 /* heap.c */
296 PHEAP_FREE_ENTRY NTAPI
297 RtlpCoalesceFreeBlocks (PHEAP Heap,
298 PHEAP_FREE_ENTRY FreeEntry,
299 PSIZE_T FreeSize,
300 BOOLEAN Remove);
301
302 PHEAP_ENTRY_EXTRA NTAPI
303 RtlpGetExtraStuffPointer(PHEAP_ENTRY HeapEntry);
304
305 /* heapdbg.c */
306 HANDLE NTAPI
307 RtlpPageHeapCreate(ULONG Flags,
308 PVOID Addr,
309 SIZE_T TotalSize,
310 SIZE_T CommitSize,
311 PVOID Lock,
312 PRTL_HEAP_PARAMETERS Parameters);
313
314 #endif