Skip to content

Commit

Permalink
[mono][sgen] Add separate card mark function to be used with debug
Browse files Browse the repository at this point in the history
When marking cards for a non-array object or a an element vt in an object, it is enough to mark a card for any address within that object/vt because they are always fully scanned. Cardtable consistency checks are not accounting for this detail and it is difficult to have it implemented. Instead, when having such debug flags enabled, we use an explicit approach where every single card is being marked.
  • Loading branch information
BrzVlad authored and github-actions committed Nov 29, 2024
1 parent b0f058b commit 21e30ed
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 4 deletions.
32 changes: 30 additions & 2 deletions src/mono/mono/sgen/sgen-cardtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,31 @@ sgen_card_table_wbarrier_range_copy (gpointer _dest, gconstpointer _src, int siz
}
}

// Marks more cards so that it works with remset consistency debug checks
static void
sgen_card_table_wbarrier_range_copy_debug (gpointer _dest, gconstpointer _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;

while (size) {
GCObject *value = *src;
*dest = value;
if (SGEN_PTR_IN_NURSERY (value, nursery_bits, start, end) || sgen_concurrent_collection_in_progress) {
volatile guint8 *card_address = (volatile guint8 *)sgen_card_table_get_card_address ((mword)dest);
*card_address = 1;
sgen_dummy_use (value);
}
++src;
++dest;
size -= SIZEOF_VOID_P;
}
}

MONO_RESTORE_WARNING

#ifdef SGEN_HAVE_OVERLAPPING_CARDS
Expand Down Expand Up @@ -606,7 +631,7 @@ sgen_cardtable_scan_object (GCObject *obj, mword block_obj_size, guint8 *cards,
}

void
sgen_card_table_init (SgenRememberedSet *remset)
sgen_card_table_init (SgenRememberedSet *remset, gboolean consistency_checks)
{
sgen_cardtable = (guint8 *)sgen_alloc_os_memory (CARD_COUNT_IN_BYTES, (SgenAllocFlags)(SGEN_ALLOC_INTERNAL | SGEN_ALLOC_ACTIVATE), "card table", MONO_MEM_ACCOUNT_SGEN_CARD_TABLE);

Expand Down Expand Up @@ -637,7 +662,10 @@ sgen_card_table_init (SgenRememberedSet *remset)

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;
if (consistency_checks)
remset->wbarrier_range_copy = sgen_card_table_wbarrier_range_copy_debug;
else
remset->wbarrier_range_copy = sgen_card_table_wbarrier_range_copy;

need_mod_union = sgen_get_major_collector ()->is_concurrent;
}
Expand Down
2 changes: 1 addition & 1 deletion src/mono/mono/sgen/sgen-cardtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ void sgen_card_table_preclean_mod_union (guint8 *cards, guint8 *cards_preclean,
guint8* sgen_get_card_table_configuration (int *shift_bits, gpointer *mask);
guint8* sgen_get_target_card_table_configuration (int *shift_bits, target_mgreg_t *mask);

void sgen_card_table_init (SgenRememberedSet *remset);
void sgen_card_table_init (SgenRememberedSet *remset, gboolean consistency_checks);

/*How many bytes a single card covers*/
#define CARD_BITS 9
Expand Down
2 changes: 1 addition & 1 deletion src/mono/mono/sgen/sgen-gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3909,7 +3909,7 @@ sgen_gc_init (void)

memset (&remset, 0, sizeof (remset));

sgen_card_table_init (&remset);
sgen_card_table_init (&remset, remset_consistency_checks);

sgen_register_root (NULL, 0, sgen_make_user_root_descriptor (sgen_mark_normal_gc_handles), ROOT_TYPE_NORMAL, MONO_ROOT_SOURCE_GC_HANDLE, GINT_TO_POINTER (ROOT_TYPE_NORMAL), "GC Handles (SGen, Normal)");

Expand Down

0 comments on commit 21e30ed

Please sign in to comment.