Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

heap.h

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1992 Microsoft Corporation 00004 00005 Module Name: 00006 00007 heap.h 00008 00009 Abstract: 00010 00011 This is the header file that describes the constants and data 00012 structures used by the user mode heap manager, exported by ntdll.dll 00013 and ntrtl.lib 00014 00015 Procedure prototypes are defined in ntrtl.h 00016 00017 Author: 00018 00019 Steve Wood (stevewo) 21-Aug-1992 00020 00021 Revision History: 00022 00023 --*/ 00024 00025 #ifndef _RTL_HEAP_ 00026 #define _RTL_HEAP_ 00027 00028 #define HEAP_LARGE_TAG_MASK 0xFF000000 00029 00030 #define ROUND_UP_TO_POWER2( x, n ) (((ULONG_PTR)(x) + ((n)-1)) & ~((ULONG_PTR)(n)-1)) 00031 #define ROUND_DOWN_TO_POWER2( x, n ) ((ULONG_PTR)(x) & ~((ULONG_PTR)(n)-1)) 00032 00033 typedef struct _HEAP_ENTRY { 00034 00035 // 00036 // This field gives the size of the current block in allocation 00037 // granularity units. (i.e. Size << HEAP_GRANULARITY_SHIFT 00038 // equals the size in bytes). 00039 // 00040 // Except if this is part of a virtual alloc block then this 00041 // value is the difference between the commit size in the virtual 00042 // alloc entry and the what the user asked for. 00043 // 00044 00045 USHORT Size; 00046 00047 // 00048 // This field gives the size of the previous block in allocation 00049 // granularity units. (i.e. PreviousSize << HEAP_GRANULARITY_SHIFT 00050 // equals the size of the previous block in bytes). 00051 // 00052 00053 USHORT PreviousSize; 00054 00055 // 00056 // This field contains the index into the segment that controls 00057 // the memory for this block. 00058 // 00059 00060 UCHAR SegmentIndex; 00061 00062 // 00063 // This field contains various flag bits associated with this block. 00064 // Currently these are: 00065 // 00066 // 0x01 - HEAP_ENTRY_BUSY 00067 // 0x02 - HEAP_ENTRY_EXTRA_PRESENT 00068 // 0x04 - HEAP_ENTRY_FILL_PATTERN 00069 // 0x08 - HEAP_ENTRY_VIRTUAL_ALLOC 00070 // 0x10 - HEAP_ENTRY_LAST_ENTRY 00071 // 0x20 - HEAP_ENTRY_SETTABLE_FLAG1 00072 // 0x40 - HEAP_ENTRY_SETTABLE_FLAG2 00073 // 0x80 - HEAP_ENTRY_SETTABLE_FLAG3 00074 // 00075 00076 UCHAR Flags; 00077 00078 // 00079 // This field contains the number of unused bytes at the end of this 00080 // block that were not actually allocated. Used to compute exact 00081 // size requested prior to rounding requested size to allocation 00082 // granularity. Also used for tail checking purposes. 00083 // 00084 00085 UCHAR UnusedBytes; 00086 00087 // 00088 // Small (8 bit) tag indexes can go here. 00089 // 00090 00091 UCHAR SmallTagIndex; 00092 00093 #if defined(_WIN64) 00094 ULONGLONG Reserved1; 00095 #endif 00096 00097 } HEAP_ENTRY, *PHEAP_ENTRY; 00098 00099 00100 // 00101 // This block describes extra information that might be at the end of a 00102 // busy block. 00103 // 00104 00105 typedef struct _HEAP_ENTRY_EXTRA { 00106 union { 00107 struct { 00108 // 00109 // This field is for debugging purposes. It will normally contain a 00110 // stack back trace index of the allocator for x86 systems. 00111 // 00112 00113 USHORT AllocatorBackTraceIndex; 00114 00115 // 00116 // This field is currently unused, but is intended for storing 00117 // any encoded value that will give the that gives the type of object 00118 // allocated. 00119 // 00120 00121 USHORT TagIndex; 00122 00123 // 00124 // This field is a 32-bit settable value that a higher level heap package 00125 // can use. The Win32 heap manager stores handle values in this field. 00126 // 00127 00128 ULONG_PTR Settable; 00129 }; 00130 #if defined(_WIN64) 00131 struct { 00132 ULONGLONG ZeroInit; 00133 ULONGLONG ZeroInit1; 00134 }; 00135 #else 00136 ULONGLONG ZeroInit; 00137 #endif 00138 }; 00139 } HEAP_ENTRY_EXTRA, *PHEAP_ENTRY_EXTRA; 00140 00141 // 00142 // This structure is present at the end of a free block if HEAP_ENTRY_EXTRA_PRESENT 00143 // is set in the Flags field of a HEAP_FREE_ENTRY structure. It is used to save the 00144 // tag index that was associated with the allocated block after it has been freed. 00145 // Works best when coalesce on free is disabled, along with decommitment. 00146 // 00147 00148 typedef struct _HEAP_FREE_ENTRY_EXTRA { 00149 USHORT TagIndex; 00150 USHORT FreeBackTraceIndex; 00151 } HEAP_FREE_ENTRY_EXTRA, *PHEAP_FREE_ENTRY_EXTRA; 00152 00153 // 00154 // This structure describes a block that lies outside normal heap memory 00155 // as it was allocated with NtAllocateVirtualMemory and has the 00156 // HEAP_ENTRY_VIRTUAL_ALLOC flag set. 00157 // 00158 00159 typedef struct _HEAP_VIRTUAL_ALLOC_ENTRY { 00160 LIST_ENTRY Entry; 00161 HEAP_ENTRY_EXTRA ExtraStuff; 00162 SIZE_T CommitSize; 00163 SIZE_T ReserveSize; 00164 HEAP_ENTRY BusyBlock; 00165 } HEAP_VIRTUAL_ALLOC_ENTRY, *PHEAP_VIRTUAL_ALLOC_ENTRY; 00166 00167 typedef struct _HEAP_FREE_ENTRY { 00168 // 00169 // This field gives the size of the current block in allocation 00170 // granularity units. (i.e. Size << HEAP_GRANULARITY_SHIFT 00171 // equals the size in bytes). 00172 // 00173 00174 USHORT Size; 00175 00176 // 00177 // This field gives the size of the previous block in allocation 00178 // granularity units. (i.e. PreviousSize << HEAP_GRANULARITY_SHIFT 00179 // equals the size of the previous block in bytes). 00180 // 00181 00182 USHORT PreviousSize; 00183 00184 // 00185 // This field contains the index into the segment that controls 00186 // the memory for this block. 00187 // 00188 00189 UCHAR SegmentIndex; 00190 00191 // 00192 // This field contains various flag bits associated with this block. 00193 // Currently for free blocks these can be: 00194 // 00195 // 0x02 - HEAP_ENTRY_EXTRA_PRESENT 00196 // 0x04 - HEAP_ENTRY_FILL_PATTERN 00197 // 0x10 - HEAP_ENTRY_LAST_ENTRY 00198 // 00199 00200 UCHAR Flags; 00201 00202 // 00203 // Two fields to encode the location of the bit in FreeListsInUse 00204 // array in HEAP_SEGMENT for blocks of this size. 00205 // 00206 00207 UCHAR Index; 00208 UCHAR Mask; 00209 00210 // 00211 // Free blocks use these two words for linking together free blocks 00212 // of the same size on a doubly linked list. 00213 // 00214 LIST_ENTRY FreeList; 00215 00216 #if defined(_WIN64) 00217 ULONGLONG Reserved1; 00218 #endif 00219 00220 } HEAP_FREE_ENTRY, *PHEAP_FREE_ENTRY; 00221 00222 00223 00224 #define HEAP_GRANULARITY ((LONG) sizeof( HEAP_ENTRY )) 00225 #if defined(_WIN64) 00226 #define HEAP_GRANULARITY_SHIFT 4 // Log2( HEAP_GRANULARITY ) 00227 #else 00228 #define HEAP_GRANULARITY_SHIFT 3 // Log2( HEAP_GRANULARITY ) 00229 #endif 00230 00231 #define HEAP_MAXIMUM_BLOCK_SIZE (USHORT)(((0x10000 << HEAP_GRANULARITY_SHIFT) - PAGE_SIZE) >> HEAP_GRANULARITY_SHIFT) 00232 00233 #define HEAP_MAXIMUM_FREELISTS 128 00234 #define HEAP_MAXIMUM_SEGMENTS 64 00235 00236 #define HEAP_ENTRY_BUSY 0x01 00237 #define HEAP_ENTRY_EXTRA_PRESENT 0x02 00238 #define HEAP_ENTRY_FILL_PATTERN 0x04 00239 #define HEAP_ENTRY_VIRTUAL_ALLOC 0x08 00240 #define HEAP_ENTRY_LAST_ENTRY 0x10 00241 #define HEAP_ENTRY_SETTABLE_FLAG1 0x20 00242 #define HEAP_ENTRY_SETTABLE_FLAG2 0x40 00243 #define HEAP_ENTRY_SETTABLE_FLAG3 0x80 00244 #define HEAP_ENTRY_SETTABLE_FLAGS 0xE0 00245 00246 // 00247 // HEAP_SEGMENT defines the structure used to describe a range of 00248 // contiguous virtual memory that has been set aside for use by 00249 // a heap. 00250 // 00251 00252 typedef struct _HEAP_UNCOMMMTTED_RANGE { 00253 struct _HEAP_UNCOMMMTTED_RANGE *Next; 00254 ULONG_PTR Address; 00255 SIZE_T Size; 00256 ULONG filler; 00257 } HEAP_UNCOMMMTTED_RANGE, *PHEAP_UNCOMMMTTED_RANGE; 00258 00259 typedef struct _HEAP_SEGMENT { 00260 HEAP_ENTRY Entry; 00261 00262 ULONG Signature; 00263 ULONG Flags; 00264 struct _HEAP *Heap; 00265 SIZE_T LargestUnCommittedRange; 00266 00267 PVOID BaseAddress; 00268 ULONG NumberOfPages; 00269 PHEAP_ENTRY FirstEntry; 00270 PHEAP_ENTRY LastValidEntry; 00271 00272 ULONG NumberOfUnCommittedPages; 00273 ULONG NumberOfUnCommittedRanges; 00274 PHEAP_UNCOMMMTTED_RANGE UnCommittedRanges; 00275 USHORT AllocatorBackTraceIndex; 00276 USHORT Reserved; 00277 PHEAP_ENTRY LastEntryInSegment; 00278 } HEAP_SEGMENT, *PHEAP_SEGMENT; 00279 00280 #define HEAP_SEGMENT_SIGNATURE 0xFFEEFFEE 00281 #define HEAP_SEGMENT_USER_ALLOCATED (ULONG)0x00000001 00282 00283 // 00284 // HEAP defines the header for a heap. 00285 // 00286 00287 typedef struct _HEAP_LOCK { 00288 union { 00289 RTL_CRITICAL_SECTION CriticalSection; 00290 ERESOURCE Resource; 00291 } Lock; 00292 } HEAP_LOCK, *PHEAP_LOCK; 00293 00294 typedef struct _HEAP_UCR_SEGMENT { 00295 struct _HEAP_UCR_SEGMENT *Next; 00296 SIZE_T ReservedSize; 00297 SIZE_T CommittedSize; 00298 ULONG filler; 00299 } HEAP_UCR_SEGMENT, *PHEAP_UCR_SEGMENT; 00300 00301 00302 typedef struct _HEAP_TAG_ENTRY { 00303 ULONG Allocs; 00304 ULONG Frees; 00305 SIZE_T Size; 00306 USHORT TagIndex; 00307 USHORT CreatorBackTraceIndex; 00308 WCHAR TagName[ 24 ]; 00309 } HEAP_TAG_ENTRY, *PHEAP_TAG_ENTRY; // sizeof( HEAP_TAG_ENTRY ) must divide page size evenly 00310 00311 typedef struct _HEAP_PSEUDO_TAG_ENTRY { 00312 ULONG Allocs; 00313 ULONG Frees; 00314 SIZE_T Size; 00315 } HEAP_PSEUDO_TAG_ENTRY, *PHEAP_PSEUDO_TAG_ENTRY; 00316 00317 00318 typedef struct _HEAP { 00319 HEAP_ENTRY Entry; 00320 00321 ULONG Signature; 00322 ULONG Flags; 00323 ULONG ForceFlags; 00324 ULONG VirtualMemoryThreshold; 00325 00326 SIZE_T SegmentReserve; 00327 SIZE_T SegmentCommit; 00328 SIZE_T DeCommitFreeBlockThreshold; 00329 SIZE_T DeCommitTotalFreeThreshold; 00330 00331 SIZE_T TotalFreeSize; 00332 SIZE_T MaximumAllocationSize; 00333 USHORT ProcessHeapsListIndex; 00334 USHORT HeaderValidateLength; 00335 PVOID HeaderValidateCopy; 00336 00337 USHORT NextAvailableTagIndex; 00338 USHORT MaximumTagIndex; 00339 PHEAP_TAG_ENTRY TagEntries; 00340 PHEAP_UCR_SEGMENT UCRSegments; 00341 PHEAP_UNCOMMMTTED_RANGE UnusedUnCommittedRanges; 00342 00343 // 00344 // The following two fields control the alignment for each new heap entry 00345 // allocation. The round is added to each size and the mask is used to 00346 // align it. The round value includes the heap entry and any tail checking 00347 // space 00348 // 00349 00350 ULONG AlignRound; 00351 ULONG AlignMask; 00352 00353 LIST_ENTRY VirtualAllocdBlocks; 00354 00355 PHEAP_SEGMENT Segments[ HEAP_MAXIMUM_SEGMENTS ]; 00356 00357 union { 00358 ULONG FreeListsInUseUlong[ HEAP_MAXIMUM_FREELISTS / 32 ]; 00359 UCHAR FreeListsInUseBytes[ HEAP_MAXIMUM_FREELISTS / 8 ]; 00360 } u; 00361 00362 USHORT FreeListsInUseTerminate; 00363 USHORT AllocatorBackTraceIndex; 00364 ULONG Reserved1[2]; 00365 PHEAP_PSEUDO_TAG_ENTRY PseudoTagEntries; 00366 00367 LIST_ENTRY FreeLists[ HEAP_MAXIMUM_FREELISTS ]; 00368 00369 PHEAP_LOCK LockVariable; 00370 PRTL_HEAP_COMMIT_ROUTINE CommitRoutine; 00371 00372 // 00373 // The following field is used to manage the heap lookaside list. The 00374 // pointer is used to locate the lookaside list array. If it is null 00375 // then the lookaside list is not active. 00376 // 00377 // The lock count is used to denote if the heap is locked. A zero value 00378 // means the heap is not locked. Each lock operation increments the 00379 // heap count and each unlock decrements the counter 00380 // 00381 00382 PVOID Lookaside; 00383 ULONG LookasideLockCount; 00384 00385 } HEAP, *PHEAP; 00386 00387 #define HEAP_SIGNATURE (ULONG)0xEEFFEEFF 00388 #define HEAP_LOCK_USER_ALLOCATED (ULONG)0x80000000 00389 #define HEAP_VALIDATE_PARAMETERS_ENABLED (ULONG)0x40000000 00390 #define HEAP_VALIDATE_ALL_ENABLED (ULONG)0x20000000 00391 #define HEAP_SKIP_VALIDATION_CHECKS (ULONG)0x10000000 00392 #define HEAP_CAPTURE_STACK_BACKTRACES (ULONG)0x08000000 00393 00394 #define CHECK_HEAP_TAIL_SIZE HEAP_GRANULARITY 00395 #define CHECK_HEAP_TAIL_FILL 0xAB 00396 #define FREE_HEAP_FILL 0xFEEEFEEE 00397 #define ALLOC_HEAP_FILL 0xBAADF00D 00398 00399 #define HEAP_MAXIMUM_SMALL_TAG 0xFF 00400 #define HEAP_SMALL_TAG_MASK (HEAP_MAXIMUM_SMALL_TAG << HEAP_TAG_SHIFT) 00401 #define HEAP_NEED_EXTRA_FLAGS ((HEAP_TAG_MASK ^ HEAP_SMALL_TAG_MASK) | \ 00402 HEAP_CAPTURE_STACK_BACKTRACES | \ 00403 HEAP_SETTABLE_USER_VALUE \ 00404 ) 00405 #define HEAP_NUMBER_OF_PSEUDO_TAG (HEAP_MAXIMUM_FREELISTS+1) 00406 00407 00408 #if (HEAP_ENTRY_SETTABLE_FLAG1 ^ \ 00409 HEAP_ENTRY_SETTABLE_FLAG2 ^ \ 00410 HEAP_ENTRY_SETTABLE_FLAG3 ^ \ 00411 HEAP_ENTRY_SETTABLE_FLAGS \ 00412 ) 00413 #error Invalid HEAP_ENTRY_SETTABLE_FLAGS 00414 #endif 00415 00416 #if ((HEAP_ENTRY_BUSY ^ \ 00417 HEAP_ENTRY_EXTRA_PRESENT ^ \ 00418 HEAP_ENTRY_FILL_PATTERN ^ \ 00419 HEAP_ENTRY_VIRTUAL_ALLOC ^ \ 00420 HEAP_ENTRY_LAST_ENTRY ^ \ 00421 HEAP_ENTRY_SETTABLE_FLAGS \ 00422 ) != \ 00423 (HEAP_ENTRY_BUSY | \ 00424 HEAP_ENTRY_EXTRA_PRESENT | \ 00425 HEAP_ENTRY_FILL_PATTERN | \ 00426 HEAP_ENTRY_VIRTUAL_ALLOC | \ 00427 HEAP_ENTRY_LAST_ENTRY | \ 00428 HEAP_ENTRY_SETTABLE_FLAGS \ 00429 ) \ 00430 ) 00431 #error Conflicting HEAP_ENTRY flags 00432 #endif 00433 00434 #if ((HEAP_SETTABLE_USER_FLAGS >> 4) ^ HEAP_ENTRY_SETTABLE_FLAGS) 00435 #error HEAP_SETTABLE_USER_FLAGS in ntrtl.h conflicts with HEAP_ENTRY_SETTABLE_FLAGS in heap.h 00436 #endif 00437 00438 typedef struct _HEAP_STOP_ON_TAG { 00439 union { 00440 ULONG HeapAndTagIndex; 00441 struct { 00442 USHORT TagIndex; 00443 USHORT HeapIndex; 00444 }; 00445 }; 00446 } HEAP_STOP_ON_TAG, *PHEAP_STOP_ON_TAG; 00447 00448 typedef struct _HEAP_STOP_ON_VALUES { 00449 SIZE_T AllocAddress; 00450 HEAP_STOP_ON_TAG AllocTag; 00451 SIZE_T ReAllocAddress; 00452 HEAP_STOP_ON_TAG ReAllocTag; 00453 SIZE_T FreeAddress; 00454 HEAP_STOP_ON_TAG FreeTag; 00455 } HEAP_STOP_ON_VALUES, *PHEAP_STOP_ON_VALUES; 00456 00457 #ifndef NTOS_KERNEL_RUNTIME 00458 00459 extern BOOLEAN RtlpDebugHeap; 00460 extern BOOLEAN RtlpValidateHeapHdrsEnable; // Set to TRUE if headers are being corrupted 00461 extern BOOLEAN RtlpValidateHeapTagsEnable; // Set to TRUE if tag counts are off and you want to know why 00462 extern PHEAP RtlpGlobalTagHeap; 00463 extern HEAP_STOP_ON_VALUES RtlpHeapStopOn; 00464 00465 BOOLEAN 00466 RtlpHeapIsLocked( 00467 IN PVOID HeapHandle 00468 ); 00469 00470 // 00471 // Page heap external interface. 00472 // 00473 00474 #include <heappage.h> 00475 00476 #endif // NTOS_KERNEL_RUNTIME 00477 00478 #endif // _RTL_HEAP_

Generated on Sat May 15 19:40:15 2004 for test by doxygen 1.3.7