Index: LeakTracer.cc =================================================================== RCS file: /home/cvs/cc-common/test/LeakTracer/LeakTracer.cc,v retrieving revision 1.1 retrieving revision 1.1.2.1 diff -u -p -r1.1 -r1.1.2.1 --- LeakTracer.cc 28 Jan 2006 02:38:55 -0000 1.1 +++ LeakTracer.cc 29 Mar 2008 05:53:50 -0000 1.1.2.1 @@ -97,7 +97,7 @@ static class LeakTracer { int newCount; // how many memory blocks do we have int leaksCount; // amount of entries in the leaks array - int firstFreeSpot; // Where is the first free spot in the leaks array? + int leaksUsed; // number of leaks used in the leaks array - i.e. > leaksUsed have not been used yet - RHW2008/03/28 int currentAllocated; // currentAllocatedMemory int maxAllocated; // maximum Allocated unsigned long totalAllocations; // total number of allocations. stats. @@ -123,6 +123,9 @@ static class LeakTracer { * stored in case of an delete. map */ int *leakHash; // fast lookup + int *freeleaks; // stack of free indexes - RHW2008/03/28 + int freeleaksCount; // number of free links available - RHW2008/03/28 + int freeleaksSize; // size of te freeleaks array - RHW2008/03/28 #ifdef THREAD_SAVE pthread_mutex_t mutex; @@ -148,7 +151,7 @@ public: initialized = true; newCount = 0; leaksCount = 0; - firstFreeSpot = 1; // index '0' is special + leaksUsed = 1; // index '0' is special currentAllocated = 0; maxAllocated = 0; totalAllocations = 0; @@ -156,6 +159,9 @@ public: report = 0; leaks = 0; leakHash = 0; + freeleaks = 0; + freeleaksCount = 0; + freeleaksSize = 0; char uniqFilename[256]; const char *filename = getenv("LEAKTRACE_FILE") ? : "leak.out"; @@ -272,6 +278,7 @@ public: writeLeakReport(); fclose(report); free(leaks); + free(freeleaks); #ifdef THREAD_SAVE pthread_mutex_destroy(&mutex); #endif @@ -321,23 +328,26 @@ void* LeakTracer::registerAlloc (size_t maxAllocated = currentAllocated; for (;;) { - for (int i = firstFreeSpot; i < leaksCount; i++) - if (leaks[i].addr == NULL) { - leaks[i].addr = p; - leaks[i].size = size; - leaks[i].type = type; - leaks[i].allocAddr=__builtin_return_address(1); - firstFreeSpot = i+1; - // allow to lookup our index fast. - int *hashPos = &leakHash[ ADDR_HASH(p) ]; - leaks[i].nextBucket = *hashPos; - *hashPos = i; + int i = 0; + if (freeleaksCount > 0) // peal off a free pre-used leak index + i = freeleaks[--freeleaksCount]; + else if(leaksUsed < leaksCount) // or, grab a completely new one, if any left + i = leaksUsed++; + if (i > 0) { + leaks[i].addr = p; + leaks[i].size = size; + leaks[i].type = type; + leaks[i].allocAddr=__builtin_return_address(1); + // allow to lookup our index fast. + int *hashPos = &leakHash[ ADDR_HASH(p) ]; + leaks[i].nextBucket = *hashPos; + *hashPos = i; #ifdef THREAD_SAVE - pthread_mutex_unlock(&mutex); + pthread_mutex_unlock(&mutex); #endif - return p; - } - + return p; + } + // Allocate a bigger array // Note that leaksCount starts out at 0. int new_leaksCount = (leaksCount == 0) ? INITIALSIZE @@ -402,9 +412,14 @@ void LeakTracer::registerFree (void *p, newCount--; leaks[i].addr = NULL; currentAllocated -= leaks[i].size; - if (i < firstFreeSpot) - firstFreeSpot = i; + // Push this onto the free stack + // Make sure there's enough space + if ( freeleaksCount >= freeleaksSize ) { + freeleaksSize += 1024; // Add a block of free indexes + freeleaks = (int *) LT_REALLOC(freeleaks, sizeof(int) * freeleaksSize); + } + freeleaks[freeleaksCount++] = i; if (leaks[i].type != type) { fprintf(report, "S %10p %10p # new%s but delete%s "