Exemplo n.º 1
0
static void
rehash (MonoGHashTable *hash)
{
	MONO_REQ_GC_UNSAFE_MODE; //we must run in unsafe mode to make rehash safe

	int diff = ABS (hash->last_rehash - hash->in_use);
	RehashData data;
	void *old_table G_GNUC_UNUSED; /* unused on Boehm */

	/* These are the factors to play with to change the rehashing strategy */
	/* I played with them with a large range, and could not really get */
	/* something that was too good, maybe the tests are not that great */
	if (!(diff * 0.75 > hash->table_size * 2))
		return;

	data.hash = hash;
	data.new_size = g_spaced_primes_closest (hash->in_use);
	data.table = mg_new0 (Slot *, data.new_size);

	if (!mono_threads_is_coop_enabled ()) {
		old_table = mono_gc_invoke_with_gc_lock (do_rehash, &data);
	} else {
		/* We cannot be preempted */
		old_table = do_rehash (&data);
	}

	mg_free (old_table);
}
Exemplo n.º 2
0
static void
rehash (MonoGHashTable *hash)
{
	int diff = ABS (hash->last_rehash - hash->in_use);
	RehashData data;
	void *old_table;

	/* These are the factors to play with to change the rehashing strategy */
	/* I played with them with a large range, and could not really get */
	/* something that was too good, maybe the tests are not that great */
	if (!(diff * 0.75 > hash->table_size * 2))
		return;

	data.hash = hash;
	data.new_size = g_spaced_primes_closest (hash->in_use);
	data.table = mg_new0 (Slot *, data.new_size);

	old_table = mono_gc_invoke_with_gc_lock (do_rehash, &data);
	mg_free (old_table);
}
Exemplo n.º 3
0
static void
rehash (MonoGHashTable *hash)
{
	MONO_REQ_GC_UNSAFE_MODE; //we must run in unsafe mode to make rehash safe

	RehashData data;
	void *old_keys = hash->keys;
	void *old_values = hash->values;

	data.hash = hash;
	/*
	 * Rehash to a size that can fit the current elements. Rehash relative to in_use
	 * to allow also for compaction.
	 */
	data.new_size = g_spaced_primes_closest (hash->in_use / HASH_TABLE_MAX_LOAD_FACTOR * HASH_TABLE_RESIZE_RATIO);
	data.keys = g_new0 (MonoObject*, data.new_size);
	data.values = g_new0 (MonoObject*, data.new_size);

	if (hash->gc_type & MONO_HASH_KEY_GC)
		mono_gc_register_root_wbarrier ((char*)data.keys, sizeof (MonoObject*) * data.new_size, mono_gc_make_vector_descr (), hash->source, hash->key, hash->msg);
	if (hash->gc_type & MONO_HASH_VALUE_GC)
		mono_gc_register_root_wbarrier ((char*)data.values, sizeof (MonoObject*) * data.new_size, mono_gc_make_vector_descr (), hash->source, hash->key, hash->msg);

	if (!mono_threads_are_safepoints_enabled ()) {
		mono_gc_invoke_with_gc_lock (do_rehash, &data);
	} else {
		/* We cannot be preempted */
		do_rehash (&data);
	}

	if (hash->gc_type & MONO_HASH_KEY_GC)
		mono_gc_deregister_root ((char*)old_keys);
	if (hash->gc_type & MONO_HASH_VALUE_GC)
		mono_gc_deregister_root ((char*)old_values);

	g_free (old_keys);
	g_free (old_values);
}