Skip to content

Commit 154eb59

Browse files
committed
Add basic late handles support.
1 parent e947990 commit 154eb59

File tree

5 files changed

+87
-8
lines changed

5 files changed

+87
-8
lines changed

mono/metadata/boehm-gc.c

Lines changed: 76 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ static gboolean gc_strict_wbarriers = FALSE;
6363
static mono_mutex_t mono_gc_lock;
6464

6565
static GC_push_other_roots_proc default_push_other_roots;
66-
static GHashTable *roots;
66+
static GHashTable* roots;
67+
static GHashTable* late_handles;
6768

6869
typedef struct ephemeron_node ephemeron_node;
6970
static 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

132133
static void
133134
mono_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+
705731
int
706732
mono_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)
21622197
static struct GC_ms_entry*
21632198
mono_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) {

mono/metadata/external-only.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ mono_gchandle_new_v2 (MonoObject *obj, mono_bool pinned)
5151
MONO_EXTERNAL_ONLY_GC_UNSAFE (MonoGCHandle, mono_gchandle_new_internal (obj, pinned));
5252
}
5353

54+
MonoGCHandle
55+
mono_gchandle_new_late_v2(MonoObject* obj)
56+
{
57+
MONO_EXTERNAL_ONLY_GC_UNSAFE(MonoGCHandle, mono_gchandle_new_late_internal(obj));
58+
}
59+
5460
/**
5561
* mono_gchandle_new_weakref:
5662
* \param obj managed object to get a handle for

mono/metadata/object-internals.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2372,6 +2372,9 @@ mono_runtime_get_aotid_arr (void);
23722372
MonoGCHandle
23732373
mono_gchandle_new_internal (MonoObject *obj, mono_bool pinned);
23742374

2375+
MonoGCHandle
2376+
mono_gchandle_new_late_internal(MonoObject* obj);
2377+
23752378
MonoGCHandle
23762379
mono_gchandle_new_weakref_internal (MonoObject *obj, mono_bool track_resurrection);
23772380

mono/metadata/object.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ MONO_API MONO_RT_EXTERNAL_ONLY void mono_gchandle_free (uint32_t
376376
UNITY_MONO_API MONO_RT_EXTERNAL_ONLY mono_bool mono_gchandle_is_in_domain (uint32_t gchandle, MonoDomain* domain);
377377

378378
MONO_API MONO_RT_EXTERNAL_ONLY MonoGCHandle mono_gchandle_new_v2 (MonoObject *obj, mono_bool pinned);
379+
MONO_API MONO_RT_EXTERNAL_ONLY MonoGCHandle mono_gchandle_new_late_v2 (MonoObject *obj);
379380
MONO_API MONO_RT_EXTERNAL_ONLY MonoGCHandle mono_gchandle_new_weakref_v2 (MonoObject *obj, mono_bool track_resurrection);
380381
MONO_API MONO_RT_EXTERNAL_ONLY MonoObject* mono_gchandle_get_target_v2 (MonoGCHandle gchandle);
381382
MONO_API MONO_RT_EXTERNAL_ONLY void mono_gchandle_free_v2 (MonoGCHandle gchandle);

mono/sgen/gc-internal-agnostic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ typedef enum {
5353
HANDLE_NORMAL,
5454
HANDLE_PINNED,
5555
HANDLE_WEAK_FIELDS,
56+
HANDLE_LATE,
5657
HANDLE_TYPE_MAX
5758
} GCHandleType;
5859

0 commit comments

Comments
 (0)