{
MonoVTable *vt = (MonoVTable*)SGEN_LOAD_VTABLE (obj);
MonoClass *klass = vt->klass;
- CopyOrMarkObjectFunc copy_func = sgen_get_copy_object ();
- ScanObjectFunc scan_object_func = sgen_get_minor_scan_object ();
- ScanVTypeFunc scan_vtype_func = sgen_get_minor_scan_vtype ();
HEAVY_STAT (++large_objects);
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;
+
for (; elem < card_end; elem += elem_size)
scan_vtype_func (elem, desc, queue);
} else {
+ CopyOrMarkObjectFunc copy_func = sgen_get_current_object_ops ()->copy_or_mark_object;
+
HEAVY_STAT (++los_array_cards);
for (; elem < card_end; elem += SIZEOF_VOID_P) {
gpointer new, old = *(gpointer*)elem;
HEAVY_STAT (++bloby_objects);
if (cards) {
if (sgen_card_table_is_range_marked (cards, (mword)obj, block_obj_size))
- scan_object_func (obj, queue);
+ sgen_get_current_object_ops ()->scan_object (obj, queue);
} else if (sgen_card_table_region_begin_scanning ((mword)obj, block_obj_size)) {
- scan_object_func (obj, queue);
+ sgen_get_current_object_ops ()->scan_object (obj, queue);
}
}
}
static void clear_unreachable_ephemerons (CopyOrMarkObjectFunc copy_func, char *start, char *end, GrayQueue *queue);
static void null_ephemerons_for_domain (MonoDomain *domain);
+SgenObjectOperations current_object_ops;
SgenMajorCollector major_collector;
static GrayQueue gray_queue;
sgen_drain_gray_stack (GrayQueue *queue, int max_objs)
{
char *obj;
+ ScanObjectFunc scan_func = current_object_ops.scan_object;
- if (current_collection_generation == GENERATION_NURSERY) {
- ScanObjectFunc scan_func = sgen_get_minor_scan_object ();
-
+ if (max_objs == -1) {
for (;;) {
GRAY_OBJECT_DEQUEUE (queue, obj);
if (!obj)
} else {
int i;
- if (sgen_collection_is_parallel () && sgen_workers_is_distributed_queue (queue))
- return TRUE;
-
do {
for (i = 0; i != max_objs; ++i) {
GRAY_OBJECT_DEQUEUE (queue, obj);
if (!obj)
return TRUE;
DEBUG (9, fprintf (gc_debug_file, "Precise gray object scan %p (%s)\n", obj, safe_name (obj)));
- major_collector.major_scan_object (obj, queue);
+ scan_func (obj, queue);
}
} while (max_objs < 0);
return FALSE;
sgen_bridge_processing_finish ();
}
-CopyOrMarkObjectFunc
-sgen_get_copy_object (void)
-{
- if (current_collection_generation == GENERATION_NURSERY) {
- if (sgen_collection_is_parallel ())
- return major_collector.copy_object;
- else
- return major_collector.nopar_copy_object;
- } else {
- return major_collector.copy_or_mark_object;
- }
-}
-
-ScanObjectFunc
-sgen_get_minor_scan_object (void)
-{
- g_assert (current_collection_generation == GENERATION_NURSERY);
-
- if (sgen_collection_is_parallel ())
- return major_collector.minor_scan_object;
- else
- return major_collector.nopar_minor_scan_object;
+SgenObjectOperations *
+sgen_get_current_object_ops (void){
+ return ¤t_object_ops;
}
-ScanVTypeFunc
-sgen_get_minor_scan_vtype (void)
-{
- g_assert (current_collection_generation == GENERATION_NURSERY);
-
- if (sgen_collection_is_parallel ())
- return major_collector.minor_scan_vtype;
- else
- return major_collector.nopar_minor_scan_vtype;
-}
static void
finish_gray_stack (char *start_addr, char *end_addr, int generation, GrayQueue *queue)
TV_DECLARE (atv);
TV_DECLARE (btv);
int done_with_ephemerons, ephemeron_rounds = 0;
- CopyOrMarkObjectFunc copy_func = sgen_get_copy_object ();
+ CopyOrMarkObjectFunc copy_func = current_object_ops.copy_or_mark_object;
/*
* We copied all the reachable objects. Now it's the time to copy
}
}
-gboolean
-sgen_nursery_collection_is_parallel (void)
-{
- return nursery_collection_is_parallel;
-}
-
typedef struct
{
char *heap_start;
{
ScanFinalizerEntriesJobData *job_data = job_data_untyped;
- scan_finalizer_entries (sgen_get_copy_object (),
+ scan_finalizer_entries (current_object_ops.copy_or_mark_object,
job_data->list,
sgen_workers_get_job_gray_queue (worker_data));
}
mono_perfcounters->gc_collections0++;
current_collection_generation = GENERATION_NURSERY;
-
+ if (sgen_collection_is_parallel ())
+ current_object_ops = major_collector.par_minor_ops;
+ else
+ current_object_ops = major_collector.minor_ops;
+
reset_pinned_from_failed_allocation ();
binary_protocol_collection (GENERATION_NURSERY);
time_minor_scan_pinned += TV_ELAPSED (btv, atv);
/* registered roots, this includes static fields */
- scrrjd_normal.func = sgen_collection_is_parallel () ? major_collector.copy_object : major_collector.nopar_copy_object;
+ scrrjd_normal.func = current_object_ops.copy_or_mark_object;
scrrjd_normal.heap_start = sgen_get_nursery_start ();
scrrjd_normal.heap_end = nursery_next;
scrrjd_normal.root_type = ROOT_TYPE_NORMAL;
sgen_workers_enqueue_job (job_scan_from_registered_roots, &scrrjd_normal);
- scrrjd_wbarrier.func = sgen_collection_is_parallel () ? major_collector.copy_object : major_collector.nopar_copy_object;
+ scrrjd_wbarrier.func = current_object_ops.copy_or_mark_object;
scrrjd_wbarrier.heap_start = sgen_get_nursery_start ();
scrrjd_wbarrier.heap_end = nursery_next;
scrrjd_wbarrier.root_type = ROOT_TYPE_WBARRIER;
mono_perfcounters->gc_collections1++;
+ current_object_ops = major_collector.major_ops;
+
reset_pinned_from_failed_allocation ();
last_collection_old_num_major_sections = major_collector.get_num_major_sections ();
time_major_scan_pinned += TV_ELAPSED (btv, atv);
/* registered roots, this includes static fields */
- scrrjd_normal.func = major_collector.copy_or_mark_object;
+ scrrjd_normal.func = current_object_ops.copy_or_mark_object;
scrrjd_normal.heap_start = heap_start;
scrrjd_normal.heap_end = heap_end;
scrrjd_normal.root_type = ROOT_TYPE_NORMAL;
sgen_workers_enqueue_job (job_scan_from_registered_roots, &scrrjd_normal);
- scrrjd_wbarrier.func = major_collector.copy_or_mark_object;
+ scrrjd_wbarrier.func = current_object_ops.copy_or_mark_object;
scrrjd_wbarrier.heap_start = heap_start;
scrrjd_wbarrier.heap_end = heap_end;
scrrjd_wbarrier.root_type = ROOT_TYPE_WBARRIER;
mono_gc_scan_object (void *obj)
{
UserCopyOrMarkData *data = mono_native_tls_get_value (user_copy_or_mark_key);
-
- if (current_collection_generation == GENERATION_NURSERY) {
- if (sgen_collection_is_parallel ())
- major_collector.copy_object (&obj, data->queue);
- else
- major_collector.nopar_copy_object (&obj, data->queue);
- } else {
- major_collector.copy_or_mark_object (&obj, data->queue);
- }
+ current_object_ops.copy_or_mark_object (&obj, data->queue);
return obj;
}
*/
#define SGEN_LOAD_VTABLE(addr) ((*(mword*)(addr)) & ~SGEN_VTABLE_BITS_MASK)
-typedef void (*CopyOrMarkObjectFunc) (void**, SgenGrayQueue*);
-typedef void (*ScanObjectFunc) (char*, SgenGrayQueue*);
-typedef void (*ScanVTypeFunc) (char*, mword desc, SgenGrayQueue*);
-
#if SGEN_MAX_DEBUG_LEVEL >= 9
#define GRAY_OBJECT_ENQUEUE sgen_gray_object_enqueue
#define GRAY_OBJECT_DEQUEUE(queue,o) ((o) = sgen_gray_object_dequeue ((queue)))
void sgen_sort_addresses (void **array, int size) MONO_INTERNAL;
void sgen_add_to_global_remset (gpointer ptr) MONO_INTERNAL;
+typedef void (*CopyOrMarkObjectFunc) (void**, SgenGrayQueue*);
+typedef void (*ScanObjectFunc) (char*, SgenGrayQueue*);
+typedef void (*ScanVTypeFunc) (char*, mword desc, SgenGrayQueue*);
+
int sgen_get_current_collection_generation (void) MONO_INTERNAL;
-gboolean sgen_nursery_collection_is_parallel (void) MONO_INTERNAL;
-CopyOrMarkObjectFunc sgen_get_copy_object (void) MONO_INTERNAL;
-ScanObjectFunc sgen_get_minor_scan_object (void) MONO_INTERNAL;
-ScanVTypeFunc sgen_get_minor_scan_vtype (void) MONO_INTERNAL;
gboolean sgen_collection_is_parallel (void) MONO_INTERNAL;
+typedef struct {
+ CopyOrMarkObjectFunc copy_or_mark_object;
+ ScanObjectFunc scan_object;
+ ScanVTypeFunc scan_vtype;
+ /*FIXME add allocation function? */
+} SgenObjectOperations;
+
+SgenObjectOperations *sgen_get_current_object_ops (void) MONO_INTERNAL;
typedef void (*sgen_cardtable_block_callback) (mword start, mword size);
void sgen_major_collector_iterate_live_block_ranges (sgen_cardtable_block_callback callback) MONO_INTERNAL;
gboolean (*is_object_live) (char *obj);
void* (*alloc_small_pinned_obj) (size_t size, gboolean has_references);
void* (*alloc_degraded) (MonoVTable *vtable, size_t size);
- void (*copy_or_mark_object) (void **obj_slot, SgenGrayQueue *queue);
- void (*minor_scan_object) (char *start, SgenGrayQueue *queue);
- void (*nopar_minor_scan_object) (char *start, SgenGrayQueue *queue);
- void (*minor_scan_vtype) (char *start, mword desc, SgenGrayQueue *queue);
- void (*nopar_minor_scan_vtype) (char *start, mword desc, SgenGrayQueue *queue);
- void (*major_scan_object) (char *start, SgenGrayQueue *queue);
- void (*copy_object) (void **obj_slot, SgenGrayQueue *queue);
- void (*nopar_copy_object) (void **obj_slot, SgenGrayQueue *queue);
+
+ SgenObjectOperations major_ops;
+ SgenObjectOperations minor_ops;
+ SgenObjectOperations par_minor_ops;
+
void* (*alloc_object) (int size, gboolean has_references);
void* (*par_alloc_object) (int size, gboolean has_references);
void (*free_pinned_object) (char *obj, size_t size);
#endif
#define FILL_COLLECTOR_COPY_OBJECT(collector) do { \
- (collector)->copy_object = copy_object; \
- (collector)->nopar_copy_object = nopar_copy_object; \
+ (collector)->minor_ops.copy_or_mark_object = nopar_copy_object; \
+ (collector)->par_minor_ops.copy_or_mark_object = copy_object; \
} while (0)
collector->is_object_live = major_is_object_live;
collector->alloc_small_pinned_obj = major_alloc_small_pinned_obj;
collector->alloc_degraded = major_alloc_degraded;
- collector->copy_or_mark_object = major_copy_or_mark_object;
collector->alloc_object = major_alloc_object;
collector->free_pinned_object = free_pinned_object;
collector->iterate_objects = major_iterate_objects;
collector->handle_gc_param = NULL;
collector->print_gc_param_usage = NULL;
+ collector->major_ops.copy_or_mark_object = major_copy_or_mark_object;
FILL_COLLECTOR_COPY_OBJECT (collector);
FILL_COLLECTOR_SCAN_OBJECT (collector);
}
}
#define FILL_COLLECTOR_SCAN_OBJECT(collector) do { \
- (collector)->major_scan_object = major_scan_object; \
- (collector)->minor_scan_object = minor_scan_object; \
- (collector)->nopar_minor_scan_object = nopar_minor_scan_object; \
- (collector)->minor_scan_vtype = minor_scan_vtype; \
- (collector)->nopar_minor_scan_vtype = nopar_minor_scan_vtype; \
+ (collector)->major_ops.scan_object = major_scan_object; \
+ (collector)->par_minor_ops.scan_object = minor_scan_object; \
+ (collector)->minor_ops.scan_object = nopar_minor_scan_object; \
+ (collector)->par_minor_ops.scan_vtype = minor_scan_vtype; \
+ (collector)->minor_ops.scan_vtype = nopar_minor_scan_vtype; \
} while (0)
info->pinned = pinned;
info->has_references = has_references;
info->has_pinned = pinned;
- info->is_to_space = (sgen_get_current_collection_generation () == GENERATION_OLD);
+ info->is_to_space = (sgen_get_current_collection_generation () == GENERATION_OLD); /*FIXME WHY??? */
#ifndef FIXED_HEAP
info->block = ms_get_empty_block ();
major_scan_card_table (SgenGrayQueue *queue)
{
MSBlockInfo *block;
+ ScanObjectFunc scan_func = sgen_get_current_object_ops ()->scan_object;
FOREACH_BLOCK (block) {
int block_obj_size;
obj += block_obj_size;
}
} else {
- ScanObjectFunc scan_func = sgen_get_minor_scan_object ();
guint8 *card_data, *card_base;
guint8 *card_data_end;
collector->is_object_live = major_is_object_live;
collector->alloc_small_pinned_obj = major_alloc_small_pinned_obj;
collector->alloc_degraded = major_alloc_degraded;
- collector->copy_or_mark_object = major_copy_or_mark_object;
+
collector->alloc_object = major_alloc_object;
#ifdef SGEN_PARALLEL_MARK
collector->par_alloc_object = major_par_alloc_object;
collector->is_worker_thread = major_is_worker_thread;
collector->post_param_init = post_param_init;
+ /* FIXME this macro mess */
+ collector->major_ops.copy_or_mark_object = major_copy_or_mark_object;
FILL_COLLECTOR_COPY_OBJECT (collector);
FILL_COLLECTOR_SCAN_OBJECT (collector);
mword count;
mword desc;
+ ScanVTypeFunc scan_vtype = sgen_get_current_object_ops ()->scan_vtype;
+
if (global)
HEAVY_STAT (++stat_global_remsets_processed);
else
//__builtin_prefetch (ptr);
if (((void*)ptr < start_nursery || (void*)ptr >= end_nursery)) {
gpointer old = *ptr;
- major_collector.copy_object (ptr, queue);
+
+ sgen_get_current_object_ops ()->copy_or_mark_object (ptr, queue);
DEBUG (9, fprintf (gc_debug_file, "Overwrote remset at %p with %p\n", ptr, *ptr));
if (old)
binary_protocol_ptr_update (ptr, old, *ptr, (gpointer)LOAD_VTABLE (*ptr), sgen_safe_object_get_size (*ptr));
DEBUG (9, fprintf (gc_debug_file, "Skipping remset at %p holding %p\n", ptr, *ptr));
}
return p + 1;
- case REMSET_RANGE:
+ case REMSET_RANGE: {
+ CopyOrMarkObjectFunc copy_func = sgen_get_current_object_ops ()->copy_or_mark_object;
+
ptr = (void**)(*p & ~REMSET_TYPE_MASK);
if (((void*)ptr >= start_nursery && (void*)ptr < end_nursery))
return p + 2;
count = p [1];
while (count-- > 0) {
- major_collector.copy_object (ptr, queue);
+ copy_func (ptr, queue);
DEBUG (9, fprintf (gc_debug_file, "Overwrote remset at %p with %p (count: %d)\n", ptr, *ptr, (int)count));
if (!global && *ptr >= start_nursery && *ptr < end_nursery)
sgen_add_to_global_remset (ptr);
++ptr;
}
return p + 2;
+ }
case REMSET_OBJECT:
ptr = (void**)(*p & ~REMSET_TYPE_MASK);
if (((void*)ptr >= start_nursery && (void*)ptr < end_nursery))
return p + 1;
- sgen_get_minor_scan_object () ((char*)ptr, queue);
+ sgen_get_current_object_ops ()->scan_object ((char*)ptr, queue);
return p + 1;
case REMSET_VTYPE: {
- ScanVTypeFunc scan_vtype = sgen_get_minor_scan_vtype ();
size_t skip_size;
ptr = (void**)(*p & ~REMSET_TYPE_MASK);
count = p [2];
skip_size = p [3];
while (count-- > 0) {
- scan_vtype ((char*)ptr, desc, queue);
+ sgen_get_current_object_ops ()->scan_vtype ((char*)ptr, desc, queue);
ptr = (void**)((char*)ptr + skip_size);
}
return p + 4;