Permalink
Browse files

[sgen] Evacuation for concurrent mark (during forced collections).

  • Loading branch information...
1 parent ba49b2c commit 0a578ac2e72a840ce0d7c1a889b249ed7cf165fc @schani schani committed Jan 27, 2013
@@ -3047,9 +3047,11 @@ major_start_collection (gboolean concurrent, int *old_next_pin_slot)
concurrent_collection_in_progress = TRUE;
sgen_cement_concurrent_start ();
- }
- current_object_ops = major_collector.major_ops;
+ current_object_ops = major_collector.major_concurrent_ops;
+ } else {
+ current_object_ops = major_collector.major_ops;
+ }
reset_pinned_from_failed_allocation ();
@@ -3100,16 +3102,18 @@ major_finish_collection (const char *reason, int old_next_pin_slot, gboolean sca
if (concurrent_collection_in_progress || major_collector.is_parallel)
wait_for_workers_to_finish ();
- current_object_ops = major_collector.major_ops;
-
if (concurrent_collection_in_progress) {
+ current_object_ops = major_collector.major_concurrent_ops;
+
major_copy_or_mark_from_roots (NULL, TRUE, scan_mod_union);
wait_for_workers_to_finish ();
g_assert (sgen_gray_object_queue_is_empty (&gray_queue));
if (do_concurrent_checks)
check_nursery_is_clean ();
+ } else {
+ current_object_ops = major_collector.major_ops;
}
/*
@@ -655,6 +655,7 @@ struct _SgenMajorCollector {
void* (*alloc_degraded) (MonoVTable *vtable, size_t size);
SgenObjectOperations major_ops;
+ SgenObjectOperations major_concurrent_ops;
void* (*alloc_object) (MonoVTable *vtable, int size, gboolean has_references);
void* (*par_alloc_object) (MonoVTable *vtable, int size, gboolean has_references);
@@ -27,12 +27,14 @@ extern long long stat_scan_object_called_major;
#define PREFETCH_DYNAMIC_HEAP(addr) PREFETCH ((addr))
#endif
-#ifdef SGEN_CONCURRENT_MARK
+#ifdef SCAN_FOR_CONCURRENT_MARK
#define FOLLOW_OBJECT(addr) (!sgen_ptr_in_nursery ((addr)))
#define ALWAYS_ADD_TO_GLOBAL_REMSET 1
+#define CONCURRENT_NAME(x) x ## _concurrent
#else
#define FOLLOW_OBJECT(addr) 1
#define ALWAYS_ADD_TO_GLOBAL_REMSET 0
+#define CONCURRENT_NAME(x) x
#endif
#undef HANDLE_PTR
@@ -41,7 +43,7 @@ extern long long stat_scan_object_called_major;
void *__copy; \
if (__old && FOLLOW_OBJECT (__old)) { \
PREFETCH_DYNAMIC_HEAP (__old); \
- major_copy_or_mark_object ((ptr), __old, queue); \
+ CONCURRENT_NAME (major_copy_or_mark_object) ((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)))) \
@@ -53,19 +55,19 @@ extern long long stat_scan_object_called_major;
} while (0)
static void
-major_scan_object (char *start, SgenGrayQueue *queue)
+CONCURRENT_NAME (major_scan_object) (char *start, SgenGrayQueue *queue)
{
#include "sgen-scan-object.h"
HEAVY_STAT (++stat_scan_object_called_major);
}
-#ifdef SGEN_CONCURRENT_MARK
+#ifdef SCAN_FOR_CONCURRENT_MARK
#ifdef SGEN_PARALLEL_MARK
#error concurrent and parallel mark not supported yet
#else
static void
-major_scan_vtype (char *start, mword desc, SgenGrayQueue *queue)
+CONCURRENT_NAME (major_scan_vtype) (char *start, mword desc, SgenGrayQueue *queue)
{
/* The descriptors include info about the MonoObject header as well */
start -= sizeof (MonoObject);
@@ -75,3 +77,8 @@ major_scan_vtype (char *start, mword desc, SgenGrayQueue *queue)
}
#endif
#endif
+
+#undef PREFETCH_DYNAMIC_HEAP
+#undef FOLLOW_OBJECT
+#undef ALWAYS_ADD_TO_GLOBAL_REMSET
+#undef CONCURRENT_NAME
@@ -1229,7 +1229,7 @@ major_copy_or_mark_object (void **ptr, void *obj, SgenGrayQueue *queue)
#else
#ifdef SGEN_CONCURRENT_MARK
static void
-major_copy_or_mark_object (void **ptr, void *obj, SgenGrayQueue *queue)
+major_copy_or_mark_object_concurrent (void **ptr, void *obj, SgenGrayQueue *queue)
{
g_assert (!SGEN_OBJECT_IS_FORWARDED (obj));
@@ -1264,7 +1264,8 @@ major_copy_or_mark_object (void **ptr, void *obj, SgenGrayQueue *queue)
}
}
}
-#else
+#endif
+
static void
major_copy_or_mark_object (void **ptr, void *obj, SgenGrayQueue *queue)
{
@@ -1402,7 +1403,6 @@ major_copy_or_mark_object (void **ptr, void *obj, SgenGrayQueue *queue)
}
}
#endif
-#endif
static void
major_copy_or_mark_object_canonical (void **ptr, SgenGrayQueue *queue)
@@ -1411,6 +1411,12 @@ major_copy_or_mark_object_canonical (void **ptr, SgenGrayQueue *queue)
}
#ifdef SGEN_CONCURRENT_MARK
+static void
+major_copy_or_mark_object_concurrent_canonical (void **ptr, SgenGrayQueue *queue)
+{
+ major_copy_or_mark_object_concurrent (ptr, *ptr, queue);
+}
+
static long long
major_get_and_reset_num_major_objects_marked (void)
{
@@ -1426,6 +1432,12 @@ major_get_and_reset_num_major_objects_marked (void)
#include "sgen-major-scan-object.h"
+#ifdef SGEN_CONCURRENT_MARK
+#define SCAN_FOR_CONCURRENT_MARK
+#include "sgen-major-scan-object.h"
+#undef SCAN_FOR_CONCURRENT_MARK
+#endif
+
static void
mark_pinned_objects_in_block (MSBlockInfo *block, SgenGrayQueue *queue)
{
@@ -2368,7 +2380,9 @@ sgen_marksweep_init
collector->major_ops.copy_or_mark_object = major_copy_or_mark_object_canonical;
collector->major_ops.scan_object = major_scan_object;
#ifdef SGEN_CONCURRENT_MARK
- collector->major_ops.scan_vtype = major_scan_vtype;
+ collector->major_concurrent_ops.copy_or_mark_object = major_copy_or_mark_object_concurrent_canonical;
+ collector->major_concurrent_ops.scan_object = major_scan_object_concurrent;
+ collector->major_concurrent_ops.scan_vtype = major_scan_vtype_concurrent;
#endif
#ifdef SGEN_HAVE_CARDTABLE
@@ -370,11 +370,12 @@ static mono_native_thread_return_t
workers_thread_func (void *data_untyped)
{
WorkerData *data = data_untyped;
+ SgenMajorCollector *major = sgen_get_major_collector ();
mono_thread_info_register_small_id ();
- if (sgen_get_major_collector ()->init_worker_thread)
- sgen_get_major_collector ()->init_worker_thread (data->major_collector_data);
+ if (major->init_worker_thread)
+ major->init_worker_thread (data->major_collector_data);
init_private_gray_queue (data);
@@ -387,8 +388,10 @@ workers_thread_func (void *data_untyped)
}
if (workers_marking && (!sgen_gray_object_queue_is_empty (&data->private_gray_queue) || workers_get_work (data))) {
- ScanCopyContext ctx = { sgen_get_major_collector ()->major_ops.scan_object, NULL,
- &data->private_gray_queue };
+ SgenObjectOperations *ops = sgen_concurrent_collection_in_progress ()
+ ? &major->major_concurrent_ops
+ : &major->major_ops;
+ ScanCopyContext ctx = { ops->scan_object, NULL, &data->private_gray_queue };
g_assert (!sgen_gray_object_queue_is_empty (&data->private_gray_queue));

0 comments on commit 0a578ac

Please sign in to comment.