summaryrefslogtreecommitdiffstats
path: root/hash.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2020-03-09 06:48:06 -0700
committerKaz Kylheku <kaz@kylheku.com>2020-03-09 06:48:06 -0700
commitb6f7c83a321f8043bc4edef12530ae25b1917579 (patch)
tree1032245626c1daa0ce4974f83b0d66e8d2fee124 /hash.c
parentd25ab176441610fb2460fa882bff7f9ce2ba22e9 (diff)
downloadtxr-b6f7c83a321f8043bc4edef12530ae25b1917579.tar.gz
txr-b6f7c83a321f8043bc4edef12530ae25b1917579.tar.bz2
txr-b6f7c83a321f8043bc4edef12530ae25b1917579.zip
hash: bugfix: maintain counts in weak processing.
* hash.c (do_weak_tables): Update the count field of each weak hash to account for the entries that get removed by expiry. Also, loop variable moves into a tighter scope.
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/hash.c b/hash.c
index 599f35f1..cf3d580c 100644
--- a/hash.c
+++ b/hash.c
@@ -1200,9 +1200,9 @@ val hash_equal(val obj, val seed)
static void do_weak_tables(void)
{
struct hash *h;
- cnum i;
for (h = reachable_weak_hashes; h != 0; h = h->next) {
+ cnum i, c;
/* 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
values have been transitively marked as reachable; and so we
@@ -1217,7 +1217,7 @@ static void do_weak_tables(void)
case hash_weak_keys:
/* Sweep through all entries. Delete any which have keys
that are garbage. */
- for (i = 0; i < h->modulus; i++) {
+ for (c = 0, i = 0; i < h->modulus; i++) {
val *pchain = &h->table->v.vec[i];
val *iter;
@@ -1231,16 +1231,18 @@ static void do_weak_tables(void)
#endif
} else {
iter = us_cdr_p(*iter);
+ c++;
}
}
}
/* Garbage is gone now. Seal things by marking the vector. */
gc_mark(h->table);
+ h->count = c;
break;
case hash_weak_vals:
/* Sweep through all entries. Delete any which have values
that are garbage. */
- for (i = 0; i < h->modulus; i++) {
+ for (i = 0, c = 0; i < h->modulus; i++) {
val *pchain = &h->table->v.vec[i];
val *iter;
@@ -1254,16 +1256,18 @@ static void do_weak_tables(void)
#endif
} else {
iter = us_cdr_p(*iter);
+ c++;
}
}
}
/* Garbage is gone now. Seal things by marking the vector. */
gc_mark(h->table);
+ h->count = c;
break;
case hash_weak_both:
/* Sweep through all entries. Delete any which have keys
or values that are garbage. */
- for (i = 0; i < h->modulus; i++) {
+ for (i = 0, c = 0; i < h->modulus; i++) {
val *pchain = &h->table->v.vec[i];
val *iter;
@@ -1281,11 +1285,13 @@ static void do_weak_tables(void)
#endif
} else {
iter = us_cdr_p(*iter);
+ c++;
}
}
}
/* Garbage is gone now. Seal things by marking the vector. */
gc_mark(h->table);
+ h->count = c;
break;
}
}