diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2020-04-11 01:07:54 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2020-04-11 01:07:54 -0700 |
commit | a4c376979d15323ad729e92e41ba43768e8dc163 (patch) | |
tree | 0c93c4b37b70b4e90340cfee6b3477852257092f /struct.c | |
parent | 4abe7b8300a89d4b8c3b3277076e76f20754b27e (diff) | |
download | txr-a4c376979d15323ad729e92e41ba43768e8dc163.tar.gz txr-a4c376979d15323ad729e92e41ba43768e8dc163.tar.bz2 txr-a4c376979d15323ad729e92e41ba43768e8dc163.zip |
hash: bugfix: spurious retention in weak processing.
The algorithm for weak processing is not correct. In
hash_mark, we must must simply not mark any of the entries,
keys or values, of a weak table regardless of what type of
weak table it is. If we do that, we cause spurious retention
in situations that the keys and values have some kind of link
together other than through the table. For instance, suppose
keys are weak, but values happen to have references to keys.
If we mark the values, we mark the keys and nothing will
expire from the table.
Such a situation happens in stream_parser_hash, which
associates streams with parsers, and has weak keys. Parsers
have references to streams. So entries in the hash never
expire. Any stream that gets a parser is retained forever.
The weak hashes used for binding in eval.c (top_vb, ...) are
also affected, because the key is some symbol <sym> and the
value is (<sym> . <val>). The key is weak, but the value
references the sym. So these hashes also will not expire the
keys: unreachable variable bindings will stick around.
* hash.c (hash_mark): If a hash table has weak keys,
values, or both, then only mark its vector if the count is
zero. If it has one or more entries, we just add it to the
reachable_weak_hashes list to be processed in do_weak_tables.
Diffstat (limited to 'struct.c')
0 files changed, 0 insertions, 0 deletions