Esempio n. 1
0
void
sgen_scan_togglerefs (CopyOrMarkObjectFunc copy_func, char *start, char *end, SgenGrayQueue *queue)
{
	int i;

	DEBUG (4, fprintf (gc_debug_file, "Scanning ToggleRefs %d\n", toggleref_array_size));

	for (i = 0; i < toggleref_array_size; ++i) {
		if (toggleref_array [i].strong_ref) {
			char *object = toggleref_array [i].strong_ref;
			if (object >= start && object < end) {
				DEBUG (6, fprintf (gc_debug_file, "\tcopying strong slot %d\n", i));
				copy_func (&toggleref_array [i].strong_ref, queue);
			}
		} else if (toggleref_array [i].weak_ref) {
			char *object = toggleref_array [i].weak_ref;

			if (object >= start && object < end) {
				if (sgen_gc_is_object_ready_for_finalization (object)) {
					DEBUG (6, fprintf (gc_debug_file, "\tcleaning weak slot %d\n", i));
					toggleref_array [i].weak_ref = NULL; /* We defer compaction to only happen on the callback step. */
				} else {
					DEBUG (6, fprintf (gc_debug_file, "\tkeeping weak slot %d\n", i));
					copy_func (&toggleref_array [i].weak_ref, queue);
				}
			}
		}
	}
}
Esempio n. 2
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. 3
0
/* LOCKING: requires that the GC lock is held */
void
sgen_collect_bridge_objects (int generation, ScanCopyContext ctx)
{
    CopyOrMarkObjectFunc copy_func = ctx.copy_func;
    GrayQueue *queue = ctx.queue;
    SgenHashTable *hash_table = get_finalize_entry_hash_table (generation);
    MonoObject *object;
    gpointer dummy;
    char *copy;

    if (no_finalize)
        return;

    SGEN_HASH_TABLE_FOREACH (hash_table, object, dummy) {
        int tag = tagged_object_get_tag (object);
        object = tagged_object_get_object (object);

        /* Bridge code told us to ignore this one */
        if (tag == BRIDGE_OBJECT_MARKED)
            continue;

        /* Object is a bridge object and major heap says it's dead  */
        if (major_collector.is_object_live ((char*)object))
            continue;

        /* Nursery says the object is dead. */
        if (!sgen_gc_is_object_ready_for_finalization (object))
            continue;

        if (!sgen_is_bridge_object (object))
            continue;

        copy = (char*)object;
        copy_func ((void**)&copy, queue);

        sgen_bridge_register_finalized_object ((MonoObject*)copy);

        if (hash_table == &minor_finalizable_hash && !ptr_in_nursery (copy)) {
            /* remove from the list */
            SGEN_HASH_TABLE_FOREACH_REMOVE (TRUE);

            /* insert it into the major hash */
            sgen_hash_table_replace (&major_finalizable_hash, tagged_object_apply (copy, tag), NULL, NULL);

            SGEN_LOG (5, "Promoting finalization of object %p (%s) (was at %p) to major table", copy, sgen_safe_name (copy), object);

            continue;
        } else {
            /* update pointer */
            SGEN_LOG (5, "Updating object for finalization: %p (%s) (was at %p)", copy, sgen_safe_name (copy), object);
            SGEN_HASH_TABLE_FOREACH_SET_KEY (tagged_object_apply (copy, tag));
        }
    }
Esempio n. 4
0
/* LOCKING: requires that the GC lock is held */
void
sgen_collect_bridge_objects (int generation, ScanCopyContext ctx)
{
	CopyOrMarkObjectFunc copy_func = ctx.ops->copy_or_mark_object;
	GrayQueue *queue = ctx.queue;
	SgenHashTable *hash_table = get_finalize_entry_hash_table (generation);
	GCObject *object;
	gpointer dummy G_GNUC_UNUSED;
	GCObject *copy;
	SgenPointerQueue moved_fin_objects;

	sgen_pointer_queue_init (&moved_fin_objects, INTERNAL_MEM_TEMPORARY);

	if (no_finalize)
		return;

	SGEN_HASH_TABLE_FOREACH (hash_table, GCObject *, object, gpointer, dummy) {
		int tag = tagged_object_get_tag (object);
		object = tagged_object_get_object (object);

		/* Bridge code told us to ignore this one */
		if (tag == BRIDGE_OBJECT_MARKED)
			continue;

		/* Object is a bridge object and major heap says it's dead  */
		if (major_collector.is_object_live (object))
			continue;

		/* Nursery says the object is dead. */
		if (!sgen_gc_is_object_ready_for_finalization (object))
			continue;

		if (!sgen_client_bridge_is_bridge_object (object))
			continue;

		copy = object;
		copy_func (&copy, queue);

		sgen_client_bridge_register_finalized_object (copy);
		
		if (hash_table == &minor_finalizable_hash && !ptr_in_nursery (copy)) {
			/* remove from the list */
			SGEN_HASH_TABLE_FOREACH_REMOVE (TRUE);

			/* insert it into the major hash */
			sgen_hash_table_replace (&major_finalizable_hash, tagged_object_apply (copy, tag), NULL, NULL);

			SGEN_LOG (5, "Promoting finalization of object %p (%s) (was at %p) to major table", copy, sgen_client_vtable_get_name (SGEN_LOAD_VTABLE (copy)), object);

			continue;
		} else if (copy != object) {
			/* update pointer */
			SGEN_HASH_TABLE_FOREACH_REMOVE (TRUE);

			/* register for reinsertion */
			sgen_pointer_queue_add (&moved_fin_objects, tagged_object_apply (copy, tag));

			SGEN_LOG (5, "Updating object for finalization: %p (%s) (was at %p)", copy, sgen_client_vtable_get_name (SGEN_LOAD_VTABLE (copy)), object);

			continue;
		}
	} SGEN_HASH_TABLE_FOREACH_END;