Rémi Bernon : ntdll: Introduce new helper to update block flags and size.
Alexandre Julliard
julliard at winehq.org
Mon May 23 15:51:52 CDT 2022
Module: wine
Branch: master
Commit: b4655f24577b38893abbedcd846d0cd35d6684d0
URL: https://source.winehq.org/git/wine.git/?a=commit;h=b4655f24577b38893abbedcd846d0cd35d6684d0
Author: Rémi Bernon <rbernon at codeweavers.com>
Date: Sat May 21 08:26:40 2022 +0200
ntdll: Introduce new helper to update block flags and size.
And use them in shrink_used_block to set the block sizes.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
dlls/ntdll/heap.c | 32 ++++++++++++++++++--------------
1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index 7e21593cd56..a22f5ec7f1e 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -253,6 +253,13 @@ static inline UINT block_get_size( const struct block *block )
return size;
}
+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);
+}
+
static inline void *subheap_base( const SUBHEAP *subheap )
{
return subheap->base;
@@ -793,18 +800,19 @@ static void HEAP_MakeInUseBlockFree( SUBHEAP *subheap, ARENA_INUSE *pArena )
}
-static void shrink_used_block( SUBHEAP *subheap, struct block *block, SIZE_T data_size, SIZE_T size )
+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_data_size = block_get_size( block ) - sizeof(*block);
if (old_data_size >= data_size + HEAP_MIN_SHRINK_SIZE)
{
- block->size = data_size | block_get_flags( block );
+ 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 );
}
else
{
struct block *next;
+ block_set_size( block, flags, old_data_size + sizeof(*block) );
block->unused_bytes = old_data_size - size;
if ((next = next_block( subheap, block ))) next->size &= ~ARENA_FLAG_PREV_FREE;
}
@@ -1521,8 +1529,8 @@ 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;
struct block *block;
- SIZE_T data_size;
SUBHEAP *subheap;
data_size = ROUND_SIZE(size) + HEAP_TAIL_EXTRA_SIZE(flags);
@@ -1538,15 +1546,11 @@ 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;
+ /* read the free block size, changing block type or flags may alter it */
+ old_data_size = block_get_size( block ) - sizeof(*block);
- /* in-use arena is smaller than free arena,
- * so we have to add the difference to the size */
- block->size = (block->size & ~ARENA_FLAG_FREE) + sizeof(struct entry) - sizeof(*block);
block_set_type( block, ARENA_INUSE_MAGIC );
-
- /* Shrink the block */
-
- shrink_used_block( subheap, block, data_size, size );
+ shrink_used_block( subheap, block, 0, old_data_size, data_size, size );
notify_alloc( block + 1, size, flags & HEAP_ZERO_MEMORY );
initialize_block( block + 1, size, block->unused_bytes, flags );
@@ -1649,10 +1653,10 @@ static NTSTATUS heap_reallocate( HEAP *heap, ULONG flags, void *ptr, SIZE_T size
/* The next block is free and large enough */
struct entry *entry = (struct entry *)next;
list_remove( &entry->entry );
- block->size += block_get_size( next );
+ old_data_size += block_get_size( next );
if (!HEAP_Commit( subheap, block, data_size )) return STATUS_NO_MEMORY;
notify_realloc( block + 1, old_size, size );
- shrink_used_block( subheap, block, data_size, size );
+ shrink_used_block( subheap, block, block_get_flags( block ), old_data_size, data_size, size );
}
else
{
@@ -1668,7 +1672,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, data_size, size );
+ shrink_used_block( subheap, block, block_get_flags( block ), old_data_size, data_size, size );
}
/* Clear the extra bytes if needed */
More information about the wine-cvs
mailing list