diff --git a/dtool/src/dtoolbase/deletedBufferChain.cxx b/dtool/src/dtoolbase/deletedBufferChain.cxx index 89f056219c..122edf8837 100644 --- a/dtool/src/dtoolbase/deletedBufferChain.cxx +++ b/dtool/src/dtoolbase/deletedBufferChain.cxx @@ -39,7 +39,7 @@ allocate(size_t size, TypeHandle type_handle) { assert(size <= _buffer_size); // Determine how much space to allocate. - const size_t alloc_size = _buffer_size + flag_reserved_bytes; + const size_t alloc_size = _buffer_size + flag_reserved_bytes + MemoryHook::get_memory_alignment() - 1; ObjectNode *obj; @@ -69,7 +69,10 @@ allocate(size_t size, TypeHandle type_handle) { // If we get here, the deleted_chain is empty; we have to allocate a new // object from the system pool. - obj = (ObjectNode *)NeverFreeMemory::alloc(alloc_size); + // Allocate memory, and make sure the object starts at the proper alignment. + void *mem = NeverFreeMemory::alloc(alloc_size); + intptr_t pad = ((intptr_t)flag_reserved_bytes - (intptr_t)mem) % MemoryHook::get_memory_alignment(); + obj = (ObjectNode *)((uintptr_t)mem + pad); #ifdef USE_DELETEDCHAINFLAG obj->_flag = DCF_alive; @@ -77,6 +80,10 @@ allocate(size_t size, TypeHandle type_handle) { void *ptr = node_to_buffer(obj); +#ifdef _DEBUG + assert(((uintptr_t)ptr % MemoryHook::get_memory_alignment()) == 0); +#endif + #ifdef DO_MEMORY_USAGE type_handle.inc_memory_usage(TypeHandle::MC_deleted_chain_active, alloc_size); #endif // DO_MEMORY_USAGE diff --git a/dtool/src/dtoolbase/deletedBufferChain.h b/dtool/src/dtoolbase/deletedBufferChain.h index 6df4583ee8..8f82c1abbc 100644 --- a/dtool/src/dtoolbase/deletedBufferChain.h +++ b/dtool/src/dtoolbase/deletedBufferChain.h @@ -95,12 +95,8 @@ private: // Without DELETEDCHAINFLAG, we don't even store the _flag member at all. 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. + // Otherwise, we need space for the integer. static const size_t flag_reserved_bytes = sizeof(AtomicAdjust::Integer); #endif // USE_DELETEDCHAINFLAG diff --git a/dtool/src/dtoolbase/memoryHook.I b/dtool/src/dtoolbase/memoryHook.I index c54e34c1f3..09f89cc9df 100644 --- a/dtool/src/dtoolbase/memoryHook.I +++ b/dtool/src/dtoolbase/memoryHook.I @@ -45,8 +45,9 @@ get_memory_alignment() { // don't strictly have to align *everything*, but it's just easier to do so. const size_t alignment_size = 16; #else - // Otherwise, use word alignment. - const size_t alignment_size = sizeof(void *); + // Otherwise, align to two words. This seems to be pretty standard to the + // point where some code may rely on this being the case. + const size_t alignment_size = sizeof(void *) * 2; #endif return alignment_size; } @@ -72,8 +73,9 @@ get_header_reserved_bytes() { 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); + // Virtually all allocators align to two words, so we make sure we preserve + // that alignment for the benefit of anyone who relies upon that. + static const size_t header_reserved_bytes = sizeof(void *) * 2; #endif return header_reserved_bytes; diff --git a/dtool/src/dtoolbase/neverFreeMemory.I b/dtool/src/dtoolbase/neverFreeMemory.I index 33e5b5851c..2156209616 100644 --- a/dtool/src/dtoolbase/neverFreeMemory.I +++ b/dtool/src/dtoolbase/neverFreeMemory.I @@ -14,6 +14,8 @@ /** * Returns a pointer to a newly-allocated block of memory of the indicated * size. + * + * Please note that the resulting pointer is not aligned to any boundary. */ INLINE void *NeverFreeMemory:: alloc(size_t size) { diff --git a/dtool/src/dtoolbase/neverFreeMemory.cxx b/dtool/src/dtoolbase/neverFreeMemory.cxx index 1ec800a749..fd10b683d8 100644 --- a/dtool/src/dtoolbase/neverFreeMemory.cxx +++ b/dtool/src/dtoolbase/neverFreeMemory.cxx @@ -39,13 +39,9 @@ void *NeverFreeMemory:: ns_alloc(size_t size) { _lock.acquire(); - // We always allocate integer multiples of this many bytes, to guarantee - // this minimum alignment. - static const size_t alignment_size = MemoryHook::get_memory_alignment(); - - // Round up to the next alignment_size. - size = ((size + alignment_size - 1) / alignment_size) * alignment_size; - + //NB: we no longer do alignment here. The only class that uses this is + // DeletedBufferChain, and we can do the alignment potentially more + // efficiently there since we don't end up overallocating as much. _total_used += size; // Look for a page that has sufficient space remaining.