Skip to content

Commit 995a0f4

Browse files
authored
Merge pull request #1065 from Unity-Technologies/scripting_memory_capture_static_field_byte_reporting_bugfix
Scripting memory capture - static field byte reporting fix
2 parents 5f030e5 + 8b1b682 commit 995a0f4

File tree

1 file changed

+98
-79
lines changed

1 file changed

+98
-79
lines changed

mono/metadata/unity-memory-info.c

Lines changed: 98 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -24,67 +24,84 @@ typedef struct CollectMetadataContext
2424
MonoMetadataSnapshot* metadata;
2525
} CollectMetadataContext;
2626

27-
static void ContextInsertClass(CollectMetadataContext* context, MonoClass* klass)
27+
static void
28+
ContextRecurseClassData (CollectMetadataContext *context, MonoClass *klass)
2829
{
2930
gpointer orig_key, value;
31+
gpointer iter = NULL;
32+
MonoClassField *field = NULL;
33+
int fieldCount;
34+
3035
/* use g_hash_table_lookup_extended as it returns boolean to indicate if value was found.
3136
* If we use g_hash_table_lookup it returns the value which we were comparing to NULL. The problem is
3237
* that 0 is a valid class index and was confusing our logic.
3338
*/
34-
if (klass->inited && !g_hash_table_lookup_extended(context->allTypes, klass, &orig_key, &value))
35-
g_hash_table_insert(context->allTypes, klass, GINT_TO_POINTER(context->currentIndex++));
39+
if (!g_hash_table_lookup_extended (context->allTypes, klass, &orig_key, &value)) {
40+
g_hash_table_insert (context->allTypes, klass, GINT_TO_POINTER (context->currentIndex++));
41+
42+
fieldCount = mono_class_num_fields (klass);
43+
44+
if (fieldCount > 0) {
45+
while ((field = mono_class_get_fields (klass, &iter))) {
46+
MonoClass *fieldKlass = mono_class_from_mono_type (field->type);
47+
48+
if (fieldKlass != klass)
49+
ContextRecurseClassData (context, fieldKlass);
50+
}
51+
}
52+
}
3653
}
3754

38-
static void CollectHashMapClass(gpointer key, gpointer value, gpointer user_data)
55+
static void
56+
CollectHashMapClass (gpointer key, gpointer value, gpointer user_data)
3957
{
40-
CollectMetadataContext* context = (CollectMetadataContext*)user_data;
41-
MonoClass* klass = (MonoClass*)value;
42-
ContextInsertClass(context, klass);
58+
CollectMetadataContext *context = (CollectMetadataContext *)user_data;
59+
MonoClass *klass = (MonoClass *)value;
60+
ContextRecurseClassData (context, klass);
4361
}
4462

