@@ -24,87 +24,102 @@ typedef struct CollectMetadataContext
24
24
MonoMetadataSnapshot * metadata ;
25
25
} CollectMetadataContext ;
26
26
27
- static void ContextInsertClass (CollectMetadataContext * context , MonoClass * klass )
27
+ static void
28
+ ContextRecurseClassData (CollectMetadataContext * context , MonoClass * klass )
28
29
{
29
30
gpointer orig_key , value ;
31
+ gpointer iter = NULL ;
32
+ MonoClassField * field = NULL ;
33
+ int fieldCount ;
34
+
30
35
/* use g_hash_table_lookup_extended as it returns boolean to indicate if value was found.
31
36
* If we use g_hash_table_lookup it returns the value which we were comparing to NULL. The problem is
32
37
* that 0 is a valid class index and was confusing our logic.
33
38
*/
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 )) {
35
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
+ }
36
53
}
37
54
38
- static void CollectHashMapClass (gpointer key , gpointer value , gpointer user_data )
55
+ static void
56
+ CollectHashMapClass (gpointer key , gpointer value , gpointer user_data )
39
57
{
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 );
43
61
}
44
62
45
- static void CollectHashMapListClasses (gpointer key , gpointer value , gpointer user_data )
63
+ static void
64
+ CollectHashMapListClasses (gpointer key , gpointer value , gpointer user_data )
46
65
{
47
- CollectMetadataContext * context = (CollectMetadataContext * )user_data ;
48
- GSList * list = (GSList * )value ;
66
+ CollectMetadataContext * context = (CollectMetadataContext * )user_data ;
67
+ GSList * list = (GSList * )value ;
49
68
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 );
54
72
55
73
list = g_slist_next (list );
56
74
}
57
75
}
58
76
59
- static void CollectGenericClass (MonoGenericClass * genericClass , gpointer user_data )
77
+ static void
78
+ CollectGenericClass (MonoGenericClass * genericClass , gpointer user_data )
60
79
{
61
- CollectMetadataContext * context = (CollectMetadataContext * )user_data ;
80
+ CollectMetadataContext * context = (CollectMetadataContext * )user_data ;
62
81
63
82
if (genericClass -> cached_class != NULL )
64
- ContextInsertClass (context , genericClass -> cached_class );
83
+ ContextRecurseClassData (context , genericClass -> cached_class );
65
84
}
66
85
67
- static void CollectImageMetaData (MonoImage * image , gpointer value , CollectMetadataContext * context )
86
+ static void
87
+ CollectImageMetaData (MonoImage * image , gpointer value , CollectMetadataContext * context )
68
88
{
69
89
int i ;
70
90
MonoTableInfo * tdef = & image -> tables [MONO_TABLE_TYPEDEF ];
71
91
GSList * list ;
72
92
73
- if (image -> dynamic )
74
- {
93
+ if (image -> dynamic ) {
75
94
GHashTableIter iter ;
76
95
gpointer key ;
77
- MonoDynamicImage * dynamicImage = (MonoDynamicImage * )image ;
78
-
96
+ MonoDynamicImage * dynamicImage = (MonoDynamicImage * )image ;
79
97
g_hash_table_iter_init (& iter , dynamicImage -> typeref );
80
98
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 );
85
102
86
103
if (klass )
87
- ContextInsertClass (context , klass );
104
+ ContextRecurseClassData (context , klass );
88
105
}
89
106
}
90
107
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.
93
110
*/
94
111
list = image -> reflection_info_unregister_classes ;
95
112
96
- while (list )
97
- {
113
+ while (list ) {
98
114
MonoClass * klass = (MonoClass * )list -> data ;
99
115
100
116
if (klass )
101
- ContextInsertClass (context , klass );
117
+ ContextRecurseClassData (context , klass );
102
118
103
119
list = list -> next ;
104
120
}
105
121
106
- for (i = 1 ; i < tdef -> rows ; ++ i )
107
- {
122
+ for (i = 1 ; i < tdef -> rows ; ++ i ) {
108
123
MonoClass * klass ;
109
124
MonoError error ;
110
125
@@ -113,7 +128,7 @@ static void CollectImageMetaData(MonoImage* image, gpointer value, CollectMetada
113
128
klass = mono_class_get_checked (image , token , & error );
114
129
115
130
if (klass )
116
- ContextInsertClass (context , klass );
131
+ ContextRecurseClassData (context , klass );
117
132
}
118
133
119
134
if (image -> array_cache )
@@ -126,7 +141,8 @@ static void CollectImageMetaData(MonoImage* image, gpointer value, CollectMetada
126
141
g_hash_table_foreach (image -> ptr_cache , CollectHashMapClass , context );
127
142
}
128
143
129
- static int FindClassIndex (GHashTable * hashTable , MonoClass * klass )
144
+ static int
145
+ FindClassIndex (GHashTable * hashTable , MonoClass * klass )
130
146
{
131
147
gpointer orig_key , value ;
132
148
@@ -136,50 +152,55 @@ static int FindClassIndex(GHashTable* hashTable, MonoClass* klass)
136
152
return GPOINTER_TO_INT (value );
137
153
}
138
154
139
- static void AddMetadataType (gpointer key , gpointer value , gpointer user_data )
155
+ static void
156
+ AddMetadataType (gpointer key , gpointer value , gpointer user_data )
140
157
{
141
- MonoClass * klass = (MonoClass * )key ;
158
+ MonoClass * klass = (MonoClass * )key ;
159
+
142
160
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 ];
146
164
147
- if (klass -> rank > 0 )
148
- {
165
+ if (klass -> rank > 0 ) {
149
166
type -> flags = (MonoMetadataTypeFlags )(kArray | (kArrayRankMask & (klass -> rank << 16 )));
150
167
type -> baseOrElementTypeIndex = FindClassIndex (context -> allTypes , mono_class_get_element_class (klass ));
151
168
}
152
- else
153
- {
169
+ else {
154
170
gpointer iter = NULL ;
155
171
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 ;
160
176
161
177
type -> flags = (klass -> valuetype || klass -> byval_arg .type == MONO_TYPE_PTR ) ? kValueType : kNone ;
162
178
type -> fieldCount = 0 ;
179
+ fieldCount = mono_class_num_fields (klass );
180
+ if (fieldCount > 0 ) {
181
+ type -> fields = g_new (MonoMetadataField , fieldCount );
163
182
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 );
167
186
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 );
172
191
173
192
// This will happen if fields type is not initialized
174
193
// 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 ) {
176
195
continue ;
196
+ }
177
197
178
198
// literals have no actual storage, and are not relevant in this context.
179
199
if ((field -> type -> attrs & FIELD_ATTRIBUTE_LITERAL ) != 0 )
180
200
continue ;
181
201
182
202
metaField -> isStatic = (field -> type -> attrs & FIELD_ATTRIBUTE_STATIC ) != 0 ;
203
+
183
204
metaField -> offset = field -> offset ;
184
205
metaField -> name = field -> name ;
185
206
type -> fieldCount ++ ;
@@ -192,8 +213,7 @@ static void AddMetadataType(gpointer key, gpointer value, gpointer user_data)
192
213
type -> staticsSize = statics_data ? mono_class_data_size (klass ) : 0 ;
193
214
type -> statics = NULL ;
194
215
195
- if (type -> staticsSize > 0 )
196
- {
216
+ if (type -> staticsSize > 0 ) {
197
217
type -> statics = g_new0 (uint8_t , type -> staticsSize );
198
218
memcpy (type -> statics , statics_data , type -> staticsSize );
199
219
}
@@ -336,7 +356,7 @@ static void IncrementCountForImageSetMemPoolNumChunks(MonoImageSet *imageSet, vo
336
356
337
357
static int MonoImageSetsMemPoolNumChunks ()
338
358
{
339
- int count = 0 ;
359
+ int count = 0 ;
340
360
mono_metadata_image_set_foreach (IncrementCountForImageSetMemPoolNumChunks , & count );
341
361
return count ;
342
362
}
@@ -630,7 +650,7 @@ MonoManagedMemorySnapshot* mono_unity_capture_memory_snapshot()
630
650
FillRuntimeInformation (& snapshot -> runtimeInformation );
631
651
632
652
#if _DEBUG
633
- // VerifySnapshot(snapshot, monoImages);
653
+ // VerifySnapshot(snapshot, monoImages);
634
654
#endif
635
655
636
656
g_hash_table_destroy (monoImages );
0 commit comments