[sgen] Report roots from togglerefs (mono/mono#17063)
authorVlad Brezae <brezaevlad@gmail.com>
Thu, 26 Sep 2019 19:38:59 +0000 (22:38 +0300)
committerGitHub <noreply@github.com>
Thu, 26 Sep 2019 19:38:59 +0000 (22:38 +0300)
Commit migrated from https://github.com/mono/mono/commit/bada36245443d57428e4048670f709d57b45cd69

src/mono/mono/metadata/mono-gc.h
src/mono/mono/metadata/sgen-mono.c
src/mono/mono/metadata/sgen-toggleref.c
src/mono/mono/sgen/sgen-client.h

index 247e32e..86111ac 100644 (file)
@@ -96,6 +96,10 @@ typedef enum {
         * Roots in the ephemeron arrays. This is a pseudo-root.
         */
        MONO_ROOT_SOURCE_EPHEMERON = 15,
+       /**
+        * Roots in the toggleref arrays. This is a pseudo-root.
+        */
+       MONO_ROOT_SOURCE_TOGGLEREF = 16,
 } MonoGCRootSource;
 
 typedef enum {
index dc8dce0..a023d60 100644 (file)
@@ -1456,6 +1456,7 @@ mono_gc_set_string_length (MonoString *str, gint32 new_length)
 #define SPECIAL_ADDRESS_FIN_QUEUE ((mono_byte*)1)
 #define SPECIAL_ADDRESS_CRIT_FIN_QUEUE ((mono_byte*)2)
 #define SPECIAL_ADDRESS_EPHEMERON ((mono_byte*)3)
+#define SPECIAL_ADDRESS_TOGGLEREF ((mono_byte*)4)
 
 typedef struct {
        int count;              /* must be the first field */
@@ -1879,6 +1880,20 @@ report_ephemeron_roots (void)
 }
 
 static void
+report_toggleref_root (MonoObject* obj, gpointer data)
+{
+       report_gc_root ((GCRootReport*)data, SPECIAL_ADDRESS_TOGGLEREF, obj);
+}
+
+static void
+report_toggleref_roots (void)
+{
+       GCRootReport report = { 0 };
+       sgen_foreach_toggleref_root (report_toggleref_root, &report);
+       notify_gc_roots (&report);
+}
+
+static void
 sgen_report_all_roots (SgenPointerQueue *fin_ready_queue, SgenPointerQueue *critical_fin_queue)
 {
        if (!MONO_PROFILER_ENABLED (gc_roots))
@@ -1886,6 +1901,7 @@ sgen_report_all_roots (SgenPointerQueue *fin_ready_queue, SgenPointerQueue *crit
 
        report_registered_roots ();
        report_ephemeron_roots ();
+       report_toggleref_roots ();
        report_pin_queue ();
        report_finalizer_roots_from_queue (fin_ready_queue, SPECIAL_ADDRESS_FIN_QUEUE);
        report_finalizer_roots_from_queue (critical_fin_queue, SPECIAL_ADDRESS_CRIT_FIN_QUEUE);
@@ -3087,6 +3103,7 @@ sgen_client_binary_protocol_collection_begin (int minor_gc_count, int generation
                MONO_PROFILER_RAISE (gc_root_register, (SPECIAL_ADDRESS_FIN_QUEUE, 1, MONO_ROOT_SOURCE_FINALIZER_QUEUE, NULL, "Finalizer Queue"));
                MONO_PROFILER_RAISE (gc_root_register, (SPECIAL_ADDRESS_CRIT_FIN_QUEUE, 1, MONO_ROOT_SOURCE_FINALIZER_QUEUE, NULL, "Finalizer Queue (Critical)"));
                MONO_PROFILER_RAISE (gc_root_register, (SPECIAL_ADDRESS_EPHEMERON, 1, MONO_ROOT_SOURCE_EPHEMERON, NULL, "Ephemerons"));
+               MONO_PROFILER_RAISE (gc_root_register, (SPECIAL_ADDRESS_TOGGLEREF, 1, MONO_ROOT_SOURCE_TOGGLEREF, NULL, "ToggleRefs"));
        }
 
 #ifndef DISABLE_PERFCOUNTERS
index 09f5cfa..3fa53bd 100644 (file)
@@ -101,6 +101,16 @@ void sgen_client_mark_togglerefs (char *start, char *end, ScanCopyContext ctx)
        sgen_drain_gray_stack (ctx);
 }
 
+void
+sgen_foreach_toggleref_root (void (*callback)(MonoObject*, gpointer), gpointer data)
+{
+       int i;
+       for (i = 0; i < toggleref_array_size; ++i) {
+               if (toggleref_array [i].strong_ref)
+                       callback (toggleref_array [i].strong_ref, data);
+       }
+}
+
 void sgen_client_clear_togglerefs (char *start, char *end, ScanCopyContext ctx)
 {
        CopyOrMarkObjectFunc copy_func = ctx.ops->copy_or_mark_object;
index 512e312..53a1a43 100644 (file)
@@ -212,6 +212,7 @@ void sgen_client_bridge_register_finalized_object (GCObject *object);
  */
 void sgen_client_mark_togglerefs (char *start, char *end, ScanCopyContext ctx);
 void sgen_client_clear_togglerefs (char *start, char *end, ScanCopyContext ctx);
+void sgen_foreach_toggleref_root (void (*callback)(MonoObject*, gpointer), gpointer data);
 
 /*
  * Called to handle `MONO_GC_PARAMS` and `MONO_GC_DEBUG` options.  The `handle` functions