From 4b3e69561390df2a67d7a7752890718da1eab5a1 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 12 Feb 2014 00:12:04 -0800 Subject: Undoing bogus optimization, which can only work when objects are treated as immutable. * hash.c (last_equal_key, last_equal_hash): Variables removed. (equal_hash, hash_process_weak): All references to removed variables scrubbed. --- ChangeLog | 9 +++++++++ hash.c | 54 +++++++++++++++--------------------------------------- 2 files changed, 24 insertions(+), 39 deletions(-) diff --git a/ChangeLog b/ChangeLog index c04dfc1d..53386f4f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2014-02-12 Kaz Kylheku + + Undoing bogus optimization, which can only work when objects + are treated as immutable. + + * hash.c (last_equal_key, last_equal_hash): Variables removed. + (equal_hash, hash_process_weak): All references to removed + variables scrubbed. + 2014-02-12 Kaz Kylheku * lib.c (some_satisfy, all_satisfy, none_satisfy): Fix coding diff --git a/hash.c b/hash.c index 6aac63a0..00b3896c 100644 --- a/hash.c +++ b/hash.c @@ -72,13 +72,6 @@ val weak_keys_k, weak_vals_k, equal_based_k; */ static struct hash *reachable_weak_hashes; -/* - * Cache of equal hashing function - * These variables are deliberately not GC-protected. - */ -static val last_equal_key; -static cnum last_equal_hash = NUM_MAX; - /* * This is is an adaptation of hashpjw, from Compilers: Principles, Techniques * and Tools, Aho, Sethi, Ulman, 1988. P. 436. The register is wider by @@ -118,38 +111,31 @@ static cnum hash_double(double n) static cnum equal_hash(val obj) { - if (obj == last_equal_key) - return last_equal_hash; - - last_equal_key = obj; - switch (type(obj)) { case NIL: - return last_equal_hash = NUM_MAX; + return NUM_MAX; case LIT: - return last_equal_hash = hash_c_str(litptr(obj)) & NUM_MAX; + return hash_c_str(litptr(obj)) & NUM_MAX; case CONS: - return last_equal_hash = (equal_hash(obj->c.car) + - equal_hash(obj->c.cdr)) & NUM_MAX; + return (equal_hash(obj->c.car) + equal_hash(obj->c.cdr)) & NUM_MAX; case STR: - return last_equal_hash = hash_c_str(obj->st.str) & NUM_MAX; + return hash_c_str(obj->st.str) & NUM_MAX; case CHR: - return last_equal_hash = c_chr(obj) & NUM_MAX; + return c_chr(obj) & NUM_MAX; case NUM: - return last_equal_hash = c_num(obj) & NUM_MAX; + return c_num(obj) & NUM_MAX; case SYM: case PKG: case ENV: switch (sizeof (mem_t *)) { case 4: - return last_equal_hash = (((cnum) obj) >> 4) & NUM_MAX; + return (((cnum) obj) >> 4) & NUM_MAX; case 8: default: - return last_equal_hash = (((cnum) obj) >> 5) & NUM_MAX; + return (((cnum) obj) >> 5) & NUM_MAX; } break; case FUN: - return last_equal_hash = ((cnum) obj->f.f.interp_fun + - equal_hash(obj->f.env)) & NUM_MAX; + return ((cnum) obj->f.f.interp_fun + equal_hash(obj->f.env)) & NUM_MAX; case VEC: { val length = obj->v.vec[vec_length]; @@ -159,7 +145,7 @@ static cnum equal_hash(val obj) for (i = 0; i < len; i++) h = (h + equal_hash(obj->v.vec[i])) & NUM_MAX; - return last_equal_hash = h; + return h; } case LCONS: return (equal_hash(car(obj)) + equal_hash(cdr(obj))) & NUM_MAX; @@ -167,11 +153,11 @@ static cnum equal_hash(val obj) lazy_str_force(obj); return equal_hash(obj->ls.prefix); case BGNUM: - return last_equal_hash = mp_hash(mp(obj)) & NUM_MAX; + return mp_hash(mp(obj)) & NUM_MAX; case FLNUM: - return last_equal_hash = hash_double(obj->fl.n); + return hash_double(obj->fl.n); case COBJ: - return last_equal_hash = obj->co.ops->hash(obj) & NUM_MAX; + return obj->co.ops->hash(obj) & NUM_MAX; } internal_error("unhandled case in equal function"); @@ -185,13 +171,9 @@ static cnum eql_hash(val obj) case NIL: return NUM_MAX; case BGNUM: - if (obj == last_equal_key) - return last_equal_hash; - return last_equal_hash = mp_hash(mp(obj)) & NUM_MAX; + return mp_hash(mp(obj)) & NUM_MAX; case FLNUM: - if (obj == last_equal_key) - return last_equal_hash; - return last_equal_hash = hash_double(obj->fl.n); + return hash_double(obj->fl.n); default: switch (sizeof (mem_t *)) { case 4: @@ -590,12 +572,6 @@ void hash_process_weak(void) struct hash *h; cnum i; - /* - * First lapse the equal cache. We can do this unconditionally. - */ - last_equal_key = nil; - last_equal_hash = NUM_MAX; - for (h = reachable_weak_hashes; h != 0; h = h->next) { /* The table of a weak hash was spuriously reached by conservative GC; it's a waste of time doing weak processing, since all keys and -- cgit v1.2.3