Rémi Bernon : ntdll: Simplify the fallback case in heap_reallocate.

Alexandre Julliard julliard at winehq.org
Wed May 18 15:38:30 CDT 2022


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

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

ntdll: Simplify the fallback case in heap_reallocate.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/heap.c | 45 ++++++++-------------------------------------
 1 file changed, 8 insertions(+), 37 deletions(-)

diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index fa9f617f482..eb45a94da95 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -1663,9 +1663,11 @@ 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 )
 {
+    struct block *next;
     ARENA_INUSE *pArena;
     SUBHEAP *subheap;
     SIZE_T oldBlockSize, oldActualSize, rounded_size;
+    NTSTATUS status;
 
     rounded_size = ROUND_SIZE(size) + HEAP_TAIL_EXTRA_SIZE(flags);
     if (rounded_size < size) return STATUS_NO_MEMORY;  /* overflow */
@@ -1684,20 +1686,8 @@ static NTSTATUS heap_reallocate( HEAP *heap, ULONG flags, void *ptr, SIZE_T size
     oldActualSize = (pArena->size & ARENA_SIZE_MASK) - pArena->unused_bytes;
     if (rounded_size > oldBlockSize)
     {
-        struct block *next;
-
-        if (rounded_size >= HEAP_MIN_LARGE_BLOCK_SIZE)
-        {
-            if (flags & HEAP_REALLOC_IN_PLACE_ONLY) return STATUS_NO_MEMORY;
-            if (!(*ret = allocate_large_block( heap, flags, size ))) return STATUS_NO_MEMORY;
-            memcpy( *ret, pArena + 1, oldActualSize );
-            notify_free( pArena + 1 );
-            HEAP_MakeInUseBlockFree( subheap, pArena );
-            return STATUS_SUCCESS;
-        }
-
         if ((next = next_block( subheap, pArena )) && (block_get_flags( next ) & ARENA_FLAG_FREE) &&
-            (oldBlockSize + block_get_size( next ) >= rounded_size))
+            rounded_size < HEAP_MIN_LARGE_BLOCK_SIZE && rounded_size <= oldBlockSize + block_get_size( next ))
         {
             /* The next block is free and large enough */
             struct entry *entry = (struct entry *)next;
@@ -1707,34 +1697,15 @@ static NTSTATUS heap_reallocate( HEAP *heap, ULONG flags, void *ptr, SIZE_T size
             notify_realloc( pArena + 1, oldActualSize, size );
             HEAP_ShrinkBlock( subheap, pArena, rounded_size );
         }
-        else  /* Do it the hard way */
+        else
         {
-            ARENA_FREE *pNew;
-            ARENA_INUSE *pInUse;
-            SUBHEAP *newsubheap;
-
             if (flags & HEAP_REALLOC_IN_PLACE_ONLY) return STATUS_NO_MEMORY;
-            if (!(pNew = HEAP_FindFreeBlock( heap, rounded_size, &newsubheap ))) return STATUS_NO_MEMORY;
-
-            /* Build the in-use arena */
-
-            list_remove( &pNew->entry );
-            pInUse = (ARENA_INUSE *)pNew;
-            pInUse->size = (pInUse->size & ~ARENA_FLAG_FREE)
-                           + sizeof(ARENA_FREE) - sizeof(ARENA_INUSE);
-            pInUse->magic = ARENA_INUSE_MAGIC;
-            HEAP_ShrinkBlock( newsubheap, pInUse, rounded_size );
-
-            mark_block_initialized( pInUse + 1, oldActualSize );
-            notify_alloc( pInUse + 1, size, FALSE );
-            memcpy( pInUse + 1, pArena + 1, oldActualSize );
-
-            /* Free the previous block */
-
+            if ((status = heap_allocate( heap, flags & ~HEAP_ZERO_MEMORY, size, ret ))) return status;
+            memcpy( *ret, pArena + 1, oldActualSize );
+            if (flags & HEAP_ZERO_MEMORY) memset( (char *)*ret + oldActualSize, 0, size - oldActualSize );
             notify_free( pArena + 1 );
             HEAP_MakeInUseBlockFree( subheap, pArena );
-            subheap = newsubheap;
-            pArena  = pInUse;
+            return STATUS_SUCCESS;
         }
     }
     else




More information about the wine-cvs mailing list