Skip to content

Commit 31a5d28

Browse files
committed
backport of PR: #1065
1 parent db0316c commit 31a5d28

File tree

1 file changed

+80
-60
lines changed

1 file changed

+80
-60
lines changed

mono/metadata/unity-memory-info.c

+80-60
Original file line numberDiff line numberDiff line change
@@ -24,87 +24,102 @@ 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))
39+
if (!g_hash_table_lookup_extended(context->allTypes, klass, &orig_key, &value)) {
3540
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

5573
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-
96+
MonoDynamicImage *dynamicImage = (MonoDynamicImage *)image;
7997
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

91-
/* Some classes are only in this list.
92-
They are added in reflection_setup_internal_class_internal.
108+
/* Some classes are only in this list.
109+
They are added in reflection_setup_internal_class_internal.
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

@@ -113,7 +128,7 @@ static void CollectImageMetaData(MonoImage* image, gpointer value, CollectMetada
113128
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)
@@ -126,7 +141,8 @@ static void CollectImageMetaData(MonoImage* image, gpointer value, CollectMetada
126141
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

@@ -136,50 +152,55 @@ static int FindClassIndex(GHashTable* hashTable, MonoClass* klass)
136152
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;
158+
MonoClass *klass = (MonoClass *)key;
159+
142160
int index = GPOINTER_TO_INT(value);
143-
CollectMetadataContext* context = (CollectMetadataContext*)user_data;
144-
MonoMetadataSnapshot* metadata = context->metadata;
145-
MonoMetadataType* type = &metadata->types[index];
161+
CollectMetadataContext *context = (CollectMetadataContext *)user_data;
162+
MonoMetadataSnapshot *metadata = context->metadata;
163+
MonoMetadataType *type = &metadata->types[index];
146164

147-
if (klass->rank > 0)
148-
{
165+
if (klass->rank > 0) {
149166
type->flags = (MonoMetadataTypeFlags)(kArray | (kArrayRankMask & (klass->rank << 16)));
150167
type->baseOrElementTypeIndex = FindClassIndex(context->allTypes, mono_class_get_element_class(klass));
151168
}
152-
else
153-
{
169+
else {
154170
gpointer iter = NULL;
155171
int fieldCount = 0;
156-
MonoClassField* field;
157-
MonoClass* baseClass;
158-
MonoVTable* vtable;
159-
void* statics_data;
172+
MonoClassField *field;
173+
MonoClass *baseClass;
174+
MonoVTable *vtable;
175+
void *statics_data;
160176

161177
type->flags = (klass->valuetype || klass->byval_arg.type == MONO_TYPE_PTR) ? kValueType : kNone;
162178
type->fieldCount = 0;
179+
fieldCount = mono_class_num_fields(klass);
180+
if (fieldCount > 0) {
181+
type->fields = g_new(MonoMetadataField, fieldCount);
163182

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

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));
187+
if (typeKlass->rank > 0)
188+
metaField->typeIndex = FindClassIndex(context->allTypes, mono_class_get_element_class(typeKlass));
189+
else
190+
metaField->typeIndex = FindClassIndex(context->allTypes, typeKlass);
172191

173192
// This will happen if fields type is not initialized
174193
// It's OK to skip it, because it means the field is guaranteed to be null on any object
175-
if (metaField->typeIndex == -1)
194+
if (metaField->typeIndex == -1) {
176195
continue;
196+
}
177197

178198
// literals have no actual storage, and are not relevant in this context.
179199
if ((field->type->attrs & FIELD_ATTRIBUTE_LITERAL) != 0)
180200
continue;
181201

182202
metaField->isStatic = (field->type->attrs & FIELD_ATTRIBUTE_STATIC) != 0;
203+
183204
metaField->offset = field->offset;
184205
metaField->name = field->name;
185206
type->fieldCount++;
@@ -192,8 +213,7 @@ static void AddMetadataType(gpointer key, gpointer value, gpointer user_data)
192213
type->staticsSize = statics_data ? mono_class_data_size(klass) : 0;
193214
type->statics = NULL;
194215

195-
if (type->staticsSize > 0)
196-
{
216+
if (type->staticsSize > 0) {
197217
type->statics = g_new0(uint8_t, type->staticsSize);
198218
memcpy(type->statics, statics_data, type->staticsSize);
199219
}
@@ -336,7 +356,7 @@ static void IncrementCountForImageSetMemPoolNumChunks(MonoImageSet *imageSet, vo
336356

337357
static int MonoImageSetsMemPoolNumChunks()
338358
{
339-
int count = 0;
359+
int count = 0;
340360
mono_metadata_image_set_foreach(IncrementCountForImageSetMemPoolNumChunks, &count);
341361
return count;
342362
}
@@ -630,7 +650,7 @@ MonoManagedMemorySnapshot* mono_unity_capture_memory_snapshot()
630650
FillRuntimeInformation(&snapshot->runtimeInformation);
631651

632652
#if _DEBUG
633-
// VerifySnapshot(snapshot, monoImages);
653+
// VerifySnapshot(snapshot, monoImages);
634654
#endif
635655

636656
g_hash_table_destroy(monoImages);

0 commit comments

Comments
 (0)