summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
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
commiteb38a7ad255cdcf655fdce3b4f0de259d67a45ac (patch)
treed979e7174f95e8cc8ea8eeeed0aeb40af4ae68b8
parent454895659e02dfa42546ec94f2e2d9243e018e71 (diff)
Align memory with MALLOC_DEBUG (nw)
-rw-r--r--src/osd/modules/lib/osdlib_win32.c57
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