Browse Source

2006-10-13 Joe Shaw <[email protected]>

	* 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
Joe Shaw 19 years ago
parent
commit
86d4be5d66
4 changed files with 106 additions and 63 deletions
  1. 6 0
      ChangeLog
  2. 1 1
      samples/size/Makefile
  3. 17 2
      samples/size/sample.cs
  4. 82 60
      samples/size/size.c

+ 6 - 0
ChangeLog

@@ -1,3 +1,9 @@
+2006-10-13  Joe Shaw  <[email protected]>
+
+	* 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  <[email protected]>
 
 	* configure.in: Disable visibility("hidden") on cygwin as well.

+ 1 - 1
samples/size/Makefile

@@ -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`

+ 17 - 2
samples/size/sample.cs

@@ -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 ();

+ 82 - 60
samples/size/size.c

@@ -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;
 }
 
 /*