Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

505 lines
13 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. heap.h
  5. Abstract:
  6. This is the header file that describes the constants and data
  7. structures used by the user mode heap manager, exported by ntdll.dll
  8. and ntrtl.lib
  9. Procedure prototypes are defined in ntrtl.h
  10. Author:
  11. Steve Wood (stevewo) 21-Aug-1992
  12. Revision History:
  13. --*/
  14. #ifndef _RTL_HEAP_
  15. #define _RTL_HEAP_
  16. #define HEAP_LARGE_TAG_MASK 0xFF000000
  17. #define ROUND_UP_TO_POWER2( x, n ) (((ULONG_PTR)(x) + ((n)-1)) & ~((ULONG_PTR)(n)-1))
  18. #define ROUND_DOWN_TO_POWER2( x, n ) ((ULONG_PTR)(x) & ~((ULONG_PTR)(n)-1))
  19. typedef struct _HEAP_ENTRY {
  20. #if !defined(_WIN64)
  21. union {
  22. struct {
  23. //
  24. // This field gives the size of the current block in allocation
  25. // granularity units. (i.e. Size << HEAP_GRANULARITY_SHIFT
  26. // equals the size in bytes).
  27. //
  28. // Except if this is part of a virtual alloc block then this
  29. // value is the difference between the commit size in the virtual
  30. // alloc entry and the what the user asked for.
  31. //
  32. USHORT Size;
  33. //
  34. // This field gives the size of the previous block in allocation
  35. // granularity units. (i.e. PreviousSize << HEAP_GRANULARITY_SHIFT
  36. // equals the size of the previous block in bytes).
  37. //
  38. USHORT PreviousSize;
  39. };
  40. volatile PVOID SubSegment;
  41. };
  42. #else
  43. USHORT Size;
  44. USHORT PreviousSize;
  45. #endif
  46. //
  47. // This field contains the index into the segment that controls
  48. // the memory for this block.
  49. //
  50. volatile UCHAR SegmentIndex;
  51. //
  52. // This field contains various flag bits associated with this block.
  53. // Currently these are:
  54. //
  55. // 0x01 - HEAP_ENTRY_BUSY
  56. // 0x02 - HEAP_ENTRY_EXTRA_PRESENT
  57. // 0x04 - HEAP_ENTRY_FILL_PATTERN
  58. // 0x08 - HEAP_ENTRY_VIRTUAL_ALLOC
  59. // 0x10 - HEAP_ENTRY_LAST_ENTRY
  60. // 0x20 - HEAP_ENTRY_SETTABLE_FLAG1
  61. // 0x40 - HEAP_ENTRY_SETTABLE_FLAG2
  62. // 0x80 - HEAP_ENTRY_SETTABLE_FLAG3
  63. //
  64. UCHAR Flags;
  65. //
  66. // This field contains the number of unused bytes at the end of this
  67. // block that were not actually allocated. Used to compute exact
  68. // size requested prior to rounding requested size to allocation
  69. // granularity. Also used for tail checking purposes.
  70. //
  71. UCHAR UnusedBytes;
  72. //
  73. // Small (8 bit) tag indexes can go here.
  74. //
  75. UCHAR SmallTagIndex;
  76. #if defined(_WIN64)
  77. volatile PVOID SubSegment;
  78. #endif
  79. } HEAP_ENTRY, *PHEAP_ENTRY;
  80. //
  81. // This block describes extra information that might be at the end of a
  82. // busy block.
  83. // Note: The heap code is assuming that:
  84. // sizeof( HEAP_ENTRY_EXTRA ) == sizeof( HEAP_ENTRY )
  85. //
  86. typedef struct _HEAP_ENTRY_EXTRA {
  87. union {
  88. struct {
  89. //
  90. // This field is for debugging purposes. It will normally contain a
  91. // stack back trace index of the allocator for x86 systems.
  92. //
  93. USHORT AllocatorBackTraceIndex;
  94. //
  95. // This field is currently unused, but is intended for storing
  96. // any encoded value that will give the that gives the type of object
  97. // allocated.
  98. //
  99. USHORT TagIndex;
  100. //
  101. // This field is a 32-bit settable value that a higher level heap package
  102. // can use. The Win32 heap manager stores handle values in this field.
  103. //
  104. ULONG_PTR Settable;
  105. };
  106. #if defined(_WIN64)
  107. struct {
  108. ULONGLONG ZeroInit;
  109. ULONGLONG ZeroInit1;
  110. };
  111. #else
  112. ULONGLONG ZeroInit;
  113. #endif
  114. };
  115. } HEAP_ENTRY_EXTRA, *PHEAP_ENTRY_EXTRA;
  116. //
  117. // This structure is present at the end of a free block if HEAP_ENTRY_EXTRA_PRESENT
  118. // is set in the Flags field of a HEAP_FREE_ENTRY structure. It is used to save the
  119. // tag index that was associated with the allocated block after it has been freed.
  120. // Works best when coalesce on free is disabled, along with decommitment.
  121. //
  122. typedef struct _HEAP_FREE_ENTRY_EXTRA {
  123. USHORT TagIndex;
  124. USHORT FreeBackTraceIndex;
  125. } HEAP_FREE_ENTRY_EXTRA, *PHEAP_FREE_ENTRY_EXTRA;
  126. //
  127. // This structure describes a block that lies outside normal heap memory
  128. // as it was allocated with NtAllocateVirtualMemory and has the
  129. // HEAP_ENTRY_VIRTUAL_ALLOC flag set.
  130. //
  131. typedef struct _HEAP_VIRTUAL_ALLOC_ENTRY {
  132. LIST_ENTRY Entry;
  133. HEAP_ENTRY_EXTRA ExtraStuff;
  134. SIZE_T CommitSize;
  135. SIZE_T ReserveSize;
  136. HEAP_ENTRY BusyBlock;
  137. } HEAP_VIRTUAL_ALLOC_ENTRY, *PHEAP_VIRTUAL_ALLOC_ENTRY;
  138. typedef struct _HEAP_FREE_ENTRY {
  139. //
  140. // This field gives the size of the current block in allocation
  141. // granularity units. (i.e. Size << HEAP_GRANULARITY_SHIFT
  142. // equals the size in bytes).
  143. //
  144. USHORT Size;
  145. //
  146. // This field gives the size of the previous block in allocation
  147. // granularity units. (i.e. PreviousSize << HEAP_GRANULARITY_SHIFT
  148. // equals the size of the previous block in bytes).
  149. //
  150. USHORT PreviousSize;
  151. //
  152. // This field contains the index into the segment that controls
  153. // the memory for this block.
  154. //
  155. UCHAR SegmentIndex;
  156. //
  157. // This field contains various flag bits associated with this block.
  158. // Currently for free blocks these can be:
  159. //
  160. // 0x02 - HEAP_ENTRY_EXTRA_PRESENT
  161. // 0x04 - HEAP_ENTRY_FILL_PATTERN
  162. // 0x10 - HEAP_ENTRY_LAST_ENTRY
  163. //
  164. UCHAR Flags;
  165. //
  166. // Two fields to encode the location of the bit in FreeListsInUse
  167. // array in HEAP_SEGMENT for blocks of this size.
  168. //
  169. UCHAR Index;
  170. UCHAR Mask;
  171. //
  172. // Free blocks use these two words for linking together free blocks
  173. // of the same size on a doubly linked list.
  174. //
  175. LIST_ENTRY FreeList;
  176. #if defined(_WIN64)
  177. ULONGLONG Reserved1;
  178. #endif
  179. } HEAP_FREE_ENTRY, *PHEAP_FREE_ENTRY;
  180. #define HEAP_GRANULARITY ((LONG) sizeof( HEAP_ENTRY ))
  181. #if defined(_WIN64)
  182. #define HEAP_GRANULARITY_SHIFT 4 // Log2( HEAP_GRANULARITY )
  183. #else
  184. #define HEAP_GRANULARITY_SHIFT 3 // Log2( HEAP_GRANULARITY )
  185. #endif
  186. #define HEAP_MAXIMUM_BLOCK_SIZE (USHORT)(((0x10000 << HEAP_GRANULARITY_SHIFT) - PAGE_SIZE) >> HEAP_GRANULARITY_SHIFT)
  187. #define HEAP_MAXIMUM_FREELISTS 128
  188. #define HEAP_MAXIMUM_SEGMENTS 64
  189. #define HEAP_ENTRY_BUSY 0x01
  190. #define HEAP_ENTRY_EXTRA_PRESENT 0x02
  191. #define HEAP_ENTRY_FILL_PATTERN 0x04
  192. #define HEAP_ENTRY_VIRTUAL_ALLOC 0x08
  193. #define HEAP_ENTRY_LAST_ENTRY 0x10
  194. #define HEAP_ENTRY_SETTABLE_FLAG1 0x20
  195. #define HEAP_ENTRY_SETTABLE_FLAG2 0x40
  196. #define HEAP_ENTRY_SETTABLE_FLAG3 0x80
  197. #define HEAP_ENTRY_SETTABLE_FLAGS 0xE0
  198. //
  199. // HEAP_SEGMENT defines the structure used to describe a range of
  200. // contiguous virtual memory that has been set aside for use by
  201. // a heap.
  202. //
  203. typedef struct _HEAP_UNCOMMMTTED_RANGE {
  204. struct _HEAP_UNCOMMMTTED_RANGE *Next;
  205. ULONG_PTR Address;
  206. SIZE_T Size;
  207. ULONG filler;
  208. } HEAP_UNCOMMMTTED_RANGE, *PHEAP_UNCOMMMTTED_RANGE;
  209. typedef struct _HEAP_SEGMENT {
  210. HEAP_ENTRY Entry;
  211. ULONG Signature;
  212. ULONG Flags;
  213. struct _HEAP *Heap;
  214. SIZE_T LargestUnCommittedRange;
  215. PVOID BaseAddress;
  216. ULONG NumberOfPages;
  217. PHEAP_ENTRY FirstEntry;
  218. PHEAP_ENTRY LastValidEntry;
  219. ULONG NumberOfUnCommittedPages;
  220. ULONG NumberOfUnCommittedRanges;
  221. PHEAP_UNCOMMMTTED_RANGE UnCommittedRanges;
  222. USHORT AllocatorBackTraceIndex;
  223. USHORT Reserved;
  224. PHEAP_ENTRY LastEntryInSegment;
  225. } HEAP_SEGMENT, *PHEAP_SEGMENT;
  226. #define HEAP_SEGMENT_SIGNATURE 0xFFEEFFEE
  227. #define HEAP_SEGMENT_USER_ALLOCATED (ULONG)0x00000001
  228. //
  229. // HEAP defines the header for a heap.
  230. //
  231. typedef struct _HEAP_LOCK {
  232. union {
  233. RTL_CRITICAL_SECTION CriticalSection;
  234. ERESOURCE Resource;
  235. } Lock;
  236. } HEAP_LOCK, *PHEAP_LOCK;
  237. typedef struct _HEAP_UCR_SEGMENT {
  238. struct _HEAP_UCR_SEGMENT *Next;
  239. SIZE_T ReservedSize;
  240. SIZE_T CommittedSize;
  241. ULONG filler;
  242. } HEAP_UCR_SEGMENT, *PHEAP_UCR_SEGMENT;
  243. typedef struct _HEAP_TAG_ENTRY {
  244. ULONG Allocs;
  245. ULONG Frees;
  246. SIZE_T Size;
  247. USHORT TagIndex;
  248. USHORT CreatorBackTraceIndex;
  249. WCHAR TagName[ 24 ];
  250. } HEAP_TAG_ENTRY, *PHEAP_TAG_ENTRY; // sizeof( HEAP_TAG_ENTRY ) must divide page size evenly
  251. typedef struct _HEAP_PSEUDO_TAG_ENTRY {
  252. ULONG Allocs;
  253. ULONG Frees;
  254. SIZE_T Size;
  255. } HEAP_PSEUDO_TAG_ENTRY, *PHEAP_PSEUDO_TAG_ENTRY;
  256. typedef struct _HEAP {
  257. HEAP_ENTRY Entry;
  258. ULONG Signature;
  259. ULONG Flags;
  260. ULONG ForceFlags;
  261. ULONG VirtualMemoryThreshold;
  262. SIZE_T SegmentReserve;
  263. SIZE_T SegmentCommit;
  264. SIZE_T DeCommitFreeBlockThreshold;
  265. SIZE_T DeCommitTotalFreeThreshold;
  266. SIZE_T TotalFreeSize;
  267. SIZE_T MaximumAllocationSize;
  268. USHORT ProcessHeapsListIndex;
  269. USHORT HeaderValidateLength;
  270. PVOID HeaderValidateCopy;
  271. USHORT NextAvailableTagIndex;
  272. USHORT MaximumTagIndex;
  273. PHEAP_TAG_ENTRY TagEntries;
  274. PHEAP_UCR_SEGMENT UCRSegments;
  275. PHEAP_UNCOMMMTTED_RANGE UnusedUnCommittedRanges;
  276. //
  277. // The following two fields control the alignment for each new heap entry
  278. // allocation. The round is added to each size and the mask is used to
  279. // align it. The round value includes the heap entry and any tail checking
  280. // space
  281. //
  282. SIZE_T AlignRound;
  283. SIZE_T AlignMask;
  284. LIST_ENTRY VirtualAllocdBlocks;
  285. PHEAP_SEGMENT Segments[ HEAP_MAXIMUM_SEGMENTS ];
  286. union {
  287. ULONG FreeListsInUseUlong[ HEAP_MAXIMUM_FREELISTS / 32 ];
  288. UCHAR FreeListsInUseBytes[ HEAP_MAXIMUM_FREELISTS / 8 ];
  289. } u;
  290. union {
  291. USHORT FreeListsInUseTerminate;
  292. USHORT DecommitCount;
  293. } u2;
  294. USHORT AllocatorBackTraceIndex;
  295. ULONG NonDedicatedListLength;
  296. PVOID LargeBlocksIndex;
  297. PHEAP_PSEUDO_TAG_ENTRY PseudoTagEntries;
  298. LIST_ENTRY FreeLists[ HEAP_MAXIMUM_FREELISTS ];
  299. PHEAP_LOCK LockVariable;
  300. PRTL_HEAP_COMMIT_ROUTINE CommitRoutine;
  301. //
  302. // The following field is used to manage the heap lookaside list. The
  303. // pointer is used to locate the lookaside list array. If it is null
  304. // then the lookaside list is not active.
  305. //
  306. // The lock count is used to denote if the heap is locked. A zero value
  307. // means the heap is not locked. Each lock operation increments the
  308. // heap count and each unlock decrements the counter
  309. //
  310. PVOID FrontEndHeap;
  311. USHORT FrontHeapLockCount;
  312. UCHAR FrontEndHeapType;
  313. UCHAR LastSegmentIndex;
  314. } HEAP, *PHEAP;
  315. #define HEAP_SIGNATURE (ULONG)0xEEFFEEFF
  316. #define HEAP_LOCK_USER_ALLOCATED (ULONG)0x80000000
  317. #define HEAP_VALIDATE_PARAMETERS_ENABLED (ULONG)0x40000000
  318. #define HEAP_VALIDATE_ALL_ENABLED (ULONG)0x20000000
  319. #define HEAP_SKIP_VALIDATION_CHECKS (ULONG)0x10000000
  320. #define HEAP_CAPTURE_STACK_BACKTRACES (ULONG)0x08000000
  321. #define CHECK_HEAP_TAIL_SIZE HEAP_GRANULARITY
  322. #define CHECK_HEAP_TAIL_FILL 0xAB
  323. #define FREE_HEAP_FILL 0xFEEEFEEE
  324. #define ALLOC_HEAP_FILL 0xBAADF00D
  325. #define HEAP_MAXIMUM_SMALL_TAG 0xFF
  326. #define HEAP_SMALL_TAG_MASK (HEAP_MAXIMUM_SMALL_TAG << HEAP_TAG_SHIFT)
  327. #define HEAP_NEED_EXTRA_FLAGS ((HEAP_TAG_MASK ^ HEAP_SMALL_TAG_MASK) | \
  328. HEAP_CAPTURE_STACK_BACKTRACES | \
  329. HEAP_SETTABLE_USER_VALUE \
  330. )
  331. #define HEAP_NUMBER_OF_PSEUDO_TAG (HEAP_MAXIMUM_FREELISTS+1)
  332. #if (HEAP_ENTRY_SETTABLE_FLAG1 ^ \
  333. HEAP_ENTRY_SETTABLE_FLAG2 ^ \
  334. HEAP_ENTRY_SETTABLE_FLAG3 ^ \
  335. HEAP_ENTRY_SETTABLE_FLAGS \
  336. )
  337. #error Invalid HEAP_ENTRY_SETTABLE_FLAGS
  338. #endif
  339. #if ((HEAP_ENTRY_BUSY ^ \
  340. HEAP_ENTRY_EXTRA_PRESENT ^ \
  341. HEAP_ENTRY_FILL_PATTERN ^ \
  342. HEAP_ENTRY_VIRTUAL_ALLOC ^ \
  343. HEAP_ENTRY_LAST_ENTRY ^ \
  344. HEAP_ENTRY_SETTABLE_FLAGS \
  345. ) != \
  346. (HEAP_ENTRY_BUSY | \
  347. HEAP_ENTRY_EXTRA_PRESENT | \
  348. HEAP_ENTRY_FILL_PATTERN | \
  349. HEAP_ENTRY_VIRTUAL_ALLOC | \
  350. HEAP_ENTRY_LAST_ENTRY | \
  351. HEAP_ENTRY_SETTABLE_FLAGS \
  352. ) \
  353. )
  354. #error Conflicting HEAP_ENTRY flags
  355. #endif
  356. #if ((HEAP_SETTABLE_USER_FLAGS >> 4) ^ HEAP_ENTRY_SETTABLE_FLAGS)
  357. #error HEAP_SETTABLE_USER_FLAGS in ntrtl.h conflicts with HEAP_ENTRY_SETTABLE_FLAGS in heap.h
  358. #endif
  359. typedef struct _HEAP_STOP_ON_TAG {
  360. union {
  361. ULONG HeapAndTagIndex;
  362. struct {
  363. USHORT TagIndex;
  364. USHORT HeapIndex;
  365. };
  366. };
  367. } HEAP_STOP_ON_TAG, *PHEAP_STOP_ON_TAG;
  368. typedef struct _HEAP_STOP_ON_VALUES {
  369. SIZE_T AllocAddress;
  370. HEAP_STOP_ON_TAG AllocTag;
  371. SIZE_T ReAllocAddress;
  372. HEAP_STOP_ON_TAG ReAllocTag;
  373. SIZE_T FreeAddress;
  374. HEAP_STOP_ON_TAG FreeTag;
  375. } HEAP_STOP_ON_VALUES, *PHEAP_STOP_ON_VALUES;
  376. #ifndef NTOS_KERNEL_RUNTIME
  377. extern BOOLEAN RtlpDebugHeap;
  378. extern BOOLEAN RtlpValidateHeapHdrsEnable; // Set to TRUE if headers are being corrupted
  379. extern BOOLEAN RtlpValidateHeapTagsEnable; // Set to TRUE if tag counts are off and you want to know why
  380. extern PHEAP RtlpGlobalTagHeap;
  381. extern HEAP_STOP_ON_VALUES RtlpHeapStopOn;
  382. BOOLEAN
  383. RtlpHeapIsLocked(
  384. IN PVOID HeapHandle
  385. );
  386. //
  387. // Page heap external interface.
  388. //
  389. #include <heappage.h>
  390. #endif // NTOS_KERNEL_RUNTIME
  391. #endif // _RTL_HEAP_