2006-10-13 Joe Shaw <joeshaw@novell.com>
authorJoe Shaw <joe@joeshaw.org>
Fri, 13 Oct 2006 20:10:55 +0000 (20:10 -0000)
committerJoe Shaw <joe@joeshaw.org>
Fri, 13 Oct 2006 20:10:55 +0000 (20:10 -0000)
* samples/size/size.c: Flesh this out quite a bit more so that
its results are more accurate.
* samples/size/sample.cs: Add a few more test cases.

svn path=/trunk/mono/; revision=66660

ChangeLog
samples/size/Makefile
samples/size/sample.cs
samples/size/size.c

index 403d9e1fcb8d6ae616568583bf853e8492b67164..07a15adcb411610e5c35577e3b512713948025dc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2006-10-13  Joe Shaw  <joeshaw@novell.com>
+
+       * samples/size/size.c: Flesh this out quite a bit more so that
+       its results are more accurate.
+       * samples/size/sample.cs: Add a few more test cases.
+
 2006-10-12  Zoltan Varga  <vargaz@freemail.hu>
 
        * configure.in: Disable visibility("hidden") on cygwin as well.
index e5dabdf1935cd258bcd2294aea746dc01022f77a..ad73bb1f43a43510b64ecc16b333082c7674cc00 100644 (file)
@@ -9,4 +9,4 @@ objectinspector.dll: objectinspector.cs
        mcs -target:library objectinspector.cs
 
 libmono-profiler-size.so: size.c
