diff options
author | Denys Vlasenko | 2021-06-29 18:33:25 +0200 |
---|---|---|
committer | Denys Vlasenko | 2021-06-29 19:06:59 +0200 |
commit | b3c91a127f8baecee0265ba92898ae1e718bdb31 (patch) | |
tree | 2f5f35d1bc4e92d10633fbb21abc1df446551907 | |
parent | 21fbee2e87ddf7b47bb501b6529b63ac2b3af0bd (diff) | |
download | busybox-b3c91a127f8baecee0265ba92898ae1e718bdb31.zip busybox-b3c91a127f8baecee0265ba92898ae1e718bdb31.tar.gz |
awk: free unused parsing structures after parse is done
function old new delta
hash_clear - 90 +90
awk_main 827 849 +22
clear_array 90 - -90
------------------------------------------------------------------------------
(add/remove: 1/1 grow/shrink: 1/0 up/down: 112/-90) Total: 22 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | editors/awk.c | 74 |
1 files changed, 47 insertions, 27 deletions
diff --git a/editors/awk.c b/editors/awk.c index 6142144..4e29b28 100644 --- a/editors/awk.c +++ b/editors/awk.c @@ -530,7 +530,8 @@ struct globals { xhash *ahash; /* argument names, used only while parsing function bodies */ xhash *fnhash; /* function names, used only in parsing stage */ xhash *vhash; /* variables and arrays */ - xhash *fdhash; /* file objects, used only in execution stage */ + //xhash *fdhash; /* file objects, used only in execution stage */ + //we are reusing ahash as fdhash, via define (see later) const char *g_progname; int g_lineno; int nfields; @@ -592,10 +593,13 @@ struct globals2 { #define break_ptr (G1.break_ptr ) #define continue_ptr (G1.continue_ptr) #define iF (G1.iF ) -#define vhash (G1.vhash ) #define ahash (G1.ahash ) -#define fdhash (G1.fdhash ) #define fnhash (G1.fnhash ) +#define vhash (G1.vhash ) +#define fdhash ahash +//^^^^^^^^^^^^^^^^^^ ahash is cleared after every function parsing, +// and ends up empty after parsing phase. Thus, we can simply reuse it +// for fdhash in execution stage. #define g_progname (G1.g_progname ) #define g_lineno (G1.g_lineno ) #define nfields (G1.nfields ) @@ -682,6 +686,33 @@ static xhash *hash_init(void) return newhash; } +static void hash_clear(xhash *hash) +{ + unsigned i; + hash_item *hi, *thi; + + for (i = 0; i < hash->csize; i++) { + hi = hash->items[i]; + while (hi) { + thi = hi; + hi = hi->next; + free(thi->data.v.string); + free(thi); + } + hash->items[i] = NULL; + } + hash->glen = hash->nel = 0; +} + +#if 0 //UNUSED +static void hash_free(xhash *hash) +{ + hash_clear(hash); + free(hash->items); + free(hash); +} +#endif + /* find item in hash, return ptr to data, NULL if not found */ static void *hash_search(xhash *hash, const char *name) { @@ -869,23 +900,7 @@ static xhash *iamarray(var *v) return a->x.array; } -static void clear_array(xhash *array) -{ - unsigned i; - hash_item *hi, *thi; - - for (i = 0; i < array->csize; i++) { - hi = array->items[i]; - while (hi) { - thi = hi; - hi = hi->next; - free(thi->data.v.string); - free(thi); - } - array->items[i] = NULL; - } - array->glen = array->nel = 0; -} +#define clear_array(array) hash_clear(array) /* clear a variable */ static var *clrvar(var *v) @@ -1742,7 +1757,7 @@ static void parse_program(char *p) } seq = &f->body; chain_group(); - clear_array(ahash); + hash_clear(ahash); } else if (tclass & TS_OPSEQ) { debug_printf_parse("%s: TS_OPSEQ\n", __func__); rollback_token(); @@ -3471,11 +3486,16 @@ int awk_main(int argc UNUSED_PARAM, char **argv) bb_show_usage(); parse_program(*argv++); } - //free_hash(ahash) // ~250 bytes, arg names, used only during parse of function bodies - //ahash = NULL; // debug - //free_hash(fnhash) // ~250 bytes, used only for function names - //fnhash = NULL; // debug - /* parsing done, on to executing */ + /* Free unused parse structures */ + //hash_free(fnhash); // ~250 bytes when empty, used only for function names + //^^^^^^^^^^^^^^^^^ does not work, hash_clear() inside SEGVs + // (IOW: hash_clear() assumes it's a hash of variables. fnhash is not). + free(fnhash->items); + free(fnhash); + fnhash = NULL; // debug + //hash_free(ahash); // empty after parsing, will reuse as fdhash instead of freeing + + /* Parsing done, on to executing */ /* fill in ARGV array */ setari_u(intvar[ARGV], 0, "awk"); @@ -3484,7 +3504,7 @@ int awk_main(int argc UNUSED_PARAM, char **argv) setari_u(intvar[ARGV], ++i, *argv++); setvar_i(intvar[ARGC], i + 1); - fdhash = hash_init(); + //fdhash = ahash - done via define newfile("/dev/stdin")->F = stdin; newfile("/dev/stdout")->F = stdout; newfile("/dev/stderr")->F = stderr; |