if (__old && FOLLOW_OBJECT (__old)) { \
void *__copy; \
PREFETCH_DYNAMIC_HEAP (__old); \
- CONCURRENT_NAME (major_copy_or_mark_object) ((ptr), __old, queue); \
+ CONCURRENT_NAME (major_copy_or_mark_object_with_evacuation) ((ptr), __old, queue); \
__copy = *(ptr); \
SGEN_COND_LOG (9, __old != __copy, "Overwrote field at %p with %p (was: %p)", (ptr), *(ptr), __old); \
if (G_UNLIKELY (sgen_ptr_in_nursery (__copy) && !sgen_ptr_in_nursery ((ptr)) && !SGEN_OBJECT_IS_CEMENTED (__copy))) \
if (sgen_nursery_is_to_space (obj))
return TRUE;
+#ifdef COPY_OR_MARK_WITH_EVACUATION
do_copy_object:
+#endif
old_obj = obj;
obj = copy_object_no_checks (obj, queue);
SGEN_ASSERT (0, old_obj != obj, "Cannot handle copy object failure.");
return FALSE;
} else {
#ifdef SGEN_MARK_ON_ENQUEUE
- char *forwarded;
mword vtable_word = *(mword*)obj;
mword desc = sgen_vtable_get_descriptor ((MonoVTable*)vtable_word);
int type = desc & 7;
HEAVY_STAT (++stat_optimized_copy_major);
- if ((forwarded = SGEN_VTABLE_IS_FORWARDED (vtable_word))) {
- HEAVY_STAT (++stat_optimized_copy_major_forwarded);
- *ptr = forwarded;
- return FALSE;
+#ifdef COPY_OR_MARK_WITH_EVACUATION
+ {
+ char *forwarded;
+ if ((forwarded = SGEN_VTABLE_IS_FORWARDED (vtable_word))) {
+ HEAVY_STAT (++stat_optimized_copy_major_forwarded);
+ *ptr = forwarded;
+ return FALSE;
+ }
}
+#endif
if (type <= DESC_TYPE_MAX_SMALL_OBJ || SGEN_ALIGN_UP (sgen_safe_object_get_size ((MonoObject*)obj)) <= SGEN_MAX_SMALL_OBJ_SIZE) {
- int size_index;
- gboolean evacuate;
-
#ifdef HEAVY_STATISTICS
if (type <= DESC_TYPE_MAX_SMALL_OBJ)
++stat_optimized_copy_major_small_fast;
#endif
block = MS_BLOCK_FOR_OBJ (obj);
- size_index = block->obj_size_index;
- evacuate = evacuate_block_obj_sizes [size_index];
-
- if (evacuate && !block->has_pinned) {
- HEAVY_STAT (++stat_optimized_copy_major_small_evacuate);
- if (block->is_to_space)
- return FALSE;
- goto do_copy_object;
+
+#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;
+ }
}
+#endif
MS_MARK_OBJECT_AND_ENQUEUE (obj, desc, block, queue);
} else {
}
#undef COPY_OR_MARK_FUNCTION_NAME
+#undef COPY_OR_MARK_WITH_EVACUATION
#undef DRAIN_GRAY_STACK_FUNCTION_NAME
#ifdef SGEN_HAVE_CONCURRENT_MARK
static void
-major_copy_or_mark_object_concurrent (void **ptr, void *obj, SgenGrayQueue *queue)
+major_copy_or_mark_object_with_evacuation_concurrent (void **ptr, void *obj, SgenGrayQueue *queue)
{
SGEN_ASSERT (9, sgen_concurrent_collection_in_progress (), "Why are we scanning concurrently when there's no concurrent collection on?");
SGEN_ASSERT (9, !sgen_workers_are_working () || sgen_is_worker_thread (mono_native_thread_id_get ()), "We must not scan from two threads at the same time!");
static void major_scan_object (char *start, mword desc, SgenGrayQueue *queue);
-#define COPY_OR_MARK_FUNCTION_NAME major_copy_or_mark_object
-#define DRAIN_GRAY_STACK_FUNCTION_NAME drain_gray_stack
+#define COPY_OR_MARK_FUNCTION_NAME major_copy_or_mark_object_no_evacuation
+#define DRAIN_GRAY_STACK_FUNCTION_NAME drain_gray_stack_no_evacuation
#include "sgen-marksweep-drain-gray-stack.h"
+#define COPY_OR_MARK_WITH_EVACUATION
+#define COPY_OR_MARK_FUNCTION_NAME major_copy_or_mark_object_with_evacuation
+#define DRAIN_GRAY_STACK_FUNCTION_NAME drain_gray_stack_with_evacuation
+#include "sgen-marksweep-drain-gray-stack.h"
+
+static gboolean
+drain_gray_stack (ScanCopyContext ctx)
+{
+ gboolean evacuation = FALSE;
+ for (int i = 0; i < num_block_obj_sizes; ++i) {
+ if (evacuate_block_obj_sizes [i]) {
+ evacuation = TRUE;
+ break;
+ }
+ }
+
+ if (evacuation)
+ return drain_gray_stack_with_evacuation (ctx);
+ else
+ return drain_gray_stack_no_evacuation (ctx);
+}
+
#include "sgen-major-scan-object.h"
#ifdef SGEN_HAVE_CONCURRENT_MARK
static void
major_copy_or_mark_object_canonical (void **ptr, SgenGrayQueue *queue)
{
- major_copy_or_mark_object (ptr, *ptr, queue);
+ major_copy_or_mark_object_with_evacuation (ptr, *ptr, queue);
}
#ifdef SGEN_HAVE_CONCURRENT_MARK
static void
major_copy_or_mark_object_concurrent_canonical (void **ptr, SgenGrayQueue *queue)
{
- major_copy_or_mark_object_concurrent (ptr, *ptr, queue);
+ major_copy_or_mark_object_with_evacuation_concurrent (ptr, *ptr, queue);
}
#endif