[sgen] Add scan/copy context for the simple parallel nursery
authorVlad Brezae <brezaevlad@gmail.com>
Wed, 1 Mar 2017 00:58:01 +0000 (02:58 +0200)
committerVlad Brezae <brezaevlad@gmail.com>
Thu, 30 Mar 2017 11:13:24 +0000 (14:13 +0300)
mono/sgen/sgen-gc.h
mono/sgen/sgen-minor-copy-object.h
mono/sgen/sgen-minor-scan-object.h
mono/sgen/sgen-simple-nursery.c

index f90c44469454e6bc50850a031464269296f61c8d..3a00ce3c7365dc3909391c86e108daba8ec0b01e 100644 (file)
@@ -565,6 +565,7 @@ typedef struct {
 
        SgenObjectOperations serial_ops;
        SgenObjectOperations serial_ops_with_concurrent_major;
+       SgenObjectOperations parallel_ops;
 
        void (*prepare_to_space) (char *to_space_bitmap, size_t space_bitmap_size);
        void (*clear_fragments) (void);
index 9ba0d129522e677b98bf87768d72b09c1e2fc2c4..3ad10aac4447fb2608803abd67bd71b77cf8441d 100644 (file)
 
 #if defined(SGEN_SIMPLE_NURSERY)
 
+#ifdef SGEN_SIMPLE_PAR_NURSERY
+/* Not supported with concurrent major yet */
+#define SERIAL_COPY_OBJECT simple_par_nursery_copy_object
+#define SERIAL_COPY_OBJECT_FROM_OBJ simple_par_nursery_copy_object_from_obj
+#else
 #ifdef SGEN_CONCURRENT_MAJOR
 #define SERIAL_COPY_OBJECT simple_nursery_serial_with_concurrent_major_copy_object
 #define SERIAL_COPY_OBJECT_FROM_OBJ simple_nursery_serial_with_concurrent_major_copy_object_from_obj
@@ -21,6 +26,7 @@
 #define SERIAL_COPY_OBJECT simple_nursery_serial_copy_object
 #define SERIAL_COPY_OBJECT_FROM_OBJ simple_nursery_serial_copy_object_from_obj
 #endif
+#endif
 
 #elif defined (SGEN_SPLIT_NURSERY)
 
@@ -108,7 +114,11 @@ SERIAL_COPY_OBJECT (GCObject **obj_slot, SgenGrayQueue *queue)
 
        HEAVY_STAT (++stat_objects_copied_nursery);
 
+#ifdef SGEN_SIMPLE_PAR_NURSERY
+       copy = copy_object_no_checks_par (obj, queue);
+#else
        copy = copy_object_no_checks (obj, queue);
+#endif
        SGEN_UPDATE_REFERENCE (obj_slot, copy);
 }
 
@@ -214,7 +224,11 @@ SERIAL_COPY_OBJECT_FROM_OBJ (GCObject **obj_slot, SgenGrayQueue *queue)
 
        HEAVY_STAT (++stat_objects_copied_nursery);
 
+#ifdef SGEN_SIMPLE_PAR_NURSERY
+       copy = copy_object_no_checks_par (obj, queue);
+#else
        copy = copy_object_no_checks (obj, queue);
