diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2014-02-01 03:45:49 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2014-02-01 03:45:49 -0800 |
commit | 9700430895a9b76d113b9b77ef226dfee711830c (patch) | |
tree | eb9ae0a2f69cc00d2216f1d6933da48e34845874 | |
parent | 6abf99b9ae4a8868e55215a74dd4c0e8a97ec99b (diff) | |
download | txr-9700430895a9b76d113b9b77ef226dfee711830c.tar.gz txr-9700430895a9b76d113b9b77ef226dfee711830c.tar.bz2 txr-9700430895a9b76d113b9b77ef226dfee711830c.zip |
* hash.c (hash_mark, hash_grow, make_similar_hash,
copy_hash, gethash_l, gethash, gethash_f, gethash_n,
hash_count, hash_next, hash_eql, hash_equal): Use
num_fast instead of num.
(make_hash): An attempt to make a weak-keys hash that has
equal-based keys is nonsensical; it is now diagnosed with
an exception. Use num_fast instead of num.
(hash_process_weak): Call breakpt whenever the weak object(s) due to
which entries are being deleted match the value in break_obj.
Use num_fast instead of num.
* parser.l (parse_init): Bugfix: the forms_to_ln_hash
was equal-based, which makes no sense.
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | hash.c | 105 | ||||
-rw-r--r-- | parser.l | 2 |
3 files changed, 82 insertions, 41 deletions
@@ -1,5 +1,21 @@ 2014-02-01 Kaz Kylheku <kaz@kylheku.com> + * hash.c (hash_mark, hash_grow, make_similar_hash, + copy_hash, gethash_l, gethash, gethash_f, gethash_n, + hash_count, hash_next, hash_eql, hash_equal): Use + num_fast instead of num. + (make_hash): An attempt to make a weak-keys hash that has + equal-based keys is nonsensical; it is now diagnosed with + an exception. Use num_fast instead of num. + (hash_process_weak): Call breakpt whenever the weak object(s) due to + which entries are being deleted match the value in break_obj. + Use num_fast instead of num. + + * parser.l (parse_init): Bugfix: the forms_to_ln_hash + was equal-based, which makes no sense. + +2014-02-01 Kaz Kylheku <kaz@kylheku.com> + Export break_obj. * gc.c (break_obj): Change to external linkage. @@ -282,7 +282,7 @@ static void hash_mark(val hash) case hash_weak_keys: /* Keys are weak: mark the values only. */ for (i = 0; i < h->modulus; i++) { - val ind = num(i); + val ind = num_fast(i); val chain = vecref(h->table, ind); val iter; @@ -298,7 +298,7 @@ static void hash_mark(val hash) /* Values are weak: mark the keys only. */ for (i = 0; i < h->modulus; i++) { - val ind = num(i); + val ind = num_fast(i); val chain = vecref(h->table, ind); val iter; @@ -328,18 +328,19 @@ static void hash_grow(struct hash *h) { cnum i; cnum new_modulus = 2 * h->modulus; - val new_table = vector(num(new_modulus)); + val new_table = vector(num_fast(new_modulus)); bug_unless (new_modulus > h->modulus); for (i = 0; i < h->modulus; i++) { - val conses = vecref(h->table, num(i)); + val conses = vecref(h->table, num_fast(i)); while (conses) { val entry = car(conses); val next = cdr(conses); val key = car(entry); - val *pchain = vecref_l(new_table, num(h->hash_fun(key) % new_modulus)); + val *pchain = vecref_l(new_table, + num_fast(h->hash_fun(key) % new_modulus)); *cdr_l(conses) = *pchain; *pchain = conses; conses = next; @@ -352,30 +353,36 @@ static void hash_grow(struct hash *h) val make_hash(val weak_keys, val weak_vals, val equal_based) { - int flags = ((weak_vals != nil) << 1) | (weak_keys != nil); - struct hash *h = (struct hash *) chk_malloc(sizeof *h); - val mod = num(256); - val table = vector(mod); - val hash = cobj((mem_t *) h, hash_s, &hash_ops); - - h->flags = (hash_flags_t) flags; - h->modulus = c_num(mod); - h->count = 0; - h->table = table; - h->userdata = nil; - - h->hash_fun = equal_based ? equal_hash : eql_hash; - h->assoc_fun = equal_based ? assoc : assql; - h->acons_new_l_fun = equal_based ? acons_new_l : aconsql_new_l; + if (weak_keys && equal_based) { + uw_throwf(error_s, + lit("make-hash: bad combination :weak-keys with :equal-based"), + nao); + } else { + int flags = ((weak_vals != nil) << 1) | (weak_keys != nil); + struct hash *h = (struct hash *) chk_malloc(sizeof *h); + val mod = num_fast(256); + val table = vector(mod); + val hash = cobj((mem_t *) h, hash_s, &hash_ops); + + h->flags = (hash_flags_t) flags; + h->modulus = c_num(mod); + h->count = 0; + h->table = table; + h->userdata = nil; + + h->hash_fun = equal_based ? equal_hash : eql_hash; + h->assoc_fun = equal_based ? assoc : assql; + h->acons_new_l_fun = equal_based ? acons_new_l : aconsql_new_l; - return hash; + return hash; + } } val make_similar_hash(val existing) { struct hash *ex = (struct hash *) cobj_handle(existing, hash_s); struct hash *h = (struct hash *) chk_malloc(sizeof *h); - val mod = num(256); + val mod = num_fast(256); val table = vector(mod); val hash = cobj((mem_t *) h, hash_s, &hash_ops); @@ -397,7 +404,7 @@ val copy_hash(val existing) struct hash *ex = (struct hash *) cobj_handle(existing, hash_s); struct hash *h = (struct hash *) chk_malloc(sizeof *h); val hash = cobj((mem_t *) h, hash_s, &hash_ops); - val mod = num(ex->modulus); + val mod = num_fast(ex->modulus); val iter; h->modulus = ex->modulus; @@ -419,7 +426,7 @@ val copy_hash(val existing) val *gethash_l(val hash, val key, val *new_p) { struct hash *h = (struct hash *) cobj_handle(hash, hash_s); - val *pchain = vecref_l(h->table, num(h->hash_fun(key) % h->modulus)); + val *pchain = vecref_l(h->table, num_fast(h->hash_fun(key) % h->modulus)); val old = *pchain; val *place = h->acons_new_l_fun(key, new_p, pchain); if (old != *pchain && ++h->count > 2 * h->modulus) @@ -430,7 +437,7 @@ val *gethash_l(val hash, val key, val *new_p) val gethash(val hash, val key) { struct hash *h = (struct hash *) cobj_handle(hash, hash_s); - val chain = vecref(h->table, num(h->hash_fun(key) % h->modulus)); + val chain = vecref(h->table, num_fast(h->hash_fun(key) % h->modulus)); val found = h->assoc_fun(key, chain); return cdr(found); } @@ -438,7 +445,7 @@ val gethash(val hash, val key) val gethash_f(val hash, val key, val *found) { struct hash *h = (struct hash *) cobj_handle(hash, hash_s); - val chain = vecref(h->table, num(h->hash_fun(key) % h->modulus)); + val chain = vecref(h->table, num_fast(h->hash_fun(key) % h->modulus)); set(*found, h->assoc_fun(key, chain)); return cdr(*found); } @@ -446,7 +453,7 @@ val gethash_f(val hash, val key, val *found) val gethash_n(val hash, val key, val notfound_val) { struct hash *h = (struct hash *) cobj_handle(hash, hash_s); - val chain = vecref(h->table, num(h->hash_fun(key) % h->modulus)); + val chain = vecref(h->table, num_fast(h->hash_fun(key) % h->modulus)); val existing = h->assoc_fun(key, chain); return if3(existing, cdr(existing), notfound_val); } @@ -468,7 +475,7 @@ val pushhash(val hash, val key, val value) val remhash(val hash, val key) { struct hash *h = (struct hash *) cobj_handle(hash, hash_s); - val *pchain = vecref_l(h->table, num(h->hash_fun(key) % h->modulus)); + val *pchain = vecref_l(h->table, num_fast(h->hash_fun(key) % h->modulus)); val existing = h->assoc_fun(key, *pchain); if (existing) { @@ -484,7 +491,7 @@ val remhash(val hash, val key) val hash_count(val hash) { struct hash *h = (struct hash *) cobj_handle(hash, hash_s); - return num(h->count); + return num_fast(h->count); } val get_hash_userdata(val hash) @@ -546,7 +553,7 @@ val hash_next(val iter) while (nullp(hi->cons)) { if (++hi->chain >= h->modulus) return nil; - set(hi->cons, vecref(h->table, num(hi->chain))); + set(hi->cons, vecref(h->table, num_fast(hi->chain))); } return car(hi->cons); } @@ -562,12 +569,12 @@ val maphash(val fun, val hash) val hash_eql(val obj) { - return num(eql_hash(obj)); + return num_fast(eql_hash(obj)); } val hash_equal(val obj) { - return num(equal_hash(obj)); + return num_fast(equal_hash(obj)); } /* @@ -602,16 +609,21 @@ void hash_process_weak(void) /* Sweep through all entries. Delete any which have keys that are garbage. */ for (i = 0; i < h->modulus; i++) { - val ind = num(i); + val ind = num_fast(i); val *pchain = vecref_l(h->table, ind); val *iter; for (iter = pchain; !gc_is_reachable(*iter); ) { val entry = car(*iter); - if (!gc_is_reachable(entry) && !gc_is_reachable(car(entry))) + if (!gc_is_reachable(entry) && !gc_is_reachable(car(entry))) { *iter = cdr(*iter); - else +#if EXTRA_DEBUGGING + if (car(entry) == break_obj) + breakpt(); +#endif + } else { iter = cdr_l(*iter); + } } } /* Garbage is gone now. Seal things by marking the vector. */ @@ -621,16 +633,21 @@ void hash_process_weak(void) /* Sweep through all entries. Delete any which have values that are garbage. */ for (i = 0; i < h->modulus; i++) { - val ind = num(i); + val ind = num_fast(i); val *pchain = vecref_l(h->table, ind); val *iter; for (iter = pchain; !gc_is_reachable(*iter); ) { val entry = car(*iter); - if (!gc_is_reachable(entry) && !gc_is_reachable(cdr(entry))) + if (!gc_is_reachable(entry) && !gc_is_reachable(cdr(entry))) { *iter = cdr(*iter); - else +#if EXTRA_DEBUGGING + if (cdr(entry) == break_obj) + breakpt(); +#endif + } else { iter = cdr_l(*iter); + } } } /* Garbage is gone now. Seal things by marking the vector. */ @@ -640,7 +657,7 @@ void hash_process_weak(void) /* Sweep through all entries. Delete any which have keys or values that are garbage. */ for (i = 0; i < h->modulus; i++) { - val ind = num(i); + val ind = num_fast(i); val *pchain = vecref_l(h->table, ind); val *iter; @@ -648,9 +665,17 @@ void hash_process_weak(void) val entry = car(*iter); if (!gc_is_reachable(entry) && (!gc_is_reachable(car(entry)) || !gc_is_reachable(cdr(entry)))) + { *iter = cdr(*iter); - else +#if EXTRA_DEBUGGING + if (!gc_is_reachable(car(entry)) && car(entry) == break_obj) + breakpt(); + if (!gc_is_reachable(cdr(entry)) && cdr(entry) == break_obj) + breakpt(); +#endif + } else { iter = cdr_l(*iter); + } } } /* Garbage is gone now. Seal things by marking the vector. */ @@ -805,7 +805,7 @@ void parse_init(void) protect(&yyin_stream, &prepared_error_message, &form_to_ln_hash, (val *) 0); - form_to_ln_hash = make_hash(t, nil, t); + form_to_ln_hash = make_hash(t, nil, nil); } void parse_reset(val spec_file) |