From: Vlad Brezae Date: Thu, 8 Sep 2016 23:54:48 +0000 (+0300) Subject: Merge pull request #3528 from BrzVlad/fix-sgen-check-before-collections X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=3fd54893bc792eee42164bfb605b418105a92f92;hp=668ee608ebba8031ea189dc050470e49499bbc63;p=mono.git Merge pull request #3528 from BrzVlad/fix-sgen-check-before-collections [sgen] Fix sgen debug flags --- diff --git a/mono/sgen/sgen-debug.c b/mono/sgen/sgen-debug.c index f073dc74064..cb2fbb7f7c6 100644 --- a/mono/sgen/sgen-debug.c +++ b/mono/sgen/sgen-debug.c @@ -216,7 +216,7 @@ is_major_or_los_object_marked (GCObject *obj) #undef HANDLE_PTR #define HANDLE_PTR(ptr,obj) do { \ if (*(ptr) && !sgen_ptr_in_nursery ((char*)*(ptr)) && !is_major_or_los_object_marked ((GCObject*)*(ptr))) { \ - if (!sgen_get_remset ()->find_address_with_cards (start, cards, (char*)(ptr))) { \ + if (!cards || !sgen_get_remset ()->find_address_with_cards (start, cards, (char*)(ptr))) { \ GCVTable __vt = SGEN_LOAD_VTABLE (obj); \ SGEN_LOG (0, "major->major reference %p at offset %zd in object %p (%s.%s) not found in remsets.", *(ptr), (char*)(ptr) - (char*)(obj), (obj), sgen_client_vtable_get_namespace (__vt), sgen_client_vtable_get_name (__vt)); \ binary_protocol_missing_remset ((obj), __vt, (int) ((char*)(ptr) - (char*)(obj)), *(ptr), (gpointer)LOAD_VTABLE(*(ptr)), object_is_pinned (*(ptr))); \ @@ -243,8 +243,6 @@ check_mod_union_callback (GCObject *obj, size_t size, void *dummy) else cards = sgen_get_major_collector ()->get_cardtable_mod_union_for_reference (start); - SGEN_ASSERT (0, cards, "we must have mod union for marked major objects"); - #include "sgen-scan-object.h" } @@ -253,7 +251,7 @@ sgen_check_mod_union_consistency (void) { missing_remsets = FALSE; - major_collector.iterate_objects (ITERATE_OBJECTS_ALL, (IterateObjectCallbackFunc)check_mod_union_callback, (void*)FALSE); + major_collector.iterate_objects (ITERATE_OBJECTS_SWEEP_ALL, (IterateObjectCallbackFunc)check_mod_union_callback, (void*)FALSE); sgen_los_iterate_objects ((IterateObjectCallbackFunc)check_mod_union_callback, (void*)TRUE); @@ -445,7 +443,7 @@ verify_object_pointers_callback (GCObject *obj, size_t size, void *data) { char *start = (char*)obj; gboolean allow_missing_pinned = (gboolean) (size_t) data; - SgenDescriptor desc = sgen_obj_get_descriptor (obj); + SgenDescriptor desc = sgen_obj_get_descriptor_safe (obj); #include "sgen-scan-object.h" } diff --git a/mono/sgen/sgen-gc.c b/mono/sgen/sgen-gc.c index 842144e56f4..ff078a71673 100644 --- a/mono/sgen/sgen-gc.c +++ b/mono/sgen/sgen-gc.c @@ -1461,7 +1461,7 @@ enqueue_scan_from_roots_jobs (SgenGrayQueue *gc_thread_gray_queue, char *heap_st * Return whether any objects were late-pinned due to being out of memory. */ static gboolean -collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_queue, gboolean finish_up_concurrent_mark) +collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_queue) { gboolean needs_major; size_t max_garbage_amount; @@ -1529,11 +1529,6 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_ gc_stats.minor_gc_count ++; - if (whole_heap_check_before_collection) { - sgen_clear_nursery_fragments (); - sgen_check_whole_heap (finish_up_concurrent_mark); - } - sgen_process_fin_stage_entries (); /* pin from pinned handles */ @@ -1552,6 +1547,11 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_ if (remset_consistency_checks) sgen_check_remset_consistency (); + if (whole_heap_check_before_collection) { + sgen_clear_nursery_fragments (); + sgen_check_whole_heap (FALSE); + } + TV_GETTIME (atv); time_minor_pinning += TV_ELAPSED (btv, atv); SGEN_LOG (2, "Finding pinned pointers: %zd in %lld usecs", sgen_get_pinned_count (), (long long)TV_ELAPSED (btv, atv)); @@ -1697,7 +1697,7 @@ major_copy_or_mark_from_roots (SgenGrayQueue *gc_thread_gray_queue, size_t *old_ sgen_clear_nursery_fragments (); if (whole_heap_check_before_collection) - sgen_check_whole_heap (mode == COPY_OR_MARK_FROM_ROOTS_FINISH_CONCURRENT); + sgen_check_whole_heap (TRUE); TV_GETTIME (btv); time_major_pre_collection_fragment_clear += TV_ELAPSED (atv, btv); @@ -1786,13 +1786,6 @@ major_copy_or_mark_from_roots (SgenGrayQueue *gc_thread_gray_queue, size_t *old_ if (old_next_pin_slot) *old_next_pin_slot = sgen_get_pinned_count (); - /* - * We don't actually pin when starting a concurrent collection, so the remset - * consistency check won't work. - */ - if (remset_consistency_checks && mode != COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT) - sgen_check_remset_consistency (); - TV_GETTIME (btv); time_major_pinning += TV_ELAPSED (atv, btv); SGEN_LOG (2, "Finding pinned pointers: %zd in %lld usecs", sgen_get_pinned_count (), (long long)TV_ELAPSED (atv, btv)); @@ -1975,9 +1968,6 @@ major_finish_collection (SgenGrayQueue *gc_thread_gray_queue, const char *reason reset_heap_boundaries (); sgen_update_heap_boundaries ((mword)sgen_get_nursery_start (), (mword)sgen_get_nursery_end ()); - if (whole_heap_check_before_collection) - sgen_check_whole_heap (FALSE); - /* walk the pin_queue, build up the fragment list of free memory, unmark * pinned objects as we go, memzero() the empty fragments so they are ready for the * next allocations. @@ -2257,7 +2247,7 @@ sgen_perform_collection (size_t requested_size, int generation_to_collect, const if (concurrent_collection_in_progress) major_update_concurrent_collection (); - if (collect_nursery (reason, FALSE, NULL, FALSE) && !concurrent_collection_in_progress) { + if (collect_nursery (reason, FALSE, NULL) && !concurrent_collection_in_progress) { overflow_generation_to_collect = GENERATION_OLD; overflow_reason = "Minor overflow"; } @@ -2267,7 +2257,7 @@ sgen_perform_collection (size_t requested_size, int generation_to_collect, const } else { SGEN_ASSERT (0, generation_to_collect == GENERATION_OLD, "We should have handled nursery collections above"); if (major_collector.is_concurrent && !wait_to_finish) { - collect_nursery ("Concurrent start", FALSE, NULL, FALSE); + collect_nursery ("Concurrent start", FALSE, NULL); major_start_concurrent_collection (reason); oldest_generation_collected = GENERATION_NURSERY; } else if (major_do_collection (reason, FALSE, wait_to_finish)) { @@ -2285,7 +2275,7 @@ sgen_perform_collection (size_t requested_size, int generation_to_collect, const */ if (overflow_generation_to_collect == GENERATION_NURSERY) - collect_nursery (overflow_reason, TRUE, NULL, FALSE); + collect_nursery (overflow_reason, TRUE, NULL); else major_do_collection (overflow_reason, TRUE, wait_to_finish); @@ -3259,7 +3249,7 @@ sgen_check_whole_heap_stw (void) { sgen_stop_world (0); sgen_clear_nursery_fragments (); - sgen_check_whole_heap (FALSE); + sgen_check_whole_heap (TRUE); sgen_restart_world (0); } diff --git a/mono/sgen/sgen-gc.h b/mono/sgen/sgen-gc.h index f67a15cd74a..dd5aef03927 100644 --- a/mono/sgen/sgen-gc.h +++ b/mono/sgen/sgen-gc.h @@ -599,7 +599,6 @@ typedef enum { ITERATE_OBJECTS_SWEEP = 1, ITERATE_OBJECTS_NON_PINNED = 2, ITERATE_OBJECTS_PINNED = 4, - ITERATE_OBJECTS_ALL = ITERATE_OBJECTS_NON_PINNED | ITERATE_OBJECTS_PINNED, ITERATE_OBJECTS_SWEEP_NON_PINNED = ITERATE_OBJECTS_SWEEP | ITERATE_OBJECTS_NON_PINNED, ITERATE_OBJECTS_SWEEP_PINNED = ITERATE_OBJECTS_SWEEP | ITERATE_OBJECTS_PINNED, ITERATE_OBJECTS_SWEEP_ALL = ITERATE_OBJECTS_SWEEP | ITERATE_OBJECTS_NON_PINNED | ITERATE_OBJECTS_PINNED diff --git a/mono/sgen/sgen-marksweep.c b/mono/sgen/sgen-marksweep.c index a215c44502c..d996be700ed 100644 --- a/mono/sgen/sgen-marksweep.c +++ b/mono/sgen/sgen-marksweep.c @@ -872,6 +872,7 @@ major_iterate_objects (IterateObjectsFlags flags, IterateObjectCallbackFunc call gboolean pinned = flags & ITERATE_OBJECTS_PINNED; MSBlockInfo *block; + /* No actual sweeping will take place if we are in the middle of a major collection. */ major_finish_sweep_checking (); FOREACH_BLOCK_NO_LOCK (block) { int count = MS_BLOCK_FREE / block->obj_size; @@ -881,26 +882,13 @@ major_iterate_objects (IterateObjectsFlags flags, IterateObjectCallbackFunc call continue; if (!block->pinned && !non_pinned) continue; - if (sweep && lazy_sweep) { + if (sweep && lazy_sweep && !block_is_swept_or_marking (block)) { sweep_block (block); SGEN_ASSERT (6, block->state == BLOCK_STATE_SWEPT, "Block must be swept after sweeping"); } for (i = 0; i < count; ++i) { void **obj = (void**) MS_BLOCK_OBJ (block, i); - /* - * We've finished sweep checking, but if we're sweeping lazily and - * the flags don't require us to sweep, the block might still need - * sweeping. In that case, we need to consult the mark bits to tell - * us whether an object slot is live. - */ - if (!block_is_swept_or_marking (block)) { - int word, bit; - SGEN_ASSERT (6, !sweep && block->state == BLOCK_STATE_NEED_SWEEPING, "Has sweeping not finished?"); - MS_CALC_MARK_BIT (word, bit, obj); - if (!MS_MARK_BIT (block, word, bit)) - continue; - } if (MS_OBJ_ALLOCED (obj, block)) callback ((GCObject*)obj, block->obj_size, data); }