fix MemoryHook internal memory alignment issues

This commit is contained in:
David Rose 2011-12-18 19:20:18 +00:00
parent c5c21a566a
commit 66a52cb6a3
4 changed files with 33 additions and 15 deletions

View File

@ -136,11 +136,11 @@ alloc_to_ptr(void *alloc, size_t size) {
#if defined(MEMORY_HOOK_DO_ALIGN) #if defined(MEMORY_HOOK_DO_ALIGN)
size_t alignment = get_memory_alignment(); size_t alignment = get_memory_alignment();
// Move the allocated pointer up to the next even alignment. // Move the allocated pointer up to the next even alignment.
void *new_ptr = (void *)((((size_t)alloc + alignment - 1) / alignment) * alignment); size_t *root = (size_t *)((((size_t)alloc + alignment - 1) / alignment) * alignment);
size_t *root = (size_t *)new_ptr; assert(alloc <= root && (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 *)new_ptr + _header_reserved_bytes); return (void *)((char *)root + _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;
@ -162,7 +162,9 @@ 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 - _header_reserved_bytes);
size = root[0]; size = root[0];
return (void *)root[1]; // Return the pointer we originally allocated. void *alloc = (void *)root[1]; // Get the pointer we originally allocated.
assert(alloc <= root && (char *)root - (char *)alloc < get_memory_alignment());
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 - _header_reserved_bytes);
size = root[0]; size = root[0];

View File

@ -224,7 +224,9 @@ heap_alloc_single(size_t size) {
} }
#endif // DO_MEMORY_USAGE #endif // DO_MEMORY_USAGE
return alloc_to_ptr(alloc, size); void *ptr = alloc_to_ptr(alloc, size);
assert(ptr >= alloc && (char *)ptr + size <= (char *)alloc + inflated_size);
return ptr;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -298,7 +300,9 @@ heap_alloc_array(size_t size) {
} }
#endif // DO_MEMORY_USAGE #endif // DO_MEMORY_USAGE
return alloc_to_ptr(alloc, size); void *ptr = alloc_to_ptr(alloc, size);
assert(ptr >= alloc && (char *)ptr + size <= (char *)alloc + inflated_size);
return ptr;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -319,30 +323,42 @@ heap_realloc_array(void *ptr, size_t size) {
size_t inflated_size = inflate_size(size); size_t inflated_size = inflate_size(size);
void *alloc1 = alloc;
#ifdef MEMORY_HOOK_MALLOC_LOCK #ifdef MEMORY_HOOK_MALLOC_LOCK
_lock.acquire(); _lock.acquire();
alloc = call_realloc(alloc, inflated_size); alloc1 = call_realloc(alloc1, inflated_size);
_lock.release(); _lock.release();
#else #else
alloc = call_realloc(alloc, inflated_size); alloc1 = call_realloc(alloc1, inflated_size);
#endif #endif
while (alloc == (void *)NULL) { while (alloc1 == (void *)NULL) {
alloc_fail(inflated_size); alloc_fail(inflated_size);
// Recover the original pointer. // Recover the original pointer.
alloc = ptr_to_alloc(ptr, orig_size); alloc1 = alloc;
#ifdef MEMORY_HOOK_MALLOC_LOCK #ifdef MEMORY_HOOK_MALLOC_LOCK
_lock.acquire(); _lock.acquire();
alloc = call_realloc(alloc, inflated_size); alloc1 = call_realloc(alloc1, inflated_size);
_lock.release(); _lock.release();
#else #else
alloc = call_realloc(alloc, inflated_size); alloc1 = call_realloc(alloc1, inflated_size);
#endif #endif
} }
return alloc_to_ptr(alloc, size); void *ptr1 = alloc_to_ptr(alloc1, size);
assert(ptr1 >= alloc1 && (char *)ptr1 + size <= (char *)alloc1 + inflated_size);
#if defined(MEMORY_HOOK_DO_ALIGN)
// We might have to shift the memory to account for the new offset
// due to the alignment.
size_t orig_delta = (char *)ptr - (char *)alloc;
size_t new_delta = (char *)ptr1 - (char *)alloc1;
if (orig_delta != new_delta) {
memmove((char *)alloc1 + new_delta, (char *)alloc1 + orig_delta, min(size, orig_size));
}
#endif // MEMORY_HOOK_DO_ALIGN
return ptr1;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -102,7 +102,7 @@ private:
// for implementing the common, very direct code paths (for // for implementing the common, very direct code paths (for
// instance, 3-component float32 to LVecBase3f) as quickly as // instance, 3-component float32 to LVecBase3f) as quickly as
// possible. // possible.
class Packer { class Packer : public MemoryBase {
public: public:
virtual ~Packer(); virtual ~Packer();

View File

@ -218,7 +218,7 @@ private:
}; };
typedef pmap<GeomCollectorKey, GeomCollector> GeomCollectorMap; typedef pmap<GeomCollectorKey, GeomCollector> GeomCollectorMap;
class GlyphPlacement { class GlyphPlacement : public MemoryBase {
public: public:
INLINE void add_piece(Geom *geom, const RenderState *state); INLINE void add_piece(Geom *geom, const RenderState *state);
void calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point, void calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,