45-
static void CollectHashMapListClasses(gpointer key, gpointer value, gpointer user_data)
63+
static void
64+
CollectHashMapListClasses (gpointer key, gpointer value, gpointer user_data)
4665
{
47-
CollectMetadataContext* context = (CollectMetadataContext*)user_data;
48-
GSList* list = (GSList*)value;
66+
CollectMetadataContext *context = (CollectMetadataContext *)user_data;
67+
GSList *list = (GSList *)value;
4968

50-
while (list != NULL)
51-
{
52-
MonoClass* klass = (MonoClass*)list->data;
53-
ContextInsertClass(context, klass);
69+
while (list != NULL) {
70+
MonoClass *klass = (MonoClass *)list->data;
71+
ContextRecurseClassData (context, klass);
5472

55-
list = g_slist_next(list);
73+
list = g_slist_next (list);
5674
}
5775
}
5876

59-
static void CollectGenericClass(MonoGenericClass* genericClass, gpointer user_data)
77+
static void
78+
CollectGenericClass (MonoGenericClass *genericClass, gpointer user_data)
6079
{
61-
CollectMetadataContext* context = (CollectMetadataContext*)user_data;
80+
CollectMetadataContext *context = (CollectMetadataContext *)user_data;
6281

6382
if (genericClass->cached_class != NULL)
64-
ContextInsertClass(context, genericClass->cached_class);
83+
ContextRecurseClassData (context, genericClass->cached_class);
6584
}
6685

67-
static void CollectImageMetaData(MonoImage* image, gpointer value, CollectMetadataContext* context)
86+
static void
87+
CollectImageMetaData (MonoImage *image, gpointer value, CollectMetadataContext *context)
6888
{
6989
int i;
7090
MonoTableInfo *tdef = &image->tables[MONO_TABLE_TYPEDEF];
7191
GSList *list;
7292

73-
if (image->dynamic)
74-
{
93+
if (image->dynamic) {
7594
GHashTableIter iter;
7695
gpointer key;
77-
MonoDynamicImage* dynamicImage = (MonoDynamicImage*)image;
78-
79-
g_hash_table_iter_init(&iter, dynamicImage->typeref);
96+
MonoDynamicImage *dynamicImage = (MonoDynamicImage *)image;
97+
g_hash_table_iter_init (&iter, dynamicImage->typeref);
8098

81-
while (g_hash_table_iter_next(&iter, &key, NULL))
82-
{
83-
MonoType* monoType = (MonoType*)key;
84-
MonoClass* klass = mono_type_get_class(monoType);
99+
while (g_hash_table_iter_next (&iter, &key, NULL)) {
100+
MonoType *monoType = (MonoType *)key;
101+
MonoClass *klass = mono_class_from_mono_type (monoType);
85102

86103
if (klass)
87-
ContextInsertClass(context, klass);
104+
ContextRecurseClassData (context, klass);
88105
}
89106
}
90107

@@ -93,119 +110,121 @@ static void CollectImageMetaData(MonoImage* image, gpointer value, CollectMetada
93110
*/
94111
list = image->reflection_info_unregister_classes;
95112

96-
while (list)
97-
{
113+
while (list) {
98114
MonoClass *klass = (MonoClass *)list->data;
99115

100116
if (klass)
101-
ContextInsertClass(context, klass);
117+
ContextRecurseClassData (context, klass);
102118

103119
list = list->next;
104120
}
105121

106-
for (i = 1; i < tdef->rows; ++i)
107-
{
122+
for (i = 1; i < tdef->rows; ++i) {
108123
MonoClass *klass;
109124
MonoError error;
110125

111126
guint32 token = (i + 1) | MONO_TOKEN_TYPE_DEF;
112127

113-
klass = mono_class_get_checked(image, token, &error);
128+
klass = mono_class_get_checked (image, token, &error);
114129

115130
if (klass)
116-
ContextInsertClass(context, klass);
131+
ContextRecurseClassData (context, klass);
117132
}
118133

119134
if (image->array_cache)
120-
g_hash_table_foreach(image->array_cache, CollectHashMapListClasses, context);
135+
g_hash_table_foreach (image->array_cache, CollectHashMapListClasses, context);
121136

122137
if (image->szarray_cache)
123-
g_hash_table_foreach(image->szarray_cache, CollectHashMapClass, context);
138+
g_hash_table_foreach (image->szarray_cache, CollectHashMapClass, context);
124139

125140
if (image->ptr_cache)
126-
g_hash_table_foreach(image->ptr_cache, CollectHashMapClass, context);
141+
g_hash_table_foreach (image->ptr_cache, CollectHashMapClass, context);
127142
}
128143

129-
static int FindClassIndex(GHashTable* hashTable, MonoClass* klass)
144+
static int
145+
FindClassIndex (GHashTable *hashTable, MonoClass *klass)
130146
{
131147
gpointer orig_key, value;
132148

133-
if (!g_hash_table_lookup_extended(hashTable, klass, &orig_key, &value))
149+
if (!g_hash_table_lookup_extended (hashTable, klass, &orig_key, &value))
134150
return -1;
135151

136-
return GPOINTER_TO_INT(value);
152+
return GPOINTER_TO_INT (value);
137153
}
138154

139-
static void AddMetadataType(gpointer key, gpointer value, gpointer user_data)
155+
static void
156+
AddMetadataType (gpointer key, gpointer value, gpointer user_data)
140157
{
141-
MonoClass* klass = (MonoClass*)key;
142-
int index = GPOINTER_TO_INT(value);
143-
CollectMetadataContext* context = (CollectMetadataContext*)user_data;
144-
MonoMetadataSnapshot* metadata = context->metadata;
145-
MonoMetadataType* type = &metadata->types[index];
158+
MonoClass *klass = (MonoClass *)key;
146159

147-
if (klass->rank > 0)
148-
{
149-
type->flags = (MonoMetadataTypeFlags)(kArray | (kArrayRankMask & (klass->rank << 16)));
150-
type->baseOrElementTypeIndex = FindClassIndex(context->allTypes, mono_class_get_element_class(klass));
151-
}
152-
else
153-
{
160+
int index = GPOINTER_TO_INT (value);
161+
CollectMetadataContext *context = (CollectMetadataContext *)user_data;
162+
MonoMetadataSnapshot *metadata = context->metadata;
163+
MonoMetadataType *type = &metadata->types[index];
164+
165+
if (klass->rank > 0) {
166+
type->flags = (MonoMetadataTypeFlags) (kArray | (kArrayRankMask & (klass->rank << 16)));
167+
type->baseOrElementTypeIndex = FindClassIndex (context->allTypes, mono_class_get_element_class (klass));
168+
} else {
154169
gpointer iter = NULL;
155170
int fieldCount = 0;
156-
MonoClassField* field;
157-
MonoClass* baseClass;
158-
MonoVTable* vtable;
159-
void* statics_data;
171+
MonoClassField *field;
172+
MonoClass *baseClass;
173+
MonoVTable *vtable;
174+
void *statics_data;
160175

161176
type->flags = (klass->valuetype || klass->byval_arg.type == MONO_TYPE_PTR) ? kValueType : kNone;
162177
type->fieldCount = 0;
178+
fieldCount = mono_class_num_fields (klass);
179+
if (fieldCount > 0) {
180+
type->fields = g_new (MonoMetadataField, fieldCount);
163181

164-
if (mono_class_num_fields(klass) > 0)
165-
{
166-
type->fields = g_new(MonoMetadataField, mono_class_num_fields(klass));
182+
while ((field = mono_class_get_fields (klass, &iter))) {
183+
MonoMetadataField *metaField = &type->fields[type->fieldCount];
184+
MonoClass *typeKlass = mono_class_from_mono_type (field->type);
167185

168-
while ((field = mono_class_get_fields(klass, &iter)))
169-
{
170-
MonoMetadataField* metaField = &type->fields[type->fieldCount];
171-
metaField->typeIndex = FindClassIndex(context->allTypes, mono_class_from_mono_type(field->type));
186+
if (typeKlass->rank > 0)
187+
metaField->typeIndex = FindClassIndex (context->allTypes, mono_class_get_element_class (typeKlass));
188+
else
189+
metaField->typeIndex = FindClassIndex (context->allTypes, typeKlass);
172190

173191
// This will happen if fields type is not initialized
174192
// It's OK to skip it, because it means the field is guaranteed to be null on any object
175-
if (metaField->typeIndex == -1)
193+
if (metaField->typeIndex == -1) {
176194
continue;
195+
}
177196

178197
// literals have no actual storage, and are not relevant in this context.
179198
if ((field->type->attrs & FIELD_ATTRIBUTE_LITERAL) != 0)
180199
continue;
181200

182201
metaField->isStatic = (field->type->attrs & FIELD_ATTRIBUTE_STATIC) != 0;
202+
183203
metaField->offset = field->offset;
184204
metaField->name = field->name;
185205
type->fieldCount++;
186206
}
187207
}
188208

189-
vtable = mono_class_try_get_vtable(mono_domain_get(), klass);
190-
statics_data = vtable ? mono_vtable_get_static_field_data(vtable) : NULL;
209+
vtable = mono_class_try_get_vtable (mono_domain_get (), klass);
210+
statics_data = vtable ? mono_vtable_get_static_field_data (vtable) : NULL;
191211

192-
type->staticsSize = statics_data ? mono_class_data_size(klass) : 0;
212+
type->staticsSize = statics_data ? mono_class_data_size (klass) : 0;
193213
type->statics = NULL;
194214

195-
if (type->staticsSize > 0)
196-
{
197-
type->statics = g_new0(uint8_t, type->staticsSize);
198-
memcpy(type->statics, statics_data, type->staticsSize);
215+
if (type->staticsSize > 0) {
216+
type->statics = g_new0 (uint8_t, type->staticsSize);
217+
memcpy (type->statics, statics_data, type->staticsSize);
199218
}
200219

201-
baseClass = mono_class_get_parent(klass);
202-
type->baseOrElementTypeIndex = baseClass ? FindClassIndex(context->allTypes, baseClass) : -1;
220+
baseClass = mono_class_get_parent (klass);
221+
type->baseOrElementTypeIndex = baseClass ? FindClassIndex (context->allTypes, baseClass) : -1;
203222
}
204223

205-
type->assemblyName = mono_class_get_image(klass)->assembly->aname.name;
206-
type->name = mono_type_get_name_full(&klass->byval_arg, MONO_TYPE_NAME_FORMAT_IL);
224+
type->assemblyName = mono_class_get_image (klass)->assembly->aname.name;
225+
type->name = mono_type_get_name_full (&klass->byval_arg, MONO_TYPE_NAME_FORMAT_IL);
207226
type->typeInfoAddress = (uint64_t)klass;
208-
type->size = (klass->valuetype) != 0 ? (mono_class_instance_size(klass) - sizeof(MonoObject)) : mono_class_instance_size(klass);
227+
type->size = (klass->valuetype) != 0 ? (mono_class_instance_size (klass) - sizeof (MonoObject)) : mono_class_instance_size (klass);
209228
}
210229

211230
static void CollectMetadata(MonoMetadataSnapshot* metadata, GHashTable* monoImages)

0 commit comments

Comments
 (0)