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>
This commit is contained in:
parent
21fbee2e87
commit
b3c91a127f
@ -530,7 +530,8 @@ struct globals {
|
|||||||
xhash *ahash; /* argument names, used only while parsing function bodies */
|
xhash *ahash; /* argument names, used only while parsing function bodies */
|
||||||
xhash *fnhash; /* function names, used only in parsing stage */
|
xhash *fnhash; /* function names, used only in parsing stage */
|
||||||
xhash *vhash; /* variables and arrays */
|
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;
|
const char *g_progname;
|
||||||
int g_lineno;
|
int g_lineno;
|
||||||
int nfields;
|
int nfields;
|
||||||
@ -592,10 +593,13 @@ struct globals2 {
|
|||||||
#define break_ptr (G1.break_ptr )
|
#define break_ptr (G1.break_ptr )
|
||||||
#define continue_ptr (G1.continue_ptr)
|
#define continue_ptr (G1.continue_ptr)
|
||||||
#define iF (G1.iF )
|
#define iF (G1.iF )
|
||||||
#define vhash (G1.vhash )
|
|
||||||
#define ahash (G1.ahash )
|
#define ahash (G1.ahash )
|
||||||
#define fdhash (G1.fdhash )
|
|
||||||
#define fnhash (G1.fnhash )
|
#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_progname (G1.g_progname )
|
||||||
#define g_lineno (G1.g_lineno )
|
#define g_lineno (G1.g_lineno )
|
||||||
#define nfields (G1.nfields )
|
#define nfields (G1.nfields )
|
||||||
@ -682,6 +686,33 @@ static xhash *hash_init(void)
|
|||||||
return newhash;
|
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 */
|
/* find item in hash, return ptr to data, NULL if not found */
|
||||||
static void *hash_search(xhash *hash, const char *name)
|
static void *hash_search(xhash *hash, const char *name)
|
||||||
{
|
{
|
||||||
@ -869,23 +900,7 @@ static xhash *iamarray(var *v)
|
|||||||
return a->x.array;
|
return a->x.array;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_array(xhash *array)
|
#define clear_array(array) hash_clear(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clear a variable */
|
/* clear a variable */
|
||||||
static var *clrvar(var *v)
|
static var *clrvar(var *v)
|
||||||
@ -1742,7 +1757,7 @@ static void parse_program(char *p)
|
|||||||
}
|
}
|
||||||
seq = &f->body;
|
seq = &f->body;
|
||||||
chain_group();
|
chain_group();
|
||||||
clear_array(ahash);
|
hash_clear(ahash);
|
||||||
} else if (tclass & TS_OPSEQ) {
|
} else if (tclass & TS_OPSEQ) {
|
||||||
debug_printf_parse("%s: TS_OPSEQ\n", __func__);
|
debug_printf_parse("%s: TS_OPSEQ\n", __func__);
|
||||||
rollback_token();
|
rollback_token();
|
||||||
@ -3471,11 +3486,16 @@ int awk_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
bb_show_usage();
|
bb_show_usage();
|
||||||
parse_program(*argv++);
|
parse_program(*argv++);
|
||||||
}
|
}
|
||||||
//free_hash(ahash) // ~250 bytes, arg names, used only during parse of function bodies
|
/* Free unused parse structures */
|
||||||
//ahash = NULL; // debug
|
//hash_free(fnhash); // ~250 bytes when empty, used only for function names
|
||||||
//free_hash(fnhash) // ~250 bytes, used only for function names
|
//^^^^^^^^^^^^^^^^^ does not work, hash_clear() inside SEGVs
|
||||||
//fnhash = NULL; // debug
|
// (IOW: hash_clear() assumes it's a hash of variables. fnhash is not).
|
||||||
/* parsing done, on to executing */
|
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 */
|
/* fill in ARGV array */
|
||||||
setari_u(intvar[ARGV], 0, "awk");
|
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++);
|
setari_u(intvar[ARGV], ++i, *argv++);
|
||||||
setvar_i(intvar[ARGC], i + 1);
|
setvar_i(intvar[ARGC], i + 1);
|
||||||
|
|
||||||
fdhash = hash_init();
|
//fdhash = ahash - done via define
|
||||||
newfile("/dev/stdin")->F = stdin;
|
newfile("/dev/stdin")->F = stdin;
|
||||||
newfile("/dev/stdout")->F = stdout;
|
newfile("/dev/stdout")->F = stdout;
|
||||||
newfile("/dev/stderr")->F = stderr;
|
newfile("/dev/stderr")->F = stderr;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user