12
12
#include <mono/metadata/mono-hash.h>
13
13
#include <mono/metadata/mempool.h>
14
14
#include <mono/utils/mono-error-internals.h>
15
+ #include <mono/metadata/metadata-update.h>
15
16
16
17
/*
17
18
* We need to return always the same object for MethodInfo, FieldInfo etc..
22
23
typedef struct {
23
24
gpointer item ;
24
25
MonoClass * refclass ;
26
+ uint32_t generation ; /* 0 is normal; hot reload may change it */
25
27
} ReflectedEntry ;
26
28
29
+ enum {
30
+ MONO_REFL_CACHE_DEFAULT = 0 ,
31
+ MONO_REFL_CACHE_NO_HOT_RELOAD_INVALIDATE = 1 ,
32
+ };
33
+
27
34
gboolean
28
35
mono_reflected_equal (gconstpointer a , gconstpointer b );
29
36
@@ -46,7 +53,7 @@ free_reflected_entry (ReflectedEntry *entry)
46
53
}
47
54
48
55
static inline MonoObject *
49
- cache_object (MonoMemoryManager * mem_manager , MonoClass * klass , gpointer item , MonoObject * o )
56
+ cache_object (MonoMemoryManager * mem_manager , int flags , MonoClass * klass , gpointer item , MonoObject * o )
50
57
{
51
58
MonoObject * obj ;
52
59
ReflectedEntry pe ;
@@ -59,6 +66,10 @@ cache_object (MonoMemoryManager *mem_manager, MonoClass *klass, gpointer item, M
59
66
ReflectedEntry * e = alloc_reflected_entry (mem_manager );
60
67
e -> item = item ;
61
68
e -> refclass = klass ;
69
+ if (G_UNLIKELY (mono_metadata_has_updates ()) && ((flags & MONO_REFL_CACHE_NO_HOT_RELOAD_INVALIDATE ) == 0 ))
70
+ e -> generation = mono_metadata_update_get_thread_generation ();
71
+ else
72
+ e -> generation = 0 ;
62
73
mono_conc_g_hash_table_insert (mem_manager -> refobject_hash , e , o );
63
74
obj = o ;
64
75
}
@@ -67,7 +78,7 @@ cache_object (MonoMemoryManager *mem_manager, MonoClass *klass, gpointer item, M
67
78
}
68
79
69
80
static inline MonoObjectHandle
70
- cache_object_handle (MonoMemoryManager * mem_manager , MonoClass * klass , gpointer item , MonoObjectHandle o )
81
+ cache_object_handle (MonoMemoryManager * mem_manager , int flags , MonoClass * klass , gpointer item , MonoObjectHandle o )
71
82
{
72
83
MonoObjectHandle obj ;
73
84
ReflectedEntry pe ;
@@ -83,6 +94,10 @@ cache_object_handle (MonoMemoryManager *mem_manager, MonoClass *klass, gpointer
83
94
ReflectedEntry * e = alloc_reflected_entry (mem_manager );
84
95
e -> item = item ;
85
96
e -> refclass = klass ;
97
+ if (G_UNLIKELY (mono_metadata_has_updates ()) && ((flags & MONO_REFL_CACHE_NO_HOT_RELOAD_INVALIDATE ) == 0 ))
98
+ e -> generation = mono_metadata_update_get_thread_generation ();
99
+ else
100
+ e -> generation = 0 ;
86
101
mono_conc_g_hash_table_insert (mem_manager -> refobject_hash , e , MONO_HANDLE_RAW (o ));
87
102
MONO_HANDLE_ASSIGN (obj , o );
88
103
}
@@ -92,6 +107,10 @@ cache_object_handle (MonoMemoryManager *mem_manager, MonoClass *klass, gpointer
92
107
ReflectedEntry * e = alloc_reflected_entry (mem_manager );
93
108
e -> item = item ;
94
109
e -> refclass = klass ;
110
+ if (G_UNLIKELY (mono_metadata_has_updates ()) && ((flags & MONO_REFL_CACHE_NO_HOT_RELOAD_INVALIDATE ) == 0 ))
111
+ e -> generation = mono_metadata_update_get_thread_generation ();
112
+ else
113
+ e -> generation = 0 ;
95
114
mono_weak_hash_table_insert (mem_manager -> weak_refobject_hash , e , MONO_HANDLE_RAW (o ));
96
115
MONO_HANDLE_ASSIGN (obj , o );
97
116
}
@@ -100,13 +119,14 @@ cache_object_handle (MonoMemoryManager *mem_manager, MonoClass *klass, gpointer
100
119
return obj ;
101
120
}
102
121
103
- #define CACHE_OBJECT (t ,mem_manager ,p ,o ,k ) ((t) (cache_object ((mem_manager), (k), (p), (o))))
104
- #define CACHE_OBJECT_HANDLE (t ,mem_manager ,p ,o ,k ) (MONO_HANDLE_CAST (t, cache_object_handle ((mem_manager), (k), (p), (o))))
122
+ #define CACHE_OBJECT (t ,mem_manager ,flags , p ,o ,k ) ((t) (cache_object ((mem_manager), (flags ), (k), (p), (o))))
123
+ #define CACHE_OBJECT_HANDLE (t ,mem_manager ,flags , p ,o ,k ) (MONO_HANDLE_CAST (t, cache_object_handle ((mem_manager), (flags ), (k), (p), (o))))
105
124
106
125
static inline MonoObjectHandle
107
- check_object_handle (MonoMemoryManager * mem_manager , MonoClass * klass , gpointer item )
126
+ check_object_handle (MonoMemoryManager * mem_manager , int flags , MonoClass * klass , gpointer item )
108
127
{
109
128
MonoObjectHandle obj_handle ;
129
+ gpointer orig_e , orig_value ;
110
130
ReflectedEntry e ;
111
131
e .item = item ;
112
132
e .refclass = klass ;
@@ -123,6 +143,24 @@ check_object_handle (MonoMemoryManager *mem_manager, MonoClass *klass, gpointer
123
143
MonoWeakHashTable * hash = mem_manager -> weak_refobject_hash ;
124
144
obj_handle = MONO_HANDLE_NEW (MonoObject , (MonoObject * )mono_weak_hash_table_lookup (hash , & e ));
125
145
}
146
+
147
+ if (!mem_manager -> collectible ) {
148
+ MonoConcGHashTable * hash = mem_manager -> refobject_hash ;
149
+ if (mono_conc_g_hash_table_lookup_extended (hash , & e , & orig_e , & orig_value ))
150
+ if (mono_metadata_has_updates () && ((flags & MONO_REFL_CACHE_NO_HOT_RELOAD_INVALIDATE ) == 0 ) && ((ReflectedEntry * )orig_e )-> generation < mono_metadata_update_get_thread_generation ()) {
151
+ mono_conc_g_hash_table_remove (hash , & e );
152
+ free_reflected_entry ((ReflectedEntry * )orig_e );
153
+ obj_handle = MONO_HANDLE_NEW (MonoObject , NULL );
154
+ } else {
155
+ obj_handle = MONO_HANDLE_NEW (MonoObject , (MonoObject * )orig_value );
156
+ }
157
+ else {
158
+ obj_handle = MONO_HANDLE_NEW (MonoObject , NULL );
159
+ }
160
+ } else {
161
+ MonoWeakHashTable * hash = mem_manager -> weak_refobject_hash ;
162
+ obj_handle = MONO_HANDLE_NEW (MonoObject , (MonoObject * )mono_weak_hash_table_lookup (hash , & e ));
163
+ }
126
164
mono_mem_manager_unlock (mem_manager );
127
165
128
166
return obj_handle ;
@@ -131,22 +169,22 @@ check_object_handle (MonoMemoryManager *mem_manager, MonoClass *klass, gpointer
131
169
typedef MonoObjectHandle (* ReflectionCacheConstructFunc_handle ) (MonoClass * , gpointer , gpointer , MonoError * );
132
170
133
171
static inline MonoObjectHandle
134
- check_or_construct_handle (MonoMemoryManager * mem_manager , MonoClass * klass , gpointer item , gpointer user_data , MonoError * error , ReflectionCacheConstructFunc_handle construct )
172
+ check_or_construct_handle (MonoMemoryManager * mem_manager , int flags , MonoClass * klass , gpointer item , gpointer user_data , MonoError * error , ReflectionCacheConstructFunc_handle construct )
135
173
{
136
174
error_init (error );
137
- MonoObjectHandle obj = check_object_handle (mem_manager , klass , item );
175
+ MonoObjectHandle obj = check_object_handle (mem_manager , flags , klass , item );
138
176
if (!MONO_HANDLE_IS_NULL (obj ))
139
177
return obj ;
140
178
MONO_HANDLE_ASSIGN (obj , construct (klass , item , user_data , error ));
141
179
return_val_if_nok (error , NULL_HANDLE );
142
180
if (MONO_HANDLE_IS_NULL (obj ))
143
181
return obj ;
144
182
/* note no caching if there was an error in construction */
145
- return cache_object_handle (mem_manager , klass , item , obj );
183
+ return cache_object_handle (mem_manager , flags , klass , item , obj );
146
184
}
147
185
148
- #define CHECK_OR_CONSTRUCT_HANDLE (type ,mem_manager , item ,klass ,construct ,user_data ) \
186
+ #define CHECK_OR_CONSTRUCT_HANDLE (type ,mem_manager ,flags , item ,klass ,construct ,user_data ) \
149
187
(MONO_HANDLE_CAST (type, check_or_construct_handle ( \
150
- (mem_manager), (klass), (item), (user_data), error, (ReflectionCacheConstructFunc_handle) (construct))))
188
+ (mem_manager), (flags), ( klass), (item), (user_data), error, (ReflectionCacheConstructFunc_handle) (construct))))
151
189
152
190
#endif /*__MONO_METADATA_REFLECTION_CACHE_H__*/
0 commit comments