#endif
void
-sgen_card_table_clear (void)
+mono_sgen_card_table_prepare_for_major_collection (void)
{
/*XXX we could do this in 2 ways. using mincore or iterating over all sections/los objects */
sgen_major_collector_iterate_live_block_ranges (clear_cards);
mono_sgen_los_iterate_live_block_ranges (move_cards_to_shadow_table);
/*Then we clear*/
- sgen_card_table_clear ();
+ mono_sgen_card_table_prepare_for_major_collection ();
#endif
SGEN_TV_GETTIME (atv);
sgen_major_collector_scan_card_table (queue);
gboolean sgen_card_table_get_card_data (guint8 *dest, mword address, mword cards) MONO_INTERNAL;
void sgen_scan_from_card_tables (void *start_nursery, void *end_nursery, SgenGrayQueue *queue) MONO_INTERNAL;
void sgen_card_tables_collect_stats (gboolean begin) MONO_INTERNAL;
-void sgen_card_table_clear (void) MONO_INTERNAL;
+void mono_sgen_card_table_prepare_for_major_collection (void) MONO_INTERNAL;
void sgen_card_table_init (void) MONO_INTERNAL;
void mono_sgen_card_table_wbarrier_set_field (MonoObject *obj, gpointer field_ptr, MonoObject* value) MONO_INTERNAL;
#define sgen_card_table_address_is_marked(p) FALSE
#define sgen_scan_from_card_tables(start,end,queue)
-#define sgen_card_table_clear()
+#define mono_sgen_card_table_prepare_for_major_collection()
#define sgen_card_table_init()
#define sgen_card_tables_collect_stats(begin)
static void pin_from_roots (void *start_nursery, void *end_nursery, GrayQueue *queue);
static int pin_objects_from_addresses (GCMemSection *section, void **start, void **end, void *start_nursery, void *end_nursery, GrayQueue *queue);
-static void clear_remsets (void);
static void finish_gray_stack (char *start_addr, char *end_addr, int generation, GrayQueue *queue);
static gboolean need_major_collection (mword space_needed);
static void major_collection (const char *reason);
check_for_xdomain_refs ();
/* Remsets are not useful for a major collection */
- if (use_cardtable) {
- sgen_card_table_clear ();
- } else {
- clear_remsets ();
- mono_sgen_ssb_prepare_for_minor_collection ();
- }
+ if (use_cardtable)
+ mono_sgen_card_table_prepare_for_major_collection ();
+ else
+ mono_sgen_ssb_prepare_for_major_collection ();
process_fin_stage_entries ();
process_dislink_stage_entries ();
}
}
-/*
- * Clear the info in the remembered sets: we're doing a major collection, so
- * the per-thread ones are not needed and the global ones will be reconstructed
- * during the copy.
- */
-static void
-clear_remsets (void)
-{
- SgenThreadInfo *info;
- RememberedSet *remset, *next;
-
- /* the global list */
- for (remset = global_remset; remset; remset = next) {
- remset->store_next = remset->data;
- next = remset->next;
- remset->next = NULL;
- if (remset != global_remset) {
- DEBUG (4, fprintf (gc_debug_file, "Freed remset at %p\n", remset->data));
- mono_sgen_free_internal_dynamic (remset, remset_byte_size (remset), INTERNAL_MEM_REMSET);
- }
- }
- /* the generic store ones */
- while (generic_store_remsets) {
- GenericStoreRememberedSet *gs_next = generic_store_remsets->next;
- mono_sgen_free_internal (generic_store_remsets, INTERNAL_MEM_STORE_REMSET);
- generic_store_remsets = gs_next;
- }
- /* the per-thread ones */
- FOREACH_THREAD (info) {
- for (remset = info->remset; remset; remset = next) {
- remset->store_next = remset->data;
- next = remset->next;
- remset->next = NULL;
- if (remset != info->remset) {
- DEBUG (3, fprintf (gc_debug_file, "Freed remset at %p\n", remset->data));
- mono_sgen_free_internal_dynamic (remset, remset_byte_size (remset), INTERNAL_MEM_REMSET);
- }
- }
- clear_thread_store_remset_buffer (info);
- } END_FOREACH_THREAD
-
- /* the freed thread ones */
- while (freed_thread_remsets) {
- next = freed_thread_remsets->next;
- DEBUG (4, fprintf (gc_debug_file, "Freed remset at %p\n", freed_thread_remsets->data));
- mono_sgen_free_internal_dynamic (freed_thread_remsets, remset_byte_size (freed_thread_remsets), INTERNAL_MEM_REMSET);
- freed_thread_remsets = next;
- }
-}
-
static void*
sgen_thread_register (SgenThreadInfo* info, void *addr)
{
#define UNLOCK_GLOBAL_REMSET mono_mutex_unlock (&global_remset_mutex)
+static void
+clear_thread_store_remset_buffer (SgenThreadInfo *info)
+{
+ *info->store_remset_buffer_index_addr = 0;
+ /* See the comment at the end of sgen_thread_unregister() */
+ if (*info->store_remset_buffer_addr)
+ memset (*info->store_remset_buffer_addr, 0, sizeof (gpointer) * STORE_REMSET_BUFFER_SIZE);
+}
+
+static size_t
+remset_byte_size (RememberedSet *remset)
+{
+ return sizeof (RememberedSet) + (remset->end_set - remset->data) * sizeof (gpointer);
+}
static void
add_generic_store_remset_from_buffer (gpointer *buffer)
memset (global_remset_cache, 0, sizeof (global_remset_cache));
}
+/*
+ * Clear the info in the remembered sets: we're doing a major collection, so
+ * the per-thread ones are not needed and the global ones will be reconstructed
+ * during the copy.
+ */
+void
+mono_sgen_ssb_prepare_for_major_collection (void)
+{
+ SgenThreadInfo *info;
+ RememberedSet *remset, *next;
+
+ mono_sgen_ssb_prepare_for_minor_collection ();
+
+ /* the global list */
+ for (remset = global_remset; remset; remset = next) {
+ remset->store_next = remset->data;
+ next = remset->next;
+ remset->next = NULL;
+ if (remset != global_remset) {
+ DEBUG (4, fprintf (gc_debug_file, "Freed remset at %p\n", remset->data));
+ mono_sgen_free_internal_dynamic (remset, remset_byte_size (remset), INTERNAL_MEM_REMSET);
+ }
+ }
+ /* the generic store ones */
+ while (generic_store_remsets) {
+ GenericStoreRememberedSet *gs_next = generic_store_remsets->next;
+ mono_sgen_free_internal (generic_store_remsets, INTERNAL_MEM_STORE_REMSET);
+ generic_store_remsets = gs_next;
+ }
+ /* the per-thread ones */
+ FOREACH_THREAD (info) {
+ for (remset = info->remset; remset; remset = next) {
+ remset->store_next = remset->data;
+ next = remset->next;
+ remset->next = NULL;
+ if (remset != info->remset) {
+ DEBUG (3, fprintf (gc_debug_file, "Freed remset at %p\n", remset->data));
+ mono_sgen_free_internal_dynamic (remset, remset_byte_size (remset), INTERNAL_MEM_REMSET);
+ }
+ }
+ clear_thread_store_remset_buffer (info);
+ } END_FOREACH_THREAD
+
+ /* the freed thread ones */
+ while (freed_thread_remsets) {
+ next = freed_thread_remsets->next;
+ DEBUG (4, fprintf (gc_debug_file, "Freed remset at %p\n", freed_thread_remsets->data));
+ mono_sgen_free_internal_dynamic (freed_thread_remsets, remset_byte_size (freed_thread_remsets), INTERNAL_MEM_REMSET);
+ freed_thread_remsets = next;
+ }
+}
+
+
/*
* Tries to check if a given remset location was already added to the global remset.
* It can
void mono_sgen_ssb_cleanup_thread (SgenThreadInfo *p) MONO_INTERNAL;
void mono_sgen_ssb_prepare_for_minor_collection (void) MONO_INTERNAL;
+void mono_sgen_ssb_prepare_for_major_collection (void) MONO_INTERNAL;
void mono_sgen_ssb_init (void) MONO_INTERNAL;
void mono_sgen_ssb_record_pointer (gpointer ptr) MONO_INTERNAL;