From b136605a738057ba706aeb5fef682149cd216a9d Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Thu, 9 Jun 2016 01:20:53 +0300 Subject: [PATCH] [sgen] Don't try to stop a stopped world On domain unload we were calling sgen_perform_collection even though we had a stopped world, when finishing a running concurrent collection. --- mono/metadata/sgen-mono.c | 2 +- mono/sgen/sgen-alloc.c | 6 +++--- mono/sgen/sgen-gc.c | 15 ++++++++++----- mono/sgen/sgen-gc.h | 2 +- mono/sgen/sgen-marksweep.c | 2 +- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/mono/metadata/sgen-mono.c b/mono/metadata/sgen-mono.c index 944bde7f63c..37133a9bd8b 100644 --- a/mono/metadata/sgen-mono.c +++ b/mono/metadata/sgen-mono.c @@ -841,7 +841,7 @@ mono_gc_clear_domain (MonoDomain * domain) sgen_stop_world (0); if (sgen_concurrent_collection_in_progress ()) - sgen_perform_collection (0, GENERATION_OLD, "clear domain", TRUE); + sgen_perform_collection (0, GENERATION_OLD, "clear domain", TRUE, FALSE); SGEN_ASSERT (0, !sgen_concurrent_collection_in_progress (), "We just ordered a synchronous collection. Why are we collecting concurrently?"); major_collector.finish_sweeping (); diff --git a/mono/sgen/sgen-alloc.c b/mono/sgen/sgen-alloc.c index dcf977c06e1..2e9f4666d21 100644 --- a/mono/sgen/sgen-alloc.c +++ b/mono/sgen/sgen-alloc.c @@ -96,7 +96,7 @@ alloc_degraded (GCVTable vtable, size_t size, gboolean for_mature) sgen_ensure_free_space (size, GENERATION_OLD); } else { if (sgen_need_major_collection (size)) - sgen_perform_collection (size, GENERATION_OLD, "mature allocation failure", !for_mature); + sgen_perform_collection (size, GENERATION_OLD, "mature allocation failure", !for_mature, TRUE); } @@ -164,7 +164,7 @@ sgen_alloc_obj_nolock (GCVTable vtable, size_t size) if (collect_before_allocs) { if (((current_alloc % collect_before_allocs) == 0) && nursery_section) { - sgen_perform_collection (0, GENERATION_NURSERY, "collect-before-alloc-triggered", TRUE); + sgen_perform_collection (0, GENERATION_NURSERY, "collect-before-alloc-triggered", TRUE, TRUE); if (!degraded_mode && sgen_can_alloc_size (size) && real_size <= SGEN_MAX_SMALL_OBJ_SIZE) { // FIXME: g_assert_not_reached (); @@ -424,7 +424,7 @@ sgen_alloc_obj (GCVTable vtable, size_t size) if (collect_before_allocs) { if (((current_alloc % collect_before_allocs) == 0) && nursery_section) { LOCK_GC; - sgen_perform_collection (0, GENERATION_NURSERY, "collect-before-alloc-triggered", TRUE); + sgen_perform_collection (0, GENERATION_NURSERY, "collect-before-alloc-triggered", TRUE, TRUE); UNLOCK_GC; } } diff --git a/mono/sgen/sgen-gc.c b/mono/sgen/sgen-gc.c index 6304d166df8..1aa55199e7f 100644 --- a/mono/sgen/sgen-gc.c +++ b/mono/sgen/sgen-gc.c @@ -2226,14 +2226,14 @@ sgen_ensure_free_space (size_t size, int generation) if (generation_to_collect == -1) return; - sgen_perform_collection (size, generation_to_collect, reason, FALSE); + sgen_perform_collection (size, generation_to_collect, reason, FALSE, TRUE); } /* * LOCKING: Assumes the GC lock is held. */ void -sgen_perform_collection (size_t requested_size, int generation_to_collect, const char *reason, gboolean wait_to_finish) +sgen_perform_collection (size_t requested_size, int generation_to_collect, const char *reason, gboolean wait_to_finish, gboolean stw) { TV_DECLARE (gc_total_start); TV_DECLARE (gc_total_end); @@ -2246,7 +2246,11 @@ sgen_perform_collection (size_t requested_size, int generation_to_collect, const SGEN_ASSERT (0, generation_to_collect == GENERATION_NURSERY || generation_to_collect == GENERATION_OLD, "What generation is this?"); - sgen_stop_world (generation_to_collect); + if (stw) + sgen_stop_world (generation_to_collect); + else + SGEN_ASSERT (0, sgen_is_world_stopped (), "We can only collect if the world is stopped"); + TV_GETTIME (gc_total_start); @@ -2306,7 +2310,8 @@ sgen_perform_collection (size_t requested_size, int generation_to_collect, const TV_GETTIME (gc_total_end); time_max = MAX (time_max, TV_ELAPSED (gc_total_start, gc_total_end)); - sgen_restart_world (oldest_generation_collected); + if (stw) + sgen_restart_world (oldest_generation_collected); } /* @@ -2676,7 +2681,7 @@ sgen_gc_collect (int generation) LOCK_GC; if (generation > 1) generation = 1; - sgen_perform_collection (0, generation, "user request", TRUE); + sgen_perform_collection (0, generation, "user request", TRUE, TRUE); UNLOCK_GC; } diff --git a/mono/sgen/sgen-gc.h b/mono/sgen/sgen-gc.h index 94b453b6e27..b0ac3dbcb10 100644 --- a/mono/sgen/sgen-gc.h +++ b/mono/sgen/sgen-gc.h @@ -830,7 +830,7 @@ void sgen_set_pinned_from_failed_allocation (mword objsize); void sgen_ensure_free_space (size_t size, int generation); void sgen_gc_collect (int generation); -void sgen_perform_collection (size_t requested_size, int generation_to_collect, const char *reason, gboolean wait_to_finish); +void sgen_perform_collection (size_t requested_size, int generation_to_collect, const char *reason, gboolean wait_to_finish, gboolean stw); int sgen_gc_collection_count (int generation); /* FIXME: what exactly does this return? */ diff --git a/mono/sgen/sgen-marksweep.c b/mono/sgen/sgen-marksweep.c index f2c646b3952..4d0c09d40a8 100644 --- a/mono/sgen/sgen-marksweep.c +++ b/mono/sgen/sgen-marksweep.c @@ -713,7 +713,7 @@ major_alloc_small_pinned_obj (GCVTable vtable, size_t size, gboolean has_referen *as pinned alloc is requested by the runtime. */ if (!res) { - sgen_perform_collection (0, GENERATION_OLD, "pinned alloc failure", TRUE); + sgen_perform_collection (0, GENERATION_OLD, "pinned alloc failure", TRUE, TRUE); res = alloc_obj (vtable, size, TRUE, has_references); } return (GCObject *)res; -- 2.11.4.GIT