Example #1
0
static gboolean
is_bridge_object_dead (GCObject *obj, void *data)
{
	SgenHashTable *table = (SgenHashTable *)data;
	unsigned char *value = (unsigned char *)sgen_hash_table_lookup (table, obj);
	if (!value)
		return FALSE;
	return !*value;
}
Example #2
0
static mono_bool
is_bridge_object_alive (MonoObject *obj, void *data)
{
	SgenHashTable *table = data;
	unsigned char *value = sgen_hash_table_lookup (table, obj);
	if (!value)
		return TRUE;
	return *value;
}
Example #3
0
static gboolean
sgen_compare_bridge_processor_results (SgenBridgeProcessor *a, SgenBridgeProcessor *b)
{
	int i;
	SgenHashTable obj_to_a_scc = SGEN_HASH_TABLE_INIT (INTERNAL_MEM_BRIDGE_DEBUG, INTERNAL_MEM_BRIDGE_DEBUG, sizeof (int), mono_aligned_addr_hash, NULL);
	SgenHashTable b_scc_to_a_scc = SGEN_HASH_TABLE_INIT (INTERNAL_MEM_BRIDGE_DEBUG, INTERNAL_MEM_BRIDGE_DEBUG, sizeof (int), g_direct_hash, NULL);
	MonoGCBridgeXRef *a_xrefs, *b_xrefs;
	size_t xrefs_alloc_size;

	// dump_processor_state (a);
	// dump_processor_state (b);

	if (a->num_sccs != b->num_sccs)
		g_error ("SCCS count expected %d but got %d", a->num_sccs, b->num_sccs);
	if (a->num_xrefs != b->num_xrefs)
		g_error ("SCCS count expected %d but got %d", a->num_xrefs, b->num_xrefs);

	/*
	 * First we build a hash of each object in `a` to its respective SCC index within
	 * `a`.  Along the way we also assert that no object is more than one SCC.
	 */
	for (i = 0; i < a->num_sccs; ++i) {
		int j;
		MonoGCBridgeSCC *scc = a->api_sccs [i];

		g_assert (scc->num_objs > 0);

		for (j = 0; j < scc->num_objs; ++j) {
			GCObject *obj = scc->objs [j];
			gboolean new_entry = sgen_hash_table_replace (&obj_to_a_scc, obj, &i, NULL);
			g_assert (new_entry);
		}
	}

	/*
	 * Now we check whether each of the objects in `b` are in `a`, and whether the SCCs
	 * of `b` contain the same sets of objects as those of `a`.
	 *
	 * While we're doing this, build a hash table to map from `b` SCC indexes to `a` SCC
	 * indexes.
	 */
	for (i = 0; i < b->num_sccs; ++i) {
		MonoGCBridgeSCC *scc = b->api_sccs [i];
		MonoGCBridgeSCC *a_scc;
		int *a_scc_index_ptr;
		int a_scc_index;
		int j;
		gboolean new_entry;

		g_assert (scc->num_objs > 0);
		a_scc_index_ptr = (int *)sgen_hash_table_lookup (&obj_to_a_scc, scc->objs [0]);
		g_assert (a_scc_index_ptr);
		a_scc_index = *a_scc_index_ptr;

		//g_print ("A SCC %d -> B SCC %d\n", a_scc_index, i);

		a_scc = a->api_sccs [a_scc_index];
		g_assert (a_scc->num_objs == scc->num_objs);

		for (j = 1; j < scc->num_objs; ++j) {
			a_scc_index_ptr = (int *)sgen_hash_table_lookup (&obj_to_a_scc, scc->objs [j]);
			g_assert (a_scc_index_ptr);
			g_assert (*a_scc_index_ptr == a_scc_index);
		}

		new_entry = sgen_hash_table_replace (&b_scc_to_a_scc, GINT_TO_POINTER (i), &a_scc_index, NULL);
		g_assert (new_entry);
	}

	/*
	 * Finally, check that we have the same xrefs.  We do this by making copies of both
	 * xref arrays, and replacing the SCC indexes in the copy for `b` with the
	 * corresponding indexes in `a`.  Then we sort both arrays and assert that they're
	 * the same.
	 *
	 * At the same time, check that no xref is self-referential and that there are no
	 * duplicate ones.
	 */

	xrefs_alloc_size = a->num_xrefs * sizeof (MonoGCBridgeXRef);
	a_xrefs = (MonoGCBridgeXRef *)sgen_alloc_internal_dynamic (xrefs_alloc_size, INTERNAL_MEM_BRIDGE_DEBUG, TRUE);
	b_xrefs = (MonoGCBridgeXRef *)sgen_alloc_internal_dynamic (xrefs_alloc_size, INTERNAL_MEM_BRIDGE_DEBUG, TRUE);

	memcpy (a_xrefs, a->api_xrefs, xrefs_alloc_size);
	for (i = 0; i < b->num_xrefs; ++i) {
		MonoGCBridgeXRef *xref = &b->api_xrefs [i];
		int *scc_index_ptr;

		g_assert (xref->src_scc_index != xref->dst_scc_index);

		scc_index_ptr = (int *)sgen_hash_table_lookup (&b_scc_to_a_scc, GINT_TO_POINTER (xref->src_scc_index));
		g_assert (scc_index_ptr);
		b_xrefs [i].src_scc_index = *scc_index_ptr;

		scc_index_ptr = (int *)sgen_hash_table_lookup (&b_scc_to_a_scc, GINT_TO_POINTER (xref->dst_scc_index));
		g_assert (scc_index_ptr);
		b_xrefs [i].dst_scc_index = *scc_index_ptr;
	}

	qsort (a_xrefs, a->num_xrefs, sizeof (MonoGCBridgeXRef), compare_xrefs);
	qsort (b_xrefs, a->num_xrefs, sizeof (MonoGCBridgeXRef), compare_xrefs);

	for (i = 0; i < a->num_xrefs; ++i) {
		g_assert (a_xrefs [i].src_scc_index == b_xrefs [i].src_scc_index);
		g_assert (a_xrefs [i].dst_scc_index == b_xrefs [i].dst_scc_index);
	}

	sgen_hash_table_clean (&obj_to_a_scc);
	sgen_hash_table_clean (&b_scc_to_a_scc);
	sgen_free_internal_dynamic (a_xrefs, xrefs_alloc_size, INTERNAL_MEM_BRIDGE_DEBUG);
	sgen_free_internal_dynamic (b_xrefs, xrefs_alloc_size, INTERNAL_MEM_BRIDGE_DEBUG);

	return TRUE;
}
Example #4
0
				pinned_byte_counts [i] += size;
				*pin_types |= pin_bit;
			}
		}
	}
	if (obj < node->addr)
		pin_stats_count_object_from_tree (obj, size, node->left, pin_types);
	if (obj + size - 1 > node->addr)
		pin_stats_count_object_from_tree (obj, size, node->right, pin_types);
}

static gpointer
lookup_class_entry (SgenHashTable *hash_table, MonoClass *class, gpointer empty_entry)
{
	char *name = g_strdup_printf ("%s.%s", class->name_space, class->name);
	gpointer entry = sgen_hash_table_lookup (hash_table, name);

	if (entry) {
		g_free (name);
	} else {
		sgen_hash_table_replace (hash_table, name, empty_entry, NULL);
		entry = sgen_hash_table_lookup (hash_table, name);
	}

	return entry;
}

static void
register_class (MonoClass *class, int pin_types)
{
	PinnedClassEntry empty_entry;