xref: /reactos/sdk/lib/rtl/heap.h (revision 53221834)
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 HANDLE NTAPI
343 RtlDebugCreateHeap(ULONG Flags,
344                    PVOID Addr,
345                    SIZE_T TotalSize,
346                    SIZE_T CommitSize,
347                    PVOID Lock,
348                    PRTL_HEAP_PARAMETERS Parameters);
349 
350 BOOLEAN NTAPI
351 RtlDebugDestroyHeap(HANDLE HeapPtr);
352 
353 PVOID NTAPI
354 RtlDebugAllocateHeap(PVOID HeapPtr,
355                      ULONG Flags,
356                      SIZE_T Size);
357 
358 PVOID NTAPI
359 RtlDebugReAllocateHeap(HANDLE HeapPtr,
360                        ULONG Flags,
361                        PVOID Ptr,
362                        SIZE_T Size);
363 
364 BOOLEAN NTAPI
365 RtlDebugFreeHeap(HANDLE HeapPtr,
366                  ULONG Flags,
367                  PVOID Ptr);
368 
369 BOOLEAN NTAPI
370 RtlDebugGetUserInfoHeap(PVOID HeapHandle,
371                         ULONG Flags,
372                         PVOID BaseAddress,
373                         PVOID *UserValue,
374                         PULONG UserFlags);
375 
376 BOOLEAN NTAPI
377 RtlDebugSetUserValueHeap(PVOID HeapHandle,
378                          ULONG Flags,
379                          PVOID BaseAddress,
380                          PVOID UserValue);
381 
382 BOOLEAN
383 NTAPI
384 RtlDebugSetUserFlagsHeap(PVOID HeapHandle,
385                          ULONG Flags,
386                          PVOID BaseAddress,
387                          ULONG UserFlagsReset,
388                          ULONG UserFlagsSet);
389 
390 SIZE_T NTAPI
391 RtlDebugSizeHeap(HANDLE HeapPtr,
392                  ULONG Flags,
393                  PVOID Ptr);
394 
395 /* heappage.c */
396 
397 HANDLE NTAPI
398 RtlpPageHeapCreate(ULONG Flags,
399                    PVOID Addr,
400                    SIZE_T TotalSize,
401                    SIZE_T CommitSize,
402                    PVOID Lock,
403                    PRTL_HEAP_PARAMETERS Parameters);
404 
405 PVOID NTAPI
406 RtlpPageHeapDestroy(HANDLE HeapPtr);
407 
408 PVOID NTAPI
409 RtlpPageHeapAllocate(IN PVOID HeapPtr,
410                      IN ULONG Flags,
411                      IN SIZE_T Size);
412 
413 BOOLEAN NTAPI
414 RtlpPageHeapFree(HANDLE HeapPtr,
415                  ULONG Flags,
416                  PVOID Ptr);
417 
418 PVOID NTAPI
419 RtlpPageHeapReAllocate(HANDLE HeapPtr,
420                        ULONG Flags,
421                        PVOID Ptr,
422                        SIZE_T Size);
423 
424 BOOLEAN NTAPI
425 RtlpPageHeapLock(HANDLE HeapPtr);
426 
427 BOOLEAN NTAPI
428 RtlpPageHeapUnlock(HANDLE HeapPtr);
429 
430 BOOLEAN NTAPI
431 RtlpPageHeapGetUserInfo(PVOID HeapHandle,
432                         ULONG Flags,
433                         PVOID BaseAddress,
434                         PVOID *UserValue,
435                         PULONG UserFlags);
436 
437 BOOLEAN NTAPI
438 RtlpPageHeapSetUserValue(PVOID HeapHandle,
439                          ULONG Flags,
440                          PVOID BaseAddress,
441                          PVOID UserValue);
442 
443 BOOLEAN
444 NTAPI
445 RtlpPageHeapSetUserFlags(PVOID HeapHandle,
446                          ULONG Flags,
447                          PVOID BaseAddress,
448                          ULONG UserFlagsReset,
449                          ULONG UserFlagsSet);
450 
451 BOOLEAN
452 NTAPI
453 RtlpDebugPageHeapValidate(PVOID HeapPtr,
454                           ULONG Flags,
455                           PVOID Block);
456 
457 SIZE_T NTAPI
458 RtlpPageHeapSize(HANDLE HeapPtr,
459                  ULONG Flags,
460                  PVOID Ptr);
461 
462 VOID
463 NTAPI
464 RtlpAddHeapToProcessList(PHEAP Heap);
465 
466 VOID
467 NTAPI
468 RtlpRemoveHeapFromProcessList(PHEAP Heap);
469 
470 VOID
471 NTAPI
472 RtlInitializeHeapManager(VOID);
473 
474 #endif
475