diff options
Diffstat (limited to 'samples/size')
-rw-r--r-- | samples/size/Makefile | 2 | ||||
-rw-r--r-- | samples/size/sample.cs | 19 | ||||
-rw-r--r-- | samples/size/size.c | 142 |
3 files changed, 100 insertions, 63 deletions
diff --git a/samples/size/Makefile b/samples/size/Makefile index e5dabdf1935..ad73bb1f43a 100644 --- a/samples/size/Makefile +++ b/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` diff --git a/samples/size/sample.cs b/samples/size/sample.cs index e5da814435b..ae4256bf435 100644 --- a/samples/size/sample.cs +++ b/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 (); diff --git a/samples/size/size.c b/samples/size/size.c index 94174ba0a65..12f39bdcb8c 100644 --- a/samples/size/size.c +++ b/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; } /* |