summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2010-01-26 16:18:17 -0800
committerKaz Kylheku <kaz@kylheku.com>2010-01-26 16:18:17 -0800
commit45988e6a180543e3ffbff756e0b06bb37d409666 (patch)
tree95ed5fd961bfbd69688e7a8ec2d09e9bb28d41bf
parent1b2a7dc06a92c0098ecf279ec8e645b64dffdc36 (diff)
downloadtxr-45988e6a180543e3ffbff756e0b06bb37d409666.tar.gz
txr-45988e6a180543e3ffbff756e0b06bb37d409666.tar.bz2
txr-45988e6a180543e3ffbff756e0b06bb37d409666.zip
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.
-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);