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:
rdb 2016-12-08 23:21:01 +01:00
parent 32377cb618
commit c422f5952f
5 changed files with 21 additions and 18 deletions

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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) {

View File

@ -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.