2 #include <mono/jit/jit.h>
3 #include <mono/metadata/environment.h>
4 #include <mono/metadata/profiler.h>
5 #include <mono/metadata/tokentype.h>
6 #include <mono/metadata/debug-helpers.h>
7 #include <mono/metadata/assembly.h>
10 #define FIELD_ATTRIBUTE_STATIC 0x10
11 #define FIELD_ATTRIBUTE_HAS_FIELD_RVA 0x100
13 static int memory_usage (MonoObject
*obj
, GHashTable
*visited
);
16 memory_usage_array (MonoArray
*array
, GHashTable
*visited
)
19 MonoClass
*array_class
= mono_object_get_class ((MonoObject
*) array
);
20 MonoClass
*element_class
= mono_class_get_element_class (array_class
);
21 MonoType
*element_type
= mono_class_get_type (element_class
);
23 if (MONO_TYPE_IS_REFERENCE (element_type
)) {
26 for (i
= 0; i
< mono_array_length (array
); i
++) {
27 MonoObject
*element
= mono_array_get (array
, gpointer
, i
);
30 total
+= memory_usage (element
, visited
);
38 memory_usage (MonoObject
*obj
, GHashTable
*visited
)
44 MonoClassField
*field
;
46 if (g_hash_table_lookup (visited
, obj
))
49 g_hash_table_insert (visited
, obj
, obj
);
51 klass
= mono_object_get_class (obj
);
52 type
= mono_class_get_type (klass
);
54 /* This is an array, so drill down into it */
55 if (type
->type
== MONO_TYPE_SZARRAY
)
56 total
+= memory_usage_array ((MonoArray
*) obj
, visited
);
58 while ((field
= mono_class_get_fields (klass
, &iter
)) != NULL
) {
59 MonoType
*ftype
= mono_field_get_type (field
);
62 if ((ftype
->attrs
& (FIELD_ATTRIBUTE_STATIC
| FIELD_ATTRIBUTE_HAS_FIELD_RVA
)) != 0)
65 /* FIXME: There are probably other types we need to drill down into */
66 switch (ftype
->type
) {
69 case MONO_TYPE_OBJECT
:
70 mono_field_get_value (obj
, field
, &value
);
73 total
+= memory_usage ((MonoObject
*) value
, visited
);
77 case MONO_TYPE_SZARRAY
:
78 mono_field_get_value (obj
, field
, &value
);
81 total
+= memory_usage_array ((MonoArray
*) value
, visited
);
82 total
+= mono_object_get_size ((MonoObject
*) value
);
88 /* printf ("Got type 0x%x\n", ftype->type); */
89 /* ignore, this will be included in mono_object_get_size () */
94 total
+= mono_object_get_size (obj
);
100 * Only returns data for instances, not for static fields, those might
101 * be larger, or hold larger structures
104 GetObjectSize (MonoObject
*this)
106 GHashTable
*visited
= g_hash_table_new (NULL
, NULL
);
109 n
= memory_usage (this, visited
);
111 g_hash_table_destroy (visited
);
117 GetObjectPointer (MonoObject
*this)
123 mono_glue_install_icall (void)
125 mono_add_internal_call ("Beagle.Util.SystemInformation::GetObjectSizeIcall", GetObjectSize
);
126 mono_add_internal_call ("Beagle.Util.SystemInformation::GetObjectPointerIcall", GetObjectPointer
);