fix more static-init ordering issues caused by new alignment code

This commit is contained in:
David Rose 2012-02-12 19:55:52 +00:00
parent 59c0a3c0e4
commit 4820b4a2db
6 changed files with 56 additions and 29 deletions

View File

@ -59,7 +59,7 @@ node_to_buffer(DeletedBufferChain::ObjectNode *node) {
#if defined(USE_DELETEDCHAINFLAG) && defined(USE_DELETED_CHAIN) #if defined(USE_DELETEDCHAINFLAG) && defined(USE_DELETED_CHAIN)
// In development mode, we increment the pointer so that the // In development mode, we increment the pointer so that the
// returned data does not overlap our _flag member. // returned data does not overlap our _flag member.
return (void *)(((char *)node) + _flag_reserved_bytes); return (void *)(((char *)node) + get_flag_reserved_bytes());
#else #else
return (void *)node; return (void *)node;
#endif // NDEBUG #endif // NDEBUG
@ -75,8 +75,33 @@ buffer_to_node(void *ptr) {
#if defined(USE_DELETEDCHAINFLAG) && defined(USE_DELETED_CHAIN) #if defined(USE_DELETEDCHAINFLAG) && defined(USE_DELETED_CHAIN)
// In development mode, we decrement the pointer to undo the // In development mode, we decrement the pointer to undo the
// increment we did above. // increment we did above.
return (ObjectNode *)(((char *)ptr) - _flag_reserved_bytes); return (ObjectNode *)(((char *)ptr) - get_flag_reserved_bytes());
#else #else
return (ObjectNode *)ptr; return (ObjectNode *)ptr;
#endif // NDEBUG #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;
}

View File

@ -15,10 +15,6 @@
#include "deletedBufferChain.h" #include "deletedBufferChain.h"
#include "memoryHook.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 // Function: DeletedBufferChain::Constructor
// Access: Protected // Access: Protected
@ -33,7 +29,7 @@ DeletedBufferChain(size_t buffer_size) {
#ifdef USE_DELETEDCHAINFLAG #ifdef USE_DELETEDCHAINFLAG
// In development mode, we also need to reserve space for _flag. // 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 #endif // USE_DELETEDCHAINFLAG
// We must allocate at least this much space for bookkeeping // We must allocate at least this much space for bookkeeping

View File

@ -93,6 +93,7 @@ private:
static INLINE void *node_to_buffer(ObjectNode *node); static INLINE void *node_to_buffer(ObjectNode *node);
static INLINE ObjectNode *buffer_to_node(void *buffer); static INLINE ObjectNode *buffer_to_node(void *buffer);
static INLINE size_t get_flag_reserved_bytes();
ObjectNode *_deleted_chain; ObjectNode *_deleted_chain;
@ -100,12 +101,6 @@ private:
size_t _buffer_size; size_t _buffer_size;
size_t _alloc_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; friend class MemoryHook;
}; };

View File

@ -72,7 +72,27 @@ get_memory_alignment() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE size_t MemoryHook:: INLINE size_t MemoryHook::
get_header_reserved_bytes() { 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 defined(MEMORY_HOOK_DO_ALIGN)
// If we're aligning, we need to request the header size, plus extra // If we're aligning, we need to request the header size, plus extra
// bytes to give us wiggle room to adjust the pointer. // 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) #elif defined(DO_MEMORY_USAGE)
// If we're not aligning, but we're tracking memory allocations, we // 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 // just need the header size extra (this gives us a place to store
// the size of the allocated block). // the size of the allocated block).
return size + _header_reserved_bytes; return size + get_header_reserved_bytes();
#else #else
// If we're not doing any of that, we can just allocate the precise // If we're not doing any of that, we can just allocate the precise
// requested amount. // requested amount.
@ -140,11 +160,11 @@ alloc_to_ptr(void *alloc, size_t size) {
assert(alloc <= root && (size_t)((char *)root - (char *)alloc) < alignment); assert(alloc <= root && (size_t)((char *)root - (char *)alloc) < alignment);
root[0] = size; root[0] = size;
root[1] = (size_t)alloc; // Save the pointer we originally allocated. 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) #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 + get_header_reserved_bytes());
#else #else
return alloc; return alloc;
#endif // DO_MEMORY_USAGE #endif // DO_MEMORY_USAGE
@ -160,13 +180,13 @@ 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) {
#if defined(MEMORY_HOOK_DO_ALIGN) #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]; size = root[0];
void *alloc = (void *)root[1]; // Get the pointer we originally allocated. void *alloc = (void *)root[1]; // Get the pointer we originally allocated.
assert(alloc <= root && (size_t)((char *)root - (char *)alloc) < get_memory_alignment()); assert(alloc <= root && (size_t)((char *)root - (char *)alloc) < get_memory_alignment());
return alloc; return alloc;
#elif defined(DO_MEMORY_USAGE) #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]; size = root[0];
return (void *)root; return (void *)root;
#else #else

View File

@ -107,14 +107,6 @@
#endif // USE_MEMORY_* #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 // Function: MemoryHook::Constructor
// Access: Public // Access: Public

View File

@ -92,7 +92,6 @@ protected:
#endif // DO_MEMORY_USAGE #endif // DO_MEMORY_USAGE
private: private:
static size_t _header_reserved_bytes;
size_t _page_size; size_t _page_size;
typedef map<size_t, DeletedBufferChain *> DeletedChains; typedef map<size_t, DeletedBufferChain *> DeletedChains;