[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 /* Heap structures */
58 struct _HEAP_COMMON_ENTRY
59 {
60 union
61 {
62 struct
63 {
64 USHORT Size;
65 UCHAR Flags;
66 UCHAR SmallTagIndex;
67 };
68 struct
69 {
70 PVOID SubSegmentCode;
71 USHORT PreviousSize;
72 union
73 {
74 UCHAR SegmentOffset;
75 UCHAR LFHFlags;
76 };
77 UCHAR UnusedBytes;
78 };
79 struct
80 {
81 USHORT FunctionIndex;
82 USHORT ContextValue;
83 };
84 struct
85 {
86 ULONG InterceptorValue;
87 USHORT UnusedBytesLength;
88 UCHAR EntryOffset;
89 UCHAR ExtendedBlockSignature;
90 };
91 struct
92 {
93 ULONG Code1;
94 USHORT Code2;
95 UCHAR Code3;
96 UCHAR Code4;
97 };
98 ULONGLONG AgregateCode;
99 };
100 };
101
102 typedef struct _HEAP_FREE_ENTRY
103 {
104 struct _HEAP_COMMON_ENTRY;
105 LIST_ENTRY FreeList;
106 } HEAP_FREE_ENTRY, *PHEAP_FREE_ENTRY;
107
108 typedef struct _HEAP_ENTRY
109 {
110 struct _HEAP_COMMON_ENTRY;
111 } HEAP_ENTRY, *PHEAP_ENTRY;
112
113 #ifdef _WIN64
114 C_ASSERT(sizeof(HEAP_ENTRY) == 16);
115 #else
116 C_ASSERT(sizeof(HEAP_ENTRY) == 8);
117 #endif
118 C_ASSERT((1 << HEAP_ENTRY_SHIFT) == sizeof(HEAP_ENTRY));
119
120 typedef struct _HEAP_TAG_ENTRY
121 {
122 ULONG Allocs;
123 ULONG Frees;
124 ULONG Size;
125 USHORT TagIndex;
126 USHORT CreatorBackTraceIndex;
127 WCHAR TagName[24];
128 } HEAP_TAG_ENTRY, *PHEAP_TAG_ENTRY;
129
130 typedef struct _HEAP_PSEUDO_TAG_ENTRY
131 {
132 ULONG Allocs;
133 ULONG Frees;
134 ULONG Size;
135 } HEAP_PSEUDO_TAG_ENTRY, *PHEAP_PSEUDO_TAG_ENTRY;
136
137 typedef struct _HEAP_COUNTERS
138 {
139 ULONG TotalMemoryReserved;
140 ULONG TotalMemoryCommitted;
141 ULONG TotalMemoryLargeUCR;
142 ULONG TotalSizeInVirtualBlocks;
143 ULONG TotalSegments;
144 ULONG TotalUCRs;
145 ULONG CommittOps;
146 ULONG DeCommitOps;
147 ULONG LockAcquires;
148 ULONG LockCollisions;
149 ULONG CommitRate;
150 ULONG DecommittRate;
151 ULONG CommitFailures;
152 ULONG InBlockCommitFailures;
153 ULONG CompactHeapCalls;
154 ULONG CompactedUCRs;
155 ULONG InBlockDeccommits;
156 ULONG InBlockDeccomitSize;
157 } HEAP_COUNTERS, *PHEAP_COUNTERS;
158
159 typedef struct _HEAP_TUNING_PARAMETERS
160 {
161 ULONG CommittThresholdShift;
162 ULONG MaxPreCommittThreshold;
163 } HEAP_TUNING_PARAMETERS, *PHEAP_TUNING_PARAMETERS;
164
165 typedef struct _HEAP
166 {
167 HEAP_ENTRY Entry;
168 ULONG SegmentSignature;
169 ULONG SegmentFlags;
170 LIST_ENTRY SegmentListEntry;
171 struct _HEAP *Heap;
172 PVOID BaseAddress;
173 ULONG NumberOfPages;
174 PHEAP_ENTRY FirstEntry;
175 PHEAP_ENTRY LastValidEntry;
176 ULONG NumberOfUnCommittedPages;
177 ULONG NumberOfUnCommittedRanges;
178 USHORT SegmentAllocatorBackTraceIndex;
179 USHORT Reserved;
180 LIST_ENTRY UCRSegmentList;
181 ULONG Flags;
182 ULONG ForceFlags;
183 ULONG CompatibilityFlags;
184 ULONG EncodeFlagMask;
185 HEAP_ENTRY Encoding;
186 ULONG PointerKey;
187 ULONG Interceptor;
188 ULONG VirtualMemoryThreshold;
189 ULONG Signature;
190 ULONG SegmentReserve;
191 ULONG SegmentCommit;
192 ULONG DeCommitFreeBlockThreshold;
193 ULONG DeCommitTotalFreeThreshold;
194 ULONG TotalFreeSize;
195 ULONG MaximumAllocationSize;
196 USHORT ProcessHeapsListIndex;
197 USHORT HeaderValidateLength;
198 PVOID HeaderValidateCopy;
199 USHORT NextAvailableTagIndex;
200 USHORT MaximumTagIndex;
201 PHEAP_TAG_ENTRY TagEntries;
202 LIST_ENTRY UCRList;
203 ULONG AlignRound;
204 ULONG AlignMask;
205 LIST_ENTRY VirtualAllocdBlocks;
206 LIST_ENTRY SegmentList;
207 struct _HEAP_SEGMENT *Segments[HEAP_SEGMENTS]; //FIXME: non-Vista
208 USHORT AllocatorBackTraceIndex;
209 ULONG NonDedicatedListLength;
210 PVOID BlocksIndex;
211 PVOID UCRIndex;
212 PHEAP_PSEUDO_TAG_ENTRY PseudoTagEntries;
213 LIST_ENTRY FreeLists[HEAP_FREELISTS]; //FIXME: non-Vista
214 union
215 {
216 ULONG FreeListsInUseUlong[HEAP_FREELISTS / (sizeof(ULONG) * 8)]; //FIXME: non-Vista
217 UCHAR FreeListsInUseBytes[HEAP_FREELISTS / (sizeof(UCHAR) * 8)]; //FIXME: non-Vista
218 } u;
219 PHEAP_LOCK LockVariable;
220 PRTL_HEAP_COMMIT_ROUTINE CommitRoutine;
221 PVOID FrontEndHeap;
222 USHORT FrontHeapLockCount;
223 UCHAR FrontEndHeapType;
224 HEAP_COUNTERS Counters;
225 HEAP_TUNING_PARAMETERS TuningParameters;
226 } HEAP, *PHEAP;
227
228 typedef struct _HEAP_SEGMENT
229 {
230 HEAP_ENTRY Entry;
231 ULONG SegmentSignature;
232 ULONG SegmentFlags;
233 LIST_ENTRY SegmentListEntry;
234 PHEAP Heap;
235 PVOID BaseAddress;
236 ULONG NumberOfPages;
237 PHEAP_ENTRY FirstEntry;
238 PHEAP_ENTRY LastValidEntry;
239 ULONG NumberOfUnCommittedPages;
240 ULONG NumberOfUnCommittedRanges;
241 USHORT SegmentAllocatorBackTraceIndex;
242 USHORT Reserved;
243 LIST_ENTRY UCRSegmentList;
244 PHEAP_ENTRY LastEntryInSegment; //FIXME: non-Vista
245 } HEAP_SEGMENT, *PHEAP_SEGMENT;
246
247 typedef struct _HEAP_UCR_DESCRIPTOR
248 {
249 LIST_ENTRY ListEntry;
250 LIST_ENTRY SegmentEntry;
251 PVOID Address;
252 ULONG Size;
253 } HEAP_UCR_DESCRIPTOR, *PHEAP_UCR_DESCRIPTOR;
254
255 typedef struct _HEAP_ENTRY_EXTRA
256 {
257 union
258 {
259 struct
260 {
261 USHORT AllocatorBackTraceIndex;
262 USHORT TagIndex;
263 ULONG_PTR Settable;
264 };
265 UINT64 ZeroInit;
266 };
267 } HEAP_ENTRY_EXTRA, *PHEAP_ENTRY_EXTRA;
268
269 typedef HEAP_ENTRY_EXTRA HEAP_FREE_ENTRY_EXTRA, *PHEAP_FREE_ENTRY_EXTRA;
270
271 typedef struct _HEAP_VIRTUAL_ALLOC_ENTRY
272 {
273 LIST_ENTRY Entry;
274 HEAP_ENTRY_EXTRA ExtraStuff;
275 ULONG CommitSize;
276 ULONG ReserveSize;
277 HEAP_ENTRY BusyBlock;
278 } HEAP_VIRTUAL_ALLOC_ENTRY, *PHEAP_VIRTUAL_ALLOC_ENTRY;
279
280 /* Global variables */
281 extern HEAP_LOCK RtlpProcessHeapsListLock;
282 extern BOOLEAN RtlpPageHeapEnabled;
283
284 /* Functions declarations */
285
286 /* heap.c */
287 PHEAP_FREE_ENTRY NTAPI
288 RtlpCoalesceFreeBlocks (PHEAP Heap,
289 PHEAP_FREE_ENTRY FreeEntry,
290 PSIZE_T FreeSize,
291 BOOLEAN Remove);
292
293 PHEAP_ENTRY_EXTRA NTAPI
294 RtlpGetExtraStuffPointer(PHEAP_ENTRY HeapEntry);
295
296 /* heapdbg.c */
297 HANDLE NTAPI
298 RtlpPageHeapCreate(ULONG Flags,
299 PVOID Addr,
300 SIZE_T TotalSize,
301 SIZE_T CommitSize,
302 PVOID Lock,
303 PRTL_HEAP_PARAMETERS Parameters);
304
305 #endif