+#endif
 #ifdef SGEN_CONCURRENT_MAJOR
        /*
         * If an object is evacuated to the major heap and a reference to it, from the major
index aadfe068e24f401bf99510dcebda4595031c6b91..b92d309f4ec1228d02086deb5d856902459c94cc 100644 (file)
@@ -18,6 +18,12 @@ extern guint64 stat_scan_object_called_nursery;
 
 #if defined(SGEN_SIMPLE_NURSERY)
 
+#ifdef SGEN_SIMPLE_PAR_NURSERY
+#define SERIAL_SCAN_OBJECT simple_par_nursery_serial_scan_object
+#define SERIAL_SCAN_VTYPE simple_par_nursery_serial_scan_vtype
+#define SERIAL_SCAN_PTR_FIELD simple_par_nursery_serial_scan_ptr_field
+#define SERIAL_DRAIN_GRAY_STACK simple_par_nursery_serial_drain_gray_stack
+#else
 #ifdef SGEN_CONCURRENT_MAJOR
 #define SERIAL_SCAN_OBJECT simple_nursery_serial_with_concurrent_major_scan_object
 #define SERIAL_SCAN_VTYPE simple_nursery_serial_with_concurrent_major_scan_vtype
@@ -29,6 +35,7 @@ extern guint64 stat_scan_object_called_nursery;
 #define SERIAL_SCAN_PTR_FIELD simple_nursery_serial_scan_ptr_field
 #define SERIAL_DRAIN_GRAY_STACK simple_nursery_serial_drain_gray_stack
 #endif
+#endif
 
 #elif defined (SGEN_SPLIT_NURSERY)
 
@@ -104,16 +111,31 @@ SERIAL_SCAN_PTR_FIELD (GCObject *full_object, GCObject **ptr, SgenGrayQueue *que
 static gboolean
 SERIAL_DRAIN_GRAY_STACK (SgenGrayQueue *queue)
 {
-        for (;;) {
-                GCObject *obj;
-                SgenDescriptor desc;
+#ifdef SGEN_SIMPLE_PAR_NURSERY
+       int i;
+       /*
+        * We do bounded iteration so we can switch to optimized context
+        * when we are the last worker remaining.
+        */
+       for (i = 0; i < 32; i++) {
+#else
+       for (;;) {
+#endif
+               GCObject *obj;
+               SgenDescriptor desc;
+
+#ifdef SGEN_SIMPLE_PAR_NURSERY
+               GRAY_OBJECT_DEQUEUE_PARALLEL (queue, &obj, &desc);
+#else
+               GRAY_OBJECT_DEQUEUE_SERIAL (queue, &obj, &desc);
+#endif
+               if (!obj)
+                       return TRUE;
 
-                GRAY_OBJECT_DEQUEUE_SERIAL (queue, &obj, &desc);
-                if (!obj)
-                        return TRUE;
+               SERIAL_SCAN_OBJECT (obj, desc, queue);
+       }
 
-                SERIAL_SCAN_OBJECT (obj, desc, queue);
-        }
+       return FALSE;
 }
 
 #define FILL_MINOR_COLLECTOR_SCAN_OBJECT(ops)  do {                    \
index 2222a12d75a94b27c11d614b6028dd0895f19834..4234559e9e8cec8ced5617f60fe64e9e9e862c38 100644 (file)
@@ -66,6 +66,7 @@ init_nursery (SgenFragmentAllocator *allocator, char *start, char *end)
 #define collector_pin_object(obj, queue) sgen_pin_object (obj, queue);
 #define COLLECTOR_SERIAL_ALLOC_FOR_PROMOTION alloc_for_promotion
 
+#define COPY_OR_MARK_PARALLEL
 #include "sgen-copy-object.h"
 
 #define SGEN_SIMPLE_NURSERY
@@ -80,6 +81,19 @@ fill_serial_ops (SgenObjectOperations *ops)
        FILL_MINOR_COLLECTOR_SCAN_OBJECT (ops);
 }
 
+#define SGEN_SIMPLE_PAR_NURSERY
+
+#include "sgen-minor-copy-object.h"
+#include "sgen-minor-scan-object.h"
+
+static void
+fill_parallel_ops (SgenObjectOperations *ops)
+{
+       ops->copy_or_mark_object = SERIAL_COPY_OBJECT;
+       FILL_MINOR_COLLECTOR_SCAN_OBJECT (ops);
+}
+
+#undef SGEN_SIMPLE_PAR_NURSERY
 #define SGEN_CONCURRENT_MAJOR
 
 #include "sgen-minor-copy-object.h"
@@ -109,6 +123,7 @@ sgen_simple_nursery_init (SgenMinorCollector *collector, gboolean parallel)
 
        fill_serial_ops (&collector->serial_ops);
        fill_serial_with_concurrent_major_ops (&collector->serial_ops_with_concurrent_major);
+       fill_parallel_ops (&collector->parallel_ops);
 }