[jit] Don't sample threads that are not fully attached.
[mono.git] / mono / mini / mini-gc.c
index b3c1519ddc80461929d9cd9f6ea670f3fe0bd2e9..6c616a5f6f234db359eafe663c1173dce555000f 100644 (file)
 //#if 0
 #if defined(MONO_ARCH_GC_MAPS_SUPPORTED)
 
+#include <mono/metadata/sgen-conf.h>
 #include <mono/metadata/gc-internal.h>
 #include <mono/utils/mono-counters.h>
 
-#if SIZEOF_VOID_P == 4
-typedef guint32 mword;
-#else
-typedef guint64 mword;
-#endif
-
 #define SIZEOF_SLOT ((int)sizeof (mgreg_t))
 
 #define GC_BITS_PER_WORD (sizeof (mword) * 8)
@@ -436,8 +431,13 @@ static int callee_saved_regs [] = { AMD64_RBP, AMD64_RBX, AMD64_R12, AMD64_R13,
 static int callee_saved_regs [] = { X86_EBX, X86_ESI, X86_EDI };
 #elif defined(TARGET_ARM)
 static int callee_saved_regs [] = { ARMREG_V1, ARMREG_V2, ARMREG_V3, ARMREG_V4, ARMREG_V5, ARMREG_V7, ARMREG_FP };
+#elif defined(TARGET_ARM64)
+// FIXME:
+static int callee_saved_regs [] = { };
 #elif defined(TARGET_S390X)
 static int callee_saved_regs [] = { s390_r6, s390_r7, s390_r8, s390_r9, s390_r10, s390_r11, s390_r12, s390_r13, s390_r14 };
+#elif defined(TARGET_POWERPC)
+static int callee_saved_regs [] = { ppc_r6, ppc_r7, ppc_r8, ppc_r9, ppc_r10, ppc_r11, ppc_r12, ppc_r13, ppc_r14 };
 #endif
 
 static guint32
@@ -590,21 +590,30 @@ thread_suspend_func (gpointer user_data, void *sigctx, MonoContext *ctx)
 
        if (!tls) {
                /* Happens during startup */
-               tls->unwind_state.valid = FALSE;
                return;
        }
 
        if (tls->tid != GetCurrentThreadId ()) {
                /* Happens on osx because threads are not suspended using signals */
+#ifndef TARGET_WIN32
                gboolean res;
+#endif
 
                g_assert (tls->info);
-               res = mono_thread_state_init_from_handle (&tls->unwind_state, (MonoNativeThreadId)tls->tid, tls->info->native_handle);
+#ifdef TARGET_WIN32
+               return;
+#else
+               res = mono_thread_state_init_from_handle (&tls->unwind_state, tls->info);
+#endif
        } else {
                tls->unwind_state.unwind_data [MONO_UNWIND_DATA_LMF] = mono_get_lmf ();
                if (sigctx) {
-                       mono_arch_sigctx_to_monoctx (sigctx, &tls->unwind_state.ctx);
+#ifdef MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX
+                       mono_sigctx_to_monoctx (sigctx, &tls->unwind_state.ctx);
                        tls->unwind_state.valid = TRUE;
+#else
+                       tls->unwind_state.valid = FALSE;
+#endif
                } else if (ctx) {
                        memcpy (&tls->unwind_state.ctx, ctx, sizeof (MonoContext));
                        tls->unwind_state.valid = TRUE;
@@ -695,6 +704,7 @@ static void
 conservative_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end)
 {
        MonoJitInfo *ji;
+       MonoMethod *method;
        MonoContext ctx, new_ctx;
        MonoLMF *lmf;
        guint8 *stack_limit;
@@ -804,10 +814,15 @@ conservative_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end)
                        continue;
                }
 
+               if (ji)
+                       method = jinfo_get_method (ji);
+               else
+                       method = NULL;
+
                /* The last frame can be in any state so mark conservatively */
                if (last) {
                        if (ji) {
-                               DEBUG (char *fname = mono_method_full_name (ji->method, TRUE); fprintf (logfile, "Mark(0): %s+0x%x (%p)\n", fname, pc_offset, (gpointer)MONO_CONTEXT_GET_IP (&ctx)); g_free (fname));
+                               DEBUG (char *fname = mono_method_full_name (method, TRUE); fprintf (logfile, "Mark(0): %s+0x%x (%p)\n", fname, pc_offset, (gpointer)MONO_CONTEXT_GET_IP (&ctx)); g_free (fname));
                        }
                        DEBUG (fprintf (logfile, "\t <Last frame>\n"));
                        last = FALSE;
@@ -834,8 +849,8 @@ conservative_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end)
                pc_offset = (guint8*)MONO_CONTEXT_GET_IP (&ctx) - (guint8*)ji->code_start;
 
                /* These frames are very problematic */
-               if (ji->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
-                       DEBUG (char *fname = mono_method_full_name (ji->method, TRUE); fprintf (logfile, "Mark(0): %s+0x%x (%p)\n", fname, pc_offset, (gpointer)MONO_CONTEXT_GET_IP (&ctx)); g_free (fname));
+               if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
+                       DEBUG (char *fname = mono_method_full_name (method, TRUE); fprintf (logfile, "Mark(0): %s+0x%x (%p)\n", fname, pc_offset, (gpointer)MONO_CONTEXT_GET_IP (&ctx)); g_free (fname));
                        DEBUG (fprintf (logfile, "\tSkip.\n"));
                        continue;
                }
@@ -866,7 +881,7 @@ conservative_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end)
                emap = ji->gc_info;
 
                if (!emap) {
-                       DEBUG (char *fname = mono_method_full_name (ji->method, TRUE); fprintf (logfile, "Mark(0): %s+0x%x (%p)\n", fname, pc_offset, (gpointer)MONO_CONTEXT_GET_IP (&ctx)); g_free (fname));
+                       DEBUG (char *fname = mono_method_full_name (jinfo_get_method (ji), TRUE); fprintf (logfile, "Mark(0): %s+0x%x (%p)\n", fname, pc_offset, (gpointer)MONO_CONTEXT_GET_IP (&ctx)); g_free (fname));
                        DEBUG (fprintf (logfile, "\tNo GC Map.\n"));
                        continue;
                }
