void VM::intern_current_environment(scm_symbol_t symbol, scm_obj_t value) { scm_hashtable_t ht = m_current_environment->variable; scoped_lock lock(ht->lock); scm_obj_t obj = get_hashtable(ht, symbol); if (obj != scm_undef) { assert(GLOCP(obj)); #if USE_PARALLEL_VM if (m_interp->live_thread_count() > 1) { assert(m_heap->in_heap(obj)); m_interp->remember(((scm_gloc_t)obj)->value, value); } #endif m_heap->write_barrier(value); ((scm_gloc_t)obj)->value = value; return; } scm_gloc_t gloc = make_gloc(m_heap, symbol); gloc->value = value; m_heap->write_barrier(symbol); m_heap->write_barrier(gloc); int nsize = put_hashtable(ht, symbol, gloc); if (nsize) rehash_hashtable(m_heap, ht, nsize); }
const char * add_string(struct hashtable *h, const char *string) { struct hashnode *n, *head; int bucket_index; unsigned int hv; if((n = node_lookup(h, string, &hv))) return n->string; bucket_index = MOD(hv, h->maxp); if (bucket_index < h->p) bucket_index = MOD(hv, (2*h->maxp)); /* allocate new node */ n = (struct hashnode *)malloc(sizeof(*n)); /* fill in newly allocated node */ n->value = hv; n->string_length = strlen(string); n->string = malloc(n->string_length+1); n->data = NULL; memcpy(n->string, string, n->string_length+1); /* add newly allocated node to appropriate chain */ head = h->buckets[bucket_index]; /* just push it on the chain */ n->next = head->next; head->next = n; n->next->prev = n; n->prev = head; ++h->buckets[bucket_index]->nodes_in_chain; ++h->node_cnt; /* "load" on hashtable too high? */ if (h->node_cnt/h->currentsize > h->maxload) rehash_hashtable(h); return n->string; }
void * add_data(struct hashtable *h, const char *string, void *data) { struct hashnode *n, *head; int bucket_index; unsigned int hv; int hash_mod; if((n = node_lookup(h, string, &hv))) { void *r = NULL; if (data) { r = (void *)n->data; n->data = data; } else { r = (void *)n->string; } return r; } bucket_index = MOD(hv, h->maxp); hash_mod = h->maxp; if (bucket_index < h->p) { bucket_index = MOD(hv, (2*h->maxp)); hash_mod = 2*h->maxp; } if (h->flags > 1) printf("# \"%s\": hash value %u, base %d, bucket %d\n", string, hv, hash_mod, bucket_index); /* allocate new node */ n = (struct hashnode *)malloc(sizeof(*n)); /* fill in newly allocated node */ n->value = hv; n->string_length = strlen(string); n->string = malloc(n->string_length+1); memcpy(n->string, string, n->string_length+1); n->data = data; /* add newly allocated node to appropriate chain */ head = h->buckets[bucket_index]; /* just push it on the chain */ n->next = head->next; head->next = n; n->next->prev = n; n->prev = head; ++h->buckets[bucket_index]->nodes_in_chain; ++h->node_cnt; /* "load" on hashtable too high? */ if (h->node_cnt/h->currentsize > h->maxload) rehash_hashtable(h); return (NULL == data)? (void *)n->string: NULL; }