diff --git a/dtool/src/dtoolbase/deletedBufferChain.I b/dtool/src/dtoolbase/deletedBufferChain.I index 46f94ee1b4..683b5b285e 100644 --- a/dtool/src/dtoolbase/deletedBufferChain.I +++ b/dtool/src/dtoolbase/deletedBufferChain.I @@ -59,7 +59,7 @@ node_to_buffer(DeletedBufferChain::ObjectNode *node) { #if defined(USE_DELETEDCHAINFLAG) && defined(USE_DELETED_CHAIN) // In development mode, we increment the pointer so that the // returned data does not overlap our _flag member. - return (void *)(((char *)node) + _flag_reserved_bytes); + return (void *)(((char *)node) + get_flag_reserved_bytes()); #else return (void *)node; #endif // NDEBUG @@ -75,8 +75,33 @@ buffer_to_node(void *ptr) { #if defined(USE_DELETEDCHAINFLAG) && defined(USE_DELETED_CHAIN) // In development mode, we decrement the pointer to undo the // increment we did above. - return (ObjectNode *)(((char *)ptr) - _flag_reserved_bytes); + return (ObjectNode *)(((char *)ptr) - get_flag_reserved_bytes()); #else return (ObjectNode *)ptr; #endif // NDEBUG } + +//////////////////////////////////////////////////////////////////// +// Function: DeletedBufferChain::get_flag_reserved_bytes +// Access: Private, Static +// Description: Returns the number of extra bytes reserved at the +// beginning of each buffer for the _flag member. +//////////////////////////////////////////////////////////////////// +INLINE size_t DeletedBufferChain:: +get_flag_reserved_bytes() { +#ifndef USE_DELETEDCHAINFLAG + // Without DELETEDCHAINFLAG, we don't even store the _flag member at + // all, and this method is never called. + static const size_t flag_reserved_bytes = 0; + +#elif defined(LINMATH_ALIGN) + // With SSE2 alignment, we need all 16 bytes to preserve alignment. + static const size_t flag_reserved_bytes = 16; + +#else + // Otherwise, we only need enough space for the Integer itself. + static const size_t flag_reserved_bytes = sizeof(AtomicAdjust::Integer); +#endif // USE_DELETEDCHAINFLAG + + return flag_reserved_bytes; +} diff --git a/dtool/src/dtoolbase/deletedBufferChain.cxx b/dtool/src/dtoolbase/deletedBufferChain.cxx index caa3a36eab..33e5672949 100644 --- a/dtool/src/dtoolbase/deletedBufferChain.cxx +++ b/dtool/src/dtoolbase/deletedBufferChain.cxx @@ -15,10 +15,6 @@ #include "deletedBufferChain.h" #include "memoryHook.h" -#ifdef USE_DELETEDCHAINFLAG -size_t DeletedBufferChain::_flag_reserved_bytes = max(MemoryHook::get_memory_alignment(), (size_t)sizeof(AtomicAdjust::Integer)); -#endif // USE_DELETEDCHAINFLAG - //////////////////////////////////////////////////////////////////// // Function: DeletedBufferChain::Constructor // Access: Protected @@ -33,7 +29,7 @@ DeletedBufferChain(size_t buffer_size) { #ifdef USE_DELETEDCHAINFLAG // In development mode, we also need to reserve space for _flag. - _alloc_size += _flag_reserved_bytes; + _alloc_size += get_flag_reserved_bytes(); #endif // USE_DELETEDCHAINFLAG // We must allocate at least this much space for bookkeeping diff --git a/dtool/src/dtoolbase/deletedBufferChain.h b/dtool/src/dtoolbase/deletedBufferChain.h index e5a0bb37a2..07825423ed 100644 --- a/dtool/src/dtoolbase/deletedBufferChain.h +++ b/dtool/src/dtoolbase/deletedBufferChain.h @@ -93,6 +93,7 @@ private: static INLINE void *node_to_buffer(ObjectNode *node); static INLINE ObjectNode *buffer_to_node(void *buffer); + static INLINE size_t get_flag_reserved_bytes(); ObjectNode *_deleted_chain; @@ -100,12 +101,6 @@ private: size_t _buffer_size; size_t _alloc_size; -#ifdef USE_DELETEDCHAINFLAG - // The number of extra bytes reserved at the beginning of each - // buffer for the _flag, above. - static size_t _flag_reserved_bytes; -#endif - friend class MemoryHook; }; diff --git a/dtool/src/dtoolbase/memoryHook.I b/dtool/src/dtoolbase/memoryHook.I index 3498b2431e..9286a18d7a 100644 --- a/dtool/src/dtoolbase/memoryHook.I +++ b/dtool/src/dtoolbase/memoryHook.I @@ -72,7 +72,27 @@ get_memory_alignment() { //////////////////////////////////////////////////////////////////// INLINE size_t MemoryHook:: get_header_reserved_bytes() { - return _header_reserved_bytes; + // We need to figure out the minimum amount of additional space we + // need in order to place a single word at the start of each + // allocated block, to store the size of the block. + +#ifdef LINMATH_ALIGN + // If we're doing SSE2 alignment, we must reserve a full 16-byte + // block, since anything less than that will spoil the alignment. + static const size_t header_reserved_bytes = 16; + +#elif defined(MEMORY_HOOK_DO_ALIGN) + // If we're just aligning to words, we reserve a block as big as two + // words, to allow us wiggle room to align the word precisely within + // that block. + static const size_t header_reserved_bytes = sizeof(size_t) + sizeof(size_t); + +#else + // If we're not aligning, we just need space for the word itself. + static const size_t header_reserved_bytes = sizeof(size_t); +#endif + + return header_reserved_bytes; } //////////////////////////////////////////////////////////////////// @@ -111,12 +131,12 @@ inflate_size(size_t size) { #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; + return size + get_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; + return size + get_header_reserved_bytes(); #else // If we're not doing any of that, we can just allocate the precise // requested amount. @@ -140,11 +160,11 @@ alloc_to_ptr(void *alloc, size_t size) { assert(alloc <= root && (size_t)((char *)root - (char *)alloc) < alignment); root[0] = size; root[1] = (size_t)alloc; // Save the pointer we originally allocated. - return (void *)((char *)root + _header_reserved_bytes); + return (void *)((char *)root + get_header_reserved_bytes()); #elif defined(DO_MEMORY_USAGE) size_t *root = (size_t *)alloc; root[0] = size; - return (void *)((char *)root + _header_reserved_bytes); + return (void *)((char *)root + get_header_reserved_bytes()); #else return alloc; #endif // DO_MEMORY_USAGE @@ -160,13 +180,13 @@ alloc_to_ptr(void *alloc, size_t size) { INLINE void *MemoryHook:: ptr_to_alloc(void *ptr, size_t &size) { #if defined(MEMORY_HOOK_DO_ALIGN) - size_t *root = (size_t *)((char *)ptr - _header_reserved_bytes); + size_t *root = (size_t *)((char *)ptr - get_header_reserved_bytes()); size = root[0]; void *alloc = (void *)root[1]; // Get the pointer we originally allocated. assert(alloc <= root && (size_t)((char *)root - (char *)alloc) < get_memory_alignment()); return alloc; #elif defined(DO_MEMORY_USAGE) - size_t *root = (size_t *)((char *)ptr - _header_reserved_bytes); + size_t *root = (size_t *)((char *)ptr - get_header_reserved_bytes()); size = root[0]; return (void *)root; #else diff --git a/dtool/src/dtoolbase/memoryHook.cxx b/dtool/src/dtoolbase/memoryHook.cxx index 618a0e0d33..e830b871b7 100644 --- a/dtool/src/dtoolbase/memoryHook.cxx +++ b/dtool/src/dtoolbase/memoryHook.cxx @@ -107,14 +107,6 @@ #endif // USE_MEMORY_* -// Reserve enough bytes at the beginning of each allocated record to -// 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)); -#endif // MEMORY_HOOK_DO_ALIGN - //////////////////////////////////////////////////////////////////// // Function: MemoryHook::Constructor // Access: Public diff --git a/dtool/src/dtoolbase/memoryHook.h b/dtool/src/dtoolbase/memoryHook.h index bdb57916fc..74bdad276d 100644 --- a/dtool/src/dtoolbase/memoryHook.h +++ b/dtool/src/dtoolbase/memoryHook.h @@ -92,7 +92,6 @@ protected: #endif // DO_MEMORY_USAGE private: - static size_t _header_reserved_bytes; size_t _page_size; typedef map DeletedChains;