[sgen] Move stack limits to client code.
authorMark Probst <mark.probst@gmail.com>
Thu, 1 Jan 2015 17:21:40 +0000 (09:21 -0800)
committerMark Probst <mark.probst@gmail.com>
Wed, 29 Apr 2015 17:59:46 +0000 (10:59 -0700)
mono/metadata/sgen-client-mono.h
mono/metadata/sgen-debug.c
mono/metadata/sgen-gc.c
mono/metadata/sgen-gc.h
mono/metadata/sgen-mono.c
mono/metadata/sgen-os-mach.c
mono/metadata/sgen-os-posix.c
mono/metadata/sgen-stw.c

index b9eae28e33cd2235bafcfc9a4b2e7bcdcc72897d..309d8bf1ad610ccda59d4a5935738eb2dc63c9a4 100644 (file)
@@ -118,6 +118,10 @@ struct _SgenClientThreadInfo {
        been scanned.
        */
        gboolean gc_disabled;
+
+       void *stack_end;
+       void *stack_start;
+       void *stack_start_limit;
 };
 
 #else
index 1a0a11fb0b6a17dbc81cc4d636b23e2f9e83a5f9..17481b37141a54b8bfe0f98addab11bf7ec2999f 100644 (file)
@@ -501,13 +501,12 @@ find_pinning_ref_from_thread (char *obj, size_t size)
        char *endobj = obj + size;
 
        FOREACH_THREAD (info) {
-               char **start = (char**)info->stack_start;
+               char **start = (char**)info->client_info.stack_start;
                if (info->client_info.skip)
                        continue;
-               while (start < (char**)info->stack_end) {
-                       if (*start >= obj && *start < endobj) {
-                               SGEN_LOG (0, "Object %p referenced in thread %p (id %p) at %p, stack: %p-%p", obj, info, (gpointer)mono_thread_info_get_tid (info), start, info->stack_start, info->stack_end);
-                       }
+               while (start < (char**)info->client_info.stack_end) {
+                       if (*start >= obj && *start < endobj)
+                               SGEN_LOG (0, "Object %p referenced in thread %p (id %p) at %p, stack: %p-%p", obj, info, (gpointer)mono_thread_info_get_tid (info), start, info->client_info.stack_start, info->client_info.stack_end);
                        start++;
                }
 
index f455884391bac98ca255ce0e136dabb23b4ba1c1..d1aaedf44571885b149152af84fd7330390d9ede 100644 (file)
@@ -408,7 +408,6 @@ MonoNativeTlsKey thread_info_key;
 
 #ifdef HAVE_KW_THREAD
 __thread SgenThreadInfo *sgen_thread_info;
-__thread char *stack_end;
 #endif
 
 /* The size of a TLAB */
@@ -2748,9 +2747,6 @@ mono_gc_get_gc_callbacks ()
 void*
 sgen_thread_register (SgenThreadInfo* info, void *stack_bottom_fallback)
 {
-       size_t stsize = 0;
-       guint8 *staddr = NULL;
-
 #ifndef HAVE_KW_THREAD
        info->tlab_start = info->tlab_next = info->tlab_temp_end = info->tlab_real_end = NULL;
 
@@ -2765,7 +2761,6 @@ sgen_thread_register (SgenThreadInfo* info, void *stack_bottom_fallback)
        info->signal = 0;
 #endif
        sgen_client_thread_register (info, stack_bottom_fallback);
-       info->stack_start = NULL;
 #ifdef USE_MONO_CTX
        memset (&info->ctx, 0, sizeof (MonoContext));
 #else
@@ -2776,26 +2771,6 @@ sgen_thread_register (SgenThreadInfo* info, void *stack_bottom_fallback)
 
        binary_protocol_thread_register ((gpointer)mono_thread_info_get_tid (info));
 
-       /* On win32, stack_start_limit should be 0, since the stack can grow dynamically */
-       mono_thread_info_get_stack_bounds (&staddr, &stsize);
-       if (staddr) {
-#ifndef HOST_WIN32
-               info->stack_start_limit = staddr;
-#endif
-               info->stack_end = staddr + stsize;
-       } else {
-               gsize stack_bottom = (gsize)stack_bottom_fallback;
-               stack_bottom += 4095;
-               stack_bottom &= ~4095;
-               info->stack_end = (char*)stack_bottom;
-       }
-
-#ifdef HAVE_KW_THREAD
-       stack_end = info->stack_end;
-#endif
-
-       SGEN_LOG (3, "registered thread %p (%p) stack end %p", info, (gpointer)mono_thread_info_get_tid (info), info->stack_end);
-
        if (gc_callbacks.thread_attach_func)
                info->runtime_data = gc_callbacks.thread_attach_func ();
        return info;
@@ -2843,26 +2818,6 @@ mono_gc_register_thread (void *baseptr)
        return mono_thread_info_attach (baseptr) != NULL;
 }
 
-/*
- * mono_gc_set_stack_end:
- *
- *   Set the end of the current threads stack to STACK_END. The stack space between 
- * STACK_END and the real end of the threads stack will not be scanned during collections.
- */
-void
-mono_gc_set_stack_end (void *stack_end)
-{
-       SgenThreadInfo *info;
-
-       LOCK_GC;
-       info = mono_thread_info_current ();
-       if (info) {
-               g_assert (stack_end < info->stack_end);
-               info->stack_end = stack_end;
-       }
-       UNLOCK_GC;
-}
-
 #if USE_PTHREAD_INTERCEPT
 
 
index 016696819492d17ccef224df1d4d74f339b55252..f50a2b65cb9e356c0f5f142c8f49d2e44fdd1022 100644 (file)
@@ -389,9 +389,6 @@ void sgen_init_internal_allocator (void);
 struct _SgenThreadInfo {
        SgenClientThreadInfo client_info;
 
-       void *stack_end;
-       void *stack_start;
-       void *stack_start_limit;
        char **tlab_next_addr;
        char **tlab_start_addr;
        char **tlab_temp_end_addr;
@@ -973,7 +970,6 @@ extern MonoNativeTlsKey thread_info_key;
 
 #ifdef HAVE_KW_THREAD
 extern __thread SgenThreadInfo *sgen_thread_info;
-extern __thread char *stack_end;
 #endif
 
 /* Other globals */
index ae9eb24fe78a3d40648da1d3c8ed88a2cef35947..69f55d180518d91c578d7e85f71e9a7bbc29454a 100644 (file)
@@ -62,7 +62,7 @@ ptr_on_stack (void *ptr)
        gpointer stack_start = &stack_start;
        SgenThreadInfo *info = mono_thread_info_current ();
 
-       if (ptr >= stack_start && ptr < (gpointer)info->stack_end)
+       if (ptr >= stack_start && ptr < (gpointer)info->client_info.stack_end)
                return TRUE;
        return FALSE;
 }
@@ -218,13 +218,6 @@ mono_gc_get_specific_write_barrier (gboolean is_concurrent)
        MonoMethod **write_barrier_method_addr;
 #ifdef MANAGED_WBARRIER
        int i, nursery_check_labels [2];
-
-#ifdef HAVE_KW_THREAD
-       int stack_end_offset = -1;
-
-       MONO_THREAD_VAR_OFFSET (stack_end, stack_end_offset);
-       g_assert (stack_end_offset != -1);
-#endif
 #endif
 
        // FIXME: Maybe create a separate version for ctors (the branch would be
@@ -1967,9 +1960,30 @@ mono_gc_walk_heap (int flags, MonoGCReferences callback, void *data)
 void
 sgen_client_thread_register (SgenThreadInfo* info, void *stack_bottom_fallback)
 {
+       size_t stsize = 0;
+       guint8 *staddr = NULL;
+
        info->client_info.skip = 0;
        info->client_info.stopped_ip = NULL;
        info->client_info.stopped_domain = NULL;
+
+       info->client_info.stack_start = NULL;
+
+       /* On win32, stack_start_limit should be 0, since the stack can grow dynamically */
+       mono_thread_info_get_stack_bounds (&staddr, &stsize);
+       if (staddr) {
+#ifndef HOST_WIN32
+               info->client_info.stack_start_limit = staddr;
+#endif
+               info->client_info.stack_end = staddr + stsize;
+       } else {
+               gsize stack_bottom = (gsize)stack_bottom_fallback;
+               stack_bottom += 4095;
+               stack_bottom &= ~4095;
+               info->client_info.stack_end = (char*)stack_bottom;
+       }
+
+       SGEN_LOG (3, "registered thread %p (%p) stack end %p", info, (gpointer)mono_thread_info_get_tid (info), info->client_info.stack_end);
 }
 
 void
@@ -2037,27 +2051,27 @@ sgen_client_scan_thread_data (void *start_nursery, void *end_nursery, gboolean p
 
        FOREACH_THREAD (info) {
                if (info->client_info.skip) {
-                       SGEN_LOG (3, "Skipping dead thread %p, range: %p-%p, size: %td", info, info->stack_start, info->stack_end, (char*)info->stack_end - (char*)info->stack_start);
+                       SGEN_LOG (3, "Skipping dead thread %p, range: %p-%p, size: %td", info, info->client_info.stack_start, info->client_info.stack_end, (char*)info->client_info.stack_end - (char*)info->client_info.stack_start);
                        continue;
                }
                if (info->client_info.gc_disabled) {
-                       SGEN_LOG (3, "GC disabled for thread %p, range: %p-%p, size: %td", info, info->stack_start, info->stack_end, (char*)info->stack_end - (char*)info->stack_start);
+                       SGEN_LOG (3, "GC disabled for thread %p, range: %p-%p, size: %td", info, info->client_info.stack_start, info->client_info.stack_end, (char*)info->client_info.stack_end - (char*)info->client_info.stack_start);
                        continue;
                }
                if (!mono_thread_info_is_live (info)) {
-                       SGEN_LOG (3, "Skipping non-running thread %p, range: %p-%p, size: %td (state %x)", info, info->stack_start, info->stack_end, (char*)info->stack_end - (char*)info->stack_start, info->client_info.info.thread_state);
+                       SGEN_LOG (3, "Skipping non-running thread %p, range: %p-%p, size: %td (state %x)", info, info->client_info.stack_start, info->client_info.stack_end, (char*)info->client_info.stack_end - (char*)info->client_info.stack_start, info->client_info.info.thread_state);
                        continue;
                }
                g_assert (info->client_info.suspend_done);
-               SGEN_LOG (3, "Scanning thread %p, range: %p-%p, size: %td, pinned=%zd", info, info->stack_start, info->stack_end, (char*)info->stack_end - (char*)info->stack_start, sgen_get_pinned_count ());
+               SGEN_LOG (3, "Scanning thread %p, range: %p-%p, size: %td, 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->runtime_data, info->stack_start, info->stack_end, precise, &ctx);
+                       mono_gc_get_gc_callbacks ()->thread_mark_func (info->runtime_data, info->client_info.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->stack_start, info->stack_end, start_nursery, end_nursery, PIN_TYPE_STACK);
+                       sgen_conservatively_pin_objects_from (info->client_info.stack_start, info->client_info.stack_end, start_nursery, end_nursery, PIN_TYPE_STACK);
                }
 
                if (!precise) {
@@ -2072,6 +2086,26 @@ sgen_client_scan_thread_data (void *start_nursery, void *end_nursery, gboolean p
        } END_FOREACH_THREAD
 }
 
+/*
+ * mono_gc_set_stack_end:
+ *
+ *   Set the end of the current threads stack to STACK_END. The stack space between 
+ * STACK_END and the real end of the threads stack will not be scanned during collections.
+ */
+void
+mono_gc_set_stack_end (void *stack_end)
+{
+       SgenThreadInfo *info;
+
+       LOCK_GC;
+       info = mono_thread_info_current ();
+       if (info) {
+               SGEN_ASSERT (0, stack_end < info->client_info.stack_end, "Can only lower stack end");
+               info->client_info.stack_end = stack_end;
+       }
+       UNLOCK_GC;
+}
+
 /*
  * Miscellaneous
  */
index 2aae07ce8125356eb5e21e784095407dee50beee..84f83f44ad84640053db049d9f3426ca245607da 100644 (file)
@@ -73,11 +73,11 @@ sgen_suspend_thread (SgenThreadInfo *info)
 
        info->client_info.stopped_domain = mono_thread_info_tls_get (info, TLS_KEY_DOMAIN);
        info->client_info.stopped_ip = (gpointer) mono_mach_arch_get_ip (state);
-       info->stack_start = NULL;
+       info->client_info.stack_start = NULL;
        stack_start = (char*) mono_mach_arch_get_sp (state) - REDZONE_SIZE;
        /* If stack_start is not within the limits, then don't set it in info and we will be restarted. */
-       if (stack_start >= info->stack_start_limit && stack_start <= info->stack_end) {
-               info->stack_start = stack_start;
+       if (stack_start >= info->client_info.stack_start_limit && stack_start <= info->client_info.stack_end) {
+               info->client_info.stack_start = stack_start;
 
 #ifdef USE_MONO_CTX
                mono_sigctx_to_monoctx (&ctx, &info->ctx);
@@ -85,14 +85,14 @@ sgen_suspend_thread (SgenThreadInfo *info)
                ARCH_COPY_SIGCTX_REGS (&info->regs, &ctx);
 #endif
        } else {
-               g_assert (!info->stack_start);
+               g_assert (!info->client_info.stack_start);
        }
 
        /* Notify the JIT */
        if (mono_gc_get_gc_callbacks ()->thread_suspend_func)
                mono_gc_get_gc_callbacks ()->thread_suspend_func (info->runtime_data, &ctx, NULL);
 
-       SGEN_LOG (2, "thread %p stopped at %p stack_start=%p", (void*)(gsize)info->client_info.info.native_handle, info->client_info.stopped_ip, info->stack_start);
+       SGEN_LOG (2, "thread %p stopped at %p stack_start=%p", (void*)(gsize)info->client_info.info.native_handle, info->client_info.stopped_ip, info->client_info.stack_start);
        binary_protocol_thread_suspend ((gpointer)mono_thread_info_get_tid (info), info->client_info.stopped_ip);
 
        return TRUE;
index edba9aa1d03f25ce3850961a2bf7ec23ea41a6f9..e3737b39560a94f6226a00f031f0e4d37676bee7 100644 (file)
@@ -82,8 +82,8 @@ suspend_thread (SgenThreadInfo *info, void *context)
 
        /* If stack_start is not within the limits, then don't set it
           in info and we will be restarted. */
-       if (stack_start >= info->stack_start_limit && stack_start <= info->stack_end) {
-               info->stack_start = stack_start;
+       if (stack_start >= info->client_info.stack_start_limit && stack_start <= info->client_info.stack_end) {
+               info->client_info.stack_start = stack_start;
 
 #ifdef USE_MONO_CTX
                if (context) {
@@ -100,7 +100,7 @@ suspend_thread (SgenThreadInfo *info, void *context)
                }
 #endif
        } else {
-               g_assert (!info->stack_start);
+               g_assert (!info->client_info.stack_start);
        }
 
        /* Notify the JIT */
index 85cf2d31d56fb025e23eebb36b60643686b610c8..dd791419224a6e824d14fa36f879da554753760c 100644 (file)
@@ -66,8 +66,8 @@ update_current_thread_stack (void *start)
 #endif
        SgenThreadInfo *info = mono_thread_info_current ();
        
-       info->stack_start = align_pointer (&stack_guard);
-       g_assert (info->stack_start >= info->stack_start_limit && info->stack_start < info->stack_end);
+       info->client_info.stack_start = align_pointer (&stack_guard);
+       g_assert (info->client_info.stack_start >= info->client_info.stack_start_limit && info->client_info.stack_start < info->client_info.stack_end);
 #ifdef USE_MONO_CTX
        MONO_CONTEXT_GET_CURRENT (cur_thread_ctx);
        memcpy (&info->ctx, &cur_thread_ctx, sizeof (MonoContext));
@@ -123,7 +123,7 @@ restart_threads_until_none_in_managed_allocator (void)
                        if (info->client_info.skip || info->client_info.gc_disabled || info->client_info.suspend_done)
                                continue;
                        if (mono_thread_info_is_live (info) &&
-                                       (!info->stack_start || info->client_info.in_critical_region || info->client_info.info.inside_critical_region ||
+                                       (!info->client_info.stack_start || info->client_info.in_critical_region || info->client_info.info.inside_critical_region ||
                                        is_ip_in_managed_allocator (info->client_info.stopped_domain, info->client_info.stopped_ip))) {
                                binary_protocol_thread_restart ((gpointer)mono_thread_info_get_tid (info));
                                SGEN_LOG (3, "thread %p resumed.", (void*) (size_t) info->client_info.info.native_handle);
@@ -264,7 +264,7 @@ sgen_client_restart_world (int generation, GGTimingInfo *timing)
                mono_sgen_gc_event_moves ();
 
        FOREACH_THREAD (info) {
-               info->stack_start = NULL;
+               info->client_info.stack_start = NULL;
 #ifdef USE_MONO_CTX
                memset (&info->ctx, 0, sizeof (MonoContext));
 #else
@@ -376,10 +376,10 @@ update_sgen_info (SgenThreadInfo *info)
        stack_start = (char*)MONO_CONTEXT_GET_SP (&mono_thread_info_get_suspend_state (info)->ctx) - REDZONE_SIZE;
 
        /* altstack signal handler, sgen can't handle them, mono-threads should have handled this. */
-       if (stack_start < (char*)info->stack_start_limit || stack_start >= (char*)info->stack_end)
+       if (stack_start < (char*)info->client_info.stack_start_limit || stack_start >= (char*)info->client_info.stack_end)
                g_error ("BAD STACK");
 
-       info->stack_start = stack_start;
+       info->client_info.stack_start = stack_start;
 #ifdef USE_MONO_CTX
        info->ctx = mono_thread_info_get_suspend_state (info)->ctx;
 #else