@@ -878,14 +893,14 @@ conservative_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end)
                 * Debugging aid to control the number of frames scanned precisely
                 */
                if (!precise_frame_limit_inited) {
-                       if (getenv ("MONO_PRECISE_COUNT"))
-                               precise_frame_limit = atoi (getenv ("MONO_PRECISE_COUNT"));
+                       if (g_getenv ("MONO_PRECISE_COUNT"))
+                               precise_frame_limit = atoi (g_getenv ("MONO_PRECISE_COUNT"));
                        precise_frame_limit_inited = TRUE;
                }
                                
                if (precise_frame_limit != -1) {
                        if (precise_frame_count [FALSE] == precise_frame_limit)
-                               printf ("LAST PRECISE FRAME: %s\n", mono_method_full_name (ji->method, TRUE));
+                               printf ("LAST PRECISE FRAME: %s\n", mono_method_full_name (method, TRUE));
                        if (precise_frame_count [FALSE] > precise_frame_limit)
                                continue;
                }
@@ -906,7 +921,7 @@ conservative_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end)
                frame_start = fp + map->start_offset + map->map_offset;
                frame_end = fp + map->end_offset;
 
-               DEBUG (char *fname = mono_method_full_name (ji->method, TRUE); fprintf (logfile, "Mark(0): %s+0x%x (%p) limit=%p fp=%p frame=%p-%p (%d)\n", fname, pc_offset, (gpointer)MONO_CONTEXT_GET_IP (&ctx), stack_limit, fp, frame_start, frame_end, (int)(frame_end - frame_start)); g_free (fname));
+               DEBUG (char *fname = mono_method_full_name (jinfo_get_method (ji), TRUE); fprintf (logfile, "Mark(0): %s+0x%x (%p) limit=%p fp=%p frame=%p-%p (%d)\n", fname, pc_offset, (gpointer)MONO_CONTEXT_GET_IP (&ctx), stack_limit, fp, frame_start, frame_end, (int)(frame_end - frame_start)); g_free (fname));
 
                /* Find the callsite index */
                if (map->callsite_entry_size == 1) {
@@ -928,7 +943,7 @@ conservative_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end)
                                        break;
                }
                if (i == map->ncallsites) {
-                       printf ("Unable to find ip offset 0x%x in callsite list of %s.\n", pc_offset + 1, mono_method_full_name (ji->method, TRUE));
+                       printf ("Unable to find ip offset 0x%x in callsite list of %s.\n", pc_offset + 1, mono_method_full_name (method, TRUE));
                        g_assert_not_reached ();
                }
                cindex = i;
