mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
Increase default alignment to 2x word size, make DeletedBufferChain allocations more efficient
NB. NeverFreeMemory no longer performs alignment. This fixes the Bullet crash on Win64. Need to check Win32.
This commit is contained in:
parent
32377cb618
commit
c422f5952f
@ -39,7 +39,7 @@ allocate(size_t size, TypeHandle type_handle) {
|
|||||||
assert(size <= _buffer_size);
|
assert(size <= _buffer_size);
|
||||||
|
|
||||||
// Determine how much space to allocate.
|
// 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;
|
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
|
// If we get here, the deleted_chain is empty; we have to allocate a new
|
||||||
// object from the system pool.
|
// 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
|
#ifdef USE_DELETEDCHAINFLAG
|
||||||
obj->_flag = DCF_alive;
|
obj->_flag = DCF_alive;
|
||||||
@ -77,6 +80,10 @@ allocate(size_t size, TypeHandle type_handle) {
|
|||||||
|
|
||||||
void *ptr = node_to_buffer(obj);
|
void *ptr = node_to_buffer(obj);
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
assert(((uintptr_t)ptr % MemoryHook::get_memory_alignment()) == 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DO_MEMORY_USAGE
|
#ifdef DO_MEMORY_USAGE
|
||||||
type_handle.inc_memory_usage(TypeHandle::MC_deleted_chain_active, alloc_size);
|
type_handle.inc_memory_usage(TypeHandle::MC_deleted_chain_active, alloc_size);
|
||||||
#endif // DO_MEMORY_USAGE
|
#endif // DO_MEMORY_USAGE
|
||||||
|
@ -95,12 +95,8 @@ private:
|
|||||||
// Without DELETEDCHAINFLAG, we don't even store the _flag member at all.
|
// Without DELETEDCHAINFLAG, we don't even store the _flag member at all.
|
||||||
static const size_t flag_reserved_bytes = 0;
|
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
|
#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);
|
static const size_t flag_reserved_bytes = sizeof(AtomicAdjust::Integer);
|
||||||
#endif // USE_DELETEDCHAINFLAG
|
#endif // USE_DELETEDCHAINFLAG
|
||||||
|
|
||||||
|
@ -45,8 +45,9 @@ get_memory_alignment() {
|
|||||||
// don't strictly have to align *everything*, but it's just easier to do so.
|
// don't strictly have to align *everything*, but it's just easier to do so.
|
||||||
const size_t alignment_size = 16;
|
const size_t alignment_size = 16;
|
||||||
#else
|
#else
|
||||||
// Otherwise, use word alignment.
|
// Otherwise, align to two words. This seems to be pretty standard to the
|
||||||
const size_t alignment_size = sizeof(void *);
|
// point where some code may rely on this being the case.
|
||||||
|
const size_t alignment_size = sizeof(void *) * 2;
|
||||||
#endif
|
#endif
|
||||||
return alignment_size;
|
return alignment_size;
|
||||||
}
|
}
|
||||||
@ -72,8 +73,9 @@ get_header_reserved_bytes() {
|
|||||||
static const size_t header_reserved_bytes = sizeof(size_t) + sizeof(size_t);
|
static const size_t header_reserved_bytes = sizeof(size_t) + sizeof(size_t);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
// If we're not aligning, we just need space for the word itself.
|
// Virtually all allocators align to two words, so we make sure we preserve
|
||||||
static const size_t header_reserved_bytes = sizeof(size_t);
|
// that alignment for the benefit of anyone who relies upon that.
|
||||||
|
static const size_t header_reserved_bytes = sizeof(void *) * 2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return header_reserved_bytes;
|
return header_reserved_bytes;
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
/**
|
/**
|
||||||
* Returns a pointer to a newly-allocated block of memory of the indicated
|
* Returns a pointer to a newly-allocated block of memory of the indicated
|
||||||
* size.
|
* size.
|
||||||
|
*
|
||||||
|
* Please note that the resulting pointer is not aligned to any boundary.
|
||||||
*/
|
*/
|
||||||
INLINE void *NeverFreeMemory::
|
INLINE void *NeverFreeMemory::
|
||||||
alloc(size_t size) {
|
alloc(size_t size) {
|
||||||
|
@ -39,13 +39,9 @@ void *NeverFreeMemory::
|
|||||||
ns_alloc(size_t size) {
|
ns_alloc(size_t size) {
|
||||||
_lock.acquire();
|
_lock.acquire();
|
||||||
|
|
||||||
// We always allocate integer multiples of this many bytes, to guarantee
|
//NB: we no longer do alignment here. The only class that uses this is
|
||||||
// this minimum alignment.
|
// DeletedBufferChain, and we can do the alignment potentially more
|
||||||
static const size_t alignment_size = MemoryHook::get_memory_alignment();
|
// efficiently there since we don't end up overallocating as much.
|
||||||
|
|
||||||
// Round up to the next alignment_size.
|
|
||||||
size = ((size + alignment_size - 1) / alignment_size) * alignment_size;
|
|
||||||
|
|
||||||
_total_used += size;
|
_total_used += size;
|
||||||
|
|
||||||
// Look for a page that has sufficient space remaining.
|
// Look for a page that has sufficient space remaining.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user