X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fsgen%2Fsgen-gc.c;h=4c3454823fdd42c2f5e0073a87f650601d6b84bf;hb=a7c9e39f0f58a1dcd41475f5623f301f14e31da7;hp=49c630f03f373ef59a4a37d6aafc96f29a157f0f;hpb=42874b6479cf103ca2e044b95c27a2edbb21d75c;p=mono.git diff --git a/mono/sgen/sgen-gc.c b/mono/sgen/sgen-gc.c index 49c630f03f3..4c3454823fd 100644 --- a/mono/sgen/sgen-gc.c +++ b/mono/sgen/sgen-gc.c @@ -177,6 +177,7 @@ #include #include #include +#include #include "mono/sgen/sgen-gc.h" #include "mono/sgen/sgen-cardtable.h" @@ -194,6 +195,7 @@ #include #include +#include #undef pthread_create #undef pthread_join @@ -335,13 +337,6 @@ nursery_canaries_enabled (void) #define safe_object_get_size sgen_safe_object_get_size -#if defined(HAVE_CONC_GC_AS_DEFAULT) -/* Use concurrent major on deskstop platforms */ -#define DEFAULT_MAJOR SGEN_MAJOR_CONCURRENT -#else -#define DEFAULT_MAJOR SGEN_MAJOR_SERIAL -#endif - typedef enum { SGEN_MAJOR_DEFAULT, SGEN_MAJOR_SERIAL, @@ -1701,7 +1696,7 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_ TV_GETTIME (last_minor_collection_start_tv); atv = last_minor_collection_start_tv; - binary_protocol_collection_begin (gc_stats.minor_gc_count, GENERATION_NURSERY); + binary_protocol_collection_begin (InterlockedRead (&gc_stats.minor_gc_count), GENERATION_NURSERY); object_ops_nopar = sgen_concurrent_collection_in_progress () ? &sgen_minor_collector.serial_ops_with_concurrent_major @@ -1729,7 +1724,7 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_ degraded_mode = 0; objects_pinned = 0; - SGEN_LOG (1, "Start nursery collection %d %p-%p, size: %d", gc_stats.minor_gc_count, nursery_section->data, nursery_section->end_data, (int)(nursery_section->end_data - nursery_section->data)); + SGEN_LOG (1, "Start nursery collection %" G_GINT32_FORMAT " %p-%p, size: %d", InterlockedRead (&gc_stats.minor_gc_count), nursery_section->data, nursery_section->end_data, (int)(nursery_section->end_data - nursery_section->data)); /* world must be stopped already */ TV_GETTIME (btv); @@ -1744,7 +1739,7 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_ init_gray_queue (&gc_thread_gray_queue); ctx = CONTEXT_FROM_OBJECT_OPERATIONS (object_ops_nopar, &gc_thread_gray_queue); - gc_stats.minor_gc_count ++; + InterlockedIncrement (&gc_stats.minor_gc_count); sgen_process_fin_stage_entries (); @@ -1861,9 +1856,9 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_ major_collector.finish_nursery_collection (); TV_GETTIME (last_minor_collection_end_tv); - gc_stats.minor_gc_time += TV_ELAPSED (last_minor_collection_start_tv, last_minor_collection_end_tv); + UnlockedAdd64 (&gc_stats.minor_gc_time, TV_ELAPSED (last_minor_collection_start_tv, last_minor_collection_end_tv)); - sgen_debug_dump_heap ("minor", gc_stats.minor_gc_count - 1, NULL); + sgen_debug_dump_heap ("minor", InterlockedRead (&gc_stats.minor_gc_count) - 1, NULL); /* prepare the pin queue for the next collection */ sgen_finish_pinning (); @@ -1896,7 +1891,7 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_ time_minor_scan_los - los_scan_start, time_minor_finish_gray_stack - finish_gray_start); - binary_protocol_collection_end (gc_stats.minor_gc_count - 1, GENERATION_NURSERY, 0, 0); + binary_protocol_collection_end (InterlockedRead (&gc_stats.minor_gc_count) - 1, GENERATION_NURSERY, 0, 0); if (check_nursery_objects_pinned && !sgen_minor_collector.is_split) sgen_check_nursery_objects_pinned (unpin_queue != NULL); @@ -2147,7 +2142,7 @@ major_start_collection (SgenGrayQueue *gc_thread_gray_queue, const char *reason, { SgenObjectOperations *object_ops_nopar, *object_ops_par = NULL; - binary_protocol_collection_begin (gc_stats.major_gc_count, GENERATION_OLD); + binary_protocol_collection_begin (InterlockedRead (&gc_stats.major_gc_count), GENERATION_OLD); current_collection_generation = GENERATION_OLD; @@ -2178,8 +2173,8 @@ major_start_collection (SgenGrayQueue *gc_thread_gray_queue, const char *reason, check_scan_starts (); degraded_mode = 0; - SGEN_LOG (1, "Start major collection %d", gc_stats.major_gc_count); - gc_stats.major_gc_count ++; + SGEN_LOG (1, "Start major collection %" G_GINT32_FORMAT, InterlockedRead (&gc_stats.major_gc_count)); + InterlockedIncrement (&gc_stats.major_gc_count); if (major_collector.start_major_collection) major_collector.start_major_collection (); @@ -2295,7 +2290,7 @@ major_finish_collection (SgenGrayQueue *gc_thread_gray_queue, const char *reason TV_GETTIME (atv); time_major_sweep += TV_ELAPSED (btv, atv); - sgen_debug_dump_heap ("major", gc_stats.major_gc_count - 1, reason); + sgen_debug_dump_heap ("major", InterlockedRead (&gc_stats.major_gc_count) - 1, reason); if (sgen_have_pending_finalizers ()) { SGEN_LOG (4, "Finalizer-thread wakeup"); @@ -2327,7 +2322,7 @@ major_finish_collection (SgenGrayQueue *gc_thread_gray_queue, const char *reason time_major_scan_mod_union_los - los_scan_start, time_major_finish_gray_stack - finish_gray_start); - binary_protocol_collection_end (gc_stats.major_gc_count - 1, GENERATION_OLD, counts.num_scanned_objects, counts.num_unique_scanned_objects); + binary_protocol_collection_end (InterlockedRead (&gc_stats.major_gc_count) - 1, GENERATION_OLD, counts.num_scanned_objects, counts.num_unique_scanned_objects); } static gboolean @@ -2355,7 +2350,7 @@ major_do_collection (const char *reason, gboolean is_overflow, gboolean forced) sgen_gray_object_queue_dispose (&gc_thread_gray_queue); TV_GETTIME (time_end); - gc_stats.major_gc_time += TV_ELAPSED (time_start, time_end); + UnlockedAdd64 (&gc_stats.major_gc_time, TV_ELAPSED (time_start, time_end)); /* FIXME: also report this to the user, preferably in gc-end. */ if (major_collector.get_and_reset_num_major_objects_marked) @@ -2391,7 +2386,7 @@ major_start_concurrent_collection (const char *reason) num_objects_marked = major_collector.get_and_reset_num_major_objects_marked (); TV_GETTIME (time_end); - gc_stats.major_gc_time += TV_ELAPSED (time_start, time_end); + UnlockedAdd64 (&gc_stats.major_gc_time, TV_ELAPSED (time_start, time_end)); current_collection_generation = -1; } @@ -2419,7 +2414,7 @@ major_update_concurrent_collection (void) sgen_los_update_cardtable_mod_union (); TV_GETTIME (total_end); - gc_stats.major_gc_time += TV_ELAPSED (total_start, total_end); + UnlockedAdd64 (&gc_stats.major_gc_time, TV_ELAPSED (total_start, total_end)); } static void @@ -2441,7 +2436,7 @@ major_finish_concurrent_collection (gboolean forced) sgen_workers_stop_all_workers (GENERATION_OLD); SGEN_TV_GETTIME (time_major_conc_collection_end); - gc_stats.major_gc_time_concurrent += SGEN_TV_ELAPSED (time_major_conc_collection_start, time_major_conc_collection_end); + UnlockedAdd64 (&gc_stats.major_gc_time_concurrent, SGEN_TV_ELAPSED (time_major_conc_collection_start, time_major_conc_collection_end)); major_collector.update_cardtable_mod_union (); sgen_los_update_cardtable_mod_union (); @@ -2456,7 +2451,7 @@ major_finish_concurrent_collection (gboolean forced) sgen_gray_object_queue_dispose (&gc_thread_gray_queue); TV_GETTIME (total_end); - gc_stats.major_gc_time += TV_ELAPSED (total_start, total_end); + UnlockedAdd64 (&gc_stats.major_gc_time, TV_ELAPSED (total_start, total_end)); current_collection_generation = -1; } @@ -2508,7 +2503,7 @@ sgen_ensure_free_space (size_t size, int generation) * 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, gboolean stw) +sgen_perform_collection_inner (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); @@ -2587,6 +2582,52 @@ sgen_perform_collection (size_t requested_size, int generation_to_collect, const sgen_restart_world (oldest_generation_collected); } +#ifdef HOST_WASM + +typedef struct { + size_t requested_size; + int generation_to_collect; + const char *reason; +} SgenGcRequest; + +static SgenGcRequest gc_request; +static gboolean pending_request; + +extern void request_gc_cycle (void); + +#include + +EMSCRIPTEN_KEEPALIVE void +mono_gc_pump_callback (void) +{ + if (!pending_request) + return; + pending_request = FALSE; + sgen_perform_collection_inner (gc_request.requested_size, gc_request.generation_to_collect, gc_request.reason, TRUE, TRUE); +} +#endif + +void +sgen_perform_collection (size_t requested_size, int generation_to_collect, const char *reason, gboolean wait_to_finish, gboolean stw) +{ +#ifdef HOST_WASM + g_assert (stw); //can't handle non-stw mode (IE, domain unload) + //we ignore wait_to_finish + if (!pending_request || gc_request.generation_to_collect <= generation_to_collect) { //no active request or request was for a smaller part of the heap + gc_request.requested_size = requested_size; + gc_request.generation_to_collect = generation_to_collect; + gc_request.reason = reason; + if (!pending_request) { + request_gc_cycle (); + pending_request = TRUE; + } + } + + degraded_mode = 1; //enable degraded mode so allocation can continue +#else + sgen_perform_collection_inner (requested_size, generation_to_collect, reason, wait_to_finish, stw); +#endif +} /* * ###################################################################### * ######## Memory allocation from the OS @@ -3053,9 +3094,7 @@ sgen_gc_collect (int generation) int sgen_gc_collection_count (int generation) { - if (generation == 0) - return gc_stats.minor_gc_count; - return gc_stats.major_gc_count; + return InterlockedRead (generation == GENERATION_NURSERY ? &gc_stats.minor_gc_count : &gc_stats.major_gc_count); } size_t