From 6bb78cace33fdf95696fda3dd73397f433b4621f Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Tue, 20 Jun 2017 15:22:39 +0300 Subject: [PATCH] [sgen] Run the scan pinned object job concurrently with minors Concurrent mark doesn't normally scan objects in the nursery since they can be moved. At the end of the concurrent mark, we were locking over the entire gc pause in order to make sure that the we can scan the latest pinned object list (aka none of those objects can be moved). Lock only over the pinning phase of the collection, since it is enough. --- mono/sgen/sgen-gc.c | 9 +++++++++ mono/sgen/sgen-pinning.c | 12 +++++++++++- mono/sgen/sgen-pinning.h | 2 ++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/mono/sgen/sgen-gc.c b/mono/sgen/sgen-gc.c index 2f761cc8a13..b7951955ca5 100644 --- a/mono/sgen/sgen-gc.c +++ b/mono/sgen/sgen-gc.c @@ -1705,6 +1705,8 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_ /* pin from pinned handles */ sgen_init_pinning (); + if (concurrent_collection_in_progress) + sgen_init_pinning_for_conc (); sgen_client_binary_protocol_mark_start (GENERATION_NURSERY); pin_from_roots (nursery_section->data, nursery_section->end_data, ctx); /* pin cemented objects */ @@ -1715,6 +1717,8 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_ pin_objects_in_nursery (FALSE, ctx); sgen_pinning_trim_queue_to_section (nursery_section); + if (concurrent_collection_in_progress) + sgen_finish_pinning_for_conc (); if (remset_consistency_checks) sgen_check_remset_consistency (); @@ -1904,6 +1908,8 @@ major_copy_or_mark_from_roots (SgenGrayQueue *gc_thread_gray_queue, size_t *old_ TV_GETTIME (atv); sgen_init_pinning (); + if (mode == COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT) + sgen_init_pinning_for_conc (); SGEN_LOG (6, "Collecting pinned addresses"); pin_from_roots ((void*)lowest_heap_address, (void*)highest_heap_address, ctx); if (mode == COPY_OR_MARK_FROM_ROOTS_FINISH_CONCURRENT) { @@ -1974,6 +1980,9 @@ major_copy_or_mark_from_roots (SgenGrayQueue *gc_thread_gray_queue, size_t *old_ SGEN_LOG (2, "Finding pinned pointers: %zd in %lld usecs", sgen_get_pinned_count (), (long long)TV_ELAPSED (atv, btv)); SGEN_LOG (4, "Start scan with %zd pinned objects", sgen_get_pinned_count ()); + if (mode == COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT) + sgen_finish_pinning_for_conc (); + major_collector.init_to_space (); SGEN_ASSERT (0, sgen_workers_all_done (), "Why are the workers not done when we start or finish a major collection?"); diff --git a/mono/sgen/sgen-pinning.c b/mono/sgen/sgen-pinning.c index 904688c2ae8..0e711d1aa15 100644 --- a/mono/sgen/sgen-pinning.c +++ b/mono/sgen/sgen-pinning.c @@ -41,9 +41,14 @@ sgen_pinning_init (void) void sgen_init_pinning (void) { - mono_os_mutex_lock (&pin_queue_mutex); memset (pin_hash_filter, 0, sizeof (pin_hash_filter)); pin_queue.mem_type = INTERNAL_MEM_PIN_QUEUE; +} + +void +sgen_init_pinning_for_conc (void) +{ + mono_os_mutex_lock (&pin_queue_mutex); sgen_pointer_queue_clear (&pin_queue_objs); } @@ -52,6 +57,11 @@ sgen_finish_pinning (void) { last_num_pinned = pin_queue.next_slot; sgen_pointer_queue_clear (&pin_queue); +} + +void +sgen_finish_pinning_for_conc (void) +{ mono_os_mutex_unlock (&pin_queue_mutex); } diff --git a/mono/sgen/sgen-pinning.h b/mono/sgen/sgen-pinning.h index cdd673f29b5..797e12b2614 100644 --- a/mono/sgen/sgen-pinning.h +++ b/mono/sgen/sgen-pinning.h @@ -23,6 +23,8 @@ void sgen_pinning_init (void); void sgen_pin_stage_ptr (void *ptr); void sgen_optimize_pin_queue (void); void sgen_init_pinning (void); +void sgen_init_pinning_for_conc (void); +void sgen_finish_pinning_for_conc (void); void sgen_finish_pinning (void); void sgen_pinning_register_pinned_in_nursery (GCObject *obj); void sgen_scan_pin_queue_objects (ScanCopyContext ctx); -- 2.25.1