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_STRING
:
78 mono_field_get_value (obj
, field
, &value
);
80 total
+= mono_object_get_size ((MonoObject
*) value
);
83 case MONO_TYPE_SZARRAY
:
84 mono_field_get_value (obj
, field
, &value
);
87 total
+= memory_usage_array ((MonoArray
*) value
, visited
);
88 total
+= mono_object_get_size ((MonoObject
*) value
);
94 /* printf ("Got type 0x%x\n", ftype->type); */
95 /* ignore, this will be included in mono_object_get_size () */
100 total
+= mono_object_get_size (obj
);
106 * Only returns data for instances, not for static fields, those might
107 * be larger, or hold larger structures
110 GetMemoryUsage (MonoObject
*this)
112 GHashTable
*visited
= g_hash_table_new (NULL
, NULL
);
115 n
= memory_usage (this, visited
);
117 g_hash_table_destroy (visited
);
122 static int installed
= 0;
124 void install_icall (MonoProfiler
*prof
, MonoMethod
*method
, MonoJitInfo
* jinfo
, int result
)
129 mono_add_internal_call ("Mono.ObjectServices.ObjectInspector::GetMemoryUsage", GetMemoryUsage
);
134 mono_profiler_startup (const char *desc
)
136 mono_profiler_install_jit_end (install_icall
);
137 mono_profiler_set_events (MONO_PROFILE_JIT_COMPILATION
);