[sgen] Do pinning of M&S blocks in one pass. Saves time and memory.
authorMark Probst <mark.probst@gmail.com>
Wed, 11 Feb 2015 20:55:58 +0000 (12:55 -0800)
committerMark Probst <mark.probst@gmail.com>
Mon, 23 Mar 2015 22:34:05 +0000 (15:34 -0700)
mono/metadata/sgen-gc.c
mono/metadata/sgen-gc.h
mono/metadata/sgen-marksweep.c

index 5bfdbb48ecc28dc1bc19d8ab69d39e19ebe7b586..2ec945d91ca79c00f4f375ce70da7878d3bdecdf 100644 (file)
@@ -2537,7 +2537,6 @@ major_copy_or_mark_from_roots (size_t *old_next_pin_slot, gboolean start_concurr
        SGEN_LOG (6, "Pinning from sections");
        /* first pass for the sections */
        sgen_find_section_pin_queue_start_end (nursery_section);
-       major_collector.find_pin_queue_start_ends (WORKERS_DISTRIBUTE_GRAY_QUEUE);
        /* identify possible pointers to the insize of large objects */
        SGEN_LOG (6, "Pinning from large objects");
        for (bigobj = los_object_list; bigobj; bigobj = bigobj->next) {
index d3e7151819efa03c094e549a8d25cd2daa2996d8..0a0d746c600a77d3a634de290273995c994373a8 100644 (file)
@@ -684,7 +684,6 @@ struct _SgenMajorCollector {
        void (*free_pinned_object) (char *obj, size_t size);
        void (*iterate_objects) (IterateObjectsFlags flags, IterateObjectCallbackFunc callback, void *data);
        void (*free_non_pinned_object) (char *obj, size_t size);
-       void (*find_pin_queue_start_ends) (SgenGrayQueue *queue);
        void (*pin_objects) (SgenGrayQueue *queue);
        void (*pin_major_object) (char *obj, SgenGrayQueue *queue);
        void (*scan_card_table) (gboolean mod_union, SgenGrayQueue *queue);
index 8f12c59a6392a81d0cd2e948dd32524afa596731..78a396825068d8f154f3a3536b10f325e0d2e62b 100644 (file)
@@ -82,8 +82,6 @@ struct _MSBlockInfo {
        unsigned int swept : 1;
        void ** volatile free_list;
        MSBlockInfo * volatile next_free;
-       size_t pin_queue_first_entry;
-       size_t pin_queue_last_entry;
        guint8 *cardtable_mod_union;
        mword mark_words [MS_NUM_MARK_WORDS];
 };
@@ -987,18 +985,18 @@ major_copy_or_mark_object_concurrent_canonical (void **ptr, SgenGrayQueue *queue
 }
 
 static void
-mark_pinned_objects_in_block (MSBlockInfo *block, SgenGrayQueue *queue)
+mark_pinned_objects_in_block (MSBlockInfo *block, size_t first_entry, size_t last_entry, SgenGrayQueue *queue)
 {
        void **entry, **end;
        int last_index = -1;
 
-       if (block->pin_queue_first_entry == block->pin_queue_last_entry)
+       if (first_entry == last_entry)
                return;
 
        block->has_pinned = TRUE;
 
-       entry = sgen_pinning_get_entry (block->pin_queue_first_entry);
-       end = sgen_pinning_get_entry (block->pin_queue_last_entry);
+       entry = sgen_pinning_get_entry (first_entry);
+       end = sgen_pinning_get_entry (last_entry);
 
        for (; entry < end; ++entry) {
                int index = MS_BLOCK_OBJ_INDEX (*entry, block);
@@ -1542,24 +1540,17 @@ major_free_swept_blocks (void)
        }
 }
 
-static void
-major_find_pin_queue_start_ends (SgenGrayQueue *queue)
-{
-       MSBlockInfo *block;
-
-       FOREACH_BLOCK (block) {
-               sgen_find_optimized_pin_queue_area (MS_BLOCK_FOR_BLOCK_INFO (block) + MS_BLOCK_SKIP, MS_BLOCK_FOR_BLOCK_INFO (block) + MS_BLOCK_SIZE,
-                               &block->pin_queue_first_entry, &block->pin_queue_last_entry);
-       } END_FOREACH_BLOCK;
-}
-
 static void
 major_pin_objects (SgenGrayQueue *queue)
 {
        MSBlockInfo *block;
 
        FOREACH_BLOCK (block) {
-               mark_pinned_objects_in_block (block, queue);
+               size_t first_entry, last_entry;
+               SGEN_ASSERT (0, block->swept, "All blocks must be swept when we're pinning.");
+               sgen_find_optimized_pin_queue_area (MS_BLOCK_FOR_BLOCK_INFO (block) + MS_BLOCK_SKIP, MS_BLOCK_FOR_BLOCK_INFO (block) + MS_BLOCK_SIZE,
+                               &first_entry, &last_entry);
+               mark_pinned_objects_in_block (block, first_entry, last_entry, queue);
        } END_FOREACH_BLOCK;
 }
 
@@ -1967,7 +1958,6 @@ sgen_marksweep_init_internal (SgenMajorCollector *collector, gboolean is_concurr
        collector->free_pinned_object = free_pinned_object;
        collector->iterate_objects = major_iterate_objects;
        collector->free_non_pinned_object = major_free_non_pinned_object;
-       collector->find_pin_queue_start_ends = major_find_pin_queue_start_ends;
        collector->pin_objects = major_pin_objects;
        collector->pin_major_object = pin_major_object;
        collector->scan_card_table = major_scan_card_table;