Esempio n. 1
0
void sgen_client_clear_togglerefs (char *start, char *end, ScanCopyContext ctx)
{
	CopyOrMarkObjectFunc copy_func = ctx.ops->copy_or_mark_object;
	SgenGrayQueue *queue = ctx.queue;
	int i;

	SGEN_LOG (4, "Clearing ToggleRefs %d", toggleref_array_size);

	for (i = 0; i < toggleref_array_size; ++i) {
		if (toggleref_array [i].weak_ref) {
			GCObject *object = toggleref_array [i].weak_ref;

			if ((char*)object >= start && (char*)object < end) {
				if (sgen_gc_is_object_ready_for_finalization (object)) {
					SGEN_LOG (6, "\tcleaning weak slot %d", i);
					toggleref_array [i].weak_ref = NULL; /* We defer compaction to only happen on the callback step. */
				} else {
					SGEN_LOG (6, "\tkeeping weak slot %d", i);
					copy_func (&toggleref_array [i].weak_ref, queue);
				}
			}
		}
	}
	sgen_drain_gray_stack (ctx);
}
Esempio n. 2
0
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 (major->init_worker_thread)
		major->init_worker_thread (data->major_collector_data);

	init_private_gray_queue (data);

	for (;;) {
		gboolean did_work = FALSE;

		SGEN_ASSERT (0, sgen_get_current_collection_generation () != GENERATION_NURSERY, "Why are we doing work while there's a nursery collection happening?");

		while (workers_state.data.state == STATE_WORKING && workers_dequeue_and_do_job (data)) {
			did_work = TRUE;
			/* FIXME: maybe distribute the gray queue here? */
		}

		if (!did_work && (!sgen_gray_object_queue_is_empty (&data->private_gray_queue) || workers_get_work (data))) {
			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));

			while (!sgen_drain_gray_stack (32, ctx)) {
				if (workers_state.data.state == STATE_NURSERY_COLLECTION)
					workers_wait ();
			}
			g_assert (sgen_gray_object_queue_is_empty (&data->private_gray_queue));

			init_private_gray_queue (data);

			did_work = TRUE;
		}

		if (!did_work)
			workers_wait ();
	}

	/* dummy return to make compilers happy */
	return NULL;
}
Esempio n. 3
0
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 (major->init_worker_thread)
		major->init_worker_thread (data->major_collector_data);

	init_private_gray_queue (data);

	for (;;) {
		gboolean did_work = FALSE;

		while (workers_dequeue_and_do_job (data)) {
			did_work = TRUE;
			/* FIXME: maybe distribute the gray queue here? */
		}

		if (workers_marking && (!sgen_gray_object_queue_is_empty (&data->private_gray_queue) || workers_get_work (data))) {
			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));

			while (!sgen_drain_gray_stack (32, ctx))
				workers_gray_queue_share_redirect (&data->private_gray_queue);
			g_assert (sgen_gray_object_queue_is_empty (&data->private_gray_queue));

			init_private_gray_queue (data);

			did_work = TRUE;
		}

		if (!did_work)
			workers_wait ();
	}

	/* dummy return to make compilers happy */
	return NULL;
}
Esempio n. 4
0
void sgen_client_mark_togglerefs (char *start, char *end, ScanCopyContext ctx)
{
	CopyOrMarkObjectFunc copy_func = ctx.ops->copy_or_mark_object;
	SgenGrayQueue *queue = ctx.queue;
	int i;

	SGEN_LOG (4, "Marking ToggleRefs %d", toggleref_array_size);

	for (i = 0; i < toggleref_array_size; ++i) {
		if (toggleref_array [i].strong_ref) {
			GCObject *object = toggleref_array [i].strong_ref;
			if ((char*)object >= start && (char*)object < end) {
				SGEN_LOG (6, "\tcopying strong slot %d", i);
				copy_func (&toggleref_array [i].strong_ref, queue);
			}
		}
	}
	sgen_drain_gray_stack (ctx);
}
Esempio n. 5
0
static mono_native_thread_return_t
workers_thread_func (void *data_untyped)
{
	WorkerData *data = data_untyped;

	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);

	sgen_gray_object_queue_init_with_alloc_prepare (&data->private_gray_queue,
			workers_gray_queue_share_redirect, data);

	for (;;) {
		gboolean did_work = FALSE;

		while (workers_dequeue_and_do_job (data)) {
			did_work = TRUE;
			/* FIXME: maybe distribute the gray queue here? */
		}

		if (workers_marking && (!sgen_gray_object_queue_is_empty (&data->private_gray_queue) || workers_get_work (data))) {
			g_assert (!sgen_gray_object_queue_is_empty (&data->private_gray_queue));

			while (!sgen_drain_gray_stack (&data->private_gray_queue, 32))
				workers_gray_queue_share_redirect (&data->private_gray_queue);
			g_assert (sgen_gray_object_queue_is_empty (&data->private_gray_queue));

			sgen_gray_object_queue_init (&data->private_gray_queue);

			did_work = TRUE;
		}

		if (!did_work)
			workers_wait ();
	}

	/* dummy return to make compilers happy */
	return NULL;
}
Esempio n. 6
0
static void
marker_idle_func (void *data_untyped)
{
    WorkerData *data = data_untyped;

    SGEN_ASSERT (0, continue_idle_func (), "Why are we called when we're not supposed to work?");
    SGEN_ASSERT (0, sgen_concurrent_collection_in_progress (), "The worker should only mark in concurrent collections.");

    if (workers_state == STATE_WORK_ENQUEUED) {
        set_state (STATE_WORK_ENQUEUED, STATE_WORKING);
        SGEN_ASSERT (0, workers_state != STATE_NOT_WORKING, "How did we get from WORK ENQUEUED to NOT WORKING?");
    }

    if (!sgen_gray_object_queue_is_empty (&data->private_gray_queue) || workers_get_work (data)) {
        ScanCopyContext ctx = CONTEXT_FROM_OBJECT_OPERATIONS (idle_func_object_ops, &data->private_gray_queue);

        SGEN_ASSERT (0, !sgen_gray_object_queue_is_empty (&data->private_gray_queue), "How is our gray queue empty if we just got work?");

        sgen_drain_gray_stack (ctx);
    } else {
        worker_try_finish ();
    }
}