From efae6b73d0c6cd81cc9f013c2078ff35b0c76d2b Mon Sep 17 00:00:00 2001
From: Per Hedbor <ph@opera.com>
Date: Mon, 16 Sep 2013 11:37:21 +0200
Subject: [PATCH] Updated pp_memory_usge to use the new fields in memory_usage.

Also format it slightly differently.
---
 lib/modules/Debug.pmod/module.pmod | 83 ++++++++++++++++++++++++++----
 1 file changed, 72 insertions(+), 11 deletions(-)

diff --git a/lib/modules/Debug.pmod/module.pmod b/lib/modules/Debug.pmod/module.pmod
index 81528332b9..e434952ada 100644
--- a/lib/modules/Debug.pmod/module.pmod
+++ b/lib/modules/Debug.pmod/module.pmod
@@ -5,6 +5,7 @@ constant verify_internals = _verify_internals;
 constant memory_usage = _memory_usage;
 constant gc_status = _gc_status;
 constant describe_program = _describe_program;
+constant size_object = _size_object;
 
 #if constant(_debug)
 // These functions require --with-rtldebug.
@@ -32,29 +33,89 @@ constant dump_dmalloc_locations = _dump_dmalloc_locations;
 constant compiler_trace  = _compiler_trace;
 #endif
 
+/* significantly more compact version of size2string */
+private string mi2sz( int i )
+{
+    constant un = ({ "", "k","M","G","T" });
+    float x = (float)i;
+    int u = 0;
+    do
+    {
+        x /= 1024.0;
+        u++;
+    } while( x > 1000.0 );
+    return sprintf("%.1f%s",x,un[u]);
+}
+
 //! Returns a pretty printed version of the
 //! output from @[memory_usage].
 string pp_memory_usage() {
-  string ret="             Num   Bytes\n";
-  mapping mu = memory_usage();
-  foreach( ({ "array", "callable", "callback", "frame", "mapping",
-              "multiset", "object", "program", "string" }),
-           string what) {
-    ret += sprintf("%-8s  %6d  %6d (%s)\n", what, mu["num_"+what+"s"],
-                   mu[what+"_bytes"], String.int2size(mu[what+"_bytes"]));
-  }
-  return ret;
+    string ret="             Num   Bytes\n";
+    mapping q = _memory_usage();
+    mapping res = ([]), malloc = ([]);
+    foreach( q; string key; int val )
+    {
+        mapping in = res;
+        string sub ;
+        if( has_suffix( key, "_bytes" ) )
+        {
+            sub = "bytes";
+            key = key[..<6]+"s";
+            if( key == "mallocs" )
+                key = "malloc";
+        }
+        if( has_prefix( key, "num_" ) )
+        {
+            sub = "num";
+            key = key[4..];
+        }
+        if( key == "short_pike_strings" )
+            key = "strings";
+
+        if(key == "free_blocks" || key == "malloc" || key == "malloc_blocks" )
+            in = malloc;
+        if( val )
+        {
+            if( !in[key] )
+                in[key] = ([]);
+            in[key][sub] += val;
+        }
+    }
+
+    string output_one( mapping res, bool trailer )
+    {
+        array output = ({});
+        foreach( res; string key; mapping what )
+            output += ({({ what->bytes, what->num, key })});
+        output = reverse(sort( output ));
+
+        string format_row( array x )
+        {
+            return sprintf("%-20s %10s %10d\n", x[2], mi2sz(x[0]), x[1] );
+        };
+
+        return
+            sprintf("%-20s %10s %10s\n", "Type", "Bytes", "Num")+
+            "-"*(21+11+10)+"\n"+
+            map( output, format_row )*""+
+            "-"*(21+11+10)+"\n"+
+            (trailer?
+             format_row( ({ Array.sum( column(output,0) ), Array.sum( column(output,1) ), "total" }) ):"");
+    };
+    return output_one(res,true) + 
+        "\nMalloc info:\n"+output_one(malloc,false);
 }
 
 //! Returns the number of objects of every kind in memory.
-mapping(string:int) count_objects() {
+mapping(string:int) count_objects()
+{
   int orig_enabled = Pike.gc_parameters()->enabled;
   Pike.gc_parameters( (["enabled":0]) );
 
   mapping(string:int) ret = ([]);
 
   object obj = next_object();
-  //  while( zero_type(_prev(obj)) ) obj=_prev(obj);
+
   while(1) {
     object next_obj;
     if(catch(next_obj=_next(obj))) break;
-- 
GitLab