X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fsgen%2Fsgen-los.c;h=eb620281410ed984d4efb4aa96024afa633c28e3;hb=e097ce511153036b9146ee9ca32b766b260e6d1e;hp=c0ea17bb329982efe49392adda5ff15df6bdfe1d;hpb=2c0682c70f566061ab912cd7b91431f13e772f44;p=mono.git diff --git a/mono/sgen/sgen-los.c b/mono/sgen/sgen-los.c index c0ea17bb329..eb620281410 100644 --- a/mono/sgen/sgen-los.c +++ b/mono/sgen/sgen-los.c @@ -73,6 +73,7 @@ struct _LOSSection { unsigned char *free_chunk_map; }; +/* We allow read only access on the list while sweep is not running */ LOSObject *los_object_list = NULL; mword los_memory_usage = 0; @@ -380,7 +381,7 @@ sgen_los_alloc_large_inner (GCVTable vtable, size_t size) los_segment_index += size + sizeof (LOSObject); g_assert (los_segment_index <= LOS_SEGMENT_SIZE); #else - sgen_ensure_free_space (size); + sgen_ensure_free_space (size, GENERATION_OLD); #ifdef USE_MALLOC obj = malloc (size + sizeof (LOSObject)); @@ -410,6 +411,11 @@ sgen_los_alloc_large_inner (GCVTable vtable, size_t size) *vtslot = vtable; sgen_update_heap_boundaries ((mword)obj->data, (mword)obj->data + size); obj->next = los_object_list; + /* + * We need a memory barrier so we don't expose as head of the los object list + * a LOSObject that doesn't have its fields initialized. + */ + mono_memory_write_barrier (); los_object_list = obj; los_memory_usage += size; los_num_objects++; @@ -617,28 +623,44 @@ get_cardtable_mod_union_for_object (LOSObject *obj) } void -sgen_los_scan_card_table (gboolean mod_union, ScanCopyContext ctx) +sgen_los_scan_card_table (CardTableScanType scan_type, ScanCopyContext ctx) { LOSObject *obj; + binary_protocol_los_card_table_scan_start (sgen_timestamp (), scan_type & CARDTABLE_SCAN_MOD_UNION); for (obj = los_object_list; obj; obj = obj->next) { + mword num_cards = 0; guint8 *cards; if (!SGEN_OBJECT_HAS_REFERENCES (obj->data)) continue; - if (mod_union) { + if (scan_type & CARDTABLE_SCAN_MOD_UNION) { if (!sgen_los_object_is_pinned (obj->data)) continue; cards = get_cardtable_mod_union_for_object (obj); g_assert (cards); + if (scan_type == CARDTABLE_SCAN_MOD_UNION_PRECLEAN) { + guint8 *cards_preclean; + mword obj_size = sgen_los_object_size (obj); + num_cards = sgen_card_table_number_of_cards_in_range ((mword) obj->data, obj_size); + cards_preclean = (guint8 *)sgen_alloc_internal_dynamic (num_cards, INTERNAL_MEM_CARDTABLE_MOD_UNION, TRUE); + + sgen_card_table_preclean_mod_union (cards, cards_preclean, num_cards); + + cards = cards_preclean; + } } else { cards = NULL; } - sgen_cardtable_scan_object (obj->data, sgen_los_object_size (obj), cards, mod_union, ctx); + sgen_cardtable_scan_object (obj->data, sgen_los_object_size (obj), cards, ctx); + + if (scan_type == CARDTABLE_SCAN_MOD_UNION_PRECLEAN) + sgen_free_internal_dynamic (cards, num_cards, INTERNAL_MEM_CARDTABLE_MOD_UNION); } + binary_protocol_los_card_table_scan_end (sgen_timestamp (), scan_type & CARDTABLE_SCAN_MOD_UNION); } void