/* Lock is held. Signals are disabled. */ void GC_grow_table(struct hash_chain_entry ***table, signed_word *log_size_ptr) { register word i; register struct hash_chain_entry *p; signed_word log_old_size = *log_size_ptr; signed_word log_new_size = log_old_size + 1; word old_size = ((log_old_size == -1)? 0: (1 << log_old_size)); word new_size = 1 << log_new_size; struct hash_chain_entry **new_table = (struct hash_chain_entry **) GC_INTERNAL_MALLOC_IGNORE_OFF_PAGE( (size_t)new_size * sizeof(struct hash_chain_entry *), NORMAL); if (new_table == 0) { if (*table == 0) { ABORT("Insufficient space for initial table allocation"); } else { return; } } for (i = 0; i < old_size; i++) { p = (*table)[i]; while (p != 0) { ptr_t real_key = (ptr_t)REVEAL_POINTER(p -> hidden_key); struct hash_chain_entry *next = p -> next; int new_hash = HASH3(real_key, new_size, log_new_size); p -> next = new_table[new_hash]; new_table[new_hash] = p; p = next; } } *log_size_ptr = log_new_size; *table = new_table; }
int bdd_lookup_in_cache31(cmu_bdd_manager bddm, int tag, INT_PTR d1, INT_PTR d2, INT_PTR d3, INT_PTR *result) { long hash; cache_entry *bin; cache_entry p; cache_entry q; bdd f; void (*return_fn)(cmu_bdd_manager, cache_entry); bddm->op_cache.lookups++; hash=HASH3(d1, d2, d3); BDD_REDUCE(hash, bddm->op_cache.size); bin=bddm->op_cache.table[hash].entry; if ((p=bin[0])) { q=CACHE_POINTER(p); if (q->slot[0] != d1 || q->slot[1] != d2 || q->slot[2] != d3 || TAG(p) != tag) { if ((p=bin[1])) { q=CACHE_POINTER(p); if (q->slot[0] != d1 || q->slot[1] != d2 || q->slot[2] != d3 || TAG(p) != tag) return (0); bin[1]=bin[0]; bin[0]=p; } else return (0); } } else return (0); bddm->op_cache.hits++; if ((return_fn=bddm->op_cache.return_fn[TAG(p)])) { if (return_fn == RETURN_BDD_FN) { f=(bdd)q->slot[3]; { BDD_SETUP(f); BDD_TEMP_INCREFS(f); } } else (*return_fn)(bddm, q); } *result=q->slot[3]; return (1); }
void bdd_insert_in_cache31(cmu_bdd_manager bddm, int tag, INT_PTR d1, INT_PTR d2, INT_PTR d3, INT_PTR result) { long hash; cache_entry p; hash=HASH3(d1, d2, d3); BDD_REDUCE(hash, bddm->op_cache.size); if (hash < 0) hash= -hash; p=bdd_get_entry(bddm, tag, bddm->op_cache.table[hash].entry); p->slot[0]=d1; p->slot[1]=d2; p->slot[2]=d3; p->slot[3]=result; bddm->op_cache.inserts++; }
/* update both *table and *log_size_ptr. Lock is held. */ STATIC void GC_grow_table(struct hash_chain_entry ***table, signed_word *log_size_ptr) { register word i; register struct hash_chain_entry *p; signed_word log_old_size = *log_size_ptr; signed_word log_new_size = log_old_size + 1; word old_size = log_old_size == -1 ? 0 : (word)1 << log_old_size; word new_size = (word)1 << log_new_size; /* FIXME: Power of 2 size often gets rounded up to one more page. */ struct hash_chain_entry **new_table; GC_ASSERT(I_HOLD_LOCK()); new_table = (struct hash_chain_entry **) GC_INTERNAL_MALLOC_IGNORE_OFF_PAGE( (size_t)new_size * sizeof(struct hash_chain_entry *), NORMAL); if (new_table == 0) { if (*table == 0) { ABORT("Insufficient space for initial table allocation"); } else { return; } } for (i = 0; i < old_size; i++) { p = (*table)[i]; while (p != 0) { ptr_t real_key = GC_REVEAL_POINTER(p -> hidden_key); struct hash_chain_entry *next = p -> next; size_t new_hash = HASH3(real_key, new_size, log_new_size); p -> next = new_table[new_hash]; new_table[new_hash] = p; p = next; } } *log_size_ptr = log_new_size; *table = new_table; }
static long bdd_rehash3(cmu_bdd_manager bddm, cache_entry p) { return (HASH3(p->slot[0], p->slot[1], p->slot[2])); }