X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fsgen%2Fsgen-los.c;h=791eaa25abc15fc3868559945a0da42c43f5f7c4;hb=HEAD;hp=4b52eefb3f00cdf295504d29a21780667e99f144;hpb=8c32f9c042d4e05acf8d712dcb9f00b8362da55f;p=mono.git diff --git a/mono/sgen/sgen-los.c b/mono/sgen/sgen-los.c index 4b52eefb3f0..791eaa25abc 100644 --- a/mono/sgen/sgen-los.c +++ b/mono/sgen/sgen-los.c @@ -1,5 +1,6 @@ -/* - * sgen-los.c: Large objects space. +/** + * \file + * Large objects space. * * Author: * Paolo Molaro (lupus@ximian.com) @@ -251,7 +252,7 @@ get_los_section_memory (size_t size) if (!sgen_memgov_try_alloc_space (LOS_SECTION_SIZE, SPACE_LOS)) return NULL; - section = (LOSSection *)sgen_alloc_os_memory_aligned (LOS_SECTION_SIZE, LOS_SECTION_SIZE, (SgenAllocFlags)(SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE), NULL); + section = (LOSSection *)sgen_alloc_os_memory_aligned (LOS_SECTION_SIZE, LOS_SECTION_SIZE, (SgenAllocFlags)(SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE), NULL, MONO_MEM_ACCOUNT_SGEN_LOS); if (!section) return NULL; @@ -323,13 +324,13 @@ sgen_los_free_object (LOSObject *obj) los_num_objects--; #ifdef USE_MALLOC - free (obj); + g_free (obj); #else if (size > LOS_SECTION_OBJECT_LIMIT) { int pagesize = mono_pagesize (); size += sizeof (LOSObject); size = SGEN_ALIGN_UP_TO (size, pagesize); - sgen_free_os_memory ((gpointer)SGEN_ALIGN_DOWN_TO ((mword)obj, pagesize), size, SGEN_ALLOC_HEAP); + sgen_free_os_memory ((gpointer)SGEN_ALIGN_DOWN_TO ((mword)obj, pagesize), size, SGEN_ALLOC_HEAP, MONO_MEM_ACCOUNT_SGEN_LOS); los_memory_usage_total -= size; sgen_memgov_release_space (size, SPACE_LOS); } else { @@ -379,7 +380,7 @@ sgen_los_alloc_large_inner (GCVTable vtable, size_t size) sgen_ensure_free_space (size, GENERATION_OLD); #ifdef USE_MALLOC - obj = malloc (size + sizeof (LOSObject)); + obj = g_malloc (size + sizeof (LOSObject)); memset (obj, 0, size + sizeof (LOSObject)); #else if (size > LOS_SECTION_OBJECT_LIMIT) { @@ -387,7 +388,7 @@ sgen_los_alloc_large_inner (GCVTable vtable, size_t size) int pagesize = mono_pagesize (); size_t alloc_size = SGEN_ALIGN_UP_TO (obj_size, pagesize); if (sgen_memgov_try_alloc_space (alloc_size, SPACE_LOS)) { - obj = (LOSObject *)sgen_alloc_os_memory (alloc_size, (SgenAllocFlags)(SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE), NULL); + obj = (LOSObject *)sgen_alloc_os_memory (alloc_size, (SgenAllocFlags)(SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE), NULL, MONO_MEM_ACCOUNT_SGEN_LOS); if (obj) { los_memory_usage_total += alloc_size; obj = randomize_los_object_start (obj, obj_size, alloc_size, pagesize); @@ -479,7 +480,7 @@ sgen_los_sweep (void) prev->next = next; else los_sections = next; - sgen_free_os_memory (section, LOS_SECTION_SIZE, SGEN_ALLOC_HEAP); + sgen_free_os_memory (section, LOS_SECTION_SIZE, SGEN_ALLOC_HEAP, MONO_MEM_ACCOUNT_SGEN_LOS); sgen_memgov_release_space (LOS_SECTION_SIZE, SPACE_LOS); section = next; --los_num_sections; @@ -526,12 +527,14 @@ sgen_ptr_is_in_los (char *ptr, char **start) { LOSObject *obj; - *start = NULL; + if (start) + *start = NULL; for (obj = los_object_list; obj; obj = obj->next) { char *end = (char*)obj->data + sgen_los_object_size (obj); if (ptr >= (char*)obj->data && ptr < end) { - *start = (char*)obj->data; + if (start) + *start = (char*)obj->data; return TRUE; } } @@ -622,15 +625,19 @@ get_cardtable_mod_union_for_object (LOSObject *obj) } void -sgen_los_scan_card_table (CardTableScanType scan_type, ScanCopyContext ctx) +sgen_los_scan_card_table (CardTableScanType scan_type, ScanCopyContext ctx, int job_index, int job_split_count) { LOSObject *obj; + int i = 0; binary_protocol_los_card_table_scan_start (sgen_timestamp (), scan_type & CARDTABLE_SCAN_MOD_UNION); - for (obj = los_object_list; obj; obj = obj->next) { + for (obj = los_object_list; obj; obj = obj->next, i++) { mword num_cards = 0; guint8 *cards; + if (i % job_split_count != job_index) + continue; + if (!SGEN_OBJECT_HAS_REFERENCES (obj->data)) continue; @@ -638,6 +645,9 @@ sgen_los_scan_card_table (CardTableScanType scan_type, ScanCopyContext ctx) if (!sgen_los_object_is_pinned (obj->data)) continue; + if (!obj->cardtable_mod_union) + continue; + cards = get_cardtable_mod_union_for_object (obj); g_assert (cards); if (scan_type == CARDTABLE_SCAN_MOD_UNION_PRECLEAN) { @@ -720,6 +730,24 @@ sgen_los_pin_object (GCObject *data) binary_protocol_pin (data, (gpointer)SGEN_LOAD_VTABLE (data), sgen_safe_object_get_size (data)); } +gboolean +sgen_los_pin_object_par (GCObject *data) +{ + LOSObject *obj = sgen_los_header_for_object (data); + mword old_size = obj->size; + if (old_size & 1) + return FALSE; +#if SIZEOF_VOID_P == 4 + old_size = InterlockedCompareExchange ((volatile gint32*)&obj->size, old_size | 1, old_size); +#else + old_size = InterlockedCompareExchange64 ((volatile gint64*)&obj->size, old_size | 1, old_size); +#endif + if (old_size & 1) + return FALSE; + binary_protocol_pin (data, (gpointer)SGEN_LOAD_VTABLE (data), sgen_safe_object_get_size (data)); + return TRUE; +} + static void sgen_los_unpin_object (GCObject *data) {