use hashed set in allocator for O(1) lookup

This commit is contained in:
Eduardo Bart 2011-07-12 19:29:06 -03:00
parent 4e6a1106fa
commit 5299ac0233
2 changed files with 33 additions and 36 deletions

View File

@ -106,6 +106,25 @@ static void addr2line(void *address, const char* name, bool viewSource = false)
printf("\n"); printf("\n");
} }
void printBacktrace()
{
void *buffer[128];
int size = backtrace(buffer, 128);
char **strings = backtrace_symbols(buffer, size);
for(int i = 1; i < size; i++) {
if(i == 1) {
printf("\tfrom ");
} else {
printf("\tat ");
}
std::string str = strings[i];
addr2line(buffer[i], str.substr(0, str.find('(')).c_str());
}
printf("\n");
free(strings);
}
Allocator::Allocator() Allocator::Allocator()
{ {
} }
@ -118,16 +137,12 @@ Allocator::~Allocator()
dumpLeaks(); dumpLeaks();
disableAllocator();
for(AllocationBlocksList::iterator it = m_allocationsBlocks.begin(), end = m_allocationsBlocks.end(); it != end; ++it) { for(AllocationBlocksList::iterator it = m_allocationsBlocks.begin(), end = m_allocationsBlocks.end(); it != end; ++it) {
AllocationBlock* block = (*it); AllocationBlock* block = (*it);
free(block->backtraceBuffer); free(block->backtraceBuffer);
free(block); free(block);
} }
m_allocationsBlocks.clear(); m_allocationsBlocks.clear();
enableAllocator();
} }
void Allocator::dumpLeaks() void Allocator::dumpLeaks()
@ -136,7 +151,11 @@ void Allocator::dumpLeaks()
boost::recursive_mutex::scoped_lock lock(m_allocatorLock); boost::recursive_mutex::scoped_lock lock(m_allocatorLock);
#endif #endif
disableAllocator(); bool shouldRenable = false;
if(isAllocatorEnabled()) {
disableAllocator();
shouldRenable = true;
}
unsigned int definitelyLostBytes = 0; unsigned int definitelyLostBytes = 0;
unsigned int blockNumber = 1; unsigned int blockNumber = 1;
@ -187,25 +206,8 @@ void Allocator::dumpLeaks()
printf("leaked blocks: %d in %d blocks\n", numberOfLeakedBlocks, numberOfBlocks); printf("leaked blocks: %d in %d blocks\n", numberOfLeakedBlocks, numberOfBlocks);
} }
enableAllocator(); if(shouldRenable)
} enableAllocator();
void printBacktrace()
{
void *buffer[128];
int size = backtrace(buffer, 128);
char **strings = backtrace_symbols(buffer, size);
for(int i = 1; i < size; i++) {
if(i == 1) {
printf("\tfrom ");
} else {
printf("\tat ");
}
std::string str = strings[i];
addr2line(buffer[i], str.substr(0, str.find('(')).c_str());
}
printf("\n");
free(strings);
} }
AllocationBlock* Allocator::findBlock(void **backtraceBuffer, int backtraceSize, unsigned int bytes) AllocationBlock* Allocator::findBlock(void **backtraceBuffer, int backtraceSize, unsigned int bytes)

View File

@ -4,6 +4,7 @@
#ifdef _DEBUG_MEMORY #ifdef _DEBUG_MEMORY
#include <unordered_set> #include <unordered_set>
#include <boost/functional/hash.hpp>
#ifdef _REENTRANT #ifdef _REENTRANT
#include <boost/thread.hpp> #include <boost/thread.hpp>
@ -19,23 +20,17 @@ struct AllocationBlock
struct block_hash : std::unary_function<AllocationBlock *, std::size_t> { struct block_hash : std::unary_function<AllocationBlock *, std::size_t> {
std::size_t operator()(const AllocationBlock *block) const { std::size_t operator()(const AllocationBlock *block) const {
struct HashKey { std::size_t seed = 0;
unsigned int bytes;
void *backtraceTop[3];
unsigned char backtraceSize;
} hashKey;
hashKey.bytes = block->bytes; boost::hash_combine(seed, block->bytes);
for(int i=0;i<3;++i) { for(int i=0;i<3;++i) {
if(i < block->backtraceSize) if(i < block->backtraceSize)
hashKey.backtraceTop[i] = block->backtraceBuffer[i]; boost::hash_combine(seed, block->backtraceBuffer[i]);
else else
hashKey.backtraceTop[i] = NULL; boost::hash_combine(seed, 0);
} }
hashKey.backtraceSize = block->backtraceSize; boost::hash_combine(seed, block->backtraceSize);
return seed;
//std::hash<HashKey> hasher;
return 1;//hasher(hashKey);
} }
}; };