[RTL/HEAP]
[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_LIST_LOOKUP
186 {
187 struct _HEAP_LIST_LOOKUP *ExtendedLookup;
188 ULONG ArraySize;
189 ULONG ExtraItem;
190 ULONG ItemCount;
191 ULONG OutOfRangeItems;
192 ULONG BaseIndex;
193 PLIST_ENTRY ListHead;
194 PULONG ListsInUseUlong;
195 PLIST_ENTRY *ListHints;
196 } HEAP_LIST_LOOKUP, *PHEAP_LIST_LOOKUP;
197
198 typedef struct _HEAP
199 {
200 HEAP_ENTRY Entry;
201 ULONG SegmentSignature;
202 ULONG SegmentFlags;
203 LIST_ENTRY SegmentListEntry;
204 struct _HEAP *Heap;
205 PVOID BaseAddress;
206 ULONG NumberOfPages;
207 PHEAP_ENTRY FirstEntry;
208 PHEAP_ENTRY LastValidEntry;
209 ULONG NumberOfUnCommittedPages;
210 ULONG NumberOfUnCommittedRanges;
211 USHORT SegmentAllocatorBackTraceIndex;
212 USHORT Reserved;
213 LIST_ENTRY UCRSegmentList;
214
215 ULONG Flags;
216 ULONG ForceFlags;
217 ULONG CompatibilityFlags;
218 ULONG EncodeFlagMask;
219 HEAP_ENTRY Encoding;
220 ULONG PointerKey;
221 ULONG Interceptor;
222 ULONG VirtualMemoryThreshold;
223 ULONG Signature;
224 ULONG SegmentReserve;
225 ULONG SegmentCommit;
226 ULONG DeCommitFreeBlockThreshold;
227 ULONG DeCommitTotalFreeThreshold;
228 ULONG TotalFreeSize;
229 ULONG MaximumAllocationSize;
230 USHORT ProcessHeapsListIndex;
231 USHORT HeaderValidateLength;
232 PVOID HeaderValidateCopy;
233 USHORT NextAvailableTagIndex;
234 USHORT MaximumTagIndex;
235 PHEAP_TAG_ENTRY TagEntries;
236 LIST_ENTRY UCRList;
237 LIST_ENTRY UCRSegments; // FIXME: non-Vista
238 ULONG AlignRound;
239 ULONG AlignMask;
240 LIST_ENTRY VirtualAllocdBlocks;
241 LIST_ENTRY SegmentList;
242 struct _HEAP_SEGMENT *Segments[HEAP_SEGMENTS]; //FIXME: non-Vista
243 USHORT AllocatorBackTraceIndex;
244 ULONG NonDedicatedListLength;
245 PVOID BlocksIndex; // HEAP_LIST_LOOKUP
246 PVOID UCRIndex;
247 PHEAP_PSEUDO_TAG_ENTRY PseudoTagEntries;
248 LIST_ENTRY FreeLists[HEAP_FREELISTS]; //FIXME: non-Vista
249 //LIST_ENTRY FreeLists;
250 union
251 {
252 ULONG FreeListsInUseUlong[HEAP_FREELISTS / (sizeof(ULONG) * 8)]; //FIXME: non-Vista
253 UCHAR FreeListsInUseBytes[HEAP_FREELISTS / (sizeof(UCHAR) * 8)]; //FIXME: non-Vista
254 } u;
255 PHEAP_LOCK LockVariable;
256 PRTL_HEAP_COMMIT_ROUTINE CommitRoutine;
257 PVOID FrontEndHeap;
258 USHORT FrontHeapLockCount;
259 UCHAR FrontEndHeapType;
260 HEAP_COUNTERS Counters;
261 HEAP_TUNING_PARAMETERS TuningParameters;
262 } HEAP, *PHEAP;
263
264 typedef struct _HEAP_SEGMENT
265 {
266 HEAP_ENTRY Entry;
267 ULONG SegmentSignature;
268 ULONG SegmentFlags;
269 LIST_ENTRY SegmentListEntry;
270 PHEAP Heap;
271 PVOID BaseAddress;
272 ULONG NumberOfPages;
273 PHEAP_ENTRY FirstEntry;
274 PHEAP_ENTRY LastValidEntry;
275 ULONG NumberOfUnCommittedPages;
276 ULONG NumberOfUnCommittedRanges;
277 USHORT SegmentAllocatorBackTraceIndex;
278 USHORT Reserved;
279 LIST_ENTRY UCRSegmentList;
280 PHEAP_ENTRY LastEntryInSegment; //FIXME: non-Vista
281 } HEAP_SEGMENT, *PHEAP_SEGMENT;
282
283 typedef struct _HEAP_UCR_DESCRIPTOR
284 {
285 LIST_ENTRY ListEntry;
286 LIST_ENTRY SegmentEntry;
287 PVOID Address;
288 ULONG Size;
289 } HEAP_UCR_DESCRIPTOR, *PHEAP_UCR_DESCRIPTOR;
290
291 typedef struct _HEAP_UCR_SEGMENT
292 {
293 LIST_ENTRY ListEntry;
294 SIZE_T ReservedSize;
295 SIZE_T CommittedSize;
296 } HEAP_UCR_SEGMENT, *PHEAP_UCR_SEGMENT;
297
298 typedef struct _HEAP_ENTRY_EXTRA
299 {
300 union
301 {
302 struct
303 {
304 USHORT AllocatorBackTraceIndex;
305 USHORT TagIndex;
306 ULONG_PTR Settable;
307 };
308 UINT64 ZeroInit;
309 };
310 } HEAP_ENTRY_EXTRA, *PHEAP_ENTRY_EXTRA;
311
312 typedef HEAP_ENTRY_EXTRA HEAP_FREE_ENTRY_EXTRA, *PHEAP_FREE_ENTRY_EXTRA;
313
314 typedef struct _HEAP_VIRTUAL_ALLOC_ENTRY
315 {
316 LIST_ENTRY Entry;
317 HEAP_ENTRY_EXTRA ExtraStuff;
318 ULONG CommitSize;
319 ULONG ReserveSize;
320 HEAP_ENTRY BusyBlock;
321 } HEAP_VIRTUAL_ALLOC_ENTRY, *PHEAP_VIRTUAL_ALLOC_ENTRY;
322
323 /* Global variables */
324 extern HEAP_LOCK RtlpProcessHeapsListLock;
325 extern BOOLEAN RtlpPageHeapEnabled;
326
327 /* Functions declarations */
328
329 /* heap.c */
330 PHEAP_FREE_ENTRY NTAPI
331 RtlpCoalesceFreeBlocks (PHEAP Heap,
332 PHEAP_FREE_ENTRY FreeEntry,
333 PSIZE_T FreeSize,
334 BOOLEAN Remove);
335
336 PHEAP_ENTRY_EXTRA NTAPI
337 RtlpGetExtraStuffPointer(PHEAP_ENTRY HeapEntry);
338
339 BOOLEAN NTAPI
340 RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation);
341
342 BOOLEAN NTAPI
343 RtlpValidateHeapEntry(PHEAP Heap, PHEAP_ENTRY HeapEntry);
344
345 BOOLEAN NTAPI
346 RtlpValidateHeapHeaders(PHEAP Heap, BOOLEAN Recalculate);
347
348 /* heapdbg.c */
349 HANDLE NTAPI
350 RtlDebugCreateHeap(ULONG Flags,
351 PVOID Addr,
352 SIZE_T TotalSize,
353 SIZE_T CommitSize,
354 PVOID Lock,
355 PRTL_HEAP_PARAMETERS Parameters);
356
357 BOOLEAN NTAPI
358 RtlDebugDestroyHeap(HANDLE HeapPtr);
359
360 PVOID NTAPI
361 RtlDebugAllocateHeap(PVOID HeapPtr,
362 ULONG Flags,
363 SIZE_T Size);
364
365 PVOID NTAPI
366 RtlDebugReAllocateHeap(HANDLE HeapPtr,
367 ULONG Flags,
368 PVOID Ptr,
369 SIZE_T Size);
370
371 BOOLEAN NTAPI
372 RtlDebugFreeHeap(HANDLE HeapPtr,
373 ULONG Flags,
374 PVOID Ptr);
375
376 BOOLEAN NTAPI
377 RtlDebugGetUserInfoHeap(PVOID HeapHandle,
378 ULONG Flags,
379 PVOID BaseAddress,
380 PVOID *UserValue,
381 PULONG UserFlags);
382
383 BOOLEAN NTAPI
384 RtlDebugSetUserValueHeap(PVOID HeapHandle,
385 ULONG Flags,
386 PVOID BaseAddress,
387 PVOID UserValue);
388
389 BOOLEAN
390 NTAPI
391 RtlDebugSetUserFlagsHeap(PVOID HeapHandle,
392 ULONG Flags,
393 PVOID BaseAddress,
394 ULONG UserFlagsReset,
395 ULONG UserFlagsSet);
396
397 SIZE_T NTAPI
398 RtlDebugSizeHeap(HANDLE HeapPtr,
399 ULONG Flags,
400 PVOID Ptr);
401
402 /* heappage.c */
403
404 HANDLE NTAPI
405 RtlpPageHeapCreate(ULONG Flags,
406 PVOID Addr,
407 SIZE_T TotalSize,
408 SIZE_T CommitSize,
409 PVOID Lock,
410 PRTL_HEAP_PARAMETERS Parameters);
411
412 PVOID NTAPI
413 RtlpPageHeapDestroy(HANDLE HeapPtr);
414
415 PVOID NTAPI
416 RtlpPageHeapAllocate(IN PVOID HeapPtr,
417 IN ULONG Flags,
418 IN SIZE_T Size);
419
420 BOOLEAN NTAPI
421 RtlpPageHeapFree(HANDLE HeapPtr,
422 ULONG Flags,
423 PVOID Ptr);
424
425 PVOID NTAPI
426 RtlpPageHeapReAllocate(HANDLE HeapPtr,
427 ULONG Flags,
428 PVOID Ptr,
429 SIZE_T Size);
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 #endif