Author: rfm
Date: Thu Jul 9 13:37:37 2015
New Revision: 38773
URL: http://svn.gna.org/viewcvs/gnustep?rev=38773&view=rev
Log:
improve memory allocation statistics report
Modified:
libs/base/trunk/ChangeLog
libs/base/trunk/Source/NSDebug.m
Modified: libs/base/trunk/ChangeLog
URL:
http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/ChangeLog?rev=38773&r1=38772&r2=38773&view=diff
==============================================================================
--- libs/base/trunk/ChangeLog (original)
+++ libs/base/trunk/ChangeLog Thu Jul 9 13:37:37 2015
@@ -1,3 +1,8 @@
+2015-07-09 Richard Frith-Macdonald <[email protected]>
+
+ * Source/NSDebug.m: List memory allocation statistics in alphabetical
+ order (by class name) for easier interpretation.
+
2015-07-08 Richard Frith-Macdonald <[email protected]>
* Headers/Foundation/NSLock.h:
Modified: libs/base/trunk/Source/NSDebug.m
URL:
http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/Source/NSDebug.m?rev=38773&r1=38772&r2=38773&view=diff
==============================================================================
--- libs/base/trunk/Source/NSDebug.m (original)
+++ libs/base/trunk/Source/NSDebug.m Thu Jul 9 13:37:37 2015
@@ -39,6 +39,8 @@
#import "Foundation/NSNotificationQueue.h"
#import "Foundation/NSThread.h"
#import "Foundation/NSValue.h"
+
+#import "GSSorting.h"
#if HAVE_EXECINFO_H
#include <execinfo.h>
@@ -59,6 +61,16 @@
unsigned int stack_size;
} table_entry;
+typedef struct {
+ const char *name;
+ int count;
+} list_entry;
+
+static NSInteger itemComp(id v0, id v1, void *ctxt)
+{
+ return strcmp(((list_entry*)v0)->name, ((list_entry *)v1)->name);
+}
+
static unsigned int num_classes = 0;
static unsigned int table_size = 0;
@@ -72,8 +84,8 @@
static IMP doLockImp = 0;
static IMP unLockImp = 0;
-static const char* _GSDebugAllocationList(BOOL difference);
-static const char* _GSDebugAllocationListAll(void);
+static void _GSDebugAllocationFetch(list_entry *items, BOOL difference);
+static void _GSDebugAllocationFetchAll(list_entry *items);
static void _GSDebugAllocationAdd(Class c, id o);
static void _GSDebugAllocationRemove(Class c, id o);
@@ -402,29 +414,131 @@
const char*
GSDebugAllocationList(BOOL changeFlag)
{
- const char *ans;
- NSData *d;
+ list_entry *items;
+ unsigned size;
if (debug_allocation == NO)
{
return "Debug allocation system is not active!\n";
}
+
doLock();
- ans = _GSDebugAllocationList(changeFlag);
- d = [NSData dataWithBytes: ans length: strlen(ans) + 1];
+ size = num_classes;
+ if (size > 0)
+ {
+ items = malloc(sizeof(list_entry) * size);
+ _GSDebugAllocationFetch(items, changeFlag);
+ }
+ else
+ {
+ items = 0;
+ }
unLock();
- return (const char*)[d bytes];
-}
-
-static const char*
-_GSDebugAllocationList(BOOL difference)
-{
- unsigned int pos = 0;
- unsigned int i;
- static unsigned int siz = 0;
- static char *buf = 0;
-
- for (i = 0; i < num_classes; i++)
+
+ while (size > 0 && 0 == items[size - 1].name)
+ {
+ size--;
+ }
+ if (0 == size)
+ {
+ if (items != 0)
+ {
+ free(items);
+ }
+ if (changeFlag)
+ {
+ return "There are NO newly allocated or deallocated object!\n";
+ }
+ else
+ {
+ return "I can find NO allocated object!\n";
+ }
+ }
+ else
+ {
+ NSMutableString *result;
+ id order[size];
+ unsigned index;
+
+ for (index = 0; index < size; index++)
+ {
+ order[index] = (id)&items[index];
+ }
+ GSSortUnstable(order, NSMakeRange(0,size), (id)itemComp,
+ GSComparisonTypeFunction, 0);
+
+ result = [NSMutableString stringWithCapacity: 1000];
+ for (index = 0; index < size; index++)
+ {
+ list_entry *item = (list_entry*)order[index];
+
+ [result appendFormat: @"%d\t%s\n", item->count, item->name];
+ }
+ free(items);
+ return [result UTF8String];
+ }
+}
+
+const char*
+GSDebugAllocationListAll()
+{
+ list_entry *items;
+ unsigned size;
+
+ if (debug_allocation == NO)
+ {
+ return "Debug allocation system is not active!\n";
+ }
+
+ doLock();
+ size = num_classes;
+ if (size > 0)
+ {
+ items = malloc(sizeof(list_entry) * size);
+ _GSDebugAllocationFetchAll(items);
+ }
+ else
+ {
+ items = 0;
+ }
+ unLock();
+
+ if (0 == items)
+ {
+ return "I can find NO allocated object!\n";
+ }
+ else
+ {
+ NSMutableString *result;
+ id order[size];
+ unsigned index;
+
+ for (index = 0; index < size; index++)
+ {
+ order[index] = (id)&items[index];
+ }
+ GSSortUnstable(order, NSMakeRange(0,size), (id)itemComp,
+ GSComparisonTypeFunction, 0);
+
+ result = [NSMutableString stringWithCapacity: 1000];
+ for (index = 0; index < size; index++)
+ {
+ list_entry *item = (list_entry*)order[index];
+
+ [result appendFormat: @"%d\t%s\n", item->count, item->name];
+ }
+ free(items);
+ return [result UTF8String];
+ }
+}
+
+static void
+_GSDebugAllocationFetch(list_entry *items, BOOL difference)
+{
+ unsigned i;
+ unsigned pos;
+
+ for (i = pos = 0; i < num_classes; i++)
{
int val = the_table[i].count;
@@ -432,139 +546,32 @@
{
val -= the_table[i].lastc;
}
- if (val != 0)
- {
- pos += 22 + strlen(class_getName(the_table[i].class));
- }
- }
- if (pos == 0)
- {
- if (difference)
- {
- return "There are NO newly allocated or deallocated object!\n";
- }
- else
- {
- return "I can find NO allocated object!\n";
- }
- }
-
- pos++;
-
- if (pos > siz)
- {
- if (pos & 0xff)
- {
- pos = ((pos >> 8) + 1) << 8;
- }
- siz = pos;
- if (buf)
- {
- NSZoneFree(NSDefaultMallocZone(), buf);
- }
- buf = NSZoneMalloc(NSDefaultMallocZone(), siz);
- }
-
- if (0 == buf)
- {
- return "";
- }
-
- pos = 0;
+ the_table[i].lastc = the_table[i].count;
+ if (val)
+ {
+ items[pos].name = class_getName(the_table[i].class);
+ items[pos].count = val;
+ pos++;
+ }
+ }
+ while (pos < num_classes)
+ {
+ items[pos].name = 0;
+ items[pos].count = 0;
+ pos++;
+ }
+}
+
+static void
+_GSDebugAllocationFetchAll(list_entry *items)
+{
+ unsigned i;
+
for (i = 0; i < num_classes; i++)
{
- int val = the_table[i].count;
-
- if (difference)
- {
- val -= the_table[i].lastc;
- }
- the_table[i].lastc = the_table[i].count;
-
- if (val != 0)
- {
- snprintf(&buf[pos], siz - pos, "%d\t%s\n",
- val, class_getName(the_table[i].class));
- pos += strlen(&buf[pos]);
- }
- }
-
- return buf;
-}
-
-const char*
-GSDebugAllocationListAll()
-{
- const char *ans;
- NSData *d;
-
- if (debug_allocation == NO)
- {
- return "Debug allocation system is not active!\n";
- }
- doLock();
- ans = _GSDebugAllocationListAll();
- d = [NSData dataWithBytes: ans length: strlen(ans)+1];
- unLock();
- return (const char*)[d bytes];
-}
-
-static const char*
-_GSDebugAllocationListAll(void)
-{
- unsigned int pos = 0;
- unsigned int i;
- static unsigned int siz = 0;
- static char *buf = 0;
-
- for (i = 0; i < num_classes; i++)
- {
- int val = the_table[i].total;
-
- if (val != 0)
- {
- pos += 22 + strlen(class_getName(the_table[i].class));
- }
- }
- if (pos == 0)
- {
- return "I can find NO allocated object!\n";
- }
- pos++;
-
- if (pos > siz)
- {
- if (pos & 0xff)
- {
- pos = ((pos >> 8) + 1) << 8;
- }
- siz = pos;
- if (buf)
- {
- NSZoneFree(NSDefaultMallocZone(), buf);
- }
- buf = NSZoneMalloc(NSDefaultMallocZone(), siz);
- }
-
- if (0 == buf)
- {
- return "";
- }
-
- pos = 0;
- for (i = 0; i < num_classes; i++)
- {
- int val = the_table[i].total;
-
- if (val != 0)
- {
- snprintf(&buf[pos], siz - pos, "%d\t%s\n",
- val, class_getName(the_table[i].class));
- pos += strlen(&buf[pos]);
- }
- }
-
- return buf;
+ items[i].name = class_getName(the_table[i].class);
+ items[i].count = the_table[i].total;
+ }
}
void
_______________________________________________
Gnustep-cvs mailing list
[email protected]
https://mail.gna.org/listinfo/gnustep-cvs