xref: /reactos/sdk/lib/rtl/heap.h (revision 9cfd8dd9)
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_SEGMENTS 64
16 
17 #define HEAP_ENTRY_SIZE ((ULONG)sizeof(HEAP_ENTRY))
18 #ifdef _WIN64
19 #define HEAP_ENTRY_SHIFT 4
20 #else
21 #define HEAP_ENTRY_SHIFT 3
22 #endif
23 #define HEAP_MAX_BLOCK_SIZE ((0x80000 - PAGE_SIZE) >> HEAP_ENTRY_SHIFT)
24 
25 #define ARENA_INUSE_FILLER     0xBAADF00D
26 #define ARENA_FREE_FILLER      0xFEEEFEEE
27 #define HEAP_TAIL_FILL         0xab
28 
29 // from ntifs.h, should go to another header!
30 #define HEAP_GLOBAL_TAG                 0x0800
31 #define HEAP_PSEUDO_TAG_FLAG            0x8000
32 #define HEAP_TAG_MASK                  (HEAP_MAXIMUM_TAG << HEAP_TAG_SHIFT)
33 #define HEAP_TAGS_MASK                 (HEAP_TAG_MASK ^ (0xFF << HEAP_TAG_SHIFT))
34 
35 #define HEAP_EXTRA_FLAGS_MASK (HEAP_CAPTURE_STACK_BACKTRACES | \
36                                HEAP_SETTABLE_USER_VALUE | \
37                                HEAP_TAGS_MASK)
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 #ifdef _M_AMD64
81     PVOID PreviousBlockPrivateData;
82 #endif
83     union
84     {
85         struct
86         {
87             USHORT Size;
88             UCHAR Flags;
89             UCHAR SmallTagIndex;
90         };
91         struct
92         {
93 #ifndef _M_AMD64
94             PVOID SubSegmentCode;
95 #else
96             ULONG SubSegmentCodeDummy;
97 #endif
98             USHORT PreviousSize;
99             union
100             {
101                 UCHAR SegmentOffset;
102                 UCHAR LFHFlags;
103             };
104             UCHAR UnusedBytes;
105         };
106         struct
107         {
108             USHORT FunctionIndex;
109             USHORT ContextValue;
110         };
111         struct
112         {
113             ULONG InterceptorValue;
114             USHORT UnusedBytesLength;
115             UCHAR EntryOffset;
116             UCHAR ExtendedBlockSignature;
117         };
118         struct
119         {
120             ULONG Code1;
121             USHORT Code2;
122             UCHAR Code3;
123             UCHAR Code4;
124         };
125         ULONGLONG AgregateCode;
126     };
127 };
128 
129 typedef struct _HEAP_FREE_ENTRY
130 {
131     struct _HEAP_COMMON_ENTRY;
132     LIST_ENTRY FreeList;
133 }  HEAP_FREE_ENTRY, *PHEAP_FREE_ENTRY;
134 
135 typedef struct _HEAP_ENTRY
136 {
137     struct _HEAP_COMMON_ENTRY;
138 }  HEAP_ENTRY, *PHEAP_ENTRY;
139 
140 #ifdef _WIN64
141 C_ASSERT(sizeof(HEAP_ENTRY) == 16);
142 #else
143 C_ASSERT(sizeof(HEAP_ENTRY) == 8);
144 #endif
145 C_ASSERT((1 << HEAP_ENTRY_SHIFT) == sizeof(HEAP_ENTRY));
146 C_ASSERT((2 << HEAP_ENTRY_SHIFT) == sizeof(HEAP_FREE_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 #define HEAP_SEGMENT_MEMBERS                \
207     HEAP_ENTRY Entry;                       \
208     ULONG SegmentSignature;                 \
209     ULONG SegmentFlags;                     \
210     LIST_ENTRY SegmentListEntry;            \
211     struct _HEAP *Heap;                     \
212     PVOID BaseAddress;                      \
213     ULONG NumberOfPages;                    \
214     PHEAP_ENTRY FirstEntry;                 \
215     PHEAP_ENTRY LastValidEntry;             \
216     ULONG NumberOfUnCommittedPages;         \
217     ULONG NumberOfUnCommittedRanges;        \
218     USHORT SegmentAllocatorBackTraceIndex;  \
219     USHORT Reserved;                        \
220     LIST_ENTRY UCRSegmentList
221 
222 typedef struct _HEAP
223 {
224     HEAP_SEGMENT_MEMBERS;
225 
226     ULONG Flags;
227     ULONG ForceFlags;
228     ULONG CompatibilityFlags;
229     ULONG EncodeFlagMask;
230     HEAP_ENTRY Encoding;
231     ULONG_PTR PointerKey;
232     ULONG Interceptor;
233     ULONG VirtualMemoryThreshold;
234     ULONG Signature;
235     SIZE_T SegmentReserve;
236     SIZE_T SegmentCommit;
237     SIZE_T DeCommitFreeBlockThreshold;
238     SIZE_T DeCommitTotalFreeThreshold;
239     SIZE_T TotalFreeSize;
240     SIZE_T MaximumAllocationSize;
241     USHORT ProcessHeapsListIndex;
242     USHORT HeaderValidateLength;
243     PVOID HeaderValidateCopy;
244     USHORT NextAvailableTagIndex;
245     USHORT MaximumTagIndex;
246     PHEAP_TAG_ENTRY TagEntries;
247     LIST_ENTRY UCRList;
248     LIST_ENTRY UCRSegments; // FIXME: non-Vista
249     ULONG_PTR AlignRound;
250     ULONG_PTR AlignMask;
251     LIST_ENTRY VirtualAllocdBlocks;
252     LIST_ENTRY SegmentList;
253     struct _HEAP_SEGMENT *Segments[HEAP_SEGMENTS]; //FIXME: non-Vista
254     USHORT AllocatorBackTraceIndex;
255     ULONG NonDedicatedListLength;
256     PVOID BlocksIndex; // HEAP_LIST_LOOKUP
257     PVOID UCRIndex;
258     PHEAP_PSEUDO_TAG_ENTRY PseudoTagEntries;
259     LIST_ENTRY FreeLists;
260     PHEAP_LOCK LockVariable;
261     PRTL_HEAP_COMMIT_ROUTINE CommitRoutine;
262     PVOID FrontEndHeap;
263     USHORT FrontHeapLockCount;
264     UCHAR FrontEndHeapType;
265     HEAP_COUNTERS Counters;
266     HEAP_TUNING_PARAMETERS TuningParameters;
267     RTL_BITMAP FreeHintBitmap;  // FIXME: non-Vista
268     PLIST_ENTRY FreeHints[ANYSIZE_ARRAY]; // FIXME: non-Vista
269 } HEAP, *PHEAP;
270 
271 typedef struct _HEAP_SEGMENT
272 {
273     HEAP_SEGMENT_MEMBERS;
274 } HEAP_SEGMENT, *PHEAP_SEGMENT;
275 
276 typedef struct _HEAP_UCR_DESCRIPTOR
277 {
278     LIST_ENTRY ListEntry;
279     LIST_ENTRY SegmentEntry;
280     PVOID Address;
281     SIZE_T Size;
282 } HEAP_UCR_DESCRIPTOR, *PHEAP_UCR_DESCRIPTOR;
283 
284 typedef struct _HEAP_UCR_SEGMENT
285 {
286     LIST_ENTRY ListEntry;
287     SIZE_T ReservedSize;
288     SIZE_T CommittedSize;
289 } HEAP_UCR_SEGMENT, *PHEAP_UCR_SEGMENT;
290 
291 typedef struct _HEAP_ENTRY_EXTRA
292 {
293      union
294      {
295           struct
296           {
297                USHORT AllocatorBackTraceIndex;
298                USHORT TagIndex;
299                ULONG_PTR Settable;
300           };
301           UINT64 ZeroInit;
302      };
303 } HEAP_ENTRY_EXTRA, *PHEAP_ENTRY_EXTRA;
304 
305 typedef HEAP_ENTRY_EXTRA HEAP_FREE_ENTRY_EXTRA, *PHEAP_FREE_ENTRY_EXTRA;
306 
307 typedef struct _HEAP_VIRTUAL_ALLOC_ENTRY
308 {
309     LIST_ENTRY Entry;
310     HEAP_ENTRY_EXTRA ExtraStuff;
311     SIZE_T CommitSize;
312     SIZE_T ReserveSize;
313     HEAP_ENTRY BusyBlock;
314 } HEAP_VIRTUAL_ALLOC_ENTRY, *PHEAP_VIRTUAL_ALLOC_ENTRY;
315 
316 /* Global variables */
317 extern RTL_CRITICAL_SECTION RtlpProcessHeapsListLock;
318 extern BOOLEAN RtlpPageHeapEnabled;
319 
320 /* Functions declarations */
321 
322 /* heap.c */
323 PHEAP_FREE_ENTRY NTAPI
324 RtlpCoalesceFreeBlocks (PHEAP Heap,
325                         PHEAP_FREE_ENTRY FreeEntry,
326                         PSIZE_T FreeSize,
327                         BOOLEAN Remove);
328 
329 PHEAP_ENTRY_EXTRA NTAPI
330 RtlpGetExtraStuffPointer(PHEAP_ENTRY HeapEntry);
331 
332 BOOLEAN NTAPI
333 RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation);
334 
335 BOOLEAN NTAPI
336 RtlpValidateHeapEntry(PHEAP Heap, PHEAP_ENTRY HeapEntry);
337 
338 BOOLEAN NTAPI
339 RtlpValidateHeapHeaders(PHEAP Heap, BOOLEAN Recalculate);
340 
341 /* heapdbg.c */
342 NTSYSAPI
343 HANDLE NTAPI
344 RtlDebugCreateHeap(ULONG Flags,
345                    PVOID Addr,
346                    SIZE_T TotalSize,
347                    SIZE_T CommitSize,
348                    PVOID Lock,
349                    PRTL_HEAP_PARAMETERS Parameters);
350 
351 BOOLEAN NTAPI
352 RtlDebugDestroyHeap(HANDLE HeapPtr);
353 
354 PVOID NTAPI
355 RtlDebugAllocateHeap(PVOID HeapPtr,
356                      ULONG Flags,
357                      SIZE_T Size);
358 
359 PVOID NTAPI
360 RtlDebugReAllocateHeap(HANDLE HeapPtr,
361                        ULONG Flags,
362                        PVOID Ptr,
363                        SIZE_T Size);
364 
365 BOOLEAN NTAPI
366 RtlDebugFreeHeap(HANDLE HeapPtr,
367                  ULONG Flags,
368                  PVOID Ptr);
369 
370 BOOLEAN NTAPI
371 RtlDebugGetUserInfoHeap(PVOID HeapHandle,
372                         ULONG Flags,
373                         PVOID BaseAddress,
374                         PVOID *UserValue,
375                         PULONG UserFlags);
376 
377 BOOLEAN NTAPI
378 RtlDebugSetUserValueHeap(PVOID HeapHandle,
379                          ULONG Flags,
380                          PVOID BaseAddress,
381                          PVOID UserValue);
382 
383 BOOLEAN
384 NTAPI
385 RtlDebugSetUserFlagsHeap(PVOID HeapHandle,
386                          ULONG Flags,
387                          PVOID BaseAddress,
388                          ULONG UserFlagsReset,
389                          ULONG UserFlagsSet);
390 
391 SIZE_T NTAPI
392 RtlDebugSizeHeap(HANDLE HeapPtr,
393                  ULONG Flags,
394                  PVOID Ptr);
395 
396 /* heappage.c */
397 
398 HANDLE NTAPI
399 RtlpPageHeapCreate(ULONG Flags,
400                    PVOID Addr,
401                    SIZE_T TotalSize,
402                    SIZE_T CommitSize,
403                    PVOID Lock,
404                    PRTL_HEAP_PARAMETERS Parameters);
405 
406 PVOID NTAPI
407 RtlpPageHeapDestroy(HANDLE HeapPtr);
408 
409 PVOID NTAPI
410 RtlpPageHeapAllocate(IN PVOID HeapPtr,
411                      IN ULONG Flags,
412                      IN SIZE_T Size);
413 
414 BOOLEAN NTAPI
415 RtlpPageHeapFree(HANDLE HeapPtr,
416                  ULONG Flags,
417                  PVOID Ptr);
418 
419 PVOID NTAPI
420 RtlpPageHeapReAllocate(HANDLE HeapPtr,
421                        ULONG Flags,
422                        PVOID Ptr,
423                        SIZE_T Size);
424 
425 BOOLEAN NTAPI
426 RtlpPageHeapLock(HANDLE HeapPtr);
427 
428 BOOLEAN NTAPI
429 RtlpPageHeapUnlock(HANDLE HeapPtr);
430 
431 BOOLEAN NTAPI
432 RtlpPageHeapGetUserInfo(PVOID HeapHandle,
433                         ULONG Flags,
434                         PVOID BaseAddress,
435                         PVOID *UserValue,
436                         PULONG UserFlags);
437 
438 BOOLEAN NTAPI
439 RtlpPageHeapSetUserValue(PVOID HeapHandle,
440                          ULONG Flags,
441                          PVOID BaseAddress,
442                          PVOID UserValue);
443 
444 BOOLEAN
445 NTAPI
446 RtlpPageHeapSetUserFlags(PVOID HeapHandle,
447                          ULONG Flags,
448                          PVOID BaseAddress,
449                          ULONG UserFlagsReset,
450                          ULONG UserFlagsSet);
451 
452 BOOLEAN
453 NTAPI
454 RtlpDebugPageHeapValidate(PVOID HeapPtr,
455                           ULONG Flags,
456                           PVOID Block);
457 
458 SIZE_T NTAPI
459 RtlpPageHeapSize(HANDLE HeapPtr,
460                  ULONG Flags,
461                  PVOID Ptr);
462 
463 VOID
464 NTAPI
465 RtlpAddHeapToProcessList(PHEAP Heap);
466 
467 VOID
468 NTAPI
469 RtlpRemoveHeapFromProcessList(PHEAP Heap);
470 
471 VOID
472 NTAPI
473 RtlInitializeHeapManager(VOID);
474 
475 #endif
476