X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fsgen%2Fsgen-marksweep-drain-gray-stack.h;h=ad2bb6fe272a44cbf08ce80ac65da5dbd177a0c7;hb=56ad8f4e5dfb8198e4671f631a3103b1e8b83dd3;hp=90dc7f4af6c92eaf930c573caa0468a290859837;hpb=3137468f103d0d45338c371451095bb5345b338c;p=mono.git diff --git a/mono/sgen/sgen-marksweep-drain-gray-stack.h b/mono/sgen/sgen-marksweep-drain-gray-stack.h index 90dc7f4af6c..ad2bb6fe272 100644 --- a/mono/sgen/sgen-marksweep-drain-gray-stack.h +++ b/mono/sgen/sgen-marksweep-drain-gray-stack.h @@ -4,18 +4,7 @@ * * Copyright (C) 2014 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ /* @@ -40,7 +29,7 @@ COPY_OR_MARK_FUNCTION_NAME (GCObject **ptr, GCObject *obj, SgenGrayQueue *queue) #ifdef HEAVY_STATISTICS ++stat_optimized_copy; { - char *forwarded; + GCObject *forwarded; SgenDescriptor desc; if ((forwarded = SGEN_OBJECT_IS_FORWARDED (obj))) desc = sgen_obj_get_descriptor_safe (forwarded); @@ -52,9 +41,12 @@ COPY_OR_MARK_FUNCTION_NAME (GCObject **ptr, GCObject *obj, SgenGrayQueue *queue) #endif SGEN_ASSERT (9, obj, "null object from pointer %p", ptr); +#if !defined(COPY_OR_MARK_CONCURRENT) && !defined(COPY_OR_MARK_CONCURRENT_WITH_EVACUATION) SGEN_ASSERT (9, current_collection_generation == GENERATION_OLD, "old gen parallel allocator called from a %d collection", current_collection_generation); +#endif if (sgen_ptr_in_nursery (obj)) { +#if !defined(COPY_OR_MARK_CONCURRENT) && !defined(COPY_OR_MARK_CONCURRENT_WITH_EVACUATION) int word, bit; GCObject *forwarded, *old_obj; mword vtable_word = *(mword*)obj; @@ -71,7 +63,7 @@ COPY_OR_MARK_FUNCTION_NAME (GCObject **ptr, GCObject *obj, SgenGrayQueue *queue) HEAVY_STAT (++stat_optimized_copy_nursery_pinned); return TRUE; } - if ((forwarded = SGEN_VTABLE_IS_FORWARDED (vtable_word))) { + if ((forwarded = (GCObject *)SGEN_VTABLE_IS_FORWARDED (vtable_word))) { HEAVY_STAT (++stat_optimized_copy_nursery_forwarded); SGEN_UPDATE_REFERENCE (ptr, forwarded); return sgen_ptr_in_nursery (forwarded); @@ -128,6 +120,7 @@ COPY_OR_MARK_FUNCTION_NAME (GCObject **ptr, GCObject *obj, SgenGrayQueue *queue) binary_protocol_mark (obj, (gpointer)LOAD_VTABLE (obj), sgen_safe_object_get_size (obj)); return FALSE; +#endif } else { mword vtable_word = *(mword*)obj; SgenDescriptor desc; @@ -138,7 +131,7 @@ COPY_OR_MARK_FUNCTION_NAME (GCObject **ptr, GCObject *obj, SgenGrayQueue *queue) #ifdef COPY_OR_MARK_WITH_EVACUATION { GCObject *forwarded; - if ((forwarded = SGEN_VTABLE_IS_FORWARDED (vtable_word))) { + if ((forwarded = (GCObject *)SGEN_VTABLE_IS_FORWARDED (vtable_word))) { HEAVY_STAT (++stat_optimized_copy_major_forwarded); SGEN_UPDATE_REFERENCE (ptr, forwarded); SGEN_ASSERT (9, !sgen_ptr_in_nursery (forwarded), "Cannot be forwarded to nursery."); @@ -162,16 +155,21 @@ COPY_OR_MARK_FUNCTION_NAME (GCObject **ptr, GCObject *obj, SgenGrayQueue *queue) block = MS_BLOCK_FOR_OBJ (obj); +#ifdef COPY_OR_MARK_CONCURRENT_WITH_EVACUATION + if (G_UNLIKELY (major_block_is_evacuating (block))) { + /* + * We don't copy within the concurrent phase. These objects will + * be handled below in the finishing pause, by scanning the mod-union + * card table. + */ + return FALSE; + } +#endif + #ifdef COPY_OR_MARK_WITH_EVACUATION - { - int size_index = block->obj_size_index; - - if (evacuate_block_obj_sizes [size_index] && !block->has_pinned) { - HEAVY_STAT (++stat_optimized_copy_major_small_evacuate); - if (block->is_to_space) - return FALSE; - goto do_copy_object; - } + if (major_block_is_evacuating (block)) { + HEAVY_STAT (++stat_optimized_copy_major_small_evacuate); + goto do_copy_object; } #endif @@ -189,14 +187,14 @@ COPY_OR_MARK_FUNCTION_NAME (GCObject **ptr, GCObject *obj, SgenGrayQueue *queue) } return FALSE; } - SGEN_ASSERT (0, FALSE, "How is this happening?"); - return FALSE; + + return TRUE; } static void -SCAN_OBJECT_FUNCTION_NAME (GCObject *obj, SgenDescriptor desc, SgenGrayQueue *queue) +SCAN_OBJECT_FUNCTION_NAME (GCObject *full_object, SgenDescriptor desc, SgenGrayQueue *queue) { - char *start = (char*)obj; + char *start = (char*)full_object; #ifdef HEAVY_STATISTICS ++stat_optimized_major_scan; @@ -211,26 +209,94 @@ SCAN_OBJECT_FUNCTION_NAME (GCObject *obj, SgenDescriptor desc, SgenGrayQueue *qu /* Now scan the object. */ #undef HANDLE_PTR +#if defined(COPY_OR_MARK_CONCURRENT_WITH_EVACUATION) #define HANDLE_PTR(ptr,obj) do { \ - void *__old = *(ptr); \ - binary_protocol_scan_process_reference ((obj), (ptr), __old); \ + GCObject *__old = *(ptr); \ + binary_protocol_scan_process_reference ((full_object), (ptr), __old); \ + if (__old && !sgen_ptr_in_nursery (__old)) { \ + if (G_UNLIKELY (!sgen_ptr_in_nursery (ptr) && \ + sgen_safe_object_is_small (__old, sgen_obj_get_descriptor (__old) & DESC_TYPE_MASK) && \ + major_block_is_evacuating (MS_BLOCK_FOR_OBJ (__old)))) { \ + mark_mod_union_card ((full_object), (void**)(ptr), __old); \ + } else { \ + PREFETCH_READ (__old); \ + COPY_OR_MARK_FUNCTION_NAME ((ptr), __old, queue); \ + } \ + } else { \ + if (G_UNLIKELY (sgen_ptr_in_nursery (__old) && !sgen_ptr_in_nursery ((ptr)) && !sgen_cement_is_forced (__old))) \ + mark_mod_union_card ((full_object), (void**)(ptr), __old); \ + } \ + } while (0) +#elif defined(COPY_OR_MARK_CONCURRENT) +#define HANDLE_PTR(ptr,obj) do { \ + GCObject *__old = *(ptr); \ + binary_protocol_scan_process_reference ((full_object), (ptr), __old); \ + if (__old && !sgen_ptr_in_nursery (__old)) { \ + PREFETCH_READ (__old); \ + COPY_OR_MARK_FUNCTION_NAME ((ptr), __old, queue); \ + } else { \ + if (G_UNLIKELY (sgen_ptr_in_nursery (__old) && !sgen_ptr_in_nursery ((ptr)) && !sgen_cement_is_forced (__old))) \ + mark_mod_union_card ((full_object), (void**)(ptr), __old); \ + } \ + } while (0) +#else +#define HANDLE_PTR(ptr,obj) do { \ + GCObject *__old = *(ptr); \ + binary_protocol_scan_process_reference ((full_object), (ptr), __old); \ if (__old) { \ gboolean __still_in_nursery = COPY_OR_MARK_FUNCTION_NAME ((ptr), __old, queue); \ if (G_UNLIKELY (__still_in_nursery && !sgen_ptr_in_nursery ((ptr)) && !SGEN_OBJECT_IS_CEMENTED (*(ptr)))) { \ - void *__copy = *(ptr); \ + GCObject *__copy = *(ptr); \ sgen_add_to_global_remset ((ptr), __copy); \ } \ } \ } while (0) +#endif + +#define SCAN_OBJECT_PROTOCOL +#include "sgen-scan-object.h" +} + +#ifdef SCAN_VTYPE_FUNCTION_NAME +static void +SCAN_VTYPE_FUNCTION_NAME (GCObject *full_object, char *start, SgenDescriptor desc, SgenGrayQueue *queue BINARY_PROTOCOL_ARG (size_t size)) +{ + SGEN_OBJECT_LAYOUT_STATISTICS_DECLARE_BITMAP; + +#ifdef HEAVY_STATISTICS + /* FIXME: We're half scanning this object. How do we account for that? */ + //add_scanned_object (start); +#endif + + /* The descriptors include info about the object header as well */ + start -= SGEN_CLIENT_OBJECT_HEADER_SIZE; + /* We use the same HANDLE_PTR from the obj scan function */ +#define SCAN_OBJECT_NOVTABLE #define SCAN_OBJECT_PROTOCOL #include "sgen-scan-object.h" + + SGEN_OBJECT_LAYOUT_STATISTICS_COMMIT_BITMAP; } +#endif + +#ifdef SCAN_PTR_FIELD_FUNCTION_NAME +static void +SCAN_PTR_FIELD_FUNCTION_NAME (GCObject *full_object, GCObject **ptr, SgenGrayQueue *queue) +{ + HANDLE_PTR (ptr, NULL); +} +#endif static gboolean DRAIN_GRAY_STACK_FUNCTION_NAME (SgenGrayQueue *queue) { +#if defined(COPY_OR_MARK_CONCURRENT) || defined(COPY_OR_MARK_CONCURRENT_WITH_EVACUATION) + int i; + for (i = 0; i < 32; i++) { +#else for (;;) { +#endif GCObject *obj; SgenDescriptor desc; @@ -242,9 +308,14 @@ DRAIN_GRAY_STACK_FUNCTION_NAME (SgenGrayQueue *queue) SCAN_OBJECT_FUNCTION_NAME (obj, desc, queue); } + return FALSE; } #undef COPY_OR_MARK_FUNCTION_NAME #undef COPY_OR_MARK_WITH_EVACUATION +#undef COPY_OR_MARK_CONCURRENT +#undef COPY_OR_MARK_CONCURRENT_WITH_EVACUATION #undef SCAN_OBJECT_FUNCTION_NAME +#undef SCAN_VTYPE_FUNCTION_NAME +#undef SCAN_PTR_FIELD_FUNCTION_NAME #undef DRAIN_GRAY_STACK_FUNCTION_NAME