void mono_g_hash_table_destroy (MonoGHashTable *hash) { int i; g_return_if_fail (hash != NULL); #ifdef HAVE_SGEN_GC mono_gc_deregister_root ((char*)hash); #endif for (i = 0; i < hash->table_size; i++){ Slot *s, *next; for (s = hash->table [i]; s != NULL; s = next){ next = s->next; if (hash->key_destroy_func != NULL) (*hash->key_destroy_func)(s->key); if (hash->value_destroy_func != NULL) (*hash->value_destroy_func)(s->value); free_slot (hash, s); } } mg_free (hash->table); mg_free (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); }
/** * mono_g_hash_table_destroy: */ void mono_g_hash_table_destroy (MonoGHashTable *hash) { int i; g_return_if_fail (hash != NULL); if (hash->gc_type & MONO_HASH_KEY_GC) mono_gc_deregister_root ((char*)hash->keys); if (hash->gc_type & MONO_HASH_VALUE_GC) mono_gc_deregister_root ((char*)hash->values); for (i = 0; i < hash->table_size; i++) { if (hash->keys [i]) { if (hash->key_destroy_func) (*hash->key_destroy_func)(hash->keys [i]); if (hash->value_destroy_func) (*hash->value_destroy_func)(hash->values [i]); } } g_free (hash->keys); g_free (hash->values); g_free (hash); }
/** * g_hash_table_destroy: * @hash_table: a #GHashTable. * * Destroys the #GHashTable. If keys and/or values are dynamically * allocated, you should either free them first or create the #GHashTable * using g_hash_table_new_full(). In the latter case the destroy functions * you supplied will be called on all keys and values before destroying * the #GHashTable. **/ void mono_g_hash_table_destroy (MonoGHashTable *hash_table) { guint i; g_return_if_fail (hash_table != NULL); for (i = 0; i < hash_table->size; i++) g_hash_nodes_destroy (hash_table->nodes[i], hash_table->gc_type, hash_table->key_destroy_func, hash_table->value_destroy_func); #if HAVE_BOEHM_GC #else #if HAVE_SGEN_GC mono_gc_deregister_root ((char*)hash_table); #endif g_free (hash_table->nodes); g_free (hash_table); #endif }
void mono_gc_free_fixed (void* addr) { mono_gc_deregister_root (addr); free (addr); }