Add two wrappers which are used to transition between normal and gsharedvt code.
[mono.git] / mono / metadata / sgen-cardtable.c
index f615acd477565d8c09b6fc5792f00f2d10849b28..8bd280f23725a113859c94ff52201fcbed22ff05 100644 (file)
@@ -29,6 +29,7 @@
 #include "metadata/sgen-gc.h"
 #include "metadata/sgen-cardtable.h"
 #include "metadata/sgen-memory-governor.h"
+#include "metadata/sgen-protocol.h"
 #include "utils/mono-counters.h"
 #include "utils/mono-time.h"
 #include "utils/mono-memory-model.h"
@@ -440,7 +441,7 @@ find_card_offset (mword card)
        return (__builtin_ffsll (GUINT64_TO_LE(card)) - 1) / 8;
 #else
        int i;
-       guint8 *ptr = (guint *) &card;
+       guint8 *ptr = (guint8 *) &card;
        for (i = 0; i < sizeof (mword); ++i) {
                if (ptr[i])
                        return i;
@@ -484,7 +485,8 @@ find_next_card (guint8 *card_data, guint8 *end)
 }
 
 void
-sgen_cardtable_scan_object (char *obj, mword block_obj_size, guint8 *cards, SgenGrayQueue *queue)
+sgen_cardtable_scan_object (char *obj, mword block_obj_size, guint8 *cards,
+               gboolean always_copy_or_mark, SgenGrayQueue *queue)
 {
        MonoVTable *vt = (MonoVTable*)SGEN_LOAD_VTABLE (obj);
        MonoClass *klass = vt->klass;
@@ -537,7 +539,7 @@ LOOP_HEAD:
                        int idx = (card_data - card_base) + extra_idx;
                        char *start = (char*)(obj_start + idx * CARD_SIZE_IN_BYTES);
                        char *card_end = start + CARD_SIZE_IN_BYTES;
-                       char *elem;
+                       char *first_elem, *elem;
 
                        HEAVY_STAT (++los_marked_cards);
 
@@ -551,7 +553,7 @@ LOOP_HEAD:
                        else
                                index = ARRAY_OBJ_INDEX (start, obj, elem_size);
 
-                       elem = (char*)mono_array_addr_with_size ((MonoArray*)obj, elem_size, index);
+                       elem = first_elem = (char*)mono_array_addr_with_size ((MonoArray*)obj, elem_size, index);
                        if (klass->element_class->valuetype) {
                                ScanVTypeFunc scan_vtype_func = sgen_get_current_object_ops ()->scan_vtype;
 
@@ -563,7 +565,7 @@ LOOP_HEAD:
                                HEAVY_STAT (++los_array_cards);
                                for (; elem < card_end; elem += SIZEOF_VOID_P) {
                                        gpointer new, old = *(gpointer*)elem;
-                                       if (G_UNLIKELY (sgen_ptr_in_nursery (old))) {
+                                       if ((always_copy_or_mark && old) || G_UNLIKELY (sgen_ptr_in_nursery (old))) {
                                                HEAVY_STAT (++los_array_remsets);
                                                copy_func ((void**)elem, queue);
                                                new = *(gpointer*)elem;
@@ -572,6 +574,8 @@ LOOP_HEAD:
                                        }
                                }
                        }
+
+                       binary_protocol_card_scan (first_elem, elem - first_elem);
                }
 
 #ifdef SGEN_HAVE_OVERLAPPING_CARDS
@@ -592,6 +596,8 @@ LOOP_HEAD:
                } else if (sgen_card_table_region_begin_scanning ((mword)obj, block_obj_size)) {
                        sgen_get_current_object_ops ()->scan_object (obj, queue);
                }
+
+               binary_protocol_card_scan (obj, sgen_safe_object_get_size ((MonoObject*)obj));
        }
 }