Skip to content

Commit ce596d6

Browse files
committed
Basic functionality working.
1 parent 154eb59 commit ce596d6

File tree

2 files changed

+65
-4
lines changed

2 files changed

+65
-4
lines changed

mono/metadata/boehm-gc.c

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2194,10 +2194,37 @@ mono_clear_ephemerons (void)
21942194
}
21952195
}
21962196

2197+
LateHandleCallback s_late_handle_callback;
2198+
void* s_late_handle_callback_user_data;
2199+
2200+
void
2201+
mono_gchandle_set_late_callback(LateHandleCallback late_handle_callback, void* user_data)
2202+
{
2203+
s_late_handle_callback = late_handle_callback;
2204+
s_late_handle_callback_user_data = user_data;
2205+
2206+
}
2207+
2208+
typedef struct {
2209+
struct GC_ms_entry* mark_stack_ptr;
2210+
struct GC_ms_entry* mark_stack_limit;
2211+
} MarkHandleData;
2212+
2213+
MarkHandleData* s_mark_data;
2214+
2215+
2216+
void mono_gchandle_mark_object(MonoObject* obj)
2217+
{
2218+
g_assert(s_mark_data);
2219+
s_mark_data->mark_stack_ptr = GC_mark_and_push(obj, s_mark_data->mark_stack_ptr, s_mark_data->mark_stack_limit, NULL);
2220+
}
2221+
21972222
static struct GC_ms_entry*
21982223
mono_push_ephemerons (struct GC_ms_entry* mark_stack_ptr, struct GC_ms_entry* mark_stack_limit)
21992224
{
2225+
struct GC_ms_entry* mark_stack_ptr_orig = mark_stack_ptr;
22002226
/* push late GC handles */
2227+
if (s_late_handle_callback)
22012228
{
22022229
GHashTableIter iter;
22032230
g_hash_table_iter_init(&iter, late_handles);
@@ -2217,14 +2244,42 @@ mono_push_ephemerons (struct GC_ms_entry* mark_stack_ptr, struct GC_ms_entry* ma
22172244
MonoObject* object = *handle;
22182245

22192246
if (GC_is_marked(object)) {
2220-
continue;
2247+
MarkHandleData data;
2248+
data.mark_stack_ptr = mark_stack_ptr;
2249+
data.mark_stack_limit = mark_stack_limit;
2250+
s_mark_data = &data;
2251+
// optimize, only process newly marked object
2252+
s_late_handle_callback(object, s_late_handle_callback_user_data);
2253+
mark_stack_ptr = data.mark_stack_ptr;
2254+
s_mark_data = NULL;
22212255
}
2222-
else {
2256+
}
2257+
}
2258+
}
22232259

2224-
mark_stack_ptr = GC_mark_and_push(object, mark_stack_ptr, mark_stack_limit, handle);
2225-
}
2260+
// mark all handles, as we want to keep all targets alive like a strong handle
2261+
if (mark_stack_ptr_orig == mark_stack_ptr)
2262+
{
2263+
GHashTableIter iter;
2264+
g_hash_table_iter_init(&iter, late_handles);
2265+
2266+
gpointer key;
2267+
gpointer value;
2268+
2269+
while (g_hash_table_iter_next(&iter, &key, &value)) {
2270+
/* process handles */
2271+
gpointer* handles = key;
2272+
size_t length = (size_t)value;
2273+
for (size_t i = 0; i < length; ++i) {
2274+
MonoObject** handle = handles + i;
2275+
if (!*handle)
2276+
continue;
2277+
2278+
MonoObject* object = *handle;
2279+
mark_stack_ptr = GC_mark_and_push(object, mark_stack_ptr, mark_stack_limit, handle);
22262280
}
22272281
}
2282+
s_late_handle_callback = NULL;
22282283
}
22292284

22302285

mono/metadata/object.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,12 @@ MONO_API MONO_RT_EXTERNAL_ONLY MonoGCHandle mono_gchandle_new_weakref_v2 (MonoOb
381381
MONO_API MONO_RT_EXTERNAL_ONLY MonoObject* mono_gchandle_get_target_v2 (MonoGCHandle gchandle);
382382
MONO_API MONO_RT_EXTERNAL_ONLY void mono_gchandle_free_v2 (MonoGCHandle gchandle);
383383

384+
385+
typedef void (*DoUnityProcessing)(void* handle);
386+
typedef void (*LateHandleCallback)(MonoObject* obj, void* user_data);
387+
MONO_API MONO_RT_EXTERNAL_ONLY void mono_gchandle_set_late_callback(LateHandleCallback late_handle_callback, void* user_data);
388+
MONO_API MONO_RT_EXTERNAL_ONLY void mono_gchandle_mark_object(MonoObject* obj);
389+
384390
/* make sure the gchandle was allocated for an object in domain */
385391
UNITY_MONO_API MONO_RT_EXTERNAL_ONLY mono_bool mono_gchandle_is_in_domain_v2 (MonoGCHandle gchandle, MonoDomain* domain);
386392

0 commit comments

Comments
 (0)