#endif
SGEN_ASSERT (9, obj, "null object from pointer %p", ptr);
-#ifndef COPY_OR_MARK_CONCURRENT
+#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)) {
-#ifndef COPY_OR_MARK_CONCURRENT
+#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;
block = MS_BLOCK_FOR_OBJ (obj);
-#ifdef COPY_OR_MARK_CONCURRENT
+#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
/* Now scan the object. */
#undef HANDLE_PTR
-#ifdef COPY_OR_MARK_CONCURRENT
+#if defined(COPY_OR_MARK_CONCURRENT_WITH_EVACUATION)
#define HANDLE_PTR(ptr,obj) do { \
GCObject *__old = *(ptr); \
binary_protocol_scan_process_reference ((full_object), (ptr), __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)))) \
+ mark_mod_union_card ((full_object), (void**)(ptr), __old); \
+ } \
+ } while (0)
#else
#define HANDLE_PTR(ptr,obj) do { \
GCObject *__old = *(ptr); \
static gboolean
DRAIN_GRAY_STACK_FUNCTION_NAME (SgenGrayQueue *queue)
{
-#ifdef COPY_OR_MARK_CONCURRENT
+#if defined(COPY_OR_MARK_CONCURRENT) || defined(COPY_OR_MARK_CONCURRENT_WITH_EVACUATION)
int i;
for (i = 0; i < 32; i++) {
#else
#undef COPY_OR_MARK_WITH_EVACUATION
#define COPY_OR_MARK_CONCURRENT
-#define COPY_OR_MARK_FUNCTION_NAME major_copy_or_mark_object_concurrent
-#define SCAN_OBJECT_FUNCTION_NAME major_scan_object_concurrent
-#define DRAIN_GRAY_STACK_FUNCTION_NAME drain_gray_stack_concurrent
+#define COPY_OR_MARK_FUNCTION_NAME major_copy_or_mark_object_concurrent_no_evacuation
+#define SCAN_OBJECT_FUNCTION_NAME major_scan_object_concurrent_no_evacuation
+#define DRAIN_GRAY_STACK_FUNCTION_NAME drain_gray_stack_concurrent_no_evacuation
#include "sgen-marksweep-drain-gray-stack.h"
-static gboolean
-drain_gray_stack (SgenGrayQueue *queue)
+#undef COPY_OR_MARK_CONCURRENT
+#define COPY_OR_MARK_CONCURRENT_WITH_EVACUATION
+#define COPY_OR_MARK_FUNCTION_NAME major_copy_or_mark_object_concurrent_with_evacuation
+#define SCAN_OBJECT_FUNCTION_NAME major_scan_object_concurrent_with_evacuation
+#define DRAIN_GRAY_STACK_FUNCTION_NAME drain_gray_stack_concurrent_with_evacuation
+#include "sgen-marksweep-drain-gray-stack.h"
+
+static inline gboolean
+major_is_evacuating (void)
{
- gboolean evacuation = FALSE;
int i;
for (i = 0; i < num_block_obj_sizes; ++i) {
if (evacuate_block_obj_sizes [i]) {
- evacuation = TRUE;
- break;
+ return TRUE;
}
}
- if (evacuation)
+ return FALSE;
+}
+
+static gboolean
+drain_gray_stack (SgenGrayQueue *queue)
+{
+ if (major_is_evacuating ())
return drain_gray_stack_with_evacuation (queue);
else
return drain_gray_stack_no_evacuation (queue);
}
+static gboolean
+drain_gray_stack_concurrent (SgenGrayQueue *queue)
+{
+ if (major_is_evacuating ())
+ return drain_gray_stack_concurrent_with_evacuation (queue);
+ else
+ return drain_gray_stack_concurrent_no_evacuation (queue);
+}
+
#include "sgen-marksweep-scan-object-concurrent.h"
static void
static void
major_copy_or_mark_object_concurrent_canonical (GCObject **ptr, SgenGrayQueue *queue)
{
- major_copy_or_mark_object_concurrent (ptr, *ptr, queue);
+ major_copy_or_mark_object_concurrent_with_evacuation (ptr, *ptr, queue);
}
static void
collector->major_ops_serial.drain_gray_stack = drain_gray_stack;
if (is_concurrent) {
collector->major_ops_concurrent_start.copy_or_mark_object = major_copy_or_mark_object_concurrent_canonical;
- collector->major_ops_concurrent_start.scan_object = major_scan_object_concurrent;
+ collector->major_ops_concurrent_start.scan_object = major_scan_object_concurrent_with_evacuation;
collector->major_ops_concurrent_start.drain_gray_stack = drain_gray_stack_concurrent;
collector->major_ops_concurrent_finish.copy_or_mark_object = major_copy_or_mark_object_concurrent_finish_canonical;