#include <mono/utils/memcheck.h>
#include <mono/utils/mono-mmap-internals.h>
+#include <mono/utils/unlocked.h>
#undef pthread_create
#undef pthread_join
#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,
major_collector.finish_nursery_collection ();
TV_GETTIME (last_minor_collection_end_tv);
- InterlockedAdd64 (&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", InterlockedRead (&gc_stats.minor_gc_count) - 1, NULL);
sgen_gray_object_queue_dispose (&gc_thread_gray_queue);
TV_GETTIME (time_end);
- InterlockedAdd64 (&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)
num_objects_marked = major_collector.get_and_reset_num_major_objects_marked ();
TV_GETTIME (time_end);
- InterlockedAdd64 (&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;
}
sgen_los_update_cardtable_mod_union ();
TV_GETTIME (total_end);
- InterlockedAdd64 (&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
sgen_workers_stop_all_workers (GENERATION_OLD);
SGEN_TV_GETTIME (time_major_conc_collection_end);
- InterlockedAdd64 (&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 ();
sgen_gray_object_queue_dispose (&gc_thread_gray_queue);
TV_GETTIME (total_end);
- InterlockedAdd64 (&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;
}
* 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);
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.h>
+
+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