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 #define HEAP_TAGS_MASK (HEAP_TAG_MASK ^ (0xFF << HEAP_TAG_SHIFT)) 35 36 #define HEAP_EXTRA_FLAGS_MASK (HEAP_CAPTURE_STACK_BACKTRACES | \ 37 HEAP_SETTABLE_USER_VALUE | \ 38 HEAP_TAGS_MASK) 39 40 /* Heap entry flags */ 41 #define HEAP_ENTRY_BUSY 0x01 42 #define HEAP_ENTRY_EXTRA_PRESENT 0x02 43 #define HEAP_ENTRY_FILL_PATTERN 0x04 44 #define HEAP_ENTRY_VIRTUAL_ALLOC 0x08 45 #define HEAP_ENTRY_LAST_ENTRY 0x10 46 #define HEAP_ENTRY_SETTABLE_FLAG1 0x20 47 #define HEAP_ENTRY_SETTABLE_FLAG2 0x40 48 #define HEAP_ENTRY_SETTABLE_FLAG3 0x80 49 #define HEAP_ENTRY_SETTABLE_FLAGS (HEAP_ENTRY_SETTABLE_FLAG1 | HEAP_ENTRY_SETTABLE_FLAG2 | HEAP_ENTRY_SETTABLE_FLAG3) 50 51 /* Signatures */ 52 #define HEAP_SIGNATURE 0xeefeeff 53 #define HEAP_SEGMENT_SIGNATURE 0xffeeffee 54 55 /* Segment flags */ 56 #define HEAP_USER_ALLOCATED 0x1 57 58 /* A handy inline to distinguis normal heap, special "debug heap" and special "page heap" */ 59 FORCEINLINE BOOLEAN 60 RtlpHeapIsSpecial(ULONG Flags) 61 { 62 if (Flags & HEAP_SKIP_VALIDATION_CHECKS) return FALSE; 63 64 if (Flags & (HEAP_FLAG_PAGE_ALLOCS | 65 HEAP_VALIDATE_ALL_ENABLED | 66 HEAP_VALIDATE_PARAMETERS_ENABLED | 67 HEAP_CAPTURE_STACK_BACKTRACES | 68 HEAP_CREATE_ENABLE_TRACING)) 69 { 70 /* This is a special heap */ 71 return TRUE; 72 } 73 74 /* No need for a special treatment */ 75 return FALSE; 76 } 77 78 /* Heap structures */ 79 struct _HEAP_COMMON_ENTRY 80 { 81 #ifdef _M_AMD64 82 PVOID PreviousBlockPrivateData; 83 #endif 84 union 85 { 86 struct 87 { 88 USHORT Size; 89 UCHAR Flags; 90 UCHAR SmallTagIndex; 91 }; 92 struct 93 { 94 #ifndef _M_AMD64 95 PVOID SubSegmentCode; 96 #else 97 ULONG SubSegmentCodeDummy; 98 #endif 99 USHORT PreviousSize; 100 union 101 { 102 UCHAR SegmentOffset; 103 UCHAR LFHFlags; 104 }; 105 UCHAR UnusedBytes; 106 }; 107 struct 108 { 109 USHORT FunctionIndex; 110 USHORT ContextValue; 111 }; 112 struct 113 { 114 ULONG InterceptorValue; 115 USHORT UnusedBytesLength; 116 UCHAR EntryOffset; 117 UCHAR ExtendedBlockSignature; 118 }; 119 struct 120 { 121 ULONG Code1; 122 USHORT Code2; 123 UCHAR Code3; 124 UCHAR Code4; 125 }; 126 ULONGLONG AgregateCode; 127 }; 128 }; 129 130 typedef struct _HEAP_FREE_ENTRY 131 { 132 struct _HEAP_COMMON_ENTRY; 133 LIST_ENTRY FreeList; 134 } HEAP_FREE_ENTRY, *PHEAP_FREE_ENTRY; 135 136 typedef struct _HEAP_ENTRY 137 { 138 struct _HEAP_COMMON_ENTRY; 139 } HEAP_ENTRY, *PHEAP_ENTRY; 140 141 #ifdef _WIN64 142 C_ASSERT(sizeof(HEAP_ENTRY) == 16); 143 #else 144 C_ASSERT(sizeof(HEAP_ENTRY) == 8); 145 #endif 146 C_ASSERT((1 << HEAP_ENTRY_SHIFT) == sizeof(HEAP_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 PVOID LastEntryInSegment //FIXME: non-Vista 222 223 typedef struct _HEAP 224 { 225 HEAP_SEGMENT_MEMBERS; 226 227 ULONG Flags; 228 ULONG ForceFlags; 229 ULONG CompatibilityFlags; 230 ULONG EncodeFlagMask; 231 HEAP_ENTRY Encoding; 232 ULONG_PTR PointerKey; 233 ULONG Interceptor; 234 ULONG VirtualMemoryThreshold; 235 ULONG Signature; 236 SIZE_T SegmentReserve; 237 SIZE_T SegmentCommit; 238 SIZE_T DeCommitFreeBlockThreshold; 239 SIZE_T DeCommitTotalFreeThreshold; 240 SIZE_T TotalFreeSize; 241 SIZE_T MaximumAllocationSize; 242 USHORT ProcessHeapsListIndex; 243 USHORT HeaderValidateLength; 244 PVOID HeaderValidateCopy; 245 USHORT NextAvailableTagIndex; 246 USHORT MaximumTagIndex; 247 PHEAP_TAG_ENTRY TagEntries; 248 LIST_ENTRY UCRList; 249 LIST_ENTRY UCRSegments; // FIXME: non-Vista 250 ULONG_PTR AlignRound; 251 ULONG_PTR AlignMask; 252 LIST_ENTRY VirtualAllocdBlocks; 253 LIST_ENTRY SegmentList; 254 struct _HEAP_SEGMENT *Segments[HEAP_SEGMENTS]; //FIXME: non-Vista 255 USHORT AllocatorBackTraceIndex; 256 ULONG NonDedicatedListLength; 257 PVOID BlocksIndex; // HEAP_LIST_LOOKUP 258 PVOID UCRIndex; 259 PHEAP_PSEUDO_TAG_ENTRY PseudoTagEntries; 260 LIST_ENTRY FreeLists[HEAP_FREELISTS]; //FIXME: non-Vista 261 //LIST_ENTRY FreeLists; 262 union 263 { 264 ULONG FreeListsInUseUlong[HEAP_FREELISTS / (sizeof(ULONG) * 8)]; //FIXME: non-Vista 265 UCHAR FreeListsInUseBytes[HEAP_FREELISTS / (sizeof(UCHAR) * 8)]; //FIXME: non-Vista 266 } u; 267 PHEAP_LOCK LockVariable; 268 PRTL_HEAP_COMMIT_ROUTINE CommitRoutine; 269 PVOID FrontEndHeap; 270 USHORT FrontHeapLockCount; 271 UCHAR FrontEndHeapType; 272 HEAP_COUNTERS Counters; 273 HEAP_TUNING_PARAMETERS TuningParameters; 274 } HEAP, *PHEAP; 275 276 typedef struct _HEAP_SEGMENT 277 { 278 HEAP_SEGMENT_MEMBERS; 279 } HEAP_SEGMENT, *PHEAP_SEGMENT; 280 281 typedef struct _HEAP_UCR_DESCRIPTOR 282 { 283 LIST_ENTRY ListEntry; 284 LIST_ENTRY SegmentEntry; 285 PVOID Address; 286 SIZE_T Size; 287 } HEAP_UCR_DESCRIPTOR, *PHEAP_UCR_DESCRIPTOR; 288 289 typedef struct _HEAP_UCR_SEGMENT 290 { 291 LIST_ENTRY ListEntry; 292 SIZE_T ReservedSize; 293 SIZE_T CommittedSize; 294 } HEAP_UCR_SEGMENT, *PHEAP_UCR_SEGMENT; 295 296 typedef struct _HEAP_ENTRY_EXTRA 297 { 298 union 299 { 300 struct 301 { 302 USHORT AllocatorBackTraceIndex; 303 USHORT TagIndex; 304 ULONG_PTR Settable; 305 }; 306 UINT64 ZeroInit; 307 }; 308 } HEAP_ENTRY_EXTRA, *PHEAP_ENTRY_EXTRA; 309 310 typedef HEAP_ENTRY_EXTRA HEAP_FREE_ENTRY_EXTRA, *PHEAP_FREE_ENTRY_EXTRA; 311 312 typedef struct _HEAP_VIRTUAL_ALLOC_ENTRY 313 { 314 LIST_ENTRY Entry; 315 HEAP_ENTRY_EXTRA ExtraStuff; 316 SIZE_T CommitSize; 317 SIZE_T ReserveSize; 318 HEAP_ENTRY BusyBlock; 319 } HEAP_VIRTUAL_ALLOC_ENTRY, *PHEAP_VIRTUAL_ALLOC_ENTRY; 320 321 /* Global variables */ 322 extern RTL_CRITICAL_SECTION RtlpProcessHeapsListLock; 323 extern BOOLEAN RtlpPageHeapEnabled; 324 325 /* Functions declarations */ 326 327 /* heap.c */ 328 PHEAP_FREE_ENTRY NTAPI 329 RtlpCoalesceFreeBlocks (PHEAP Heap, 330 PHEAP_FREE_ENTRY FreeEntry, 331 PSIZE_T FreeSize, 332 BOOLEAN Remove); 333 334 PHEAP_ENTRY_EXTRA NTAPI 335 RtlpGetExtraStuffPointer(PHEAP_ENTRY HeapEntry); 336 337 BOOLEAN NTAPI 338 RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation); 339 340 BOOLEAN NTAPI 341 RtlpValidateHeapEntry(PHEAP Heap, PHEAP_ENTRY HeapEntry); 342 343 BOOLEAN NTAPI 344 RtlpValidateHeapHeaders(PHEAP Heap, BOOLEAN Recalculate); 345 346 /* heapdbg.c */ 347 HANDLE NTAPI 348 RtlDebugCreateHeap(ULONG Flags, 349 PVOID Addr, 350 SIZE_T TotalSize, 351 SIZE_T CommitSize, 352 PVOID Lock, 353 PRTL_HEAP_PARAMETERS Parameters); 354 355 BOOLEAN NTAPI 356 RtlDebugDestroyHeap(HANDLE HeapPtr); 357 358 PVOID NTAPI 359 RtlDebugAllocateHeap(PVOID HeapPtr, 360 ULONG Flags, 361 SIZE_T Size); 362 363 PVOID NTAPI 364 RtlDebugReAllocateHeap(HANDLE HeapPtr, 365 ULONG Flags, 366 PVOID Ptr, 367 SIZE_T Size); 368 369 BOOLEAN NTAPI 370 RtlDebugFreeHeap(HANDLE HeapPtr, 371 ULONG Flags, 372 PVOID Ptr); 373 374 BOOLEAN NTAPI 375 RtlDebugGetUserInfoHeap(PVOID HeapHandle, 376 ULONG Flags, 377 PVOID BaseAddress, 378 PVOID *UserValue, 379 PULONG UserFlags); 380 381 BOOLEAN NTAPI 382 RtlDebugSetUserValueHeap(PVOID HeapHandle, 383 ULONG Flags, 384 PVOID BaseAddress, 385 PVOID UserValue); 386 387 BOOLEAN 388 NTAPI 389 RtlDebugSetUserFlagsHeap(PVOID HeapHandle, 390 ULONG Flags, 391 PVOID BaseAddress, 392 ULONG UserFlagsReset, 393 ULONG UserFlagsSet); 394 395 SIZE_T NTAPI 396 RtlDebugSizeHeap(HANDLE HeapPtr, 397 ULONG Flags, 398 PVOID Ptr); 399 400 /* heappage.c */ 401 402 HANDLE NTAPI 403 RtlpPageHeapCreate(ULONG Flags, 404 PVOID Addr, 405 SIZE_T TotalSize, 406 SIZE_T CommitSize, 407 PVOID Lock, 408 PRTL_HEAP_PARAMETERS Parameters); 409 410 PVOID NTAPI 411 RtlpPageHeapDestroy(HANDLE HeapPtr); 412 413 PVOID NTAPI 414 RtlpPageHeapAllocate(IN PVOID HeapPtr, 415 IN ULONG Flags, 416 IN SIZE_T Size); 417 418 BOOLEAN NTAPI 419 RtlpPageHeapFree(HANDLE HeapPtr, 420 ULONG Flags, 421 PVOID Ptr); 422 423 PVOID NTAPI 424 RtlpPageHeapReAllocate(HANDLE HeapPtr, 425 ULONG Flags, 426 PVOID Ptr, 427 SIZE_T Size); 428 429 BOOLEAN NTAPI 430 RtlpPageHeapLock(HANDLE HeapPtr); 431 432 BOOLEAN NTAPI 433 RtlpPageHeapUnlock(HANDLE HeapPtr); 434 435 BOOLEAN NTAPI 436 RtlpPageHeapGetUserInfo(PVOID HeapHandle, 437 ULONG Flags, 438 PVOID BaseAddress, 439 PVOID *UserValue, 440 PULONG UserFlags); 441 442 BOOLEAN NTAPI 443 RtlpPageHeapSetUserValue(PVOID HeapHandle, 444 ULONG Flags, 445 PVOID BaseAddress, 446 PVOID UserValue); 447 448 BOOLEAN 449 NTAPI 450 RtlpPageHeapSetUserFlags(PVOID HeapHandle, 451 ULONG Flags, 452 PVOID BaseAddress, 453 ULONG UserFlagsReset, 454 ULONG UserFlagsSet); 455 456 BOOLEAN 457 NTAPI 458 RtlpDebugPageHeapValidate(PVOID HeapPtr, 459 ULONG Flags, 460 PVOID Block); 461 462 SIZE_T NTAPI 463 RtlpPageHeapSize(HANDLE HeapPtr, 464 ULONG Flags, 465 PVOID Ptr); 466 467 VOID 468 NTAPI 469 RtlpAddHeapToProcessList(PHEAP Heap); 470 471 VOID 472 NTAPI 473 RtlpRemoveHeapFromProcessList(PHEAP Heap); 474 475 VOID 476 NTAPI 477 RtlInitializeHeapManager(VOID); 478 479 #endif 480