[PATCH 5/6] ntdll: Prefer using block size rather than data size.
Rémi Bernon
wine at gitlab.winehq.org
Wed May 25 03:00:01 CDT 2022
From: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Rémi Bernon <rbernon at 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 */
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/128
More information about the wine-devel
mailing list