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