From: Rémi Bernon rbernon@codeweavers.com
Instead of subheap->heap.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntdll/heap.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index 540625bff27..15b708f66c2 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -1393,6 +1393,7 @@ HANDLE WINAPI RtlCreateHeap( ULONG flags, PVOID addr, SIZE_T totalSize, SIZE_T c PVOID unknown, PRTL_HEAP_DEFINITION definition ) { SUBHEAP *subheap; + HEAP *heap;
/* Allocate the heap block */
@@ -1402,24 +1403,24 @@ HANDLE WINAPI RtlCreateHeap( ULONG flags, PVOID addr, SIZE_T totalSize, SIZE_T c if (!totalSize) totalSize = HEAP_DEF_SIZE;
if (!(subheap = HEAP_CreateSubHeap( NULL, addr, flags, commitSize, totalSize ))) return 0; + heap = subheap->heap;
- heap_set_debug_flags( subheap->heap ); + heap_set_debug_flags( heap );
/* link it into the per-process heap list */ if (processHeap) { - HEAP *heapPtr = subheap->heap; RtlEnterCriticalSection( &processHeap->cs ); - list_add_head( &processHeap->entry, &heapPtr->entry ); + list_add_head( &processHeap->entry, &heap->entry ); RtlLeaveCriticalSection( &processHeap->cs ); } else if (!addr) { - processHeap = subheap->heap; /* assume the first heap we create is the process main heap */ + processHeap = heap; /* assume the first heap we create is the process main heap */ list_init( &processHeap->entry ); }
- return subheap->heap; + return heap; }
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntdll/heap.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index 15b708f66c2..52c9e120a64 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -122,6 +122,7 @@ typedef struct #define ALIGNMENT (2*sizeof(void*)) #define LARGE_ALIGNMENT 16 /* large blocks have stricter alignment */ #define ARENA_OFFSET (ALIGNMENT - sizeof(ARENA_INUSE)) +#define COMMIT_MASK 0xffff /* bitmask for commit/decommit granularity */
C_ASSERT( sizeof(ARENA_LARGE) % LARGE_ALIGNMENT == 0 );
@@ -162,7 +163,6 @@ struct tagHEAP;
typedef struct tagSUBHEAP { - void *base; /* Base address of the sub-heap memory block */ SIZE_T size; /* Size of the whole sub-heap */ SIZE_T min_commit; /* Minimum committed size */ SIZE_T commitSize; /* Committed size of the sub-heap */ @@ -199,10 +199,11 @@ typedef struct tagHEAP SUBHEAP subheap; } HEAP;
+C_ASSERT( offsetof(HEAP, subheap) <= COMMIT_MASK ); + #define HEAP_MAGIC ((DWORD)('H' | ('E'<<8) | ('A'<<16) | ('P'<<24)))
#define HEAP_DEF_SIZE 0x110000 /* Default heap size = 1Mb + 64Kb */ -#define COMMIT_MASK 0xffff /* bitmask for commit/decommit granularity */ #define MAX_FREE_PENDING 1024 /* max number of free requests to delay */
/* some undocumented flags (names are made up) */ @@ -263,7 +264,7 @@ static inline void block_set_size( struct block *block, UINT flags, UINT block_s
static inline void *subheap_base( const SUBHEAP *subheap ) { - return subheap->base; + return ROUND_ADDR( subheap, COMMIT_MASK ); }
static inline SIZE_T subheap_size( const SUBHEAP *subheap ) @@ -301,7 +302,7 @@ static inline struct block *next_block( const SUBHEAP *subheap, const struct blo
static inline BOOL check_subheap( const SUBHEAP *subheap ) { - const char *base = subheap->base; + const char *base = ROUND_ADDR( subheap, COMMIT_MASK ); return contains( base, subheap->size, base + subheap->headerSize, subheap->commitSize - subheap->headerSize ); }
@@ -936,7 +937,6 @@ static SUBHEAP *HEAP_CreateSubHeap( HEAP *heap, LPVOID address, DWORD flags, /* If this is a secondary subheap, insert it into list */
subheap = address; - subheap->base = address; subheap->heap = heap; subheap->size = totalSize; subheap->min_commit = 0x10000; @@ -960,7 +960,6 @@ static SUBHEAP *HEAP_CreateSubHeap( HEAP *heap, LPVOID address, DWORD flags, list_init( &heap->large_list );
subheap = &heap->subheap; - subheap->base = address; subheap->heap = heap; subheap->size = totalSize; subheap->min_commit = commitSize; @@ -1476,13 +1475,13 @@ HANDLE WINAPI RtlDestroyHeap( HANDLE heap ) notify_free_all( subheap ); list_remove( &subheap->entry ); size = 0; - addr = subheap->base; + addr = ROUND_ADDR( subheap, COMMIT_MASK ); NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE ); } notify_free_all( &heapPtr->subheap ); RtlFreeHeap( GetProcessHeap(), 0, heapPtr->pending_free ); size = 0; - addr = heapPtr->subheap.base; + addr = heap; NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE ); return 0; }
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntdll/heap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index 52c9e120a64..061dbd8a731 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -164,7 +164,6 @@ struct tagHEAP; typedef struct tagSUBHEAP { SIZE_T size; /* Size of the whole sub-heap */ - SIZE_T min_commit; /* Minimum committed size */ SIZE_T commitSize; /* Committed size of the sub-heap */ struct list entry; /* Entry in sub-heap list */ struct tagHEAP *heap; /* Main heap structure */ @@ -191,6 +190,7 @@ typedef struct tagHEAP struct list subheap_list; /* Sub-heap list */ struct list large_list; /* Large blocks list */ SIZE_T grow_size; /* Size of next subheap for growing heap */ + SIZE_T min_size; /* Minimum committed size */ DWORD magic; /* Magic number */ DWORD pending_pos; /* Position in pending free requests ring */ ARENA_INUSE **pending_free; /* Ring buffer for pending free requests */ @@ -649,12 +649,13 @@ static inline BOOL subheap_commit( SUBHEAP *subheap, const struct block *block,
static inline BOOL subheap_decommit( SUBHEAP *subheap, const void *commit_end ) { + char *base = subheap_base( subheap ); HEAP *heap = subheap->heap; SIZE_T size; void *addr;
commit_end = ROUND_ADDR((char *)commit_end + COMMIT_MASK, COMMIT_MASK); - commit_end = max( (char *)commit_end, (char *)subheap_base( subheap ) + subheap->min_commit ); + if (subheap == &heap->subheap) commit_end = max( (char *)commit_end, (char *)base + heap->min_size ); if (commit_end >= subheap_commit_end( subheap )) return TRUE;
size = (char *)subheap_commit_end( subheap ) - (char *)commit_end; @@ -939,7 +940,6 @@ static SUBHEAP *HEAP_CreateSubHeap( HEAP *heap, LPVOID address, DWORD flags, subheap = address; subheap->heap = heap; subheap->size = totalSize; - subheap->min_commit = 0x10000; subheap->commitSize = commitSize; subheap->magic = SUBHEAP_MAGIC; subheap->headerSize = ROUND_SIZE( sizeof(SUBHEAP) ); @@ -956,13 +956,13 @@ static SUBHEAP *HEAP_CreateSubHeap( HEAP *heap, LPVOID address, DWORD flags, heap->shared = (flags & HEAP_SHARED) != 0; heap->magic = HEAP_MAGIC; heap->grow_size = max( HEAP_DEF_SIZE, totalSize ); + heap->min_size = commitSize; list_init( &heap->subheap_list ); list_init( &heap->large_list );
subheap = &heap->subheap; subheap->heap = heap; subheap->size = totalSize; - subheap->min_commit = commitSize; subheap->commitSize = commitSize; subheap->magic = SUBHEAP_MAGIC; subheap->headerSize = ROUND_SIZE( sizeof(HEAP) );
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@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,
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntdll/heap.c | 88 +++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 44 deletions(-)
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index d83e3971420..ac0f14646c4 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -132,7 +132,7 @@ C_ASSERT( sizeof(ARENA_LARGE) % LARGE_ALIGNMENT == 0 ); /* minimum data size (without arenas) of an allocated block */ /* make sure that it's larger than a free list entry */ #define HEAP_MIN_DATA_SIZE ROUND_SIZE(2 * sizeof(struct list)) -#define HEAP_MIN_ARENA_SIZE (HEAP_MIN_DATA_SIZE + sizeof(ARENA_INUSE)) +#define HEAP_MIN_BLOCK_SIZE (HEAP_MIN_DATA_SIZE + sizeof(ARENA_INUSE)) /* minimum size that must remain to shrink an allocated block */ #define HEAP_MIN_SHRINK_SIZE (HEAP_MIN_DATA_SIZE+sizeof(ARENA_FREE)) /* minimum size to start allocating large blocks */ @@ -144,7 +144,7 @@ C_ASSERT( sizeof(ARENA_LARGE) % LARGE_ALIGNMENT == 0 ); /* There will be a free list bucket for every arena size up to and including this value */ #define HEAP_MAX_SMALL_FREE_LIST 0x100 C_ASSERT( HEAP_MAX_SMALL_FREE_LIST % ALIGNMENT == 0 ); -#define HEAP_NB_SMALL_FREE_LISTS (((HEAP_MAX_SMALL_FREE_LIST - HEAP_MIN_ARENA_SIZE) / ALIGNMENT) + 1) +#define HEAP_NB_SMALL_FREE_LISTS (((HEAP_MAX_SMALL_FREE_LIST - HEAP_MIN_BLOCK_SIZE) / ALIGNMENT) + 1)
/* Max size of the blocks on the free lists above HEAP_MAX_SMALL_FREE_LIST */ static const SIZE_T HEAP_freeListSizes[] = @@ -426,15 +426,15 @@ static void notify_free_all( SUBHEAP *subheap )
/* locate a free list entry of the appropriate size */ /* size is the size of the whole block including the arena header */ -static inline struct entry *find_free_list( HEAP *heap, SIZE_T size, BOOL last ) +static inline struct entry *find_free_list( HEAP *heap, SIZE_T block_size, BOOL last ) { FREE_LIST_ENTRY *list, *end = heap->freeList + ARRAY_SIZE(heap->freeList); unsigned int i;
- if (size <= HEAP_MAX_SMALL_FREE_LIST) - i = (size - HEAP_MIN_ARENA_SIZE) / ALIGNMENT; + if (block_size <= HEAP_MAX_SMALL_FREE_LIST) + i = (block_size - HEAP_MIN_BLOCK_SIZE) / ALIGNMENT; else for (i = HEAP_NB_SMALL_FREE_LISTS; i < HEAP_NB_FREE_LISTS - 1; i++) - if (size <= HEAP_freeListSizes[i - HEAP_NB_SMALL_FREE_LISTS]) break; + if (block_size <= HEAP_freeListSizes[i - HEAP_NB_SMALL_FREE_LISTS]) break;
list = heap->freeList + i; if (last && ++list == end) list = heap->freeList; @@ -492,7 +492,7 @@ static void heap_dump( const HEAP *heap ) TRACE( " free_lists: %p\n", heap->freeList ); for (i = 0; i < HEAP_NB_FREE_LISTS; i++) { - if (i < HEAP_NB_SMALL_FREE_LISTS) size = HEAP_MIN_ARENA_SIZE + i * ALIGNMENT; + if (i < HEAP_NB_SMALL_FREE_LISTS) size = HEAP_MIN_BLOCK_SIZE + i * ALIGNMENT; else size = HEAP_freeListSizes[i - HEAP_NB_SMALL_FREE_LISTS]; TRACE( " %p: size %8Ix, prev %p, next %p\n", heap->freeList + i, size, LIST_ENTRY( heap->freeList[i].arena.entry.prev, struct entry, entry ), @@ -624,7 +624,7 @@ static SUBHEAP *find_subheap( const HEAP *heap, const struct block *block, BOOL }
-static inline BOOL subheap_commit( SUBHEAP *subheap, const struct block *block, SIZE_T data_size ) +static inline BOOL subheap_commit( SUBHEAP *subheap, const struct block *block, SIZE_T block_size ) { const char *end = (char *)subheap_base( subheap ) + subheap_size( subheap ), *commit_end; HEAP *heap = subheap->heap; @@ -632,7 +632,7 @@ static inline BOOL subheap_commit( SUBHEAP *subheap, const struct block *block, SIZE_T size; void *addr;
- commit_end = (char *)(block + 1) + data_size + sizeof(ARENA_FREE); + commit_end = (char *)block + block_size + sizeof(ARENA_FREE); commit_end = ROUND_ADDR((char *)commit_end + COMMIT_MASK, COMMIT_MASK);
if (commit_end > end) commit_end = end; @@ -767,19 +767,19 @@ static void free_used_block( SUBHEAP *subheap, struct block *block )
static inline void shrink_used_block( SUBHEAP *subheap, struct block *block, UINT flags, - SIZE_T old_data_size, SIZE_T data_size, SIZE_T size ) + SIZE_T old_block_size, SIZE_T block_size, SIZE_T size ) { - if (old_data_size >= data_size + HEAP_MIN_SHRINK_SIZE) + if (old_block_size >= block_size + HEAP_MIN_SHRINK_SIZE) { - block_set_size( block, flags, data_size + sizeof(*block) ); - block->unused_bytes = data_size - size; - create_free_block( subheap, next_block( subheap, block ), old_data_size - data_size ); + block_set_size( block, flags, block_size ); + block->unused_bytes = block_size - sizeof(*block) - size; + create_free_block( subheap, next_block( subheap, block ), old_block_size - block_size ); } else { struct block *next; - block_set_size( block, flags, old_data_size + sizeof(*block) ); - block->unused_bytes = old_data_size - size; + block_set_size( block, flags, old_block_size ); + block->unused_bytes = old_block_size - sizeof(*block) - size; if ((next = next_block( subheap, block ))) next->size &= ~ARENA_FLAG_PREV_FREE; } } @@ -1019,9 +1019,9 @@ static SUBHEAP *HEAP_CreateSubHeap( HEAP *heap, LPVOID address, DWORD flags, }
-static struct block *find_free_block( HEAP *heap, SIZE_T data_size, SUBHEAP **subheap ) +static struct block *find_free_block( HEAP *heap, SIZE_T block_size, SUBHEAP **subheap ) { - struct list *ptr = &find_free_list( heap, data_size + sizeof(ARENA_INUSE), FALSE )->entry; + struct list *ptr = &find_free_list( heap, block_size, FALSE )->entry; struct entry *entry; struct block *block; SIZE_T total_size; @@ -1033,10 +1033,10 @@ static struct block *find_free_block( HEAP *heap, SIZE_T data_size, SUBHEAP **su entry = LIST_ENTRY( ptr, struct entry, entry ); if (entry->size == (0 | ARENA_FLAG_FREE)) continue; block = (struct block *)entry; - if (block_get_size( block ) - sizeof(*block) >= data_size) + if (block_get_size( block ) >= block_size) { *subheap = find_subheap( heap, block, FALSE ); - if (!subheap_commit( *subheap, block, data_size )) return NULL; + if (!subheap_commit( *subheap, block, block_size )) return NULL; list_remove( &entry->entry ); return block; } @@ -1046,13 +1046,13 @@ static struct block *find_free_block( HEAP *heap, SIZE_T data_size, SUBHEAP **su
if (!(heap->flags & HEAP_GROWABLE)) { - WARN("Not enough space in heap %p for %08lx bytes\n", heap, data_size ); + WARN("Not enough space in heap %p for %08lx bytes\n", heap, block_size ); return NULL; }
- /* 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 */ + /* make sure we can fit the block and a free entry at the end */ + total_size = sizeof(SUBHEAP) + block_size + sizeof(ARENA_FREE); + if (total_size < block_size) return NULL; /* overflow */
if ((*subheap = HEAP_CreateSubHeap( heap, NULL, heap->flags, total_size, max( heap->grow_size, total_size ) ))) @@ -1486,15 +1486,15 @@ HANDLE WINAPI RtlDestroyHeap( HANDLE heap )
static NTSTATUS heap_allocate( HEAP *heap, ULONG flags, SIZE_T size, void **ret ) { - SIZE_T old_data_size, data_size; + SIZE_T old_block_size, block_size; struct block *block; SUBHEAP *subheap;
- data_size = ROUND_SIZE(size) + HEAP_TAIL_EXTRA_SIZE(flags); - if (data_size < size) return STATUS_NO_MEMORY; /* overflow */ - if (data_size < HEAP_MIN_DATA_SIZE) data_size = HEAP_MIN_DATA_SIZE; + block_size = sizeof(*block) + ROUND_SIZE(size) + HEAP_TAIL_EXTRA_SIZE(flags); + if (block_size < size) return STATUS_NO_MEMORY; /* overflow */ + if (block_size < HEAP_MIN_BLOCK_SIZE) block_size = HEAP_MIN_BLOCK_SIZE;
- if (data_size >= HEAP_MIN_LARGE_BLOCK_SIZE) + if (block_size >= HEAP_MIN_LARGE_BLOCK_SIZE) { if (!(*ret = allocate_large_block( heap, flags, size ))) return STATUS_NO_MEMORY; return STATUS_SUCCESS; @@ -1502,12 +1502,12 @@ static NTSTATUS heap_allocate( HEAP *heap, ULONG flags, SIZE_T size, void **ret
/* Locate a suitable free block */
- if (!(block = find_free_block( heap, data_size, &subheap ))) return STATUS_NO_MEMORY; + if (!(block = find_free_block( heap, block_size, &subheap ))) return STATUS_NO_MEMORY; /* read the free block size, changing block type or flags may alter it */ - old_data_size = block_get_size( block ) - sizeof(*block); + old_block_size = block_get_size( block );
block_set_type( block, ARENA_INUSE_MAGIC ); - shrink_used_block( subheap, block, 0, old_data_size, data_size, size ); + shrink_used_block( subheap, block, 0, old_block_size, block_size, size );
notify_alloc( block + 1, size, flags & HEAP_ZERO_MEMORY ); initialize_block( block + 1, size, block->unused_bytes, flags ); @@ -1582,14 +1582,14 @@ BOOLEAN WINAPI DECLSPEC_HOTPATCH RtlFreeHeap( HANDLE heap, ULONG flags, void *pt
static NTSTATUS heap_reallocate( HEAP *heap, ULONG flags, void *ptr, SIZE_T size, void **ret ) { - SIZE_T old_data_size, old_size, data_size; + SIZE_T old_block_size, old_size, block_size; struct block *next, *block; SUBHEAP *subheap; NTSTATUS status;
- data_size = ROUND_SIZE(size) + HEAP_TAIL_EXTRA_SIZE(flags); - if (data_size < size) return STATUS_NO_MEMORY; /* overflow */ - if (data_size < HEAP_MIN_DATA_SIZE) data_size = HEAP_MIN_DATA_SIZE; + block_size = sizeof(*block) + ROUND_SIZE(size) + HEAP_TAIL_EXTRA_SIZE(flags); + if (block_size < size) return STATUS_NO_MEMORY; /* overflow */ + if (block_size < HEAP_MIN_BLOCK_SIZE) block_size = HEAP_MIN_BLOCK_SIZE;
if (!(block = unsafe_block_from_ptr( heap, ptr, &subheap ))) return STATUS_INVALID_PARAMETER; if (!subheap) @@ -1600,20 +1600,20 @@ static NTSTATUS heap_reallocate( HEAP *heap, ULONG flags, void *ptr, SIZE_T size
/* Check if we need to grow the block */
- old_data_size = block_get_size( block ) - sizeof(*block); - old_size = block_get_size( block ) - block_get_overhead( block ); - if (data_size > old_data_size) + old_block_size = block_get_size( block ); + old_size = old_block_size - block_get_overhead( block ); + if (block_size > old_block_size) { if ((next = next_block( subheap, block )) && (block_get_flags( next ) & ARENA_FLAG_FREE) && - data_size < HEAP_MIN_LARGE_BLOCK_SIZE && data_size <= old_data_size + block_get_size( next )) + block_size < HEAP_MIN_LARGE_BLOCK_SIZE && block_size <= old_block_size + block_get_size( next )) { /* The next block is free and large enough */ struct entry *entry = (struct entry *)next; list_remove( &entry->entry ); - old_data_size += block_get_size( next ); - if (!subheap_commit( subheap, block, data_size )) return STATUS_NO_MEMORY; + old_block_size += block_get_size( next ); + if (!subheap_commit( subheap, block, block_size )) return STATUS_NO_MEMORY; notify_realloc( block + 1, old_size, size ); - shrink_used_block( subheap, block, block_get_flags( block ), old_data_size, data_size, size ); + shrink_used_block( subheap, block, block_get_flags( block ), old_block_size, block_size, size ); } else { @@ -1629,7 +1629,7 @@ static NTSTATUS heap_reallocate( HEAP *heap, ULONG flags, void *ptr, SIZE_T size else { notify_realloc( block + 1, old_size, size ); - shrink_used_block( subheap, block, block_get_flags( block ), old_data_size, data_size, size ); + shrink_used_block( subheap, block, block_get_flags( block ), old_block_size, block_size, size ); }
/* Clear the extra bytes if needed */
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntdll/heap.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index ac0f14646c4..1b6337d4ce8 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -253,17 +253,11 @@ static inline UINT block_get_overhead( const struct block *block ) /* return the size of a block, including its header */ static inline UINT block_get_size( const struct block *block ) { - UINT data_size = block->size & ARENA_SIZE_MASK, size = data_size; - if (block_get_flags( block ) & ARENA_FLAG_FREE) size += sizeof(struct entry); - else size += sizeof(*block); - if (size < data_size) return ~0u; - return size; + return block->size & ARENA_SIZE_MASK; }
static inline void block_set_size( struct block *block, UINT flags, UINT block_size ) { - if (flags & ARENA_FLAG_FREE) block_size -= sizeof(struct entry); - else block_size -= sizeof(*block); block->size = (block_size & ARENA_SIZE_MASK) | (flags & ~ARENA_SIZE_MASK); }