From: Vlad Brezae Date: Wed, 1 Mar 2017 00:58:01 +0000 (+0200) Subject: [sgen] Add scan/copy context for the simple parallel nursery X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=mono.git;a=commitdiff_plain;h=eee846a77f481adf49d233e374734aebeab9e335 [sgen] Add scan/copy context for the simple parallel nursery --- diff --git a/mono/sgen/sgen-gc.h b/mono/sgen/sgen-gc.h index f90c4446945..3a00ce3c736 100644 --- a/mono/sgen/sgen-gc.h +++ b/mono/sgen/sgen-gc.h @@ -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); diff --git a/mono/sgen/sgen-minor-copy-object.h b/mono/sgen/sgen-minor-copy-object.h index 9ba0d129522..3ad10aac444 100644 --- a/mono/sgen/sgen-minor-copy-object.h +++ b/mono/sgen/sgen-minor-copy-object.h @@ -14,6 +14,11 @@ #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 diff --git a/mono/sgen/sgen-minor-scan-object.h b/mono/sgen/sgen-minor-scan-object.h index aadfe068e24..b92d309f4ec 100644 --- a/mono/sgen/sgen-minor-scan-object.h +++ b/mono/sgen/sgen-minor-scan-object.h @@ -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 { \ diff --git a/mono/sgen/sgen-simple-nursery.c b/mono/sgen/sgen-simple-nursery.c index 2222a12d75a..4234559e9e8 100644 --- a/mono/sgen/sgen-simple-nursery.c +++ b/mono/sgen/sgen-simple-nursery.c @@ -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); }