Introduce SgenObjectOperations that holds all copy/scan functions needed by a given...
authorRodrigo Kumpera <kumpera@gmail.com>
Wed, 4 Apr 2012 23:59:54 +0000 (20:59 -0300)
committerRodrigo Kumpera <kumpera@gmail.com>
Mon, 9 Apr 2012 19:52:22 +0000 (16:52 -0300)
mono/metadata/sgen-cardtable.c
mono/metadata/sgen-gc.c
mono/metadata/sgen-gc.h
mono/metadata/sgen-major-copy-object.h
mono/metadata/sgen-major-copying.c
mono/metadata/sgen-major-scan-object.h
mono/metadata/sgen-marksweep.c
mono/metadata/sgen-ssb.c

index d0b4cc5396e34b0a85ded7ee9d069911f4faf79a..a4c755e37efdfefe66bba42605d01d597544ce7c 100644 (file)
@@ -488,9 +488,6 @@ sgen_cardtable_scan_object (char *obj, mword block_obj_size, guint8 *cards, Sgen
 {
        MonoVTable *vt = (MonoVTable*)SGEN_LOAD_VTABLE (obj);
        MonoClass *klass = vt->klass;
-       CopyOrMarkObjectFunc copy_func = sgen_get_copy_object ();
-       ScanObjectFunc scan_object_func = sgen_get_minor_scan_object ();
-       ScanVTypeFunc scan_vtype_func = sgen_get_minor_scan_vtype ();
 
        HEAVY_STAT (++large_objects);
 
@@ -556,9 +553,13 @@ LOOP_HEAD:
 
                        elem = (char*)mono_array_addr_with_size ((MonoArray*)obj, elem_size, index);
                        if (klass->element_class->valuetype) {
+                               ScanVTypeFunc scan_vtype_func = sgen_get_current_object_ops ()->scan_vtype;
+
                                for (; elem < card_end; elem += elem_size)
                                        scan_vtype_func (elem, desc, queue);
                        } else {
+                               CopyOrMarkObjectFunc copy_func = sgen_get_current_object_ops ()->copy_or_mark_object;
+
                                HEAVY_STAT (++los_array_cards);
                                for (; elem < card_end; elem += SIZEOF_VOID_P) {
                                        gpointer new, old = *(gpointer*)elem;
@@ -587,9 +588,9 @@ LOOP_HEAD:
                HEAVY_STAT (++bloby_objects);
                if (cards) {
                        if (sgen_card_table_is_range_marked (cards, (mword)obj, block_obj_size))
-                               scan_object_func (obj, queue);
+                               sgen_get_current_object_ops ()->scan_object (obj, queue);
                } else if (sgen_card_table_region_begin_scanning ((mword)obj, block_obj_size)) {
-                       scan_object_func (obj, queue);
+                       sgen_get_current_object_ops ()->scan_object (obj, queue);
                }
        }
 }
index 6c1566f4d2ad5ff0c055d1eedaa6f2968dfc19c1..a4e1ab2456b6e20b7ec5ee8c11a3bc54763347e4 100644 (file)
@@ -663,6 +663,7 @@ static int mark_ephemerons_in_range (CopyOrMarkObjectFunc copy_func, char *start
 static void clear_unreachable_ephemerons (CopyOrMarkObjectFunc copy_func, char *start, char *end, GrayQueue *queue);
 static void null_ephemerons_for_domain (MonoDomain *domain);
 
+SgenObjectOperations current_object_ops;
 SgenMajorCollector major_collector;
 static GrayQueue gray_queue;
 
@@ -1200,10 +1201,9 @@ gboolean
 sgen_drain_gray_stack (GrayQueue *queue, int max_objs)
 {
        char *obj;
+       ScanObjectFunc scan_func = current_object_ops.scan_object;
 
-       if (current_collection_generation == GENERATION_NURSERY) {
-               ScanObjectFunc scan_func = sgen_get_minor_scan_object ();
-
+       if (max_objs == -1) {
                for (;;) {
                        GRAY_OBJECT_DEQUEUE (queue, obj);
                        if (!obj)
@@ -1214,16 +1214,13 @@ sgen_drain_gray_stack (GrayQueue *queue, int max_objs)
        } else {
                int i;
 
-               if (sgen_collection_is_parallel () && sgen_workers_is_distributed_queue (queue))
-                       return TRUE;
-
                do {
                        for (i = 0; i != max_objs; ++i) {
                                GRAY_OBJECT_DEQUEUE (queue, obj);
                                if (!obj)
                                        return TRUE;
                                DEBUG (9, fprintf (gc_debug_file, "Precise gray object scan %p (%s)\n", obj, safe_name (obj)));
-                               major_collector.major_scan_object (obj, queue);
+                               scan_func (obj, queue);
                        }
                } while (max_objs < 0);
                return FALSE;
@@ -1888,40 +1885,11 @@ bridge_process (void)
        sgen_bridge_processing_finish ();
 }
 
-CopyOrMarkObjectFunc
-sgen_get_copy_object (void)
-{
-       if (current_collection_generation == GENERATION_NURSERY) {
-               if (sgen_collection_is_parallel ())
-                       return major_collector.copy_object;
-               else
-                       return major_collector.nopar_copy_object;
-       } else {
-               return major_collector.copy_or_mark_object;
-       }
-}
-
-ScanObjectFunc
-sgen_get_minor_scan_object (void)
-{
-       g_assert (current_collection_generation == GENERATION_NURSERY);
-
-       if (sgen_collection_is_parallel ())
-               return major_collector.minor_scan_object;
-       else
-               return major_collector.nopar_minor_scan_object;
+SgenObjectOperations *
+sgen_get_current_object_ops (void){
+       return &current_object_ops;
 }
 
-ScanVTypeFunc
-sgen_get_minor_scan_vtype (void)
-{
-       g_assert (current_collection_generation == GENERATION_NURSERY);
-
-       if (sgen_collection_is_parallel ())
-               return major_collector.minor_scan_vtype;
-       else
-               return major_collector.nopar_minor_scan_vtype;
-}
 
 static void
 finish_gray_stack (char *start_addr, char *end_addr, int generation, GrayQueue *queue)
@@ -1929,7 +1897,7 @@ finish_gray_stack (char *start_addr, char *end_addr, int generation, GrayQueue *
        TV_DECLARE (atv);
        TV_DECLARE (btv);
        int done_with_ephemerons, ephemeron_rounds = 0;
-       CopyOrMarkObjectFunc copy_func = sgen_get_copy_object ();
+       CopyOrMarkObjectFunc copy_func = current_object_ops.copy_or_mark_object;
 
        /*
         * We copied all the reachable objects. Now it's the time to copy
@@ -2406,12 +2374,6 @@ sgen_collection_is_parallel (void)
        }
 }
 
-gboolean
-sgen_nursery_collection_is_parallel (void)
-{
-       return nursery_collection_is_parallel;
-}
-
 typedef struct
 {
        char *heap_start;
@@ -2470,7 +2432,7 @@ job_scan_finalizer_entries (WorkerData *worker_data, void *job_data_untyped)
 {
        ScanFinalizerEntriesJobData *job_data = job_data_untyped;
 
-       scan_finalizer_entries (sgen_get_copy_object (),
+       scan_finalizer_entries (current_object_ops.copy_or_mark_object,
                        job_data->list,
                        sgen_workers_get_job_gray_queue (worker_data));
 }
@@ -2556,7 +2518,11 @@ collect_nursery (size_t requested_size)
        mono_perfcounters->gc_collections0++;
 
        current_collection_generation = GENERATION_NURSERY;
-
+       if (sgen_collection_is_parallel ())
+               current_object_ops = major_collector.par_minor_ops;
+       else
+               current_object_ops = major_collector.minor_ops;
+       
        reset_pinned_from_failed_allocation ();
 
        binary_protocol_collection (GENERATION_NURSERY);
@@ -2649,13 +2615,13 @@ collect_nursery (size_t requested_size)
        time_minor_scan_pinned += TV_ELAPSED (btv, atv);
 
        /* registered roots, this includes static fields */
-       scrrjd_normal.func = sgen_collection_is_parallel () ? major_collector.copy_object : major_collector.nopar_copy_object;
+       scrrjd_normal.func = current_object_ops.copy_or_mark_object;
        scrrjd_normal.heap_start = sgen_get_nursery_start ();
        scrrjd_normal.heap_end = nursery_next;
        scrrjd_normal.root_type = ROOT_TYPE_NORMAL;
        sgen_workers_enqueue_job (job_scan_from_registered_roots, &scrrjd_normal);
 
-       scrrjd_wbarrier.func = sgen_collection_is_parallel () ? major_collector.copy_object : major_collector.nopar_copy_object;
+       scrrjd_wbarrier.func = current_object_ops.copy_or_mark_object;
        scrrjd_wbarrier.heap_start = sgen_get_nursery_start ();
        scrrjd_wbarrier.heap_end = nursery_next;
        scrrjd_wbarrier.root_type = ROOT_TYPE_WBARRIER;
@@ -2798,6 +2764,8 @@ major_do_collection (const char *reason)
 
        mono_perfcounters->gc_collections1++;
 
+       current_object_ops = major_collector.major_ops;
+
        reset_pinned_from_failed_allocation ();
 
        last_collection_old_num_major_sections = major_collector.get_num_major_sections ();
@@ -2922,13 +2890,13 @@ major_do_collection (const char *reason)
        time_major_scan_pinned += TV_ELAPSED (btv, atv);
 
        /* registered roots, this includes static fields */
-       scrrjd_normal.func = major_collector.copy_or_mark_object;
+       scrrjd_normal.func = current_object_ops.copy_or_mark_object;
        scrrjd_normal.heap_start = heap_start;
        scrrjd_normal.heap_end = heap_end;
        scrrjd_normal.root_type = ROOT_TYPE_NORMAL;
        sgen_workers_enqueue_job (job_scan_from_registered_roots, &scrrjd_normal);
 
-       scrrjd_wbarrier.func = major_collector.copy_or_mark_object;
+       scrrjd_wbarrier.func = current_object_ops.copy_or_mark_object;
        scrrjd_wbarrier.heap_start = heap_start;
        scrrjd_wbarrier.heap_end = heap_end;
        scrrjd_wbarrier.root_type = ROOT_TYPE_WBARRIER;
@@ -3855,15 +3823,7 @@ void*
 mono_gc_scan_object (void *obj)
 {
        UserCopyOrMarkData *data = mono_native_tls_get_value (user_copy_or_mark_key);
-
-       if (current_collection_generation == GENERATION_NURSERY) {
-               if (sgen_collection_is_parallel ())
-                       major_collector.copy_object (&obj, data->queue);
-               else
-                       major_collector.nopar_copy_object (&obj, data->queue);
-       } else {
-               major_collector.copy_or_mark_object (&obj, data->queue);
-       }
+       current_object_ops.copy_or_mark_object (&obj, data->queue);
        return obj;
 }
 
index 9a831eca822b7bc2851fadd612950fef9e641b6a..9450f3d58a668ffbc89a40b7f80a9cc75fefcbcc 100644 (file)
@@ -339,10 +339,6 @@ typedef struct {
  */
 #define SGEN_LOAD_VTABLE(addr) ((*(mword*)(addr)) & ~SGEN_VTABLE_BITS_MASK)
 
-typedef void (*CopyOrMarkObjectFunc) (void**, SgenGrayQueue*);
-typedef void (*ScanObjectFunc) (char*, SgenGrayQueue*);
-typedef void (*ScanVTypeFunc) (char*, mword desc, SgenGrayQueue*);
-
 #if SGEN_MAX_DEBUG_LEVEL >= 9
 #define GRAY_OBJECT_ENQUEUE sgen_gray_object_enqueue
 #define GRAY_OBJECT_DEQUEUE(queue,o) ((o) = sgen_gray_object_dequeue ((queue)))
@@ -488,13 +484,21 @@ void sgen_pin_stats_print_class_stats (void);
 void sgen_sort_addresses (void **array, int size) MONO_INTERNAL;
 void sgen_add_to_global_remset (gpointer ptr) MONO_INTERNAL;
 
+typedef void (*CopyOrMarkObjectFunc) (void**, SgenGrayQueue*);
+typedef void (*ScanObjectFunc) (char*, SgenGrayQueue*);
+typedef void (*ScanVTypeFunc) (char*, mword desc, SgenGrayQueue*);
+
 int sgen_get_current_collection_generation (void) MONO_INTERNAL;
-gboolean sgen_nursery_collection_is_parallel (void) MONO_INTERNAL;
-CopyOrMarkObjectFunc sgen_get_copy_object (void) MONO_INTERNAL;
-ScanObjectFunc sgen_get_minor_scan_object (void) MONO_INTERNAL;
-ScanVTypeFunc sgen_get_minor_scan_vtype (void) MONO_INTERNAL;
 gboolean sgen_collection_is_parallel (void) MONO_INTERNAL;
 
+typedef struct {
+       CopyOrMarkObjectFunc copy_or_mark_object;
+       ScanObjectFunc scan_object;
+       ScanVTypeFunc scan_vtype;
+       /*FIXME add allocation function? */
+} SgenObjectOperations;
+
+SgenObjectOperations *sgen_get_current_object_ops (void) MONO_INTERNAL;
 
 typedef void (*sgen_cardtable_block_callback) (mword start, mword size);
 void sgen_major_collector_iterate_live_block_ranges (sgen_cardtable_block_callback callback) MONO_INTERNAL;
@@ -515,14 +519,11 @@ struct _SgenMajorCollector {
        gboolean (*is_object_live) (char *obj);
        void* (*alloc_small_pinned_obj) (size_t size, gboolean has_references);
        void* (*alloc_degraded) (MonoVTable *vtable, size_t size);
-       void (*copy_or_mark_object) (void **obj_slot, SgenGrayQueue *queue);
-       void (*minor_scan_object) (char *start, SgenGrayQueue *queue);
-       void (*nopar_minor_scan_object) (char *start, SgenGrayQueue *queue);
-       void (*minor_scan_vtype) (char *start, mword desc, SgenGrayQueue *queue);
-       void (*nopar_minor_scan_vtype) (char *start, mword desc, SgenGrayQueue *queue);
-       void (*major_scan_object) (char *start, SgenGrayQueue *queue);
-       void (*copy_object) (void **obj_slot, SgenGrayQueue *queue);
-       void (*nopar_copy_object) (void **obj_slot, SgenGrayQueue *queue);
+
+       SgenObjectOperations major_ops;
+       SgenObjectOperations minor_ops;
+       SgenObjectOperations par_minor_ops;
+
        void* (*alloc_object) (int size, gboolean has_references);
        void* (*par_alloc_object) (int size, gboolean has_references);
        void (*free_pinned_object) (char *obj, size_t size);
index 3f37d5c41d28eff5b02b28afb50e39af34d46f7c..96dae15d935e32e86a2482def572956cc6a09a55 100644 (file)
@@ -253,6 +253,6 @@ copy_object (void **obj_slot, SgenGrayQueue *queue)
 #endif
 
 #define FILL_COLLECTOR_COPY_OBJECT(collector)  do {                    \
-               (collector)->copy_object = copy_object;                 \
-               (collector)->nopar_copy_object = nopar_copy_object;     \
+               (collector)->minor_ops.copy_or_mark_object = nopar_copy_object;                 \
+               (collector)->par_minor_ops.copy_or_mark_object = copy_object;   \
        } while (0)
index e5028586675d63d25a7861ab7af54555223d0e89..fdf7f4532f709d24b39c2f7e96dd2637b4835069 100644 (file)
@@ -664,7 +664,6 @@ sgen_copying_init (SgenMajorCollector *collector)
        collector->is_object_live = major_is_object_live;
        collector->alloc_small_pinned_obj = major_alloc_small_pinned_obj;
        collector->alloc_degraded = major_alloc_degraded;
-       collector->copy_or_mark_object = major_copy_or_mark_object;
        collector->alloc_object = major_alloc_object;
        collector->free_pinned_object = free_pinned_object;
        collector->iterate_objects = major_iterate_objects;
@@ -686,6 +685,7 @@ sgen_copying_init (SgenMajorCollector *collector)
        collector->handle_gc_param = NULL;
        collector->print_gc_param_usage = NULL;
 
+       collector->major_ops.copy_or_mark_object = major_copy_or_mark_object;
        FILL_COLLECTOR_COPY_OBJECT (collector);
        FILL_COLLECTOR_SCAN_OBJECT (collector);
 }
index c5e3021a6ff678ec0648b30ddabd644a2f5f766e..d056512b23798d025833ebd5c965e7a7045dd65c 100644 (file)
@@ -127,9 +127,9 @@ major_scan_object (char *start, SgenGrayQueue *queue)
 }
 
 #define FILL_COLLECTOR_SCAN_OBJECT(collector)  do {                    \
-               (collector)->major_scan_object = major_scan_object;     \
-               (collector)->minor_scan_object = minor_scan_object;     \
-               (collector)->nopar_minor_scan_object = nopar_minor_scan_object; \
-               (collector)->minor_scan_vtype = minor_scan_vtype;       \
-               (collector)->nopar_minor_scan_vtype = nopar_minor_scan_vtype; \
+               (collector)->major_ops.scan_object = major_scan_object; \
+               (collector)->par_minor_ops.scan_object = minor_scan_object;     \
+               (collector)->minor_ops.scan_object = nopar_minor_scan_object;   \
+               (collector)->par_minor_ops.scan_vtype = minor_scan_vtype;       \
+               (collector)->minor_ops.scan_vtype = nopar_minor_scan_vtype; \
        } while (0)
index 03f95ec25285f2eafffb23a8056b34056e953a7e..59fbe2bd53865b2810e4cd158f75fd276bfd6dab 100644 (file)
@@ -567,7 +567,7 @@ ms_alloc_block (int size_index, gboolean pinned, gboolean has_references)
        info->pinned = pinned;
        info->has_references = has_references;
        info->has_pinned = pinned;
-       info->is_to_space = (sgen_get_current_collection_generation () == GENERATION_OLD);
+       info->is_to_space = (sgen_get_current_collection_generation () == GENERATION_OLD); /*FIXME WHY??? */
 #ifndef FIXED_HEAP
        info->block = ms_get_empty_block ();
 
@@ -1824,6 +1824,7 @@ static void
 major_scan_card_table (SgenGrayQueue *queue)
 {
        MSBlockInfo *block;
+       ScanObjectFunc scan_func = sgen_get_current_object_ops ()->scan_object;
 
        FOREACH_BLOCK (block) {
                int block_obj_size;
@@ -1863,7 +1864,6 @@ major_scan_card_table (SgenGrayQueue *queue)
                                obj += block_obj_size;
                        }
                } else {
-                       ScanObjectFunc scan_func = sgen_get_minor_scan_object ();
                        guint8 *card_data, *card_base;
                        guint8 *card_data_end;
 
@@ -2072,7 +2072,7 @@ sgen_marksweep_init
        collector->is_object_live = major_is_object_live;
        collector->alloc_small_pinned_obj = major_alloc_small_pinned_obj;
        collector->alloc_degraded = major_alloc_degraded;
-       collector->copy_or_mark_object = major_copy_or_mark_object;
+
        collector->alloc_object = major_alloc_object;
 #ifdef SGEN_PARALLEL_MARK
        collector->par_alloc_object = major_par_alloc_object;
@@ -2105,6 +2105,8 @@ sgen_marksweep_init
        collector->is_worker_thread = major_is_worker_thread;
        collector->post_param_init = post_param_init;
 
+       /* FIXME this macro mess */
+       collector->major_ops.copy_or_mark_object = major_copy_or_mark_object;
        FILL_COLLECTOR_COPY_OBJECT (collector);
        FILL_COLLECTOR_SCAN_OBJECT (collector);
 
index b1afc5e709d7e5f06c5df9602f2443ada5e64056..75082c4a1718188c46a80a29665368fe196e7987 100644 (file)
@@ -403,6 +403,8 @@ handle_remset (mword *p, void *start_nursery, void *end_nursery, gboolean global
        mword count;
        mword desc;
 
+       ScanVTypeFunc scan_vtype = sgen_get_current_object_ops ()->scan_vtype;
+
        if (global)
                HEAVY_STAT (++stat_global_remsets_processed);
        else
@@ -415,7 +417,8 @@ handle_remset (mword *p, void *start_nursery, void *end_nursery, gboolean global
                //__builtin_prefetch (ptr);
                if (((void*)ptr < start_nursery || (void*)ptr >= end_nursery)) {
                        gpointer old = *ptr;
-                       major_collector.copy_object (ptr, queue);
+
+                       sgen_get_current_object_ops ()->copy_or_mark_object (ptr, queue);
                        DEBUG (9, fprintf (gc_debug_file, "Overwrote remset at %p with %p\n", ptr, *ptr));
                        if (old)
                                binary_protocol_ptr_update (ptr, old, *ptr, (gpointer)LOAD_VTABLE (*ptr), sgen_safe_object_get_size (*ptr));
@@ -431,27 +434,29 @@ handle_remset (mword *p, void *start_nursery, void *end_nursery, gboolean global
                        DEBUG (9, fprintf (gc_debug_file, "Skipping remset at %p holding %p\n", ptr, *ptr));
                }
                return p + 1;
-       case REMSET_RANGE:
+       case REMSET_RANGE: {
+               CopyOrMarkObjectFunc copy_func = sgen_get_current_object_ops ()->copy_or_mark_object;
+
                ptr = (void**)(*p & ~REMSET_TYPE_MASK);
                if (((void*)ptr >= start_nursery && (void*)ptr < end_nursery))
                        return p + 2;
                count = p [1];
                while (count-- > 0) {
-                       major_collector.copy_object (ptr, queue);
+                       copy_func (ptr, queue);
                        DEBUG (9, fprintf (gc_debug_file, "Overwrote remset at %p with %p (count: %d)\n", ptr, *ptr, (int)count));
                        if (!global && *ptr >= start_nursery && *ptr < end_nursery)
                                sgen_add_to_global_remset (ptr);
                        ++ptr;
                }
                return p + 2;
+       }
        case REMSET_OBJECT:
                ptr = (void**)(*p & ~REMSET_TYPE_MASK);
                if (((void*)ptr >= start_nursery && (void*)ptr < end_nursery))
                        return p + 1;
-               sgen_get_minor_scan_object () ((char*)ptr, queue);
+               sgen_get_current_object_ops ()->scan_object ((char*)ptr, queue);
                return p + 1;
        case REMSET_VTYPE: {
-               ScanVTypeFunc scan_vtype = sgen_get_minor_scan_vtype ();
                size_t skip_size;
 
                ptr = (void**)(*p & ~REMSET_TYPE_MASK);
@@ -461,7 +466,7 @@ handle_remset (mword *p, void *start_nursery, void *end_nursery, gboolean global
                count = p [2];
                skip_size = p [3];
                while (count-- > 0) {
-                       scan_vtype ((char*)ptr, desc, queue);
+                       sgen_get_current_object_ops ()->scan_vtype ((char*)ptr, desc, queue);
                        ptr = (void**)((char*)ptr + skip_size);
                }
                return p + 4;