summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/lib/osdlib_win32.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/lib/osdlib_win32.c')
-rw-r--r--src/osd/modules/lib/osdlib_win32.c63
1 files changed, 42 insertions, 21 deletions
diff --git a/src/osd/modules/lib/osdlib_win32.c b/src/osd/modules/lib/osdlib_win32.c
index 846d7e859cd..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
@@ -112,17 +122,22 @@ int osd_get_num_processors(void)
void *osd_malloc(size_t size)
{
#ifndef MALLOC_DEBUG
- return HeapAlloc(GetProcessHeap(), 0, size);
+ 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
}
@@ -134,13 +149,14 @@ void *osd_malloc(size_t size)
void *osd_malloc_array(size_t size)
{
#ifndef MALLOC_DEBUG
- return HeapAlloc(GetProcessHeap(), 0, size);
+ 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
}
@@ -169,18 +187,21 @@ void *osd_malloc_array(size_t size)
void osd_free(void *ptr)
{
#ifndef MALLOC_DEBUG
- HeapFree(GetProcessHeap(), 0, ptr);
+ 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