From eb38a7ad255cdcf655fdce3b4f0de259d67a45ac Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Sat, 4 Jul 2015 00:37:56 +1000 Subject: [PATCH] Align memory with MALLOC_DEBUG (nw) --- src/osd/modules/lib/osdlib_win32.c | 57 ++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/src/osd/modules/lib/osdlib_win32.c b/src/osd/modules/lib/osdlib_win32.c index 405b067011f..85334fd8ddc 100644 --- a/src/osd/modules/lib/osdlib_win32.c +++ b/src/osd/modules/lib/osdlib_win32.c @@ -36,6 +36,16 @@ // align allocations to start or end of the page? #define GUARD_ALIGN_START 0 +#if defined(__BIGGEST_ALIGNMENT__) +#define MAX_ALIGNMENT __BIGGEST_ALIGNMENT__ +#elif defined(__AVX__) +#define MAX_ALIGNMENT 32 +#elif defined(__SSE__) || defined(__x86_64__) || defined(_M_X64) +#define MAX_ALIGNMENT 16 +#else +#define MAX_ALIGNMENT sizeof(INT64) +#endif + //============================================================ // GLOBAL VARIABLES @@ -114,15 +124,20 @@ void *osd_malloc(size_t size) #ifndef MALLOC_DEBUG return malloc(size); #else - // add in space for the size - size += sizeof(size_t); + // add in space for the size and offset + size += MAX_ALIGNMENT + sizeof(size_t) + 2; + size &= ~size_t(1); // basic objects just come from the heap - void *result = HeapAlloc(GetProcessHeap(), 0, size); + UINT8 *const block = reinterpret_cast(HeapAlloc(GetProcessHeap(), 0, size)); + if (block == NULL) + return NULL; + UINT8 *const result = reinterpret_cast(reinterpret_cast(block + sizeof(size_t) + MAX_ALIGNMENT) & ~(FPTR(MAX_ALIGNMENT) - 1)); // store the size and return and pointer to the data afterward - *reinterpret_cast(result) = size; - return reinterpret_cast(result) + sizeof(size_t); + *reinterpret_cast(block) = size; + *(result - 1) = result - block; + return result; #endif } @@ -136,11 +151,12 @@ void *osd_malloc_array(size_t size) #ifndef MALLOC_DEBUG return malloc(size); #else - // add in space for the size - size += sizeof(size_t); + // add in space for the size and offset + size += MAX_ALIGNMENT + sizeof(size_t) + 2; + size &= ~size_t(1); // round the size up to a page boundary - size_t rounded_size = ((size + sizeof(void *) + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE; + size_t const rounded_size = ((size + sizeof(void *) + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE; // reserve that much memory, plus two guard pages void *page_base = VirtualAlloc(NULL, rounded_size + 2 * PAGE_SIZE, MEM_RESERVE, PAGE_NOACCESS); @@ -153,11 +169,13 @@ void *osd_malloc_array(size_t size) return NULL; // work backwards from the page base to get to the block base - void *result = GUARD_ALIGN_START ? page_base : (reinterpret_cast(page_base) + rounded_size - size); + UINT8 *const block = GUARD_ALIGN_START ? reinterpret_cast(page_base) : (reinterpret_cast(page_base) + rounded_size - size); + UINT8 *const result = reinterpret_cast(reinterpret_cast(block + sizeof(size_t) + MAX_ALIGNMENT) & ~(FPTR(MAX_ALIGNMENT) - 1)); // store the size at the start with a flag indicating it has a guard page - *reinterpret_cast(result) = size | 0x80000000; - return reinterpret_cast(result) + sizeof(size_t); + *reinterpret_cast(block) = size | 1; + *(result - 1) = result - block; + return result; #endif } @@ -171,16 +189,19 @@ void osd_free(void *ptr) #ifndef MALLOC_DEBUG free(ptr); #else - size_t size = reinterpret_cast(ptr)[-1]; + UINT8 const offset = *(reinterpret_cast(ptr) - 1); + UINT8 *const block = reinterpret_cast(ptr) - offset; + size_t const size = *reinterpret_cast(block); - // if no guard page, just free the pointer - if ((size & 0x80000000) == 0) - HeapFree(GetProcessHeap(), 0, reinterpret_cast(ptr) - sizeof(size_t)); - - // large items need more care + if ((size & 0x1) == 0) + { + // if no guard page, just free the pointer + HeapFree(GetProcessHeap(), 0, block); + } else { - ULONG_PTR page_base = (reinterpret_cast(ptr) - sizeof(size_t)) & ~(PAGE_SIZE - 1); + // large items need more care + ULONG_PTR const page_base = reinterpret_cast(block) & ~(PAGE_SIZE - 1); VirtualFree(reinterpret_cast(page_base - PAGE_SIZE), 0, MEM_RELEASE); } #endif