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