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