[runtime] Reworked coop GC stack handling in platforms with restricted access to...
[mono.git] / mono / metadata / sgen-mono.c
index 1b9b7ca17bad409ba948b513a25d8a6ab1376765..11ab789d422e953843bed8809be3e06a8bdc2168 100644 (file)
@@ -362,7 +362,7 @@ get_array_fill_vtable (void)
        if (!array_fill_vtable) {
                static MonoClass klass;
                static char _vtable[sizeof(MonoVTable)+8];
-               MonoVTable* vtable = (MonoVTable*) ALIGN_TO(_vtable, 8);
+               MonoVTable* vtable = (MonoVTable*) ALIGN_TO((mword)_vtable, 8);
                gsize bmap;
 
                MonoDomain *domain = mono_get_root_domain ();
@@ -2338,6 +2338,8 @@ sgen_client_scan_thread_data (void *start_nursery, void *end_nursery, gboolean p
 
        FOREACH_THREAD (info) {
                int skip_reason = 0;
+               void *aligned_stack_start = (void*)(mword) ALIGN_TO ((mword)info->client_info.stack_start, SIZEOF_VOID_P);
+
                if (info->client_info.skip) {
                        SGEN_LOG (3, "Skipping dead thread %p, range: %p-%p, size: %zd", info, info->client_info.stack_start, info->client_info.stack_end, (char*)info->client_info.stack_end - (char*)info->client_info.stack_start);
                        skip_reason = 1;
@@ -2357,13 +2359,13 @@ sgen_client_scan_thread_data (void *start_nursery, void *end_nursery, gboolean p
                g_assert (info->client_info.suspend_done);
                SGEN_LOG (3, "Scanning thread %p, range: %p-%p, size: %zd, pinned=%zd", info, info->client_info.stack_start, info->client_info.stack_end, (char*)info->client_info.stack_end - (char*)info->client_info.stack_start, sgen_get_pinned_count ());
                if (mono_gc_get_gc_callbacks ()->thread_mark_func && !conservative_stack_mark) {
-                       mono_gc_get_gc_callbacks ()->thread_mark_func (info->client_info.runtime_data, info->client_info.stack_start, info->client_info.stack_end, precise, &ctx);
+                       mono_gc_get_gc_callbacks ()->thread_mark_func (info->client_info.runtime_data, aligned_stack_start, info->client_info.stack_end, precise, &ctx);
                } else if (!precise) {
                        if (!conservative_stack_mark) {
                                fprintf (stderr, "Precise stack mark not supported - disabling.\n");
                                conservative_stack_mark = TRUE;
                        }
-                       sgen_conservatively_pin_objects_from (info->client_info.stack_start, info->client_info.stack_end, start_nursery, end_nursery, PIN_TYPE_STACK);
+                       sgen_conservatively_pin_objects_from (aligned_stack_start, info->client_info.stack_end, start_nursery, end_nursery, PIN_TYPE_STACK);
                }
 
                if (!precise) {
@@ -2374,6 +2376,15 @@ sgen_client_scan_thread_data (void *start_nursery, void *end_nursery, gboolean p
                        sgen_conservatively_pin_objects_from ((void**)&info->client_info.regs, (void**)&info->client_info.regs + ARCH_NUM_REGS,
                                        start_nursery, end_nursery, PIN_TYPE_STACK);
 #endif
+                       {
+                               // This is used on Coop GC for platforms where we cannot get the data for individual registers.
+                               // We force a spill of all registers into the stack and pass a chunk of data into sgen.                         
+                               MonoThreadUnwindState *state = mono_thread_info_get_suspend_state (info);
+                               if (state && state->gc_stackdata) {
+                                       sgen_conservatively_pin_objects_from (state->gc_stackdata, (void**)((char*)state->gc_stackdata + state->gc_stackdata_size),
+                                               start_nursery, end_nursery, PIN_TYPE_STACK);
+                               }
+                       }
                }
        } END_FOREACH_THREAD
 }
@@ -2565,35 +2576,6 @@ mono_gc_get_los_limit (void)
        return SGEN_MAX_SMALL_OBJ_SIZE;
 }
 
-void
-mono_gc_weak_link_register (volatile gpointer *link_addr, MonoObject *obj, gboolean track)
-{
-       binary_protocol_dislink_add ((gpointer)link_addr, obj, track);
-}
-
-void
-mono_gc_weak_link_unregister (volatile gpointer *link_addr, gboolean track)
-{
-       binary_protocol_dislink_remove ((gpointer)link_addr, track);
-}
-
-void
-mono_gc_ensure_weak_links_accessible (void)
-{
-       /*
-        * During the second bridge processing step the world is
-        * running again.  That step processes all weak links once
-        * more to null those that refer to dead objects.  Before that
-        * is completed, those links must not be followed, so we
-        * conservatively wait for bridge processing when any weak
-        * link is dereferenced.
-        */
-       /* FIXME: A GC can occur after this check fails, in which case we
-        * should wait for bridge processing but would fail to do so.
-        */
-       mono_gc_wait_for_bridge_processing ();
-}
-
 gpointer
 sgen_client_default_metadata (void)
 {