From: Vlad Brezae Date: Thu, 21 Apr 2016 13:53:02 +0000 (+0300) Subject: Merge pull request #2869 from BrzVlad/feature-mod-union-opt X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=mono.git;a=commitdiff_plain;h=a4a3aea41e3dcf845181c2a86f468fca22d18e4f;hp=ed9211bae9cb010426d9a3796722ac5dfd9772cd Merge pull request #2869 from BrzVlad/feature-mod-union-opt [sgen] Optimize mod union usage --- diff --git a/mono/sgen/sgen-los.c b/mono/sgen/sgen-los.c index 5cb3c71253d..c22afd22f21 100644 --- a/mono/sgen/sgen-los.c +++ b/mono/sgen/sgen-los.c @@ -307,7 +307,8 @@ free_los_section_memory (LOSObject *obj, size_t size) void sgen_los_free_object (LOSObject *obj) { - SGEN_ASSERT (0, !obj->cardtable_mod_union, "We should never free a LOS object with a mod-union table."); + if (obj->cardtable_mod_union) + sgen_card_table_free_mod_union (obj->cardtable_mod_union, (char*)obj->data, sgen_los_object_size (obj)); #ifndef LOS_DUMMY mword size = sgen_los_object_size (obj); @@ -433,12 +434,13 @@ sgen_los_sweep (void) for (bigobj = los_object_list; bigobj;) { SGEN_ASSERT (0, !SGEN_OBJECT_IS_PINNED (bigobj->data), "Who pinned a LOS object?"); - if (bigobj->cardtable_mod_union) { - sgen_card_table_free_mod_union (bigobj->cardtable_mod_union, (char*)bigobj->data, sgen_los_object_size (bigobj)); - bigobj->cardtable_mod_union = NULL; - } - if (sgen_los_object_is_pinned (bigobj->data)) { + if (bigobj->cardtable_mod_union) { + mword obj_size = sgen_los_object_size (bigobj); + mword num_cards = sgen_card_table_number_of_cards_in_range ((mword) bigobj->data, obj_size); + memset (bigobj->cardtable_mod_union, 0, num_cards); + } + sgen_los_unpin_object (bigobj->data); sgen_update_heap_boundaries ((mword)bigobj->data, (mword)bigobj->data + sgen_los_object_size (bigobj)); } else { diff --git a/mono/sgen/sgen-marksweep.c b/mono/sgen/sgen-marksweep.c index d2e3ccdd009..4c63191ad44 100644 --- a/mono/sgen/sgen-marksweep.c +++ b/mono/sgen/sgen-marksweep.c @@ -375,11 +375,14 @@ ms_get_empty_block (void) * list, where it will either be freed later on, or reused in nursery collections. */ static void -ms_free_block (void *block) +ms_free_block (MSBlockInfo *info) { void *empty; + char *block = MS_BLOCK_FOR_BLOCK_INFO (info); sgen_memgov_release_space (MS_BLOCK_SIZE, SPACE_MAJOR); + if (info->cardtable_mod_union) + sgen_card_table_free_mod_union (info->cardtable_mod_union, block, MS_BLOCK_SIZE); memset (block, 0, MS_BLOCK_SIZE); do { @@ -1507,10 +1510,8 @@ ensure_block_is_checked_for_sweeping (guint32 block_index, gboolean wait, gboole count = MS_BLOCK_FREE / block->obj_size; - if (block->cardtable_mod_union) { - sgen_card_table_free_mod_union (block->cardtable_mod_union, MS_BLOCK_FOR_BLOCK_INFO (block), MS_BLOCK_SIZE); - block->cardtable_mod_union = NULL; - } + if (block->cardtable_mod_union) + memset (block->cardtable_mod_union, 0, CARDS_PER_BLOCK); /* Count marked objects in the block */ for (i = 0; i < MS_NUM_MARK_WORDS; ++i) @@ -2484,10 +2485,21 @@ update_cardtable_mod_union (void) MSBlockInfo *block; FOREACH_BLOCK_NO_LOCK (block) { - size_t num_cards; - guint8 *mod_union = get_cardtable_mod_union_for_block (block, TRUE); - sgen_card_table_update_mod_union (mod_union, MS_BLOCK_FOR_BLOCK_INFO (block), MS_BLOCK_SIZE, &num_cards); - SGEN_ASSERT (6, num_cards == CARDS_PER_BLOCK, "Number of cards calculation is wrong"); + gpointer *card_start = (gpointer*) sgen_card_table_get_card_address ((mword)MS_BLOCK_FOR_BLOCK_INFO (block)); + gboolean has_dirty_cards = FALSE; + int i; + for (i = 0; i < CARDS_PER_BLOCK / sizeof(gpointer); i++) { + if (card_start [i]) { + has_dirty_cards = TRUE; + break; + } + } + if (has_dirty_cards) { + size_t num_cards; + guint8 *mod_union = get_cardtable_mod_union_for_block (block, TRUE); + sgen_card_table_update_mod_union (mod_union, MS_BLOCK_FOR_BLOCK_INFO (block), MS_BLOCK_SIZE, &num_cards); + SGEN_ASSERT (6, num_cards == CARDS_PER_BLOCK, "Number of cards calculation is wrong"); + } } END_FOREACH_BLOCK_NO_LOCK; }