示例#1
0
static void
describe_nursery_ptr (char *ptr)
{
    int i;

    fprintf (gc_debug_file, "nursery-ptr ");
    for (i = 0; i < valid_nursery_object_count; ++i) {
        if (valid_nursery_objects [i] >= ptr)
            break;
    }

    if (i >= valid_nursery_object_count || valid_nursery_objects [i] + safe_object_get_size ((MonoObject *)valid_nursery_objects [i]) < ptr) {
        fprintf (gc_debug_file, "(unalloc'd-memory)");
    } else {
        char *obj = valid_nursery_objects [i];
        MonoVTable *vtable = (MonoVTable*)LOAD_VTABLE (obj);
        int size = safe_object_get_size ((MonoObject *)obj);

        if (obj == ptr)
            fprintf (gc_debug_file, "(object %s.%s size %d)",
                     vtable->klass->name_space, vtable->klass->name, size);
        else
            fprintf (gc_debug_file, "(interior-ptr offset %td of %p (%s.%s) size %d)",
                     ptr - obj, obj,
                     vtable->klass->name_space, vtable->klass->name, size);
    }
}
示例#2
0
/*
 * Check that each object reference which points into the nursery can
 * be found in the remembered sets.
 */
static void
check_consistency_callback (char *start, size_t size, void *dummy)
{
    GCVTable *vt = (GCVTable*)LOAD_VTABLE (start);
    DEBUG (8, fprintf (gc_debug_file, "Scanning object %p, vtable: %p (%s)\n", start, vt, vt->klass->name));

#define SCAN_OBJECT_ACTION
#include "sgen-scan-object.h"
}
示例#3
0
static void
count_pinned_callback (char *obj, size_t size, void *data)
{
	MonoVTable *vtable = (MonoVTable*)LOAD_VTABLE (obj);

	if (vtable->klass->has_references)
		++count_pinned_ref;
	else
		++count_pinned_nonref;
}
示例#4
0
void
describe_ptr (char *ptr)
{
    MonoVTable *vtable;
    mword desc;
    int type;
    char *start;

    if (sgen_ptr_in_nursery (ptr)) {
        printf ("Pointer inside nursery.\n");
    } else {
        if (sgen_ptr_is_in_los (ptr, &start)) {
            if (ptr == start)
                printf ("Pointer is the start of object %p in LOS space.\n", start);
            else
                printf ("Pointer is at offset 0x%x of object %p in LOS space.\n", (int)(ptr - start), start);
            ptr = start;
        } else if (major_collector.ptr_is_in_non_pinned_space (ptr)) {
            printf ("Pointer inside oldspace.\n");
        } else if (major_collector.obj_is_from_pinned_alloc (ptr)) {
            printf ("Pointer is inside a pinned chunk.\n");
        } else {
            printf ("Pointer unknown.\n");
            return;
        }
    }

    if (object_is_pinned (ptr))
        printf ("Object is pinned.\n");

    if (object_is_forwarded (ptr))
        printf ("Object is forwared.\n");

    // FIXME: Handle pointers to the inside of objects
    vtable = (MonoVTable*)LOAD_VTABLE (ptr);

    printf ("VTable: %p\n", vtable);
    if (vtable == NULL) {
        printf ("VTable is invalid (empty).\n");
        return;
    }
    if (sgen_ptr_in_nursery (vtable)) {
        printf ("VTable is invalid (points inside nursery).\n");
        return;
    }
    printf ("Class: %s\n", vtable->klass->name);

    desc = ((GCVTable*)vtable)->desc;
    printf ("Descriptor: %lx\n", (long)desc);

    type = desc & 0x7;
    printf ("Descriptor type: %d (%s)\n", type, descriptor_types [type]);
}
示例#5
0
static void
missing_remset_spew (char *obj, char **slot)
{
    char *ptr = *slot;
    MonoVTable *vtable = (MonoVTable*)LOAD_VTABLE (obj);

    fprintf (gc_debug_file,  "Oldspace->newspace reference %p at offset %td in object %p (%s.%s) not found in remsets.\n",
             ptr, (char*)slot - obj, obj,
             vtable->klass->name_space, vtable->klass->name);

    broken_heap = TRUE;
}
示例#6
0
static void
bad_pointer_spew (char *obj, char **slot)
{
    char *ptr = *slot;
    MonoVTable *vtable = (MonoVTable*)LOAD_VTABLE (obj);

    fprintf (gc_debug_file, "Invalid object pointer %p [", ptr);
    describe_pointer (ptr);
    fprintf (gc_debug_file, "] at offset %td in object %p (%s.%s).\n",
             (char*)slot - obj,
             obj, vtable->klass->name_space, vtable->klass->name);
    broken_heap = TRUE;
}
示例#7
0
文件: sgen-ssb.c 项目: Sectoid/mono
static void
mono_sgen_ssb_record_pointer (gpointer ptr)
{
	RememberedSet *rs;
	gboolean lock = mono_sgen_collection_is_parallel ();
	gpointer obj = *(gpointer*)ptr;

	g_assert (!mono_sgen_ptr_in_nursery (ptr) && mono_sgen_ptr_in_nursery (obj));

	if (lock)
		LOCK_GLOBAL_REMSET;

	if (!global_remset_location_was_not_added (ptr))
		goto done;

	if (G_UNLIKELY (do_pin_stats))
		mono_sgen_pin_stats_register_global_remset (obj);

	DEBUG (8, fprintf (gc_debug_file, "Adding global remset for %p\n", ptr));
	binary_protocol_global_remset (ptr, *(gpointer*)ptr, (gpointer)LOAD_VTABLE (obj));

	HEAVY_STAT (++stat_global_remsets_added);

	/* 
	 * FIXME: If an object remains pinned, we need to add it at every minor collection.
	 * To avoid uncontrolled growth of the global remset, only add each pointer once.
	 */
	if (global_remset->store_next + 3 < global_remset->end_set) {
		*(global_remset->store_next++) = (mword)ptr;
		goto done;
	}
	rs = mono_sgen_alloc_remset (global_remset->end_set - global_remset->data, NULL, TRUE);
	rs->next = global_remset;
	global_remset = rs;
	*(global_remset->store_next++) = (mword)ptr;

	{
		int global_rs_size = 0;

		for (rs = global_remset; rs; rs = rs->next) {
			global_rs_size += rs->store_next - rs->data;
		}
		DEBUG (4, fprintf (gc_debug_file, "Global remset now has size %d\n", global_rs_size));
	}

 done:
	if (lock)
		UNLOCK_GLOBAL_REMSET;
}
示例#8
0
文件: sgen-ssb.c 项目: Sectoid/mono
static mword*
handle_remset (mword *p, void *start_nursery, void *end_nursery, gboolean global, SgenGrayQueue *queue)
{
	void **ptr;
	mword count;
	mword desc;

	if (global)
		HEAVY_STAT (++stat_global_remsets_processed);
	else
		HEAVY_STAT (++stat_local_remsets_processed);

	/* FIXME: exclude stack locations */
	switch ((*p) & REMSET_TYPE_MASK) {
	case REMSET_LOCATION:
		ptr = (void**)(*p);
		//__builtin_prefetch (ptr);
		if (((void*)ptr < start_nursery || (void*)ptr >= end_nursery)) {
			gpointer old = *ptr;
			major_collector.copy_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), mono_sgen_safe_object_get_size (*ptr));
			if (!global && *ptr >= start_nursery && *ptr < end_nursery) {
				/*
				 * If the object is pinned, each reference to it from nonpinned objects
				 * becomes part of the global remset, which can grow very large.
				 */
				DEBUG (9, fprintf (gc_debug_file, "Add to global remset because of pinning %p (%p %s)\n", ptr, *ptr, mono_sgen_safe_name (*ptr)));
				mono_sgen_add_to_global_remset (ptr);
			}
		} else {
			DEBUG (9, fprintf (gc_debug_file, "Skipping remset at %p holding %p\n", ptr, *ptr));
		}
		return p + 1;
	case REMSET_RANGE:
		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);
			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)
				mono_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;
		mono_sgen_get_minor_scan_object () ((char*)ptr, queue);
		return p + 1;
	case REMSET_VTYPE: {
		ScanVTypeFunc scan_vtype = mono_sgen_get_minor_scan_vtype ();
		size_t skip_size;

		ptr = (void**)(*p & ~REMSET_TYPE_MASK);
		if (((void*)ptr >= start_nursery && (void*)ptr < end_nursery))
			return p + 4;
		desc = p [1];
		count = p [2];
		skip_size = p [3];
		while (count-- > 0) {
			scan_vtype ((char*)ptr, desc, queue);
			ptr = (void**)((char*)ptr + skip_size);
		}
		return p + 4;
	}
	default:
		g_assert_not_reached ();
	}
	return NULL;
}
示例#9
0
static void
major_sweep (void)
{
	int i;
#ifdef FIXED_HEAP
	int j;
#else
	MSBlockInfo **iter;
#endif

	/* clear all the free lists */
	for (i = 0; i < MS_BLOCK_TYPE_MAX; ++i) {
		MSBlockInfo **free_blocks = free_block_lists [i];
		int j;
		for (j = 0; j < num_block_obj_sizes; ++j)
			free_blocks [j] = NULL;
	}

	/* traverse all blocks, free and zero unmarked objects */
#ifdef FIXED_HEAP
	for (j = 0; j < ms_heap_num_blocks; ++j) {
		MSBlockInfo *block = &block_infos [j];
#else
	iter = &all_blocks;
	while (*iter) {
		MSBlockInfo *block = *iter;
#endif
		int count;
		gboolean have_live = FALSE;
		int obj_index;

#ifdef FIXED_HEAP
		if (!block->used)
			continue;
#endif

		count = MS_BLOCK_FREE / block->obj_size;
		block->free_list = NULL;

		for (obj_index = 0; obj_index < count; ++obj_index) {
			int word, bit;
			void *obj = MS_BLOCK_OBJ (block, obj_index);

			MS_CALC_MARK_BIT (word, bit, obj);
			if (MS_MARK_BIT (block, word, bit)) {
				DEBUG (9, g_assert (MS_OBJ_ALLOCED (obj, block)));
				have_live = TRUE;
			} else {
				/* an unmarked object */
				if (MS_OBJ_ALLOCED (obj, block)) {
					binary_protocol_empty (obj, block->obj_size);
					memset (obj, 0, block->obj_size);
				}
				*(void**)obj = block->free_list;
				block->free_list = obj;
			}
		}

		/* reset mark bits */
		memset (block->mark_words, 0, sizeof (mword) * MS_NUM_MARK_WORDS);

		/*
		 * FIXME: reverse free list so that it's in address
		 * order
		 */

		if (have_live) {
#ifndef FIXED_HEAP
			iter = &block->next;
#endif

			/*
			 * If there are free slots in the block, add
			 * the block to the corresponding free list.
			 */
			if (block->free_list) {
				MSBlockInfo **free_blocks = FREE_BLOCKS (block->pinned, block->has_references);
				int index = MS_BLOCK_OBJ_SIZE_INDEX (block->obj_size);
				block->next_free = free_blocks [index];
				free_blocks [index] = block;
			}
		} else {
			/*
			 * Blocks without live objects are removed from the
			 * block list and freed.
			 */
#ifdef FIXED_HEAP
			ms_free_block (block);
#else
			*iter = block->next;

			ms_free_block (block->block);
			mono_sgen_free_internal (block, INTERNAL_MEM_MS_BLOCK_INFO);
#endif

			--num_major_sections;
		}
	}
}

static int count_pinned_ref;
static int count_pinned_nonref;
static int count_nonpinned_ref;
static int count_nonpinned_nonref;

static void
count_nonpinned_callback (char *obj, size_t size, void *data)
{
	MonoVTable *vtable = (MonoVTable*)LOAD_VTABLE (obj);

	if (vtable->klass->has_references)
		++count_nonpinned_ref;
	else
		++count_nonpinned_nonref;
}