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