diff options
author | Vas Crabb <vas@vastheman.com> | 2015-07-04 00:37:56 +1000 |
---|---|---|
committer | Vas Crabb <vas@vastheman.com> | 2015-07-04 00:37:56 +1000 |
commit | eb38a7ad255cdcf655fdce3b4f0de259d67a45ac (patch) | |
tree | d979e7174f95e8cc8ea8eeeed0aeb40af4ae68b8 | |
parent | 454895659e02dfa42546ec94f2e2d9243e018e71 (diff) |
Align memory with MALLOC_DEBUG (nw)
-rw-r--r-- | src/osd/modules/lib/osdlib_win32.c | 57 |
1 files 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<UINT8 *>(HeapAlloc(GetProcessHeap(), 0, size)); + if (block == NULL) + return NULL; + UINT8 *const result = reinterpret_cast<UINT8 *>(reinterpret_cast<FPTR>(block + sizeof(size_t) + MAX_ALIGNMENT) & ~(FPTR(MAX_ALIGNMENT) - 1)); // store the size and return and pointer to the data afterward - *reinterpret_cast<size_t *>(result) = size; - return reinterpret_cast<UINT8 *>(result) + sizeof(size_t); + *reinterpret_cast<size_t *>(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<UINT8 *>(page_base) + rounded_size - size); + UINT8 *const block = GUARD_ALIGN_START ? reinterpret_cast<UINT8 *>(page_base) : (reinterpret_cast<UINT8 *>(page_base) + rounded_size - size); + UINT8 *const result = reinterpret_cast<UINT8 *>(reinterpret_cast<FPTR>(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<size_t *>(result) = size | 0x80000000; - return reinterpret_cast<UINT8 *>(result) + sizeof(size_t); + *reinterpret_cast<size_t *>(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<size_t *>(ptr)[-1]; - - // if no guard page, just free the pointer - if ((size & 0x80000000) == 0) - HeapFree(GetProcessHeap(), 0, reinterpret_cast<UINT8 *>(ptr) - sizeof(size_t)); + UINT8 const offset = *(reinterpret_cast<UINT8 *>(ptr) - 1); + UINT8 *const block = reinterpret_cast<UINT8 *>(ptr) - offset; + size_t const size = *reinterpret_cast<size_t *>(block); - // 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<ULONG_PTR>(ptr) - sizeof(size_t)) & ~(PAGE_SIZE - 1); + // large items need more care + ULONG_PTR const page_base = reinterpret_cast<ULONG_PTR>(block) & ~(PAGE_SIZE - 1); VirtualFree(reinterpret_cast<void *>(page_base - PAGE_SIZE), 0, MEM_RELEASE); } #endif |