@@ -1090,7 +1105,7 @@ conservative_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end)
  * pass.
  */
 static void
-precise_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end)
+precise_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end, void *gc_data)
 {
        int findex, i;
        FrameInfo *fi;
@@ -1107,7 +1122,7 @@ precise_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end)
                fi = &tls->frames [findex];
                frame_start = stack_start + fi->frame_start_offset;
 
-               DEBUG (char *fname = mono_method_full_name (fi->ji->method, TRUE); fprintf (logfile, "Mark(1): %s\n", fname); g_free (fname));
+               DEBUG (char *fname = mono_method_full_name (jinfo_get_method (fi->ji), TRUE); fprintf (logfile, "Mark(1): %s\n", fname); g_free (fname));
 
                /* 
                 * FIXME: Add a function to mark using a bitmap, to avoid doing a 
@@ -1128,7 +1143,7 @@ precise_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end)
                                        MonoObject *obj = *ptr;
                                        if (obj) {
                                                DEBUG (fprintf (logfile, "\tref %s0x%x(fp)=%p: %p ->", (guint8*)ptr >= (guint8*)fi->fp ? "" : "-", ABS ((int)((gssize)ptr - (gssize)fi->fp)), ptr, obj));
-                                               *ptr = mono_gc_scan_object (obj);
+                                               *ptr = mono_gc_scan_object (obj, gc_data);
                                                DEBUG (fprintf (logfile, " %p.\n", *ptr));
                                        } else {
                                                DEBUG (fprintf (logfile, "\tref %s0x%x(fp)=%p: %p.\n", (guint8*)ptr >= (guint8*)fi->fp ? "" : "-", ABS ((int)((gssize)ptr - (gssize)fi->fp)), ptr, obj));
@@ -1169,7 +1184,7 @@ precise_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end)
 
                        if (obj) {
                                DEBUG (fprintf (logfile, "\treg %s saved at %p: %p ->", mono_arch_regname (fi->regs [i]), ptr, obj));
-                               *ptr = mono_gc_scan_object (obj);
+                               *ptr = mono_gc_scan_object (obj, gc_data);
                                DEBUG (fprintf (logfile, " %p.\n", *ptr));
                        } else {
                                DEBUG (fprintf (logfile, "\treg %s saved at %p: %p\n", mono_arch_regname (fi->regs [i]), ptr, obj));
@@ -1197,7 +1212,7 @@ precise_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end)
  * structure filled up by thread_suspend_func. 
  */
 static void
