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; }
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); }
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; }
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; }
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; }