[Remoting] Avoid needing to resolve the type by serializing the TypeInfo
[mono-project.git] / samples / size / size.c
blobc24b417d21f5cfb3527009cc6303b9bdb6e3fff7
1 #include <glib.h>
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>
8 #include <string.h>
10 #define FIELD_ATTRIBUTE_STATIC 0x10
11 #define FIELD_ATTRIBUTE_HAS_FIELD_RVA 0x100
13 static int memory_usage (MonoObject *obj, GHashTable *visited);
15 static int
16 memory_usage_array (MonoArray *array, GHashTable *visited)
18 int total = 0;
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)) {
24 int i;
26 for (i = 0; i < mono_array_length (array); i++) {
27 MonoObject *element = mono_array_get (array, gpointer, i);
29 if (element != NULL)
30 total += memory_usage (element, visited);
34 return total;
37 static int
38 memory_usage (MonoObject *obj, GHashTable *visited)
40 int total = 0;
41 MonoClass *klass;
42 MonoType *type;
43 gpointer iter = NULL;
44 MonoClassField *field;
46 if (g_hash_table_lookup (visited, obj))
47 return 0;
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);
60 gpointer value;
62 if ((ftype->attrs & (FIELD_ATTRIBUTE_STATIC | FIELD_ATTRIBUTE_HAS_FIELD_RVA)) != 0)
63 continue;
65 /* FIXME: There are probably other types we need to drill down into */
66 switch (ftype->type) {
68 case MONO_TYPE_CLASS:
69 case MONO_TYPE_OBJECT:
70 mono_field_get_value (obj, field, &value);
72 if (value != NULL)
73 total += memory_usage ((MonoObject *) value, visited);
75 break;
77 case MONO_TYPE_STRING:
78 mono_field_get_value (obj, field, &value);
79 if (value != NULL)
80 total += mono_object_get_size ((MonoObject *) value);
81 break;
83 case MONO_TYPE_SZARRAY:
84 mono_field_get_value (obj, field, &value);
86 if (value != NULL) {
87 total += memory_usage_array ((MonoArray *) value, visited);
88 total += mono_object_get_size ((MonoObject *) value);
91 break;
93 default:
94 /* printf ("Got type 0x%x\n", ftype->type); */
95 /* ignore, this will be included in mono_object_get_size () */
96 break;
100 total += mono_object_get_size (obj);
102 return total;
106 * Only returns data for instances, not for static fields, those might
107 * be larger, or hold larger structures
109 static int
110 GetMemoryUsage (MonoObject *this)
112 GHashTable *visited = g_hash_table_new (NULL, NULL);
113 int n;
115 n = memory_usage (this, visited);
117 g_hash_table_destroy (visited);
119 return n;
122 static int installed = 0;
124 void install_icall (MonoProfiler *prof, MonoMethod *method, MonoJitInfo* jinfo, int result)
126 if (installed)
127 return;
129 mono_add_internal_call ("Mono.ObjectServices.ObjectInspector::GetMemoryUsage", GetMemoryUsage);
130 installed = 1;
133 void
134 mono_profiler_startup (const char *desc)
136 mono_profiler_install_jit_end (install_icall);
137 mono_profiler_set_events (MONO_PROFILE_JIT_COMPILATION);