aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--awkgram.c6
-rw-r--r--awkgram.y6
-rw-r--r--re.c32
4 files changed, 29 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index 5a20c09b..eced4196 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2019-08-15 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ Reduce memory usage by only compiling the IGNORECASE version of
+ regexp when it's actually needed.
+
+ * awkgram.y (make_regnode): Only compile the regular version.
+ * re.c (re_cache_get): New function.
+ (re_update): Use it as appropriate.
+
2019-07-23 Koichi Murase <myoga.murase@gmail.com>
* builtin.c (do_xor): Remove unneeded local variable `i'. Simplify
diff --git a/awkgram.c b/awkgram.c
index 19a11827..b923f191 100644
--- a/awkgram.c
+++ b/awkgram.c
@@ -7764,12 +7764,6 @@ make_regnode(int type, NODE *exp)
freenode(n);
return NULL;
}
- n->re_reg[1] = make_regexp(exp->stptr, exp->stlen, true, true, false);
- if (n->re_reg[1] == NULL) {
- refree(n->re_reg[0]);
- freenode(n);
- return NULL;
- }
n->re_exp = exp;
n->re_flags = CONSTANT;
}
diff --git a/awkgram.y b/awkgram.y
index aa8ccb1d..62865e1b 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -5267,12 +5267,6 @@ make_regnode(int type, NODE *exp)
freenode(n);
return NULL;
}
- n->re_reg[1] = make_regexp(exp->stptr, exp->stlen, true, true, false);
- if (n->re_reg[1] == NULL) {
- refree(n->re_reg[0]);
- freenode(n);
- return NULL;
- }
n->re_exp = exp;
n->re_flags = CONSTANT;
}
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 */