-thread_mark_func (gpointer user_data, guint8 *stack_start, guint8 *stack_end, gboolean precise)
+thread_mark_func (gpointer user_data, guint8 *stack_start, guint8 *stack_end, gboolean precise, void *gc_data)
 {
        TlsData *tls = user_data;
 
@@ -1208,9 +1223,11 @@ thread_mark_func (gpointer user_data, guint8 *stack_start, guint8 *stack_end, gb
        if (!precise)
                conservative_pass (tls, stack_start, stack_end);
        else
-               precise_pass (tls, stack_start, stack_end);
+               precise_pass (tls, stack_start, stack_end, gc_data);
 }
 
+#ifndef DISABLE_JIT
+
 static void
 mini_gc_init_gc_map (MonoCompile *cfg)
 {
@@ -1232,10 +1249,10 @@ mini_gc_init_gc_map (MonoCompile *cfg)
                static int precise_count;
 
                precise_count ++;
-               if (getenv ("MONO_GCMAP_COUNT")) {
-                       if (precise_count == atoi (getenv ("MONO_GCMAP_COUNT")))
+               if (g_getenv ("MONO_GCMAP_COUNT")) {
+                       if (precise_count == atoi (g_getenv ("MONO_GCMAP_COUNT")))
                                printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
-                       if (precise_count > atoi (getenv ("MONO_GCMAP_COUNT")))
+                       if (precise_count > atoi (g_getenv ("MONO_GCMAP_COUNT")))
                                return;
                }
        }
@@ -1851,7 +1868,11 @@ sp_offset_to_fp_offset (MonoCompile *cfg, int sp_offset)
 #elif defined(TARGET_X86)
        /* The offset is computed from the sp at the start of the call sequence */
        g_assert (cfg->frame_reg == X86_EBP);
+#ifdef MONO_X86_NO_PUSHES
+       return (- cfg->arch.sp_fp_offset + sp_offset);
+#else
        return (- cfg->arch.sp_fp_offset - sp_offset);  
+#endif
 #else
        NOT_IMPLEMENTED;
        return -1;
@@ -2038,7 +2059,11 @@ compute_frame_size (MonoCompile *cfg)
 #ifdef TARGET_AMD64
        min_offset = MIN (min_offset, -cfg->arch.sp_fp_offset);
 #elif defined(TARGET_X86)
+#ifdef MONO_X86_NO_PUSHES
+       min_offset = MIN (min_offset, -cfg->arch.sp_fp_offset);
+#else
        min_offset = MIN (min_offset, - (cfg->arch.sp_fp_offset + cfg->arch.param_area_size));
+#endif
 #elif defined(TARGET_ARM)
        // FIXME:
 #elif defined(TARGET_s390X)
@@ -2428,13 +2453,15 @@ mini_gc_create_gc_map (MonoCompile *cfg)
        create_map (cfg);
 }
 
+#endif /* DISABLE_JIT */
+
 static void
 parse_debug_options (void)
 {
        char **opts, **ptr;
-       char *env;
+       const char *env;
 
-       env = getenv ("MONO_GCMAP_DEBUG");
+       env = g_getenv ("MONO_GCMAP_DEBUG");
        if (!env)
                return;
 
@@ -2509,11 +2536,18 @@ mini_gc_init (void)
 
 #else
 
+void
+mini_gc_enable_gc_maps_for_aot (void)
+{
+}
+
 void
 mini_gc_init (void)
 {
 }
 
+#ifndef DISABLE_JIT
+
 static void
 mini_gc_init_gc_map (MonoCompile *cfg)
 {
@@ -2534,8 +2568,12 @@ mini_gc_set_slot_type_from_cfa (MonoCompile *cfg, int slot_offset, GCSlotType ty
 {
 }
 
+#endif /* DISABLE_JIT */
+
 #endif
 
+#ifndef DISABLE_JIT
+
 /*
  * mini_gc_init_cfg:
  *
@@ -2552,6 +2590,8 @@ mini_gc_init_cfg (MonoCompile *cfg)
        mini_gc_init_gc_map (cfg);
 }
 
+#endif /* DISABLE_JIT */
+
 /*
  * Problems with the current code:
  * - the stack walk is slow