Ejemplo n.º 1
0
MonoGHashTable *
mono_g_hash_table_new_type (GHashFunc hash_func, GEqualFunc key_equal_func, MonoGHashGCType type, MonoGCRootSource source, void *key, const char *msg)
{
	MonoGHashTable *hash;

	if (!hash_func)
		hash_func = g_direct_hash;

	hash = g_new0 (MonoGHashTable, 1);

	hash->hash_func = hash_func;
	hash->key_equal_func = key_equal_func;

	hash->table_size = g_spaced_primes_closest (1);
	hash->keys = g_new0 (MonoObject*, hash->table_size);
	hash->values = g_new0 (MonoObject*, hash->table_size);

	hash->gc_type = type;
	hash->source = source;
	hash->key = key;
	hash->msg = msg;

	if (type > MONO_HASH_KEY_VALUE_GC)
		g_error ("wrong type for gc hashtable");

	if (hash->gc_type & MONO_HASH_KEY_GC)
		mono_gc_register_root_wbarrier ((char*)hash->keys, sizeof (MonoObject*) * hash->table_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*)hash->values, sizeof (MonoObject*) * hash->table_size, mono_gc_make_vector_descr (), hash->source, hash->key, hash->msg);

	return hash;
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
0
MonoGHashTable *
mono_g_hash_table_new_type (GHashFunc hash_func, GEqualFunc key_equal_func, MonoGHashGCType type)
{
	MonoGHashTable *hash = mono_g_hash_table_new (hash_func, key_equal_func);

	hash->gc_type = type;

#ifdef HAVE_SGEN_GC
	if (type < 0 || type > MONO_HASH_KEY_VALUE_GC)
		g_error ("wrong type for gc hashtable");
	/*
	 * We use a user defined marking function to avoid having to register a GC root for
	 * each hash node.
	 */
	if (!table_hash_descr)
		table_hash_descr = mono_gc_make_root_descr_user (mono_g_hash_mark);
	if (type != MONO_HASH_CONSERVATIVE_GC)
		mono_gc_register_root_wbarrier ((char*)hash, sizeof (MonoGHashTable), table_hash_descr);
#endif

	return hash;
}
Ejemplo n.º 4
0
MonoGHashTable*
mono_g_hash_table_new_type (GHashFunc    hash_func,
		  GEqualFunc   key_equal_func,
		  MonoGHashGCType type)
{
  MonoGHashTable *table = mono_g_hash_table_new_full (hash_func, key_equal_func, NULL, NULL);
  if (type == MONO_HASH_KEY_GC || type == MONO_HASH_KEY_VALUE_GC)
	  g_assert (hash_func);
  table->gc_type = type;
#if defined(HAVE_SGEN_GC)
  if (type < 0 || type > MONO_HASH_KEY_VALUE_GC)
	  g_error ("wrong type for gc hashtable");
  /* 
   * We use a user defined marking function to avoid having to register a GC root for
   * each hash node.
   */
  if (!hash_descr)
	  hash_descr = mono_gc_make_root_descr_user (mono_g_hash_mark);
  if (type != MONO_HASH_CONSERVATIVE_GC)
	  mono_gc_register_root_wbarrier ((char*)table, sizeof (MonoGHashTable), hash_descr);
#elif defined(HAVE_BOEHM_GC)
  if (type < 0 || type > MONO_HASH_KEY_VALUE_GC)
	  g_error ("wrong type for gc hashtable");
  if (!node_gc_descs [type] && type > MONO_HASH_CONSERVATIVE_GC) {
	  gsize bmap = 0;
	  if (type & MONO_HASH_KEY_GC)
		  bmap |= 1; /* the first field in the node is the key */
	  if (type & MONO_HASH_VALUE_GC)
		  bmap |= 2; /* the second is the value */
	  bmap |= 4; /* next */
	  node_gc_descs [type] = mono_gc_make_descr_from_bitmap (&bmap, 3);

	  MONO_GC_REGISTER_ROOT (node_free_lists [type]);
  }
#endif
  return table;
}
Ejemplo n.º 5
0
MonoGHashTable *
mono_g_hash_table_new_type (GHashFunc hash_func, GEqualFunc key_equal_func, MonoGHashGCType type, MonoGCRootSource source, const char *msg)
{
	MonoGHashTable *hash = mono_g_hash_table_new (hash_func, key_equal_func);

	hash->gc_type = type;
	hash->source = source;
	hash->msg = msg;

	if (type > MONO_HASH_KEY_VALUE_GC)
		g_error ("wrong type for gc hashtable");

#ifdef HAVE_SGEN_GC
	/*
	 * We use a user defined marking function to avoid having to register a GC root for
	 * each hash node.
	 */
	if (!table_hash_descr)
		table_hash_descr = mono_gc_make_root_descr_user (mono_g_hash_mark);
	mono_gc_register_root_wbarrier ((char*)hash, sizeof (MonoGHashTable), table_hash_descr, source, msg);
#endif

	return hash;
}