aboutsummaryrefslogtreecommitdiffstats
path: root/re.c
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2019-08-15 20:19:13 +0300
committerArnold D. Robbins <arnold@skeeve.com>2019-08-15 20:19:13 +0300
commitc7c3998ed9d96b61d03c675b2105ca5da77b9bfd (patch)
tree1afcbafe745d22764fd2c1cfcb7ec966de4b6710 /re.c
parent28403d5a053d80a06bf94b57e1008ea628a12b1f (diff)
downloadegawk-c7c3998ed9d96b61d03c675b2105ca5da77b9bfd.tar.gz
egawk-c7c3998ed9d96b61d03c675b2105ca5da77b9bfd.tar.bz2
egawk-c7c3998ed9d96b61d03c675b2105ca5da77b9bfd.zip
Reduce up-front compiled regexp memory usage.
Diffstat (limited to 're.c')
-rw-r--r--re.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/re.c b/re.c
index 32d03341..91cff4d6 100644
--- a/re.c
+++ b/re.c
@@ -391,6 +391,16 @@ dfaerror(const char *s)
exit(EXIT_FATAL); /* for DJGPP */
}
+/* re_cache_get --- populate regexp cache if empty */
+
+static inline Regexp *
+re_cache_get(NODE *t)
+{
+ if (t->re_reg[IGNORECASE] == NULL)
+ t->re_reg[IGNORECASE] = make_regexp(t->re_exp->stptr, t->re_exp->stlen, IGNORECASE, t->re_cnt, true);
+ return t->re_reg[IGNORECASE];
+}
+
/* re_update --- recompile a dynamic regexp */
Regexp *
@@ -399,18 +409,18 @@ re_update(NODE *t)
NODE *t1;
if (t->type == Node_val && (t->flags & REGEX) != 0)
- return t->typed_re->re_reg[IGNORECASE];
+ return re_cache_get(t->typed_re);
if ((t->re_flags & CONSTANT) != 0) {
/* it's a constant, so just return it as is */
assert(t->type == Node_regex);
- return t->re_reg[IGNORECASE];
+ return re_cache_get(t);
}
t1 = t->re_exp;
if (t->re_text != NULL) {
/* if contents haven't changed, just return it */
if (cmp_nodes(t->re_text, t1, true) == 0)
- return t->re_reg[IGNORECASE];
+ return re_cache_get(t);
/* things changed, fall through to recompile */
unref(t->re_text);
}
@@ -420,10 +430,14 @@ re_update(NODE *t)
/* text changed */
/* free old */
- if (t->re_reg[0] != NULL)
+ if (t->re_reg[0] != NULL) {
refree(t->re_reg[0]);
- if (t->re_reg[1] != NULL)
+ t->re_reg[0] = NULL;
+ }
+ if (t->re_reg[1] != NULL) {
refree(t->re_reg[1]);
+ t->re_reg[1] = NULL;
+ }
if (t->re_cnt > 0)
t->re_cnt++;
if (t->re_cnt > 10)
@@ -434,13 +448,7 @@ re_update(NODE *t)
unref(t->re_text);
t->re_text = dupnode(t1);
}
- /* compile it */
- t->re_reg[0] = make_regexp(t->re_text->stptr, t->re_text->stlen,
- false, t->re_cnt, true);
- t->re_reg[1] = make_regexp(t->re_text->stptr, t->re_text->stlen,
- true, t->re_cnt, true);
-
- return t->re_reg[IGNORECASE];
+ return re_cache_get(t);
}
/* resetup --- choose what kind of regexps we match */