static guint64 large_objects;
static guint64 bloby_objects;
#endif
-static guint64 major_card_scan_time;
-static guint64 los_card_scan_time;
-
-static guint64 last_major_scan_time;
-static guint64 last_los_scan_time;
mword
sgen_card_table_number_of_cards_in_range (mword address, mword size)
sgen_card_table_mark_address ((mword)ptr);
}
+static void
+sgen_card_table_wbarrier_range_copy (gpointer _dest, gpointer _src, int size)
+{
+ GCObject **dest = (GCObject **)_dest;
+ GCObject **src = (GCObject **)_src;
+
+ size_t nursery_bits = sgen_nursery_bits;
+ char *start = sgen_nursery_start;
+ G_GNUC_UNUSED char *end = sgen_nursery_end;
+
+ /*
+ * It's cardtable theory time!
+ * Our cardtable scanning code supports marking any card that an object/valuetype belongs to.
+ * This function is supposed to be used to copy a range that fully belongs to a single type.
+ * It must not be used, for example, to copy 2 adjacent VTs in an array.
+ */
+ volatile guint8 *card_address = (volatile guint8 *)sgen_card_table_get_card_address ((mword)dest);
+ while (size) {
+ GCObject *value = *src;
+ *dest = value;
+ if (SGEN_PTR_IN_NURSERY (value, nursery_bits, start, end) || concurrent_collection_in_progress) {
+ *card_address = 1;
+ sgen_dummy_use (value);
+ }
+ ++src;
+ ++dest;
+ size -= SIZEOF_VOID_P;
+ }
+}
+
#ifdef SGEN_HAVE_OVERLAPPING_CARDS
guint8 *sgen_shadow_cardtable;
}
static void
-sgen_card_table_scan_remsets (ScanCopyContext ctx)
+sgen_card_table_start_scan_remsets (void)
{
- SGEN_TV_DECLARE (atv);
- SGEN_TV_DECLARE (btv);
-
#ifdef SGEN_HAVE_OVERLAPPING_CARDS
/*FIXME we should have a bit on each block/los object telling if the object have marked cards.*/
/*First we copy*/
/*Then we clear*/
sgen_card_table_clear_cards ();
#endif
- SGEN_TV_GETTIME (atv);
- sgen_get_major_collector ()->scan_card_table (CARDTABLE_SCAN_GLOBAL, ctx, 0, 1);
- SGEN_TV_GETTIME (btv);
- last_major_scan_time = SGEN_TV_ELAPSED (atv, btv);
- major_card_scan_time += last_major_scan_time;
- sgen_los_scan_card_table (CARDTABLE_SCAN_GLOBAL, ctx, 0, 1);
- SGEN_TV_GETTIME (atv);
- last_los_scan_time = SGEN_TV_ELAPSED (btv, atv);
- los_card_scan_time += last_los_scan_time;
-
- sgen_wbroots_scan_card_table (ctx);
}
guint8*
mono_counters_register ("cardtable large objects", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &large_objects);
mono_counters_register ("cardtable bloby objects", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &bloby_objects);
#endif
- mono_counters_register ("cardtable major scan time", MONO_COUNTER_GC | MONO_COUNTER_ULONG | MONO_COUNTER_TIME, &major_card_scan_time);
- mono_counters_register ("cardtable los scan time", MONO_COUNTER_GC | MONO_COUNTER_ULONG | MONO_COUNTER_TIME, &los_card_scan_time);
-
remset->wbarrier_set_field = sgen_card_table_wbarrier_set_field;
remset->wbarrier_arrayref_copy = sgen_card_table_wbarrier_arrayref_copy;
remset->wbarrier_generic_nostore = sgen_card_table_wbarrier_generic_nostore;
remset->record_pointer = sgen_card_table_record_pointer;
- remset->scan_remsets = sgen_card_table_scan_remsets;
+ remset->start_scan_remsets = sgen_card_table_start_scan_remsets;
remset->clear_cards = sgen_card_table_clear_cards;
remset->find_address = sgen_card_table_find_address;
remset->find_address_with_cards = sgen_card_table_find_address_with_cards;
+ remset->wbarrier_range_copy = sgen_card_table_wbarrier_range_copy;
need_mod_union = sgen_get_major_collector ()->is_concurrent;
}