From 275d93c9ab0f533fa70d698726afc8adaaefb664 Mon Sep 17 00:00:00 2001
From: Adeniyi Mayokun <adeniyimayokun17@gmail.com>
Date: Wed, 14 Mar 2018 06:30:20 +0100
Subject: [PATCH] ntdll/heap.c: align everything to 64 byte to reduce
������false-sharing issues.
Signed-off-by: Adeniyi Mayokun <adeniyimayokun17@gmail.com@gmail.com>
---
������dlls/ntdll/heap.c | 29 ++++++++++++++++-------------
������1 file changed, 16 insertions(+), 13 deletions(-)
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index e0ffdfec99..d59f3c8414 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -90,24 +90,27 @@ typedef struct
������#define ARENA_TAIL_FILLER������������������������������ 0xab
������#define ARENA_FREE_FILLER������������������������������ 0xfeeefeee
������
-/* everything is aligned on 8 byte boundaries (16 for Win64) */
-#define ALIGNMENT������������������������������������������������������������������������������ (2*sizeof(void*))
+/* everything is aligned on 64 byte boundaries */
+#define ALIGNMENT������������������������������������������������������������������������������ 64
������#define LARGE_ALIGNMENT������������������������������������������ 16������ /* large blocks have stricter alignment */
-#define ARENA_OFFSET������������������������������������������������������������ (ALIGNMENT - sizeof(ARENA_INUSE))
������
������C_ASSERT( sizeof(ARENA_LARGE) % LARGE_ALIGNMENT == 0 );
������
-#define ROUND_SIZE(size)������������������������������������ ((((size) + ALIGNMENT - 1) & ~(ALIGNMENT-1)) + ARENA_OFFSET)
+#define ROUND_SIZE(size)������������������������������������ ((size + ALIGNMENT - 1) & ~(ALIGNMENT - 1))
+#define ROUND_DATA_SIZE(size)������ (((size + sizeof(ARENA_INUSE) + ALIGNMENT - 1) \
+������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ & ~(ALIGNMENT - 1)) - sizeof(ARENA_INUSE))
������
������#define QUIET������������������������������������������������������������������������������������������������������ 1������������������������������������������������������������ /* Suppress messages������ */
������#define NOISY������������������������������������������������������������������������������������������������������ 0������������������������������������������������������������ /* Report all errors������ */
������
+/* minimum size of a block with arena */
+#define HEAP_MIN_BLOCK_SIZE������������ ROUND_SIZE(max(sizeof(ARENA_FREE) + sizeof(ARENA_FREE*),\
+������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ sizeof(ARENA_INUSE)))
������/* 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_DATA_SIZE������������������ HEAP_MIN_BLOCK_SIZE - sizeof(ARENA_INUSE)
������/* minimum size by which an allocated block must be shrunk */
������/* must be enough to fit the free block that will be created after it */
-#define HEAP_MIN_SHRINK_SIZE������ (HEAP_MIN_DATA_SIZE+sizeof(ARENA_FREE))
+#define HEAP_MIN_SHRINK_SIZE������ HEAP_MIN_BLOCK_SIZE
������/* minimum size to start allocating large blocks */
������#define HEAP_MIN_LARGE_BLOCK_SIZE������ 0x7f000
������/* extra size to add at the end of block for tail checking */
@@ -1316,7 +1319,7 @@ grow:
������������������������������������������������ return NULL;
������������������������ }
������
-������������������ total_size = size + ROUND_SIZE(sizeof(SUBHEAP)) + sizeof(ARENA_INUSE);
+������������������ total_size = size + ROUND_SIZE(sizeof(SUBHEAP) + sizeof(ARENA_INUSE));
������������������������ if (total_size < size) return NULL;������ /* overflow */
������
������������������������ if ((subheap = HEAP_CreateSubHeap( heap, NULL, heap->flags, total_size,
@@ -1369,7 +1372,7 @@ static BOOL HEAP_ValidateFreeArena( SUBHEAP *subheap, ARENA_FREE *pArena )
������������������������ char *heapEnd = (char *)subheap->base + subheap->size;
������
������������������������ /* Check for unaligned pointers */
-������������������ if ((ULONG_PTR)pArena % ALIGNMENT != ARENA_OFFSET)
+������������������ if ((ULONG_PTR)pArena % ALIGNMENT != 0)
������������������������ {
������������������������������������������������ ERR("Heap %p: unaligned arena pointer %p\n", subheap->heap, pArena );
������������������������������������������������ return FALSE;
@@ -1478,7 +1481,7 @@ static BOOL HEAP_ValidateInUseArena( const SUBHEAP *subheap, const ARENA_INUSE *
������������������������ const char *heapEnd = (const char *)subheap->base + subheap->size;
������
������������������������ /* Check for unaligned pointers */
-������������������ if ((ULONG_PTR)pArena % ALIGNMENT != ARENA_OFFSET)
+������������������ if ((ULONG_PTR)pArena % ALIGNMENT != 0)
������������������������ {
������������������������������������������������ if ( quiet == NOISY )
������������������������������������������������ {
@@ -1709,7 +1712,7 @@ static BOOL validate_block_pointer( HEAP *heap, SUBHEAP **ret_subheap, const ARE
������������������������������������������������ WARN( "Heap %p: pointer %p is inside subheap %p header\n", subheap->heap, arena + 1, subheap );
������������������������ else if (subheap->heap->flags & HEAP_VALIDATE)������ /* do the full validation */
������������������������������������������������ ret = HEAP_ValidateInUseArena( subheap, arena, QUIET );
-������������������ else if ((ULONG_PTR)arena % ALIGNMENT != ARENA_OFFSET)
+������������������ else if ((ULONG_PTR)arena % ALIGNMENT != 0)
������������������������������������������������ WARN( "Heap %p: unaligned arena pointer %p\n", subheap->heap, arena );
������������������������ else if (arena->magic == ARENA_PENDING_MAGIC)
������������������������������������������������ WARN( "Heap %p: block %p used after free\n", subheap->heap, arena + 1 );
@@ -1957,7 +1960,7 @@ PVOID WINAPI RtlAllocateHeap( HANDLE heap, ULONG flags, SIZE_T size )
������������������������ if (!heapPtr) return NULL;
������������������������ flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY;
������������������������ flags |= heapPtr->flags;
-������������������ rounded_size = ROUND_SIZE(size) + HEAP_TAIL_EXTRA_SIZE( flags );
+������������������ rounded_size = ROUND_DATA_SIZE(size) + HEAP_TAIL_EXTRA_SIZE( flags );
������������������������ if (rounded_size < size)������ /* overflow */
������������������������ {
������������������������������������������������ if (flags & HEAP_GENERATE_EXCEPTIONS) RtlRaiseStatus( STATUS_NO_MEMORY );
@@ -2110,7 +2113,7 @@ PVOID WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, PVOID ptr, SIZE_T size
������������������������ flags |= heapPtr->flags;
������������������������ if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterCriticalSection( &heapPtr->critSection );
������
-������������������ rounded_size = ROUND_SIZE(size) + HEAP_TAIL_EXTRA_SIZE(flags);
+������������������ rounded_size = ROUND_DATA_SIZE(size) + HEAP_TAIL_EXTRA_SIZE(flags);
������������������������ if (rounded_size < size) goto oom;������ /* overflow */
������������������������ if (rounded_size < HEAP_MIN_DATA_SIZE) rounded_size = HEAP_MIN_DATA_SIZE;
������
--
2.14.1