use hashed set in allocator for O(1) lookup
This commit is contained in:
parent
4e6a1106fa
commit
5299ac0233
|
@ -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)
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue