Browse Source

enforce alignment policies even when malloc() doesn't.

David Rose 14 years ago
parent
commit
56fb33bf00

+ 25 - 4
dtool/src/dtoolbase/memoryHook.I

@@ -108,9 +108,18 @@ round_up_to_page_size(size_t size) const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE size_t MemoryHook::
 INLINE size_t MemoryHook::
 inflate_size(size_t size) {
 inflate_size(size_t size) {
-#ifdef DO_MEMORY_USAGE
-  return size + _header_reserved_bytes;
+#if defined(MEMORY_HOOK_DO_ALIGN)
+  // If we're aligning, we need to request the header size, plus extra
+  // bytes to give us wiggle room to adjust the pointer.
+  return size + _header_reserved_bytes + get_memory_alignment() - 1;
+#elif defined(DO_MEMORY_USAGE)
+  // If we're not aligning, but we're tracking memory allocations, we
+  // just need the header size extra (this gives us a place to store
+  // the size of the allocated block).
+  return size + _header_reserved_bytes;  
 #else
 #else
+  // If we're not doing any of that, we can just allocate the precise
+  // requested amount.
   return size;
   return size;
 #endif  // DO_MEMORY_USAGE
 #endif  // DO_MEMORY_USAGE
 }
 }
@@ -124,7 +133,15 @@ inflate_size(size_t size) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void *MemoryHook::
 INLINE void *MemoryHook::
 alloc_to_ptr(void *alloc, size_t size) {
 alloc_to_ptr(void *alloc, size_t size) {
-#ifdef DO_MEMORY_USAGE
+#if defined(MEMORY_HOOK_DO_ALIGN)
+  size_t alignment = get_memory_alignment();
+  // Move the allocated pointer up to the next even alignment.
+  void *new_ptr = (void *)((((size_t)alloc + alignment - 1) / alignment) * alignment);
+  size_t *root = (size_t *)new_ptr;
+  root[0] = size;
+  root[1] = (size_t)alloc;  // Save the pointer we originally allocated.
+  return (void *)((char *)new_ptr + _header_reserved_bytes);
+#elif defined(DO_MEMORY_USAGE) 
   size_t *root = (size_t *)alloc;
   size_t *root = (size_t *)alloc;
   root[0] = size;
   root[0] = size;
   return (void *)((char *)root + _header_reserved_bytes);
   return (void *)((char *)root + _header_reserved_bytes);
@@ -142,7 +159,11 @@ alloc_to_ptr(void *alloc, size_t size) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void *MemoryHook::
 INLINE void *MemoryHook::
 ptr_to_alloc(void *ptr, size_t &size) {
 ptr_to_alloc(void *ptr, size_t &size) {
-#ifdef DO_MEMORY_USAGE
+#if defined(MEMORY_HOOK_DO_ALIGN)
+  size_t *root = (size_t *)((char *)ptr - _header_reserved_bytes);
+  size = root[0];
+  return (void *)root[1];  // Return the pointer we originally allocated.
+#elif defined(DO_MEMORY_USAGE) 
   size_t *root = (size_t *)((char *)ptr - _header_reserved_bytes);
   size_t *root = (size_t *)((char *)ptr - _header_reserved_bytes);
   size = root[0];
   size = root[0];
   return (void *)root;
   return (void *)root;

+ 4 - 0
dtool/src/dtoolbase/memoryHook.cxx

@@ -109,7 +109,11 @@
 
 
 // Reserve enough bytes at the beginning of each allocated record to
 // Reserve enough bytes at the beginning of each allocated record to
 // store its allocated size.
 // store its allocated size.
+#ifdef MEMORY_HOOK_DO_ALIGN
+size_t MemoryHook::_header_reserved_bytes = max(MemoryHook::get_memory_alignment(), (size_t)(sizeof(size_t) + sizeof(size_t)));
+#else
 size_t MemoryHook::_header_reserved_bytes = max(MemoryHook::get_memory_alignment(), (size_t)sizeof(size_t));
 size_t MemoryHook::_header_reserved_bytes = max(MemoryHook::get_memory_alignment(), (size_t)sizeof(size_t));
+#endif  // MEMORY_HOOK_DO_ALIGN
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: MemoryHook::Constructor
 //     Function: MemoryHook::Constructor

+ 24 - 0
dtool/src/dtoolbase/memoryHook.h

@@ -23,6 +23,30 @@
 
 
 class DeletedBufferChain;
 class DeletedBufferChain;
 
 
+// Do we need to implement memory-alignment enforcement within the
+// MemoryHook class, or will the underlying malloc implementation
+// provide it automatically?
+#if defined(USE_MEMORY_DLMALLOC) || defined(USE_MEMORY_PTMALLOC2)
+// Both of these specialized malloc implementations perform the
+// required alignment.
+#undef MEMORY_HOOK_DO_ALIGN
+
+#elif defined(IS_OSX) || defined(_WIN64)
+// The OS-provided malloc implementation will do the required
+// alignment.
+#undef MEMORY_HOOK_DO_ALIGN
+
+#elif !defined(LINMATH_VECTORIZE)
+// We don't actually require any special memory-alignment beyond what
+// the underlying implementation is likely to provide anyway.
+#undef MEMORY_HOOK_DO_ALIGN
+
+#else
+// Whoops, we need memory alignment, and we have to provide it ourselves.
+#define MEMORY_HOOK_DO_ALIGN 1
+
+#endif
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : MemoryHook
 //       Class : MemoryHook
 // Description : This class provides a wrapper around the various
 // Description : This class provides a wrapper around the various

+ 2 - 2
makepanda/makepanda.py

@@ -1524,8 +1524,8 @@ DTOOL_CONFIG=[
     ("IS_FREEBSD",                     'UNDEF',                  'UNDEF'),
     ("IS_FREEBSD",                     'UNDEF',                  'UNDEF'),
     ("GLOBAL_OPERATOR_NEW_EXCEPTIONS", 'UNDEF',                  '1'),
     ("GLOBAL_OPERATOR_NEW_EXCEPTIONS", 'UNDEF',                  '1'),
     ("USE_STL_ALLOCATOR",              '1',                      '1'),
     ("USE_STL_ALLOCATOR",              '1',                      '1'),
-    ("USE_MEMORY_DLMALLOC",            '1',                      'UNDEF'),
-    ("USE_MEMORY_PTMALLOC",            'UNDEF',                  'UNDEF'),
+    ("USE_MEMORY_DLMALLOC",            'UNDEF',                  'UNDEF'),
+    ("USE_MEMORY_PTMALLOC2",           '1',                      'UNDEF'),
     ("USE_MEMORY_MALLOC",              'UNDEF',                  '1'),
     ("USE_MEMORY_MALLOC",              'UNDEF',                  '1'),
     ("HAVE_ZLIB",                      'UNDEF',                  'UNDEF'),
     ("HAVE_ZLIB",                      'UNDEF',                  'UNDEF'),
     ("HAVE_PNG",                       'UNDEF',                  'UNDEF'),
     ("HAVE_PNG",                       'UNDEF',                  'UNDEF'),