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
RtlpHeapIsSpecial(ULONG Flags)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