summaryrefslogtreecommitdiffstats
path: root/hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c42
1 files changed, 10 insertions, 32 deletions
diff --git a/hash.c b/hash.c
index 8a298de2..8c2aee2d 100644
--- a/hash.c
+++ b/hash.c
@@ -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;
+ }
}
}