aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-06-29 18:33:25 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2021-06-29 19:06:59 +0200
commitb3c91a127f8baecee0265ba92898ae1e718bdb31 (patch)
tree2f5f35d1bc4e92d10633fbb21abc1df446551907
parent21fbee2e87ddf7b47bb501b6529b63ac2b3af0bd (diff)
downloadbusybox-w32-b3c91a127f8baecee0265ba92898ae1e718bdb31.tar.gz
busybox-w32-b3c91a127f8baecee0265ba92898ae1e718bdb31.tar.bz2
busybox-w32-b3c91a127f8baecee0265ba92898ae1e718bdb31.zip
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.c74
1 files changed, 47 insertions, 27 deletions
diff --git a/editors/awk.c b/editors/awk.c
index 6142144bb..4e29b28cf 100644
--- a/editors/awk.c
+++ b/editors/awk.c
@@ -530,7 +530,8 @@ struct globals {
530 xhash *ahash; /* argument names, used only while parsing function bodies */ 530 xhash *ahash; /* argument names, used only while parsing function bodies */
531 xhash *fnhash; /* function names, used only in parsing stage */ 531 xhash *fnhash; /* function names, used only in parsing stage */
532 xhash *vhash; /* variables and arrays */ 532 xhash *vhash; /* variables and arrays */
533 xhash *fdhash; /* file objects, used only in execution stage */ 533 //xhash *fdhash; /* file objects, used only in execution stage */
534 //we are reusing ahash as fdhash, via define (see later)
534 const char *g_progname; 535 const char *g_progname;
535 int g_lineno; 536 int g_lineno;
536 int nfields; 537 int nfields;
@@ -592,10 +593,13 @@ struct globals2 {
592#define break_ptr (G1.break_ptr ) 593#define break_ptr (G1.break_ptr )
593#define continue_ptr (G1.continue_ptr) 594#define continue_ptr (G1.continue_ptr)
594#define iF (G1.iF ) 595#define iF (G1.iF )
595#define vhash (G1.vhash )
596#define ahash (G1.ahash ) 596#define ahash (G1.ahash )
597#define fdhash (G1.fdhash )
598#define fnhash (G1.fnhash ) 597#define fnhash (G1.fnhash )
598#define vhash (G1.vhash )
599#define fdhash ahash
600//^^^^^^^^^^^^^^^^^^ ahash is cleared after every function parsing,
601// and ends up empty after parsing phase. Thus, we can simply reuse it
602// for fdhash in execution stage.
599#define g_progname (G1.g_progname ) 603#define g_progname (G1.g_progname )
600#define g_lineno (G1.g_lineno ) 604#define g_lineno (G1.g_lineno )
601#define nfields (G1.nfields ) 605#define nfields (G1.nfields )
@@ -682,6 +686,33 @@ static xhash *hash_init(void)
682 return newhash; 686 return newhash;
683} 687}
684 688
689static void hash_clear(xhash *hash)
690{
691 unsigned i;
692 hash_item *hi, *thi;
693
694 for (i = 0; i < hash->csize; i++) {
695 hi = hash->items[i];
696 while (hi) {
697 thi = hi;
698 hi = hi->next;
699 free(thi->data.v.string);
700 free(thi);
701 }
702 hash->items[i] = NULL;
703 }
704 hash->glen = hash->nel = 0;
705}
706
707#if 0 //UNUSED
708static void hash_free(xhash *hash)
709{
710 hash_clear(hash);
711 free(hash->items);
712 free(hash);
713}
714#endif
715
685/* find item in hash, return ptr to data, NULL if not found */ 716/* find item in hash, return ptr to data, NULL if not found */
686static void *hash_search(xhash *hash, const char *name) 717static void *hash_search(xhash *hash, const char *name)
687{ 718{
@@ -869,23 +900,7 @@ static xhash *iamarray(var *v)
869 return a->x.array; 900 return a->x.array;
870} 901}
871 902
872static void clear_array(xhash *array) 903#define clear_array(array) hash_clear(array)
873{
874 unsigned i;
875 hash_item *hi, *thi;
876
877 for (i = 0; i < array->csize; i++) {
878 hi = array->items[i];
879 while (hi) {
880 thi = hi;
881 hi = hi->next;
882 free(thi->data.v.string);
883 free(thi);
884 }
885 array->items[i] = NULL;
886 }
887 array->glen = array->nel = 0;
888}
889 904
890/* clear a variable */ 905/* clear a variable */
891static var *clrvar(var *v) 906static var *clrvar(var *v)
@@ -1742,7 +1757,7 @@ static void parse_program(char *p)
1742 } 1757 }
1743 seq = &f->body; 1758 seq = &f->body;
1744 chain_group(); 1759 chain_group();
1745 clear_array(ahash); 1760 hash_clear(ahash);
1746 } else if (tclass & TS_OPSEQ) { 1761 } else if (tclass & TS_OPSEQ) {
1747 debug_printf_parse("%s: TS_OPSEQ\n", __func__); 1762 debug_printf_parse("%s: TS_OPSEQ\n", __func__);
1748 rollback_token(); 1763 rollback_token();
@@ -3471,11 +3486,16 @@ int awk_main(int argc UNUSED_PARAM, char **argv)
3471 bb_show_usage(); 3486 bb_show_usage();
3472 parse_program(*argv++); 3487 parse_program(*argv++);
3473 } 3488 }
3474 //free_hash(ahash) // ~250 bytes, arg names, used only during parse of function bodies 3489 /* Free unused parse structures */
3475 //ahash = NULL; // debug 3490 //hash_free(fnhash); // ~250 bytes when empty, used only for function names
3476 //free_hash(fnhash) // ~250 bytes, used only for function names 3491 //^^^^^^^^^^^^^^^^^ does not work, hash_clear() inside SEGVs
3477 //fnhash = NULL; // debug 3492 // (IOW: hash_clear() assumes it's a hash of variables. fnhash is not).
3478 /* parsing done, on to executing */ 3493 free(fnhash->items);
3494 free(fnhash);
3495 fnhash = NULL; // debug
3496 //hash_free(ahash); // empty after parsing, will reuse as fdhash instead of freeing
3497
3498 /* Parsing done, on to executing */
3479 3499
3480 /* fill in ARGV array */ 3500 /* fill in ARGV array */
3481 setari_u(intvar[ARGV], 0, "awk"); 3501 setari_u(intvar[ARGV], 0, "awk");
@@ -3484,7 +3504,7 @@ int awk_main(int argc UNUSED_PARAM, char **argv)
3484 setari_u(intvar[ARGV], ++i, *argv++); 3504 setari_u(intvar[ARGV], ++i, *argv++);
3485 setvar_i(intvar[ARGC], i + 1); 3505 setvar_i(intvar[ARGC], i + 1);
3486 3506
3487 fdhash = hash_init(); 3507 //fdhash = ahash - done via define
3488 newfile("/dev/stdin")->F = stdin; 3508 newfile("/dev/stdin")->F = stdin;
3489 newfile("/dev/stdout")->F = stdout; 3509 newfile("/dev/stdout")->F = stdout;
3490 newfile("/dev/stderr")->F = stderr; 3510 newfile("/dev/stderr")->F = stderr;