[Runtime] Added logging around finalizers
[mono.git] / mono / metadata / sgen-gc.c
index c3db43b2736a4dfaf25640fe040b9e106a6d4d0f..b586cff4607f51a3cd74b9707ff09fc9a94ae2e9 100644 (file)
 #endif
 #include <stdio.h>
 #include <string.h>
-#include <signal.h>
 #include <errno.h>
 #include <assert.h>
 
@@ -279,6 +278,7 @@ static gboolean conservative_stack_mark = FALSE;
 /* If set, do a plausibility check on the scan_starts before and after
    each collection */
 static gboolean do_scan_starts_check = FALSE;
+
 /*
  * If the major collector is concurrent and this is FALSE, we will
  * never initiate a synchronous major collection, unless requested via
@@ -2735,16 +2735,25 @@ major_copy_or_mark_from_roots (size_t *old_next_pin_slot, gboolean start_concurr
 
        TV_GETTIME (btv);
        time_major_scan_big_objects += TV_ELAPSED (atv, btv);
+}
 
-       if (concurrent_collection_in_progress) {
-               /* prepare the pin queue for the next collection */
-               sgen_finish_pinning ();
+static void
+major_finish_copy_or_mark (void)
+{
+       if (!concurrent_collection_in_progress)
+               return;
 
-               sgen_pin_stats_reset ();
+       /*
+        * Prepare the pin queue for the next collection.  Since pinning runs on the worker
+        * threads we must wait for the jobs to finish before we can reset it.
+        */
+       sgen_workers_wait_for_jobs_finished ();
+       sgen_finish_pinning ();
 
-               if (do_concurrent_checks)
-                       check_nursery_is_clean ();
-       }
+       sgen_pin_stats_reset ();
+
+       if (do_concurrent_checks)
+               check_nursery_is_clean ();
 }
 
 static void
@@ -2788,6 +2797,7 @@ major_start_collection (gboolean concurrent, size_t *old_next_pin_slot)
                major_collector.start_major_collection ();
 
        major_copy_or_mark_from_roots (old_next_pin_slot, concurrent, FALSE, FALSE, FALSE);
+       major_finish_copy_or_mark ();
 }
 
 static void
@@ -2815,6 +2825,8 @@ major_finish_collection (const char *reason, size_t old_next_pin_slot, gboolean
                major_copy_or_mark_from_roots (NULL, FALSE, TRUE, scan_mod_union, scan_whole_nursery);
 
                sgen_workers_signal_finish_nursery_collection ();
+
+               major_finish_copy_or_mark ();
                gray_queue_enable_redirect (WORKERS_DISTRIBUTE_GRAY_QUEUE);
 
                sgen_workers_join ();
@@ -3034,7 +3046,6 @@ major_start_concurrent_collection (const char *reason)
        major_start_collection (TRUE, NULL);
 
        gray_queue_redirect (&gray_queue);
-       sgen_workers_wait_for_jobs_finished ();
 
        num_objects_marked = major_collector.get_and_reset_num_major_objects_marked ();
        MONO_GC_CONCURRENT_START_END (GENERATION_OLD, num_objects_marked);
@@ -3481,7 +3492,10 @@ null_ephemerons_for_domain (MonoDomain *domain)
        while (current) {
                MonoObject *object = (MonoObject*)current->array;
 
-               if (object && !object->vtable) {
+               if (object)
+                       SGEN_ASSERT (0, object->vtable, "Can't have objects without vtables.");
+
+               if (object && object->vtable->domain == domain) {
                        EphemeronLinkNode *tmp = current;
 
                        if (prev)
@@ -3820,10 +3834,11 @@ scan_thread_data (void *start_nursery, void *end_nursery, gboolean precise, Gray
                        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);
                        continue;
                }
-               if (mono_thread_info_run_state (info) != STATE_RUNNING) {
-                       SGEN_LOG (3, "Skipping non-running thread %p, range: %p-%p, size: %td (state %d)", info, info->stack_start, info->stack_end, (char*)info->stack_end - (char*)info->stack_start, mono_thread_info_run_state (info));
+               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->info.thread_state);
                        continue;
                }
+               g_assert (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 ());
                if (gc_callbacks.thread_mark_func && !conservative_stack_mark) {
                        UserCopyOrMarkData data = { NULL, queue };
@@ -4616,6 +4631,12 @@ parse_double_in_interval (const char *env_var, const char *opt_name, const char
        return TRUE;
 }
 
+static gboolean
+thread_in_critical_region (SgenThreadInfo *info)
+{
+       return info->in_critical_region;
+}
+
 void
 mono_gc_base_init (void)
 {
@@ -4665,6 +4686,7 @@ mono_gc_base_init (void)
        cb.thread_unregister = sgen_thread_unregister;
        cb.thread_attach = sgen_thread_attach;
        cb.mono_method_is_critical = (gpointer)is_critical_method;
+       cb.mono_thread_in_critical_region = thread_in_critical_region;
 #ifndef HOST_WIN32
        cb.thread_exit = mono_gc_pthread_exit;
        cb.mono_gc_pthread_create = (gpointer)mono_gc_pthread_create;
@@ -5048,6 +5070,10 @@ mono_gc_base_init (void)
                                do_verify_nursery = TRUE;
                                sgen_set_use_managed_allocator (FALSE);
                                enable_nursery_canaries = TRUE;
+                       } else if (!strcmp (opt, "do-not-finalize")) {
+                               do_not_finalize = TRUE;
+                       } else if (!strcmp (opt, "log-finalizers")) {
+                               log_finalizers = TRUE;
                        } else if (!sgen_bridge_handle_gc_debug (opt)) {
                                sgen_env_var_error (MONO_GC_DEBUG_NAME, "Ignoring.", "Unknown option `%s`.", opt);
 
@@ -5078,6 +5104,8 @@ mono_gc_base_init (void)
                                fprintf (stderr, "  heap-dump=<filename>\n");
                                fprintf (stderr, "  binary-protocol=<filename>[:<file-size-limit>]\n");
                                fprintf (stderr, "  nursery-canaries\n");
+                               fprintf (stderr, "  do-not-finalize\n");
+                               fprintf (stderr, "  log-finalizers\n");
                                sgen_bridge_print_gc_debug_usage ();
                                fprintf (stderr, "\n");