Rémi Bernon : ntdll: Use the subheap helpers in HEAP_Commit / HEAP_Decommit.
Alexandre Julliard
julliard at winehq.org
Tue May 24 15:54:59 CDT 2022
Module: wine
Branch: master
Commit: 37b1011135b590e9ce885f23454ec16b6f786b01
URL: https://source.winehq.org/git/wine.git/?a=commit;h=37b1011135b590e9ce885f23454ec16b6f786b01
Author: Rémi Bernon <rbernon at codeweavers.com>
Date: Tue May 24 08:47:11 2022 +0200
ntdll: Use the subheap helpers in HEAP_Commit / HEAP_Decommit.
And rename them to subheap_commit / subheap_decommit.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
dlls/ntdll/heap.c | 81 +++++++++++++++++++++++++++----------------------------
1 file changed, 40 insertions(+), 41 deletions(-)
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index 8e578d19d05..40fbd379772 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -125,6 +125,7 @@ typedef struct
C_ASSERT( sizeof(ARENA_LARGE) % LARGE_ALIGNMENT == 0 );
+#define ROUND_ADDR(addr, mask) ((void *)((UINT_PTR)(addr) & ~(UINT_PTR)(mask)))
#define ROUND_SIZE(size) ((((size) + ALIGNMENT - 1) & ~(ALIGNMENT-1)) + ARENA_OFFSET)
/* minimum data size (without arenas) of an allocated block */
@@ -612,56 +613,54 @@ static SUBHEAP *find_subheap( const HEAP *heap, const struct block *block, BOOL
}
-/***********************************************************************
- * HEAP_Commit
- *
- * Make sure the heap storage is committed for a given size in the specified arena.
- */
-static inline BOOL HEAP_Commit( SUBHEAP *subheap, ARENA_INUSE *pArena, SIZE_T data_size )
-{
- void *ptr = (char *)(pArena + 1) + data_size + sizeof(ARENA_FREE);
- SIZE_T size = (char *)ptr - (char *)subheap->base;
- size = (size + COMMIT_MASK) & ~COMMIT_MASK;
- if (size > subheap->size) size = subheap->size;
- if (size <= subheap->commitSize) return TRUE;
- size -= subheap->commitSize;
- ptr = (char *)subheap->base + subheap->commitSize;
- if (NtAllocateVirtualMemory( NtCurrentProcess(), &ptr, 0,
- &size, MEM_COMMIT, get_protection_type( subheap->heap->flags ) ))
- {
- WARN("Could not commit %08lx bytes at %p for heap %p\n",
- size, ptr, subheap->heap );
+static inline BOOL subheap_commit( SUBHEAP *subheap, const struct block *block, SIZE_T data_size )
+{
+ const char *end = (char *)subheap_base( subheap ) + subheap_size( subheap ), *commit_end;
+ HEAP *heap = subheap->heap;
+ ULONG flags = heap->flags;
+ SIZE_T size;
+ void *addr;
+
+ commit_end = (char *)(block + 1) + data_size + sizeof(ARENA_FREE);
+ commit_end = ROUND_ADDR((char *)commit_end + COMMIT_MASK, COMMIT_MASK);
+
+ if (commit_end > end) commit_end = end;
+ if (commit_end <= (char *)subheap_commit_end( subheap )) return TRUE;
+
+ addr = (void *)subheap_commit_end( subheap );
+ size = commit_end - (char *)addr;
+
+ if (NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 0, &size, MEM_COMMIT,
+ get_protection_type( flags ) ))
+ {
+ WARN( "Could not commit %#Ix bytes at %p for heap %p\n", size, addr, heap );
return FALSE;
}
- subheap->commitSize += size;
+
+ subheap->commitSize = (char *)commit_end - (char *)subheap_base( subheap );
return TRUE;
}
-
-/***********************************************************************
- * HEAP_Decommit
- *
- * If possible, decommit the heap storage from (including) 'ptr'.
- */
-static inline BOOL HEAP_Decommit( SUBHEAP *subheap, void *ptr )
+static inline BOOL subheap_decommit( SUBHEAP *subheap, const void *commit_end )
{
+ HEAP *heap = subheap->heap;
+ SIZE_T size;
void *addr;
- SIZE_T decommit_size;
- SIZE_T size = (char *)ptr - (char *)subheap->base;
- size = ((size + COMMIT_MASK) & ~COMMIT_MASK);
- size = max( size, subheap->min_commit );
- if (size >= subheap->commitSize) return TRUE;
- decommit_size = subheap->commitSize - size;
- addr = (char *)subheap->base + size;
+ 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 (commit_end >= subheap_commit_end( subheap )) return TRUE;
- if (NtFreeVirtualMemory( NtCurrentProcess(), &addr, &decommit_size, MEM_DECOMMIT ))
+ size = (char *)subheap_commit_end( subheap ) - (char *)commit_end;
+ addr = (void *)commit_end;
+
+ if (NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_DECOMMIT ))
{
- WARN("Could not decommit %08lx bytes at %p for heap %p\n",
- decommit_size, (char *)subheap->base + size, subheap->heap );
+ WARN( "Could not decommit %#Ix bytes at %p for heap %p\n", size, addr, heap );
return FALSE;
}
- subheap->commitSize -= decommit_size;
+
+ subheap->commitSize = (char *)commit_end - (char *)subheap_base( subheap );
return TRUE;
}
@@ -750,7 +749,7 @@ static void free_used_block( SUBHEAP *subheap, struct block *block )
else if (!heap->shared)
{
/* keep room for a full commited block as hysteresis */
- HEAP_Decommit( subheap, (char *)(entry + 1) + (COMMIT_MASK + 1) );
+ subheap_decommit( subheap, (char *)(entry + 1) + (COMMIT_MASK + 1) );
}
}
@@ -1032,7 +1031,7 @@ static struct block *find_free_block( HEAP *heap, SIZE_T data_size, SUBHEAP **su
if (block_get_size( block ) - sizeof(*block) >= data_size)
{
*subheap = find_subheap( heap, block, FALSE );
- if (!HEAP_Commit( *subheap, block, data_size )) return NULL;
+ if (!subheap_commit( *subheap, block, data_size )) return NULL;
list_remove( &entry->entry );
return block;
}
@@ -1609,7 +1608,7 @@ static NTSTATUS heap_reallocate( HEAP *heap, ULONG flags, void *ptr, SIZE_T size
struct entry *entry = (struct entry *)next;
list_remove( &entry->entry );
old_data_size += block_get_size( next );
- if (!HEAP_Commit( subheap, block, data_size )) return STATUS_NO_MEMORY;
+ if (!subheap_commit( subheap, block, data_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 );
}
More information about the wine-cvs
mailing list