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

Reply via email to