X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fsgen-cardtable.c;h=6f852df9577bcbbfdd87c421f1621aacb10ebb03;hb=9f92e1c7fd7b2553fb4567b51426209506797af8;hp=aab3bcb6153332ff59565ab941b449aea71b0fdf;hpb=630116d1b60070c2a0b09f5912df3bdd5c83bacf;p=mono.git diff --git a/mono/metadata/sgen-cardtable.c b/mono/metadata/sgen-cardtable.c index aab3bcb6153..6f852df9577 100644 --- a/mono/metadata/sgen-cardtable.c +++ b/mono/metadata/sgen-cardtable.c @@ -52,23 +52,23 @@ guint8 *sgen_cardtable; static gboolean need_mod_union; #ifdef HEAVY_STATISTICS -long long marked_cards; -long long scanned_cards; -long long scanned_objects; -long long remarked_cards; +guint64 marked_cards; +guint64 scanned_cards; +guint64 scanned_objects; +guint64 remarked_cards; -static long long los_marked_cards; -static long long large_objects; -static long long bloby_objects; -static long long los_array_cards; -static long long los_array_remsets; +static guint64 los_marked_cards; +static guint64 large_objects; +static guint64 bloby_objects; +static guint64 los_array_cards; +static guint64 los_array_remsets; #endif -static long long major_card_scan_time; -static long long los_card_scan_time; +static guint64 major_card_scan_time; +static guint64 los_card_scan_time; -static long long last_major_scan_time; -static long long last_los_scan_time; +static guint64 last_major_scan_time; +static guint64 last_los_scan_time; static void sgen_card_tables_collect_stats (gboolean begin); @@ -113,7 +113,7 @@ sgen_card_table_wbarrier_arrayref_copy (gpointer dest_ptr, gpointer src_ptr, int for (; dest >= start; --src, --dest) { gpointer value = *src; - *dest = value; + SGEN_UPDATE_REFERENCE_ALLOW_NULL (dest, value); if (need_mod_union || sgen_ptr_in_nursery (value)) sgen_card_table_mark_address ((mword)dest); sgen_dummy_use (value); @@ -122,7 +122,7 @@ sgen_card_table_wbarrier_arrayref_copy (gpointer dest_ptr, gpointer src_ptr, int gpointer *end = dest + count; for (; dest < end; ++src, ++dest) { gpointer value = *src; - *dest = value; + SGEN_UPDATE_REFERENCE_ALLOW_NULL (dest, value); if (need_mod_union || sgen_ptr_in_nursery (value)) sgen_card_table_mark_address ((mword)dest); sgen_dummy_use (value); @@ -186,10 +186,11 @@ guint8 *sgen_shadow_cardtable; #define SGEN_CARDTABLE_END (sgen_cardtable + CARD_COUNT_IN_BYTES) static gboolean -sgen_card_table_region_begin_scanning (mword start, mword end) +sgen_card_table_region_begin_scanning (mword start, mword size) { + mword end = start + size; /*XXX this can be improved to work on words and have a single loop induction var */ - while (start <= end) { + while (start < end) { if (sgen_card_table_card_begin_scanning (start)) return TRUE; start += CARD_SIZE_IN_BYTES; @@ -289,37 +290,37 @@ sgen_card_table_find_address_with_cards (char *cards_start, guint8 *cards, char } static void -update_mod_union (guint8 *dest, gboolean init, guint8 *start_card, size_t num_cards) +update_mod_union (guint8 *dest, guint8 *start_card, size_t num_cards) { - if (init) { - memcpy (dest, start_card, num_cards); - } else { - int i; - for (i = 0; i < num_cards; ++i) - dest [i] |= start_card [i]; - } + int i; + for (i = 0; i < num_cards; ++i) + dest [i] |= start_card [i]; } -static guint8* -alloc_mod_union (size_t num_cards) +guint8* +sgen_card_table_alloc_mod_union (char *obj, mword obj_size) { - return sgen_alloc_internal_dynamic (num_cards, INTERNAL_MEM_CARDTABLE_MOD_UNION, TRUE); + size_t num_cards = cards_in_range ((mword) obj, obj_size); + guint8 *mod_union = sgen_alloc_internal_dynamic (num_cards, INTERNAL_MEM_CARDTABLE_MOD_UNION, TRUE); + memset (mod_union, 0, num_cards); + return mod_union; } -guint8* -sgen_card_table_update_mod_union_from_cards (guint8 *dest, guint8 *start_card, size_t num_cards) +void +sgen_card_table_free_mod_union (guint8 *mod_union, char *obj, mword obj_size) { - gboolean init = dest == NULL; - - if (init) - dest = alloc_mod_union (num_cards); - - update_mod_union (dest, init, start_card, num_cards); + size_t num_cards = cards_in_range ((mword) obj, obj_size); + sgen_free_internal_dynamic (mod_union, num_cards, INTERNAL_MEM_CARDTABLE_MOD_UNION); +} - return dest; +void +sgen_card_table_update_mod_union_from_cards (guint8 *dest, guint8 *start_card, size_t num_cards) +{ + SGEN_ASSERT (0, dest, "Why don't we have a mod union?"); + update_mod_union (dest, start_card, num_cards); } -guint8* +void sgen_card_table_update_mod_union (guint8 *dest, char *obj, mword obj_size, size_t *out_num_cards) { guint8 *start_card = sgen_card_table_get_card_address ((mword)obj); @@ -327,7 +328,6 @@ sgen_card_table_update_mod_union (guint8 *dest, char *obj, mword obj_size, size_ guint8 *end_card = sgen_card_table_get_card_address ((mword)obj + obj_size - 1) + 1; #endif size_t num_cards; - guint8 *result = NULL; #ifdef SGEN_HAVE_OVERLAPPING_CARDS size_t rest; @@ -336,9 +336,7 @@ sgen_card_table_update_mod_union (guint8 *dest, char *obj, mword obj_size, size_ while (start_card + rest > SGEN_CARDTABLE_END) { size_t count = SGEN_CARDTABLE_END - start_card; - dest = sgen_card_table_update_mod_union_from_cards (dest, start_card, count); - if (!result) - result = dest; + sgen_card_table_update_mod_union_from_cards (dest, start_card, count); dest += count; rest -= count; start_card = sgen_cardtable; @@ -348,14 +346,10 @@ sgen_card_table_update_mod_union (guint8 *dest, char *obj, mword obj_size, size_ num_cards = end_card - start_card; #endif - dest = sgen_card_table_update_mod_union_from_cards (dest, start_card, num_cards); - if (!result) - result = dest; + sgen_card_table_update_mod_union_from_cards (dest, start_card, num_cards); if (out_num_cards) *out_num_cards = num_cards; - - return result; } #ifdef SGEN_HAVE_OVERLAPPING_CARDS @@ -411,7 +405,7 @@ clear_cards (mword start, mword size) #endif static void -sgen_card_table_prepare_for_major_collection (void) +sgen_card_table_clear_cards (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); @@ -425,7 +419,7 @@ sgen_card_table_finish_minor_collection (void) } static void -sgen_card_table_finish_scan_remsets (void *start_nursery, void *end_nursery, SgenGrayQueue *queue) +sgen_card_table_scan_remsets (ScanCopyContext ctx) { SGEN_TV_DECLARE (atv); SGEN_TV_DECLARE (btv); @@ -439,14 +433,14 @@ sgen_card_table_finish_scan_remsets (void *start_nursery, void *end_nursery, Sge sgen_los_iterate_live_block_ranges (move_cards_to_shadow_table); /*Then we clear*/ - sgen_card_table_prepare_for_major_collection (); + sgen_card_table_clear_cards (); #endif SGEN_TV_GETTIME (atv); - sgen_major_collector_scan_card_table (queue); + sgen_get_major_collector ()->scan_card_table (FALSE, ctx); 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 (FALSE, queue); + sgen_los_scan_card_table (FALSE, ctx); SGEN_TV_GETTIME (atv); last_los_scan_time = SGEN_TV_ELAPSED (btv, atv); los_card_scan_time += last_los_scan_time; @@ -455,6 +449,9 @@ sgen_card_table_finish_scan_remsets (void *start_nursery, void *end_nursery, Sge guint8* mono_gc_get_card_table (int *shift_bits, gpointer *mask) { +#ifndef MANAGED_WBARRIER + return NULL; +#else if (!sgen_cardtable) return NULL; @@ -466,6 +463,7 @@ mono_gc_get_card_table (int *shift_bits, gpointer *mask) #endif return sgen_cardtable; +#endif } gboolean @@ -475,22 +473,6 @@ mono_gc_card_table_nursery_check (void) } #if 0 -static void -collect_faulted_cards (void) -{ -#define CARD_PAGES (CARD_COUNT_IN_BYTES / 4096) - int i, count = 0; - unsigned char faulted [CARD_PAGES] = { 0 }; - mincore (sgen_cardtable, CARD_COUNT_IN_BYTES, faulted); - - for (i = 0; i < CARD_PAGES; ++i) { - if (faulted [i]) - ++count; - } - - printf ("TOTAL card pages %d faulted %d\n", CARD_PAGES, count); -} - void sgen_card_table_dump_obj_card (char *object, size_t size, void *dummy) { @@ -568,7 +550,7 @@ find_next_card (guint8 *card_data, guint8 *end) } void -sgen_cardtable_scan_object (char *obj, mword block_obj_size, guint8 *cards, gboolean mod_union, SgenGrayQueue *queue) +sgen_cardtable_scan_object (char *obj, mword block_obj_size, guint8 *cards, gboolean mod_union, ScanCopyContext ctx) { MonoVTable *vt = (MonoVTable*)SGEN_LOAD_VTABLE (obj); MonoClass *klass = vt->klass; @@ -646,19 +628,19 @@ LOOP_HEAD: elem = first_elem = (char*)mono_array_addr_with_size_fast ((MonoArray*)obj, elem_size, index); if (klass->element_class->valuetype) { - ScanVTypeFunc scan_vtype_func = sgen_get_current_object_ops ()->scan_vtype; + ScanVTypeFunc scan_vtype_func = ctx.ops->scan_vtype; for (; elem < card_end; elem += elem_size) - scan_vtype_func (elem, desc, queue BINARY_PROTOCOL_ARG (elem_size)); + scan_vtype_func (obj, elem, desc, ctx.queue BINARY_PROTOCOL_ARG (elem_size)); } else { - CopyOrMarkObjectFunc copy_func = sgen_get_current_object_ops ()->copy_or_mark_object; + CopyOrMarkObjectFunc copy_func = ctx.ops->copy_or_mark_object; HEAVY_STAT (++los_array_cards); for (; elem < card_end; elem += SIZEOF_VOID_P) { gpointer new, old = *(gpointer*)elem; if ((mod_union && old) || G_UNLIKELY (sgen_ptr_in_nursery (old))) { HEAVY_STAT (++los_array_remsets); - copy_func ((void**)elem, queue); + copy_func ((void**)elem, ctx.queue); new = *(gpointer*)elem; if (G_UNLIKELY (sgen_ptr_in_nursery (new))) sgen_add_to_global_remset (elem, new); @@ -683,9 +665,9 @@ LOOP_HEAD: HEAVY_STAT (++bloby_objects); if (cards) { if (sgen_card_table_is_range_marked (cards, (mword)obj, block_obj_size)) - sgen_get_current_object_ops ()->scan_object (obj, queue); + ctx.ops->scan_object (obj, sgen_obj_get_descriptor (obj), ctx.queue); } else if (sgen_card_table_region_begin_scanning ((mword)obj, block_obj_size)) { - sgen_get_current_object_ops ()->scan_object (obj, queue); + ctx.ops->scan_object (obj, sgen_obj_get_descriptor (obj), ctx.queue); } binary_protocol_card_scan (obj, sgen_safe_object_get_size ((MonoObject*)obj)); @@ -756,7 +738,7 @@ sgen_card_tables_collect_stats (gboolean begin) } void -sgen_card_table_init (SgenRemeberedSet *remset) +sgen_card_table_init (SgenRememberedSet *remset) { sgen_cardtable = sgen_alloc_os_memory (CARD_COUNT_IN_BYTES, SGEN_ALLOC_INTERNAL | SGEN_ALLOC_ACTIVATE, "card table"); @@ -765,19 +747,19 @@ sgen_card_table_init (SgenRemeberedSet *remset) #endif #ifdef HEAVY_STATISTICS - mono_counters_register ("marked cards", MONO_COUNTER_GC | MONO_COUNTER_LONG, &marked_cards); - mono_counters_register ("scanned cards", MONO_COUNTER_GC | MONO_COUNTER_LONG, &scanned_cards); - mono_counters_register ("remarked cards", MONO_COUNTER_GC | MONO_COUNTER_LONG, &remarked_cards); - - mono_counters_register ("los marked cards", MONO_COUNTER_GC | MONO_COUNTER_LONG, &los_marked_cards); - mono_counters_register ("los array cards scanned ", MONO_COUNTER_GC | MONO_COUNTER_LONG, &los_array_cards); - mono_counters_register ("los array remsets", MONO_COUNTER_GC | MONO_COUNTER_LONG, &los_array_remsets); - mono_counters_register ("cardtable scanned objects", MONO_COUNTER_GC | MONO_COUNTER_LONG, &scanned_objects); - mono_counters_register ("cardtable large objects", MONO_COUNTER_GC | MONO_COUNTER_LONG, &large_objects); - mono_counters_register ("cardtable bloby objects", MONO_COUNTER_GC | MONO_COUNTER_LONG, &bloby_objects); + mono_counters_register ("marked cards", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &marked_cards); + mono_counters_register ("scanned cards", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &scanned_cards); + mono_counters_register ("remarked cards", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &remarked_cards); + + mono_counters_register ("los marked cards", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &los_marked_cards); + mono_counters_register ("los array cards scanned ", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &los_array_cards); + mono_counters_register ("los array remsets", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &los_array_remsets); + mono_counters_register ("cardtable scanned objects", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &scanned_objects); + 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_LONG | MONO_COUNTER_TIME, &major_card_scan_time); - mono_counters_register ("cardtable los scan time", MONO_COUNTER_GC | MONO_COUNTER_LONG | MONO_COUNTER_TIME, &los_card_scan_time); + 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; @@ -788,10 +770,10 @@ sgen_card_table_init (SgenRemeberedSet *remset) remset->wbarrier_generic_nostore = sgen_card_table_wbarrier_generic_nostore; remset->record_pointer = sgen_card_table_record_pointer; - remset->finish_scan_remsets = sgen_card_table_finish_scan_remsets; + remset->scan_remsets = sgen_card_table_scan_remsets; remset->finish_minor_collection = sgen_card_table_finish_minor_collection; - remset->prepare_for_major_collection = sgen_card_table_prepare_for_major_collection; + 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;