Rémi Bernon : ntdll: Add a first heap block member to the subheap.

Alexandre Julliard julliard at winehq.org
Wed May 25 16:51:47 CDT 2022


Module: wine
Branch: master
Commit: 7f9efcd4169a8181b3cee9f3a910fd2390fbc101
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=7f9efcd4169a8181b3cee9f3a910fd2390fbc101

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Wed May 25 09:30:43 2022 +0200

ntdll: Add a first heap block member to the subheap.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>

---

 dlls/ntdll/heap.c | 32 +++++++++++++++-----------------
 1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index 061dbd8a731..d83e3971420 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -161,17 +161,19 @@ typedef union
 
 struct tagHEAP;
 
-typedef struct tagSUBHEAP
+typedef struct DECLSPEC_ALIGN(ALIGNMENT) tagSUBHEAP
 {
+    SIZE_T __pad[sizeof(SIZE_T) / sizeof(DWORD)];
     SIZE_T              size;       /* Size of the whole sub-heap */
     SIZE_T              commitSize; /* Committed size of the sub-heap */
     struct list         entry;      /* Entry in sub-heap list */
     struct tagHEAP     *heap;       /* Main heap structure */
-    DWORD               headerSize; /* Size of the heap header */
-    DWORD               magic;      /* Magic number */
+    struct block block;
 } SUBHEAP;
 
-#define SUBHEAP_MAGIC    ((DWORD)('S' | ('U'<<8) | ('B'<<16) | ('H'<<24)))
+/* block must be last and aligned */
+C_ASSERT( sizeof(SUBHEAP) == offsetof(SUBHEAP, block) + sizeof(struct block) );
+C_ASSERT( sizeof(SUBHEAP) == 4 * ALIGNMENT );
 
 typedef struct tagHEAP
 {                                  /* win32/win64 */
@@ -199,6 +201,9 @@ typedef struct tagHEAP
     SUBHEAP          subheap;
 } HEAP;
 
+/* subheap must be last and aligned */
+C_ASSERT( sizeof(HEAP) == offsetof(HEAP, subheap) + sizeof(SUBHEAP) );
+C_ASSERT( sizeof(HEAP) % ALIGNMENT == 0 );
 C_ASSERT( offsetof(HEAP, subheap) <= COMMIT_MASK );
 
 #define HEAP_MAGIC       ((DWORD)('H' | ('E'<<8) | ('A'<<16) | ('P'<<24)))
@@ -274,7 +279,7 @@ static inline SIZE_T subheap_size( const SUBHEAP *subheap )
 
 static inline SIZE_T subheap_overhead( const SUBHEAP *subheap )
 {
-    return subheap->headerSize;
+    return (char *)&subheap->block - (char *)subheap_base( subheap );
 }
 
 static inline const void *subheap_commit_end( const SUBHEAP *subheap )
@@ -284,7 +289,7 @@ static inline const void *subheap_commit_end( const SUBHEAP *subheap )
 
 static inline void *first_block( const SUBHEAP *subheap )
 {
-    return (char *)subheap_base( subheap ) + subheap->headerSize;
+    return (void *)&subheap->block;
 }
 
 static inline const void *last_block( const SUBHEAP *subheap )
@@ -303,7 +308,7 @@ static inline struct block *next_block( const SUBHEAP *subheap, const struct blo
 static inline BOOL check_subheap( const SUBHEAP *subheap )
 {
     const char *base = ROUND_ADDR( subheap, COMMIT_MASK );
-    return contains( base, subheap->size, base + subheap->headerSize, subheap->commitSize - subheap->headerSize );
+    return contains( base, subheap->size, &subheap->block, base + subheap->commitSize - (char *)&subheap->block );
 }
 
 static BOOL heap_validate( const HEAP *heap );
@@ -941,8 +946,6 @@ static SUBHEAP *HEAP_CreateSubHeap( HEAP *heap, LPVOID address, DWORD flags,
         subheap->heap       = heap;
         subheap->size       = totalSize;
         subheap->commitSize = commitSize;
-        subheap->magic      = SUBHEAP_MAGIC;
-        subheap->headerSize = ROUND_SIZE( sizeof(SUBHEAP) );
         list_add_head( &heap->subheap_list, &subheap->entry );
     }
     else
@@ -964,8 +967,6 @@ static SUBHEAP *HEAP_CreateSubHeap( HEAP *heap, LPVOID address, DWORD flags,
         subheap->heap       = heap;
         subheap->size       = totalSize;
         subheap->commitSize = commitSize;
-        subheap->magic      = SUBHEAP_MAGIC;
-        subheap->headerSize = ROUND_SIZE( sizeof(HEAP) );
         list_add_head( &heap->subheap_list, &subheap->entry );
 
         /* Build the free lists */
@@ -1048,12 +1049,9 @@ static struct block *find_free_block( HEAP *heap, SIZE_T data_size, SUBHEAP **su
         WARN("Not enough space in heap %p for %08lx bytes\n", heap, data_size );
         return NULL;
     }
-    /* make sure that we have a big enough size *committed* to fit another
-     * last free arena in !
-     * So just one heap struct, one first free arena which will eventually
-     * get used, and a second free arena that might get assigned all remaining
-     * free space in shrink_used_block() */
-    total_size = data_size + ROUND_SIZE(sizeof(SUBHEAP)) + sizeof(ARENA_INUSE) + sizeof(ARENA_FREE);
+
+    /* SUBHEAP includes the first block header, and we want to fit a free entry at the end */
+    total_size = sizeof(SUBHEAP) + data_size + sizeof(ARENA_FREE);
     if (total_size < data_size) return NULL;  /* overflow */
 
     if ((*subheap = HEAP_CreateSubHeap( heap, NULL, heap->flags, total_size,




More information about the wine-cvs mailing list