@@ -63,7 +63,8 @@ static gboolean gc_strict_wbarriers = FALSE;
6363static mono_mutex_t mono_gc_lock ;
6464
6565static GC_push_other_roots_proc default_push_other_roots ;
66- static GHashTable * roots ;
66+ static GHashTable * roots ;
67+ static GHashTable * late_handles ;
6768
6869typedef struct ephemeron_node ephemeron_node ;
6970static ephemeron_node * ephemeron_list ;
@@ -122,12 +123,12 @@ struct HandleData {
122123 gpointer entries [HANDLE_COUNT ];
123124};
124125
125- #define GC_HANDLE_TYPE_IS_WEAK (x ) ((x) <= HANDLE_WEAK_TRACK)
126+ #define GC_HANDLE_TYPE_IS_WEAK (x ) ((( x) == HANDLE_WEAK) ||((x) == HANDLE_WEAK_TRACK) ||((x) == HANDLE_WEAK_FIELDS) )
126127
127- #define MONO_GC_HANDLE_TYPE_IS_WEAK (x ) ((x) <= HANDLE_WEAK_TRACK)
128+ #define MONO_GC_HANDLE_TYPE_IS_WEAK (x ) ((( x) == HANDLE_WEAK) ||((x) == HANDLE_WEAK_TRACK) ||((x) == HANDLE_WEAK_FIELDS) )
128129
129- static HandleData * gc_handles [4 ];
130- static HandleData * gc_handles_free [4 ];
130+ static HandleData * gc_handles [HANDLE_TYPE_MAX ];
131+ static HandleData * gc_handles_free [HANDLE_TYPE_MAX ];
131132
132133static void
133134mono_gc_warning (char * msg , GC_word arg )
@@ -202,6 +203,7 @@ mono_gc_base_init (void)
202203#endif
203204
204205 roots = g_hash_table_new (NULL , NULL );
206+ late_handles = g_hash_table_new (NULL , NULL );
205207 default_push_other_roots = GC_get_push_other_roots ();
206208 GC_set_push_other_roots (mono_push_other_roots );
207209 GC_set_mark_stack_empty (mono_push_ephemerons );
@@ -702,6 +704,30 @@ mono_gc_register_root (char *start, size_t size, void *descr, MonoGCRootSource s
702704 return TRUE;
703705}
704706
707+ typedef struct {
708+ gpointer * start ;
709+ size_t count ;
710+ } LateHandleData ;
711+
712+ static gpointer
713+ register_late_handles (gpointer arg )
714+ {
715+ RootData * root_data = (RootData * )arg ;
716+ g_hash_table_insert (late_handles , root_data -> start , root_data -> end );
717+ return NULL ;
718+ }
719+
720+ int
721+ mono_gc_register_late_handles (gpointer * start , size_t count )
722+ {
723+ LateHandleData root_data ;
724+ root_data .start = start ;
725+ root_data .count = count ;
726+ GC_call_with_alloc_lock (register_late_handles , & root_data );
727+ //MONO_PROFILER_RAISE(gc_root_register, ((const mono_byte*)start, size, source, key, msg));
728+ return TRUE;
729+ }
730+
705731int
706732mono_gc_register_root_wbarrier (char * start , size_t size , MonoGCDescriptor descr , MonoGCRootSource source , void * key , const char * msg )
707733{
@@ -1652,7 +1678,10 @@ handle_data_alloc_entries(int type)
16521678 if (MONO_GC_HANDLE_TYPE_IS_WEAK (handles -> type )) {
16531679 handles -> domain_ids = (guint16 * )g_malloc0 (sizeof (* handles -> domain_ids ) * handles -> size );
16541680 } else {
1655- mono_gc_register_root ((char * ) & handles -> entries [0 ], HANDLE_COUNT * sizeof (gpointer ), MONO_GC_DESCRIPTOR_NULL , MONO_ROOT_SOURCE_GC_HANDLE , NULL , "GC Handle Data" );
1681+ if (handles -> type == HANDLE_LATE )
1682+ mono_gc_register_late_handles (& handles -> entries [0 ], HANDLE_COUNT );
1683+ else
1684+ mono_gc_register_root ((char * ) & handles -> entries [0 ], HANDLE_COUNT * sizeof (gpointer ), MONO_GC_DESCRIPTOR_NULL , MONO_ROOT_SOURCE_GC_HANDLE , NULL , "GC Handle Data" );
16561685 }
16571686 handles -> bitmap = (guint32 * )g_malloc0 (handles -> size / CHAR_BIT );
16581687
@@ -1801,6 +1830,12 @@ mono_gchandle_new_internal (MonoObject *obj, gboolean pinned)
18011830 return alloc_handle (pinned ? HANDLE_PINNED : HANDLE_NORMAL , obj , FALSE);
18021831}
18031832
1833+ MonoGCHandle
1834+ mono_gchandle_new_late_internal (MonoObject * obj )
1835+ {
1836+ return alloc_handle (HANDLE_LATE , obj , FALSE);
1837+ }
1838+
18041839/**
18051840 * mono_gchandle_new_weakref_internal:
18061841 * \param obj managed object to get a handle for
@@ -2036,7 +2071,7 @@ mono_gchandle_free_domain (MonoDomain *domain)
20362071{
20372072 guint type ;
20382073
2039- for (type = HANDLE_TYPE_MIN ; type <= HANDLE_PINNED ; ++ type ) {
2074+ for (type = HANDLE_TYPE_MIN ; type < HANDLE_TYPE_MAX ; ++ type ) {
20402075 guint slot ;
20412076 HandleData * handles = gc_handles [type ];
20422077 lock_handles (handles );
@@ -2162,6 +2197,37 @@ mono_clear_ephemerons (void)
21622197static struct GC_ms_entry *
21632198mono_push_ephemerons (struct GC_ms_entry * mark_stack_ptr , struct GC_ms_entry * mark_stack_limit )
21642199{
2200+ /* push late GC handles */
2201+ {
2202+ GHashTableIter iter ;
2203+ g_hash_table_iter_init (& iter , late_handles );
2204+
2205+ gpointer key ;
2206+ gpointer value ;
2207+
2208+ while (g_hash_table_iter_next (& iter , & key , & value )) {
2209+ /* process handles */
2210+ gpointer * handles = key ;
2211+ size_t length = (size_t )value ;
2212+ for (size_t i = 0 ; i < length ; ++ i ) {
2213+ MonoObject * * handle = handles + i ;
2214+ if (!* handle )
2215+ continue ;
2216+
2217+ MonoObject * object = * handle ;
2218+
2219+ if (GC_is_marked (object )) {
2220+ continue ;
2221+ }
2222+ else {
2223+
2224+ mark_stack_ptr = GC_mark_and_push (object , mark_stack_ptr , mark_stack_limit , handle );
2225+ }
2226+ }
2227+ }
2228+ }
2229+
2230+
21652231 ephemeron_node * prev_node = NULL ;
21662232 ephemeron_node * current_node = NULL ;
21672233
@@ -2257,8 +2323,10 @@ mono_gc_strong_handle_foreach(GFunc func, gpointer user_data)
22572323
22582324 lock_handles (handles );
22592325
2260- for (gcHandleTypeIndex = HANDLE_NORMAL ; gcHandleTypeIndex <= HANDLE_PINNED ; gcHandleTypeIndex ++ )
2326+ for (gcHandleTypeIndex = HANDLE_TYPE_MIN ; gcHandleTypeIndex < HANDLE_TYPE_MAX ; gcHandleTypeIndex ++ )
22612327 {
2328+ if (GC_HANDLE_TYPE_IS_WEAK (gcHandleTypeIndex ))
2329+ continue ;
22622330 HandleData * handles = gc_handles [gcHandleTypeIndex ];
22632331
22642332 while (handles != NULL ) {
0 commit comments