diff options
-rw-r--r-- | hash.c | 42 | ||||
-rw-r--r-- | txr.1 | 15 |
2 files changed, 19 insertions, 38 deletions
@@ -591,7 +591,6 @@ static void hash_print_op(val hash, val out, val pretty, struct strm_ctx *ctx) static void hash_mark(val hash) { struct hash *h = coerce(struct hash *, hash->co.handle); - cnum i; gc_mark(h->userdata); @@ -606,39 +605,18 @@ static void hash_mark(val hash) gc_mark(h->table); break; case hash_weak_keys: - /* Keys are weak: mark the values only. */ - for (i = 0; i < h->modulus; i++) { - val chain = h->table->v.vec[i]; - val iter; - - for (iter = chain; iter != nil; iter = us_cdr(iter)) { - val entry = us_car(iter); - gc_mark(us_cdr(entry)); - } - } - h->next = reachable_weak_hashes; - reachable_weak_hashes = h; - break; case hash_weak_vals: - /* Values are weak: mark the keys only. */ - - for (i = 0; i < h->modulus; i++) { - val chain = h->table->v.vec[i]; - val iter; - - for (iter = chain; iter != nil; iter = us_cdr(iter)) { - val entry = us_car(iter); - gc_mark(us_car(entry)); - } - } - h->next = reachable_weak_hashes; - reachable_weak_hashes = h; - break; case hash_weak_both: - /* Values and keys are weak: don't mark anything. */ - h->next = reachable_weak_hashes; - reachable_weak_hashes = h; - break; + /* If the hash is weak, we don't touch it at this time, + but add it to the list of reachable weak hashes, + unless it is empty. */ + if (h->count > 0) { + h->next = reachable_weak_hashes; + reachable_weak_hashes = h; + } else { + gc_mark(h->table); + break; + } } } @@ -44902,13 +44902,16 @@ references to some object are weak references, then that object is considered garbage, just as if it had no references to it. The object is reclaimed, and the weak references "lapse" in some way, which depends on what kind they are. Hash table weak references lapse by entry removal. When an object used -as a key in in one or more weak-key hash tables becomes unreachable, those -hash entries disappear. Similarly, when an object appearing as a value in +as a key in in one or more weak-key hash tables becomes unreachable, those hash +entries disappear. This happens even if the values are themselves reachable. +That is what it means that. +.IR "Vice versa" , +when an object appearing as a value in one or more hash table entries in weak-value hash tables becomes unreachable, -those entries disappear. When a hash table has both weak keys and weak values, -then its entries are removed when either keys or values become unreachable. -In other words, both the key and value must be reachable in order to -retain the entry. +those entries disappear, even if the keys are reachable. When a hash table has +both weak keys and weak values, then its entries are removed when either keys +or values become unreachable. In other words, both the key and value must be +reachable in order to retain the entry. An open traversal of a hash table is performed by the .code maphash |