11#include <config.h>
22#include <mono/utils/mono-publib.h>
3+
34#include "unity-memory-info.h"
45#include <mono/metadata/assembly-internals.h>
56#include <mono/metadata/class-internals.h>
89#include <mono/metadata/object-internals.h>
910#include <mono/metadata/tokentype.h>
1011#include <mono/metadata/gc-internals.h>
12+ #include <mono/utils/mono-conc-hashtable.h>
1113#include <glib.h>
1214#include <stdlib.h>
1315
@@ -17,7 +19,7 @@ typedef struct ClassReportContext {
1719} ClassReportContext ;
1820
1921static void
20- ReportHashMapClasses (gpointer key , gpointer value , gpointer user_data )
22+ ReportHashMapClass (gpointer key , gpointer value , gpointer user_data )
2123{
2224ClassReportContext * context = (ClassReportContext * )user_data ;
2325MonoClass * klass = (MonoClass * )value ;
@@ -41,6 +43,34 @@ ReportHashMapListClasses(gpointer key, gpointer value, gpointer user_data)
4143}
4244}
4345
46+ static void
47+ ReportGenericClass (gpointer key , gpointer value , gpointer user_data )
48+ {
49+ MonoGenericClass * genericClass = (MonoGenericClass * )key ;
50+ ClassReportContext * context = (ClassReportContext * )user_data ;
51+
52+ if (genericClass -> cached_class != NULL && genericClass -> cached_class -> inited )
53+ context -> callback (genericClass -> cached_class , context -> user_data );
54+ }
55+
56+ // Iterate MonoInternalHashTable similarly to mono_internal_hash_table_apply, but allow passing custom context
57+ static void
58+ IterateMonoInternalHashTable (MonoInternalHashTable * table , gpointer user_data )
59+ {
60+ ClassReportContext * context = (ClassReportContext * )user_data ;
61+ for (gint i = 0 ; i < table -> size ; i ++ ) {
62+ gpointer head = table -> table [i ];
63+ while (head ) {
64+ MonoClass * klass = head ;
65+
66+ if (klass -> inited )
67+ context -> callback (klass , context -> user_data );
68+
69+ head = * (table -> next_value (head ));
70+ }
71+ }
72+ }
73+
4474static void
4575ReportClassesFromAssembly (MonoAssembly * assembly , void * user_data )
4676{
@@ -80,48 +110,32 @@ ReportClassesFromAssembly(MonoAssembly *assembly, void *user_data)
80110}
81111
82112// Iterate all image classes
83- for (i = 1 ; i < tdef -> rows ; ++ i ) {
84- MonoClass * klass ;
85- MonoError error ;
86-
87- guint32 token = (i + 1 ) | MONO_TOKEN_TYPE_DEF ;
88-
89- klass = mono_class_get_checked (image , token , & error );
90-
91- if (klass && klass -> inited )
92- context -> callback (klass , context -> user_data );
93- }
113+ IterateMonoInternalHashTable (& image -> class_cache , user_data );
94114
95115if (image -> array_cache )
96116g_hash_table_foreach (image -> array_cache , ReportHashMapListClasses , user_data );
97117
98118if (image -> szarray_cache )
99- g_hash_table_foreach (image -> szarray_cache , ReportHashMapClasses , user_data );
119+ g_hash_table_foreach (image -> szarray_cache , ReportHashMapClass , user_data );
100120
101121if (image -> ptr_cache )
102- g_hash_table_foreach (image -> ptr_cache , ReportHashMapClasses , user_data );
103- }
104-
105- static void
106- ReportGenericClasses (MonoGenericClass * genericClass , gpointer user_data )
107- {
108- ClassReportContext * context = (ClassReportContext * )user_data ;
109-
110- if (genericClass -> cached_class != NULL && genericClass -> cached_class -> inited )
111- context -> callback (genericClass -> cached_class , context -> user_data );
122+ g_hash_table_foreach (image -> ptr_cache , ReportHashMapClass , user_data );
112123}
113124
114125static void
115126ReportImageSetClasses (MonoImageSet * imageSet , void * user_data )
116127{
128+ if (imageSet -> gclass_cache )
129+ mono_conc_hashtable_foreach (imageSet -> gclass_cache , ReportGenericClass , user_data );
130+
117131if (imageSet -> array_cache )
118132g_hash_table_foreach (imageSet -> array_cache , ReportHashMapListClasses , user_data );
119133
120134if (imageSet -> szarray_cache )
121- g_hash_table_foreach (imageSet -> szarray_cache , ReportHashMapClasses , user_data );
135+ g_hash_table_foreach (imageSet -> szarray_cache , ReportHashMapClass , user_data );
122136
123137if (imageSet -> ptr_cache )
124- g_hash_table_foreach (imageSet -> ptr_cache , ReportHashMapClasses , user_data );
138+ g_hash_table_foreach (imageSet -> ptr_cache , ReportHashMapClass , user_data );
125139}
126140
127141MONO_API void
@@ -132,9 +146,7 @@ mono_unity_class_for_each(ClassReportFunc callback, void *user_data)
132146reportContext .user_data = user_data ;
133147// Report all assembly classes and assembly specific arrays
134148mono_domain_assembly_foreach (mono_domain_get (), ReportClassesFromAssembly , & reportContext );
135- // Report all generic classes
136- mono_metadata_generic_class_foreach (ReportGenericClasses , & reportContext );
137- // Report all image set arrays
149+ // Report all image set arrays which include generic classes
138150mono_metadata_image_set_foreach (ReportImageSetClasses , & reportContext );
139151}
140152
0 commit comments