1
1
#include <config.h>
2
2
#include <mono/utils/mono-publib.h>
3
+
3
4
#include "unity-memory-info.h"
4
5
#include <mono/metadata/assembly-internals.h>
5
6
#include <mono/metadata/class-internals.h>
8
9
#include <mono/metadata/object-internals.h>
9
10
#include <mono/metadata/tokentype.h>
10
11
#include <mono/metadata/gc-internals.h>
12
+ #include <mono/utils/mono-conc-hashtable.h>
11
13
#include <glib.h>
12
14
#include <stdlib.h>
13
15
@@ -17,7 +19,7 @@ typedef struct ClassReportContext {
17
19
} ClassReportContext ;
18
20
19
21
static void
20
- ReportHashMapClasses (gpointer key , gpointer value , gpointer user_data )
22
+ ReportHashMapClass (gpointer key , gpointer value , gpointer user_data )
21
23
{
22
24
ClassReportContext * context = (ClassReportContext * )user_data ;
23
25
MonoClass * klass = (MonoClass * )value ;
@@ -41,6 +43,34 @@ ReportHashMapListClasses(gpointer key, gpointer value, gpointer user_data)
41
43
}
42
44
}
43
45
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
+
44
74
static void
45
75
ReportClassesFromAssembly (MonoAssembly * assembly , void * user_data )
46
76
{
@@ -80,48 +110,32 @@ ReportClassesFromAssembly(MonoAssembly *assembly, void *user_data)
80
110
}
81
111
82
112
// 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 );
94
114
95
115
if (image -> array_cache )
96
116
g_hash_table_foreach (image -> array_cache , ReportHashMapListClasses , user_data );
97
117
98
118
if (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 );
100
120
101
121
if (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 );
112
123
}
113
124
114
125
static void
115
126
ReportImageSetClasses (MonoImageSet * imageSet , void * user_data )
116
127
{
128
+ if (imageSet -> gclass_cache )
129
+ mono_conc_hashtable_foreach (imageSet -> gclass_cache , ReportGenericClass , user_data );
130
+
117
131
if (imageSet -> array_cache )
118
132
g_hash_table_foreach (imageSet -> array_cache , ReportHashMapListClasses , user_data );
119
133
120
134
if (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 );
122
136
123
137
if (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 );
125
139
}
126
140
127
141
MONO_API void
@@ -132,9 +146,7 @@ mono_unity_class_for_each(ClassReportFunc callback, void *user_data)
132
146
reportContext .user_data = user_data ;
133
147
// Report all assembly classes and assembly specific arrays
134
148
mono_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
138
150
mono_metadata_image_set_foreach (ReportImageSetClasses , & reportContext );
139
151
}
140
152
0 commit comments