-       gcc -Wall -shared -o libmono-profiler-size.so size.c `pkg-config --cflags --libs mono`
+       gcc -Wall -g -shared -o libmono-profiler-size.so size.c `pkg-config --cflags --libs mono`
index e5da814435b2a725c7cda30dd61e445c0e0bb5fd..ae4256bf43573d2568fbd7af58b540283f68123d 100644 (file)
@@ -2,13 +2,26 @@ using System;
 using Mono.ObjectServices;
 
 class Demo {
-    int a;
+
+        int a;
+
        static void Main ()
        {
                Demo d = new Demo ();
 
                prints ("d", d);
                prints ("dd", new DD ());
+               prints ("short str", "short");
+               prints ("long str", "this is a longer string which we want to measure the size of");
+
+               object[] obj_array = new object [100];
+
+               prints ("obj array", obj_array);
+
+               for (int i = 0; i < 100; i++)
+                       obj_array [i] = new Demo ();
+
+               prints ("obj array w/ demos", obj_array);
        }
 
        static void prints (string s, object x)
@@ -20,7 +33,9 @@ class Demo {
 class DD {
     Demo d = new Demo ();
     object [] o = new object [10];
-    
+    char [] ch = new char [10];
+    int junk;   
     public DD ()
     {
            o [0] = new Demo ();
index 94174ba0a654f4c17098c97958b6f2f14f08a9ff..12f39bdcb8c271a80621329a9e87878b696b5b2d 100644 (file)
@@ -8,70 +8,92 @@
 #include <string.h>
 
 #define FIELD_ATTRIBUTE_STATIC 0x10
+#define FIELD_ATTRIBUTE_HAS_FIELD_RVA 0x100
 
-int
-memory_usage (MonoObject *this, GHashTable *visited)
+static int memory_usage (MonoObject *obj, GHashTable *visited);
+
+static int
+memory_usage_array (MonoArray *array, GHashTable *visited)
 {
-       int total = 0;
-       MonoClass *class;
-       gpointer iter = (gpointer) 0;
-       MonoClassField *field;
-       
-       if (g_hash_table_lookup (visited, this))
-               return total;
+        int total = 0;
+        MonoClass *array_class = mono_object_get_class ((MonoObject *) array);
+        MonoClass *element_class = mono_class_get_element_class (array_class);
+        MonoType *element_type = mono_class_get_type (element_class);
 
-       class = mono_object_get_class (this);
-       
-       g_hash_table_insert (visited, this, this);
-
-       while ((field = mono_class_get_fields (class, &iter)) != NULL){
-               MonoType *ftype = mono_field_get_type (field);
-               void *value;
-
-               if ((ftype->attrs & FIELD_ATTRIBUTE_STATIC) != 0)
-                       continue;
-
-               switch (ftype->type){
-               case MONO_TYPE_CLASS: 
-               case MONO_TYPE_OBJECT:
-                       mono_field_get_value (this, field, &value);
-
-                       if (value != NULL)
-                               total += memory_usage ((MonoObject *) value, visited);
-                       break;
-
-               case MONO_TYPE_SZARRAY:
-                       {
-                               int len, i;
-                               mono_field_get_value (this, field, &value);
-                               len = mono_array_length ((MonoArray *)value);
-                               for (i = 0; i < len; i++){
-                                       MonoObject *item = mono_array_get ((MonoArray *) value, gpointer, i);
-                                       if (item != NULL)
-                                               total += memory_usage (item, visited);
-                               }
-                       }
-                       break;
-                       
-               case MONO_TYPE_I4:
-               case MONO_TYPE_I1:
-               case MONO_TYPE_I2:
-               case MONO_TYPE_U4:
-               case MONO_TYPE_U2:
-               case MONO_TYPE_U1:
-               case MONO_TYPE_VOID:
-               case MONO_TYPE_BOOLEAN:
-               case MONO_TYPE_CHAR:
-                       /* ignore */
-                       break;
-               default:
-                       printf ("unhandled type: 0x%x\n", ftype->type);
-               }
-       }
-       
-       total += mono_class_instance_size (class);
+        if (MONO_TYPE_IS_REFERENCE (element_type)) {
+                int i;
+
+                for (i = 0; i < mono_array_length (array); i++) {
+                        MonoObject *element = mono_array_get (array, gpointer, i);
+
+                        if (element != NULL)
+                                total += memory_usage (element, visited);
+                }
+        }
+
+        return total;
+}
+
+static int
+memory_usage (MonoObject *obj, GHashTable *visited)
+{
+        int total = 0;
+        MonoClass *klass;
+        MonoType *type;
+        gpointer iter = NULL;
+        MonoClassField *field;
+
+        if (g_hash_table_lookup (visited, obj))
+                return 0;
+
+        g_hash_table_insert (visited, obj, obj);
+
+        klass = mono_object_get_class (obj);
+        type = mono_class_get_type (klass);
+
+        /* This is an array, so drill down into it */
+        if (type->type == MONO_TYPE_SZARRAY)
+                total += memory_usage_array ((MonoArray *) obj, visited);
+
+        while ((field = mono_class_get_fields (klass, &iter)) != NULL) {
+                MonoType *ftype = mono_field_get_type (field);
+                gpointer value;
+
+                if ((ftype->attrs & (FIELD_ATTRIBUTE_STATIC | FIELD_ATTRIBUTE_HAS_FIELD_RVA)) != 0)
+                        continue;
+
+                /* FIXME: There are probably other types we need to drill down into */
+                switch (ftype->type) {
+
+                case MONO_TYPE_CLASS:
+                case MONO_TYPE_OBJECT:
+                        mono_field_get_value (obj, field, &value);
+
+                        if (value != NULL)
+                                total += memory_usage ((MonoObject *) value, visited);
+
+                        break;
+
+                case MONO_TYPE_SZARRAY:
+                        mono_field_get_value (obj, field, &value);
+
+                        if (value != NULL) {
+                                total += memory_usage_array ((MonoArray *) value, visited);
+                                total += mono_object_get_size ((MonoObject *) value);
+                        }
+
+                        break;
+
+                default:
+                        /* printf ("Got type 0x%x\n", ftype->type); */
+                        /* ignore, this will be included in mono_object_get_size () */
+                        break;
+                }
+        }
+
+        total += mono_object_get_size (obj);
 
-       return total;
+        return total;
 }
 
 /*