#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"
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;
}
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;
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);
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;
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;
}
}
}
+
+ binary_protocol_card_scan (first_elem, elem - first_elem);
}
#ifdef SGEN_HAVE_OVERLAPPING_CARDS
} 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));
}
}