8038ed8642e1d5068161dafa992e25c60d5e14d5
[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 /* A handy inline to distinguis normal heap, special "debug heap" and special "page heap" */
58 FORCEINLINE BOOLEAN
59 RtlpHeapIsSpecial(ULONG Flags)
60 {
61 if (Flags & HEAP_SKIP_VALIDATION_CHECKS) return FALSE;
62
63 if (Flags & (HEAP_FLAG_PAGE_ALLOCS |
64 HEAP_VALIDATE_ALL_ENABLED |
65 HEAP_VALIDATE_PARAMETERS_ENABLED |
66 HEAP_CAPTURE_STACK_BACKTRACES |
67 HEAP_CREATE_ENABLE_TRACING))
68 {
69 /* This is a special heap */
70 return TRUE;
71 }
72
73 /* No need for a special treatment */
74 return FALSE;
75 }
76
77 /* Heap structures */
78 struct _HEAP_COMMON_ENTRY
79 {
80 union
81 {
82 struct
83 {
84 USHORT Size;
85 UCHAR Flags;
86 UCHAR SmallTagIndex;
87 };
88 struct
89 {
90 PVOID SubSegmentCode;
91 USHORT PreviousSize;
92 union
93 {
94 UCHAR SegmentOffset;
95 UCHAR LFHFlags;
96 };
97 UCHAR UnusedBytes;
98 };
99 struct
100 {
101 USHORT FunctionIndex;
102 USHORT ContextValue;
103 };
104 struct
105 {
106 ULONG InterceptorValue;
107 USHORT UnusedBytesLength;
108 UCHAR EntryOffset;
109 UCHAR ExtendedBlockSignature;
110 };
111 struct
112 {
113 ULONG Code1;
114 USHORT Code2;
115 UCHAR Code3;
116 UCHAR Code4;
117 };
118 ULONGLONG AgregateCode;
119 };
120 };
121
122 typedef struct _HEAP_FREE_ENTRY
123 {
124 struct _HEAP_COMMON_ENTRY;
125 LIST_ENTRY FreeList;
126 } HEAP_FREE_ENTRY, *PHEAP_FREE_ENTRY;
127
128 typedef struct _HEAP_ENTRY
129 {
130 struct _HEAP_COMMON_ENTRY;
131 } HEAP_ENTRY, *PHEAP_ENTRY;
132
133 #ifdef _WIN64
134 C_ASSERT(sizeof(HEAP_ENTRY) == 16);
135 #else
136 C_ASSERT(sizeof(HEAP_ENTRY) == 8);
137 #endif
138 C_ASSERT((1 << HEAP_ENTRY_SHIFT) == sizeof(HEAP_ENTRY));
139
140 typedef struct _HEAP_TAG_ENTRY
141 {
142 ULONG Allocs;
143 ULONG Frees;
144 ULONG Size;
145 USHORT TagIndex;
146 USHORT CreatorBackTraceIndex;
147 WCHAR TagName[24];
148 } HEAP_TAG_ENTRY, *PHEAP_TAG_ENTRY;
149
150 typedef struct _HEAP_PSEUDO_TAG_ENTRY
151 {
152 ULONG Allocs;
153 ULONG Frees;
154 ULONG Size;
155 } HEAP_PSEUDO_TAG_ENTRY, *PHEAP_PSEUDO_TAG_ENTRY;
156
157 typedef struct _HEAP_COUNTERS
158 {
159 ULONG TotalMemoryReserved;
160 ULONG TotalMemoryCommitted;
161 ULONG TotalMemoryLargeUCR;
162 ULONG TotalSizeInVirtualBlocks;
163 ULONG TotalSegments;
164 ULONG TotalUCRs;
165 ULONG CommittOps;
166 ULONG DeCommitOps;
167 ULONG LockAcquires;
168 ULONG LockCollisions;
169 ULONG CommitRate;
170 ULONG DecommittRate;
171 ULONG CommitFailures;
172 ULONG InBlockCommitFailures;
173 ULONG CompactHeapCalls;
174 ULONG CompactedUCRs;
175 ULONG InBlockDeccommits;
176 ULONG InBlockDeccomitSize;
177 } HEAP_COUNTERS, *PHEAP_COUNTERS;
178
179 typedef struct _HEAP_TUNING_PARAMETERS
180 {
181 ULONG CommittThresholdShift;
182 ULONG MaxPreCommittThreshold;
183 } HEAP_TUNING_PARAMETERS, *PHEAP_TUNING_PARAMETERS;
184
185 typedef struct _HEAP
186 {
187 HEAP_ENTRY Entry;
188 ULONG SegmentSignature;
189 ULONG SegmentFlags;
190 LIST_ENTRY SegmentListEntry;
191 struct _HEAP *Heap;
192 PVOID BaseAddress;
193 ULONG NumberOfPages;
194 PHEAP_ENTRY FirstEntry;
195 PHEAP_ENTRY LastValidEntry;
196 ULONG NumberOfUnCommittedPages;
197 ULONG NumberOfUnCommittedRanges;
198 USHORT SegmentAllocatorBackTraceIndex;
199 USHORT Reserved;
200 LIST_ENTRY UCRSegmentList;
201
202 ULONG Flags;
203 ULONG ForceFlags;
204 ULONG CompatibilityFlags;
205 ULONG EncodeFlagMask;
206 HEAP_ENTRY Encoding;
207 ULONG PointerKey;
208 ULONG Interceptor;
209 ULONG VirtualMemoryThreshold;
210 ULONG Signature;
211 ULONG SegmentReserve;
212 ULONG SegmentCommit;
213 ULONG DeCommitFreeBlockThreshold;
214 ULONG DeCommitTotalFreeThreshold;
215 ULONG TotalFreeSize;
216 ULONG MaximumAllocationSize;
217 USHORT ProcessHeapsListIndex;
218 USHORT HeaderValidateLength;
219 PVOID HeaderValidateCopy;
220 USHORT NextAvailableTagIndex;
221 USHORT MaximumTagIndex;
222 PHEAP_TAG_ENTRY TagEntries;
223 LIST_ENTRY UCRList;
224 LIST_ENTRY UCRSegments; // FIXME: non-Vista
225 ULONG AlignRound;
226 ULONG AlignMask;
227 LIST_ENTRY VirtualAllocdBlocks;
228 LIST_ENTRY SegmentList;
229 struct _HEAP_SEGMENT *Segments[HEAP_SEGMENTS]; //FIXME: non-Vista
230 USHORT AllocatorBackTraceIndex;
231 ULONG NonDedicatedListLength;
232 PVOID BlocksIndex;
233 PVOID UCRIndex;
234 PHEAP_PSEUDO_TAG_ENTRY PseudoTagEntries;
235 LIST_ENTRY FreeLists[HEAP_FREELISTS]; //FIXME: non-Vista
236 union
237 {
238 ULONG FreeListsInUseUlong[HEAP_FREELISTS / (sizeof(ULONG) * 8)]; //FIXME: non-Vista
239 UCHAR FreeListsInUseBytes[HEAP_FREELISTS / (sizeof(UCHAR) * 8)]; //FIXME: non-Vista
240 } u;
241 PHEAP_LOCK LockVariable;
242 PRTL_HEAP_COMMIT_ROUTINE CommitRoutine;
243 PVOID FrontEndHeap;
244 USHORT FrontHeapLockCount;
245 UCHAR FrontEndHeapType;
246 HEAP_COUNTERS Counters;
247 HEAP_TUNING_PARAMETERS TuningParameters;
248 } HEAP, *PHEAP;
249
250 typedef struct _HEAP_SEGMENT
251 {
252 HEAP_ENTRY Entry;
253 ULONG SegmentSignature;
254 ULONG SegmentFlags;
255 LIST_ENTRY SegmentListEntry;
256 PHEAP Heap;
257 PVOID BaseAddress;
258 ULONG NumberOfPages;
259 PHEAP_ENTRY FirstEntry;
260 PHEAP_ENTRY LastValidEntry;
261 ULONG NumberOfUnCommittedPages;
262 ULONG NumberOfUnCommittedRanges;
263 USHORT SegmentAllocatorBackTraceIndex;
264 USHORT Reserved;
265 LIST_ENTRY UCRSegmentList;
266 PHEAP_ENTRY LastEntryInSegment; //FIXME: non-Vista
267 } HEAP_SEGMENT, *PHEAP_SEGMENT;
268
269 typedef struct _HEAP_UCR_DESCRIPTOR
270 {
271 LIST_ENTRY ListEntry;
272 LIST_ENTRY SegmentEntry;
273 PVOID Address;
274 ULONG Size;
275 } HEAP_UCR_DESCRIPTOR, *PHEAP_UCR_DESCRIPTOR;
276
277 typedef struct _HEAP_UCR_SEGMENT
278 {
279 LIST_ENTRY ListEntry;
280 SIZE_T ReservedSize;
281 SIZE_T CommittedSize;
282 } HEAP_UCR_SEGMENT, *PHEAP_UCR_SEGMENT;
283
284 typedef struct _HEAP_ENTRY_EXTRA
285 {
286 union
287 {
288 struct
289 {
290 USHORT AllocatorBackTraceIndex;
291 USHORT TagIndex;
292 ULONG_PTR Settable;
293 };
294 UINT64 ZeroInit;
295 };
296 } HEAP_ENTRY_EXTRA, *PHEAP_ENTRY_EXTRA;
297
298 typedef HEAP_ENTRY_EXTRA HEAP_FREE_ENTRY_EXTRA, *PHEAP_FREE_ENTRY_EXTRA;
299
300 typedef struct _HEAP_VIRTUAL_ALLOC_ENTRY
301 {
302 LIST_ENTRY Entry;
303 HEAP_ENTRY_EXTRA ExtraStuff;
304 ULONG CommitSize;
305 ULONG ReserveSize;
306 HEAP_ENTRY BusyBlock;
307 } HEAP_VIRTUAL_ALLOC_ENTRY, *PHEAP_VIRTUAL_ALLOC_ENTRY;
308
309 /* Global variables */
310 extern HEAP_LOCK RtlpProcessHeapsListLock;
311 extern BOOLEAN RtlpPageHeapEnabled;
312
313 /* Functions declarations */
314
315 /* heap.c */
316 PHEAP_FREE_ENTRY NTAPI
317 RtlpCoalesceFreeBlocks (PHEAP Heap,
318 PHEAP_FREE_ENTRY FreeEntry,
319 PSIZE_T FreeSize,
320 BOOLEAN Remove);
321
322 PHEAP_ENTRY_EXTRA NTAPI
323 RtlpGetExtraStuffPointer(PHEAP_ENTRY HeapEntry);
324
325 BOOLEAN NTAPI
326 RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation);
327
328 BOOLEAN NTAPI
329 RtlpValidateHeapEntry(PHEAP Heap, PHEAP_ENTRY HeapEntry);
330
331 BOOLEAN NTAPI
332 RtlpValidateHeapHeaders(PHEAP Heap, BOOLEAN Recalculate);
333
334 /* heapdbg.c */
335 HANDLE NTAPI
336 RtlDebugCreateHeap(ULONG Flags,
337 PVOID Addr,
338 SIZE_T TotalSize,
339 SIZE_T CommitSize,
340 PVOID Lock,
341 PRTL_HEAP_PARAMETERS Parameters);
342
343 BOOLEAN NTAPI
344 RtlDebugDestroyHeap(HANDLE HeapPtr);
345
346 PVOID NTAPI
347 RtlDebugAllocateHeap(PVOID HeapPtr,
348 ULONG Flags,
349 SIZE_T Size);
350
351 PVOID NTAPI
352 RtlDebugReAllocateHeap(HANDLE HeapPtr,
353 ULONG Flags,
354 PVOID Ptr,
355 SIZE_T Size);
356
357 BOOLEAN NTAPI
358 RtlDebugFreeHeap(HANDLE HeapPtr,
359 ULONG Flags,
360 PVOID Ptr);
361
362 BOOLEAN NTAPI
363 RtlDebugGetUserInfoHeap(PVOID HeapHandle,
364 ULONG Flags,
365 PVOID BaseAddress,
366 PVOID *UserValue,
367 PULONG UserFlags);
368
369 BOOLEAN NTAPI
370 RtlDebugSetUserValueHeap(PVOID HeapHandle,
371 ULONG Flags,
372 PVOID BaseAddress,
373 PVOID UserValue);
374
375 BOOLEAN
376 NTAPI
377 RtlDebugSetUserFlagsHeap(PVOID HeapHandle,
378 ULONG Flags,
379 PVOID BaseAddress,
380 ULONG UserFlagsReset,
381 ULONG UserFlagsSet);
382
383 SIZE_T NTAPI
384 RtlDebugSizeHeap(HANDLE HeapPtr,
385 ULONG Flags,
386 PVOID Ptr);
387
388 /* heappage.c */
389
390 HANDLE NTAPI
391 RtlpPageHeapCreate(ULONG Flags,
392 PVOID Addr,
393 SIZE_T TotalSize,
394 SIZE_T CommitSize,
395 PVOID Lock,
396 PRTL_HEAP_PARAMETERS Parameters);
397
398 PVOID NTAPI
399 RtlpPageHeapDestroy(HANDLE HeapPtr);
400
401 PVOID NTAPI
402 RtlpPageHeapAllocate(IN PVOID HeapPtr,
403 IN ULONG Flags,
404 IN SIZE_T Size);
405
406 BOOLEAN NTAPI
407 RtlpPageHeapFree(HANDLE HeapPtr,
408 ULONG Flags,
409 PVOID Ptr);
410
411 PVOID NTAPI
412 RtlpPageHeapReAllocate(HANDLE HeapPtr,
413 ULONG Flags,
414 PVOID Ptr,
415 SIZE_T Size);
416
417 BOOLEAN NTAPI
418 RtlpPageHeapGetUserInfo(PVOID HeapHandle,
419 ULONG Flags,
420 PVOID BaseAddress,
421 PVOID *UserValue,
422 PULONG UserFlags);
423
424 BOOLEAN NTAPI
425 RtlpPageHeapSetUserValue(PVOID HeapHandle,
426 ULONG Flags,
427 PVOID BaseAddress,
428 PVOID UserValue);
429
430 BOOLEAN
431 NTAPI
432 RtlpPageHeapSetUserFlags(PVOID HeapHandle,
433 ULONG Flags,
434 PVOID BaseAddress,
435 ULONG UserFlagsReset,
436 ULONG UserFlagsSet);
437
438 BOOLEAN
439 NTAPI
440 RtlpDebugPageHeapValidate(PVOID HeapPtr,
441 ULONG Flags,
442 PVOID Block);
443
444 SIZE_T NTAPI
445 RtlpPageHeapSize(HANDLE HeapPtr,
446 ULONG Flags,
447 PVOID Ptr);
448
449 #endif