summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--hash.c35
2 files changed, 24 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index c1a37dc3..d13a8801 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
2010-01-26 Kaz Kylheku <kkylheku@gmail.com>
+ hash.c (hash_process_weak): There is no point in fixing up
+ the type codes of spuriously reached nodes; reached objects
+ will not be removed by weak processing and so it's better
+ to just detect those situations and short-circuit.
+
+2010-01-26 Kaz Kylheku <kkylheku@gmail.com>
+
Optimization in derivative-based regex engine.
Exponential memory consumption behavior was observed when
matching the input aaaaaa....
diff --git a/hash.c b/hash.c
index f7c32b51..1c273254 100644
--- a/hash.c
+++ b/hash.c
@@ -286,6 +286,13 @@ void hash_process_weak(void)
cnum i;
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
+ values have been transitively marked as reachable; and so we
+ won't find anything to remove. */
+ if (gc_is_reachable(h->table))
+ continue;
+
switch (h->flags) {
case hash_weak_none:
/* what is this doing here */
@@ -298,12 +305,9 @@ void hash_process_weak(void)
val *pchain = vecref_l(h->table, ind);
val *iter;
- for (iter = pchain; *iter != nil; ) {
- val entry;
- (*iter)->t.type &= ~REACHABLE;
- entry = car(*iter);
- entry->t.type &= ~REACHABLE;
- if (!gc_is_reachable(car(entry)))
+ for (iter = pchain; !gc_is_reachable(*iter); ) {
+ val entry = car(*iter);
+ if (!gc_is_reachable(entry) && !gc_is_reachable(car(entry)))
*iter = cdr(*iter);
else
iter = cdr_l(*iter);
@@ -320,12 +324,9 @@ void hash_process_weak(void)
val *pchain = vecref_l(h->table, ind);
val *iter;
- for (iter = pchain; *iter != nil; ) {
- val entry;
- (*iter)->t.type &= ~REACHABLE;
- entry = car(*iter);
- entry->t.type &= ~REACHABLE;
- if (!gc_is_reachable(cdr(entry)))
+ for (iter = pchain; !gc_is_reachable(*iter); ) {
+ val entry = car(*iter);
+ if (!gc_is_reachable(entry) && !gc_is_reachable(car(entry)))
*iter = cdr(*iter);
else
iter = cdr_l(*iter);
@@ -342,12 +343,10 @@ void hash_process_weak(void)
val *pchain = vecref_l(h->table, ind);
val *iter;
- for (iter = pchain; *iter != nil; ) {
- val entry;
- (*iter)->t.type &= ~REACHABLE;
- entry = car(*iter);
- entry->t.type &= ~REACHABLE;
- if (!gc_is_reachable(car(entry)) || !gc_is_reachable(cdr(entry)))
+ for (iter = pchain; !gc_is_reachable(*iter); ) {
+ val entry = car(*iter);
+ if (!gc_is_reachable(entry) &&
+ (!gc_is_reachable(car(entry)) || !gc_is_reachable(cdr(entry))))
*iter = cdr(*iter);
else
iter = cdr_l(*iter);