aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-12-15 00:39:17 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-12-15 00:49:16 +0100
commit7db384338a803fc74a0e8eb62e9369e10a49ffdb (patch)
tree3ffc6b10de2c8f9d24b5e72042fe659cfc35c86d
parentf10f17f8d3ee77c469fc57634a458e8a45aeb681 (diff)
downloadbusybox-w32-7db384338a803fc74a0e8eb62e9369e10a49ffdb.tar.gz
busybox-w32-7db384338a803fc74a0e8eb62e9369e10a49ffdb.tar.bz2
busybox-w32-7db384338a803fc74a0e8eb62e9369e10a49ffdb.zip
bc: rewrite "block flag stack" using simple realloc'ed byte array
Each access to current top flag took a function call + fetch of three data items + multiplication and some additions + and then following the resulting pointer. After the change, it is: fetch pointer value + one byte access via this pointer. function old new delta bc_parse_startBody 45 49 +4 bc_parse_free 46 47 +1 zbc_parse_auto 188 185 -3 bc_parse_push 14 11 -3 bc_vm_run 398 394 -4 zbc_vm_process 63 58 -5 zdc_parse_expr 638 632 -6 zbc_parse_body 101 95 -6 bc_parse_addFunc 31 25 -6 bc_parse_noElse 56 48 -8 zcommon_parse 341 331 -10 zbc_parse_else 134 123 -11 bc_parse_create 124 108 -16 zbc_parse_text_init 123 104 -19 zbc_parse_endBody 292 252 -40 zbc_parse_stmt 1479 1420 -59 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/14 up/down: 5/-196) Total: -191 bytes text data bss dec hex filename 979880 485 7296 987661 f120d busybox_old 979689 485 7296 987470 f114e busybox_unstripped Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--miscutils/bc.c43
1 files changed, 23 insertions, 20 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index 4024a08df..2feaf7bf3 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -574,8 +574,9 @@ typedef struct BcLex {
574#define BC_PARSE_NOREAD (1 << 3) 574#define BC_PARSE_NOREAD (1 << 3)
575#define BC_PARSE_ARRAY (1 << 4) 575#define BC_PARSE_ARRAY (1 << 4)
576 576
577#define BC_PARSE_TOP_FLAG_PTR(parse) ((uint8_t *) bc_vec_top(&(parse)->flags)) 577#define BC_PARSE_TOP_FLAG_PTR(parse) ((parse)->bf_top)
578#define BC_PARSE_TOP_FLAG(parse) (*(BC_PARSE_TOP_FLAG_PTR(parse))) 578#define BC_PARSE_TOP_FLAG(parse) (*(BC_PARSE_TOP_FLAG_PTR(parse)))
579#define BC_PARSE_FLAG_STACK_EMPTY(p) ((p)->bf_top == (p)->bf_base)
579 580
580#define BC_PARSE_FLAG_FUNC_INNER (1 << 0) 581#define BC_PARSE_FLAG_FUNC_INNER (1 << 0)
581#define BC_PARSE_FLAG_FUNC (1 << 1) 582#define BC_PARSE_FLAG_FUNC (1 << 1)
@@ -598,15 +599,11 @@ typedef struct BcLex {
598#define BC_PARSE_ELSE(parse) (BC_PARSE_TOP_FLAG(parse) & BC_PARSE_FLAG_ELSE) 599#define BC_PARSE_ELSE(parse) (BC_PARSE_TOP_FLAG(parse) & BC_PARSE_FLAG_ELSE)
599#define BC_PARSE_IF_END(parse) (BC_PARSE_TOP_FLAG(parse) & BC_PARSE_FLAG_IF_END) 600#define BC_PARSE_IF_END(parse) (BC_PARSE_TOP_FLAG(parse) & BC_PARSE_FLAG_IF_END)
600 601
601struct BcParse;
602
603struct BcProgram;
604
605typedef struct BcParse { 602typedef struct BcParse {
606
607 BcLex l; 603 BcLex l;
608 604
609 BcVec flags; 605 uint8_t *bf_base;
606 uint8_t *bf_top;
610 607
611 BcVec exits; 608 BcVec exits;
612 BcVec conds; 609 BcVec conds;
@@ -618,7 +615,6 @@ typedef struct BcParse {
618 615
619 size_t nbraces; 616 size_t nbraces;
620 bool auto_part; 617 bool auto_part;
621
622} BcParse; 618} BcParse;
623 619
624typedef struct BcProgram { 620typedef struct BcProgram {
@@ -3558,7 +3554,7 @@ static void bc_parse_reset(BcParse *p)
3558 p->l.t.t = BC_LEX_EOF; 3554 p->l.t.t = BC_LEX_EOF;
3559 p->auto_part = (p->nbraces = 0); 3555 p->auto_part = (p->nbraces = 0);
3560 3556
3561 bc_vec_npop(&p->flags, p->flags.len - 1); 3557 p->bf_top = p->bf_base; // pop all flags
3562 bc_vec_pop_all(&p->exits); 3558 bc_vec_pop_all(&p->exits);
3563 bc_vec_pop_all(&p->conds); 3559 bc_vec_pop_all(&p->conds);
3564 bc_vec_pop_all(&p->ops); 3560 bc_vec_pop_all(&p->ops);
@@ -3568,7 +3564,7 @@ static void bc_parse_reset(BcParse *p)
3568 3564
3569static void bc_parse_free(BcParse *p) 3565static void bc_parse_free(BcParse *p)
3570{ 3566{
3571 bc_vec_free(&p->flags); 3567 free(p->bf_base);
3572 bc_vec_free(&p->exits); 3568 bc_vec_free(&p->exits);
3573 bc_vec_free(&p->conds); 3569 bc_vec_free(&p->conds);
3574 bc_vec_free(&p->ops); 3570 bc_vec_free(&p->ops);
@@ -3580,10 +3576,9 @@ static void bc_parse_create(BcParse *p, size_t func)
3580 memset(p, 0, sizeof(BcParse)); 3576 memset(p, 0, sizeof(BcParse));
3581 3577
3582 bc_lex_init(&p->l); 3578 bc_lex_init(&p->l);
3583 bc_vec_init(&p->flags, sizeof(uint8_t), NULL); 3579 p->bf_top = p->bf_base = xzalloc(1);
3584 bc_vec_init(&p->exits, sizeof(BcInstPtr), NULL); 3580 bc_vec_init(&p->exits, sizeof(BcInstPtr), NULL);
3585 bc_vec_init(&p->conds, sizeof(size_t), NULL); 3581 bc_vec_init(&p->conds, sizeof(size_t), NULL);
3586 bc_vec_pushZeroByte(&p->flags);
3587 bc_vec_init(&p->ops, sizeof(BcLexType), NULL); 3582 bc_vec_init(&p->ops, sizeof(BcLexType), NULL);
3588 3583
3589 // p->auto_part = p->nbraces = 0; - already is 3584 // p->auto_part = p->nbraces = 0; - already is
@@ -4050,7 +4045,7 @@ static BC_STATUS zbc_parse_endBody(BcParse *p)
4050{ 4045{
4051 BcStatus s = BC_STATUS_SUCCESS; 4046 BcStatus s = BC_STATUS_SUCCESS;
4052 4047
4053 if (p->flags.len <= 1) 4048 if (BC_PARSE_FLAG_STACK_EMPTY(p))
4054 RETURN_STATUS(bc_error_bad_token()); 4049 RETURN_STATUS(bc_error_bad_token());
4055 4050
4056 if (BC_PARSE_IF(p)) { 4051 if (BC_PARSE_IF(p)) {
@@ -4061,7 +4056,7 @@ static BC_STATUS zbc_parse_endBody(BcParse *p)
4061 if (s) RETURN_STATUS(s); 4056 if (s) RETURN_STATUS(s);
4062 } 4057 }
4063 4058
4064 bc_vec_pop(&p->flags); 4059 p->bf_top--;
4065 4060
4066 flag_ptr = BC_PARSE_TOP_FLAG_PTR(p); 4061 flag_ptr = BC_PARSE_TOP_FLAG_PTR(p);
4067 dbg_lex("%s:%d setting BC_PARSE_FLAG_IF_END bit", __func__, __LINE__); 4062 dbg_lex("%s:%d setting BC_PARSE_FLAG_IF_END bit", __func__, __LINE__);
@@ -4074,7 +4069,7 @@ static BC_STATUS zbc_parse_endBody(BcParse *p)
4074 BcInstPtr *ip; 4069 BcInstPtr *ip;
4075 size_t *label; 4070 size_t *label;
4076 4071
4077 bc_vec_pop(&p->flags); 4072 p->bf_top--;
4078 4073
4079 ip = bc_vec_top(&p->exits); 4074 ip = bc_vec_top(&p->exits);
4080 label = bc_vec_item(&p->func->labels, ip->idx); 4075 label = bc_vec_item(&p->func->labels, ip->idx);
@@ -4085,7 +4080,7 @@ static BC_STATUS zbc_parse_endBody(BcParse *p)
4085 else if (BC_PARSE_FUNC_INNER(p)) { 4080 else if (BC_PARSE_FUNC_INNER(p)) {
4086 bc_parse_push(p, BC_INST_RET0); 4081 bc_parse_push(p, BC_INST_RET0);
4087 bc_parse_updateFunc(p, BC_PROG_MAIN); 4082 bc_parse_updateFunc(p, BC_PROG_MAIN);
4088 bc_vec_pop(&p->flags); 4083 p->bf_top--;
4089 } 4084 }
4090 else { 4085 else {
4091 BcInstPtr *ip = bc_vec_top(&p->exits); 4086 BcInstPtr *ip = bc_vec_top(&p->exits);
@@ -4097,7 +4092,7 @@ static BC_STATUS zbc_parse_endBody(BcParse *p)
4097 label = bc_vec_item(&p->func->labels, ip->idx); 4092 label = bc_vec_item(&p->func->labels, ip->idx);
4098 *label = p->func->code.len; 4093 *label = p->func->code.len;
4099 4094
4100 bc_vec_pop(&p->flags); 4095 p->bf_top--;
4101 bc_vec_pop(&p->exits); 4096 bc_vec_pop(&p->exits);
4102 bc_vec_pop(&p->conds); 4097 bc_vec_pop(&p->conds);
4103 } 4098 }
@@ -4110,10 +4105,15 @@ static BC_STATUS zbc_parse_endBody(BcParse *p)
4110 4105
4111static void bc_parse_startBody(BcParse *p, uint8_t flags) 4106static void bc_parse_startBody(BcParse *p, uint8_t flags)
4112{ 4107{
4108 size_t size;
4113 uint8_t *flag_ptr = BC_PARSE_TOP_FLAG_PTR(p); 4109 uint8_t *flag_ptr = BC_PARSE_TOP_FLAG_PTR(p);
4114 flags |= (*flag_ptr & (BC_PARSE_FLAG_FUNC | BC_PARSE_FLAG_LOOP)); 4110 flags |= (*flag_ptr & (BC_PARSE_FLAG_FUNC | BC_PARSE_FLAG_LOOP));
4115 flags |= BC_PARSE_FLAG_BODY; 4111 flags |= BC_PARSE_FLAG_BODY;
4116 bc_vec_push(&p->flags, &flags); 4112
4113 size = p->bf_top - p->bf_base;
4114 p->bf_base = xrealloc(p->bf_base, size + 2);
4115 p->bf_top = p->bf_base + size + 1;
4116 *p->bf_top = flags;
4117} 4117}
4118 4118
4119static void bc_parse_noElse(BcParse *p) 4119static void bc_parse_noElse(BcParse *p)
@@ -4492,7 +4492,7 @@ err:
4492static BC_STATUS zbc_parse_body(BcParse *p, bool brace) 4492static BC_STATUS zbc_parse_body(BcParse *p, bool brace)
4493{ 4493{
4494 BcStatus s = BC_STATUS_SUCCESS; 4494 BcStatus s = BC_STATUS_SUCCESS;
4495 uint8_t *flag_ptr = bc_vec_top(&p->flags); 4495 uint8_t *flag_ptr = BC_PARSE_TOP_FLAG_PTR(p);
4496 4496
4497 dbg_lex_enter("%s:%d entered", __func__, __LINE__); 4497 dbg_lex_enter("%s:%d entered", __func__, __LINE__);
4498 *flag_ptr &= ~(BC_PARSE_FLAG_BODY); 4498 *flag_ptr &= ~(BC_PARSE_FLAG_BODY);
@@ -4535,10 +4535,12 @@ static BC_STATUS zbc_parse_stmt(BcParse *p)
4535 RETURN_STATUS(zbc_lex_next(&p->l)); 4535 RETURN_STATUS(zbc_lex_next(&p->l));
4536 4536
4537 case BC_LEX_KEY_ELSE: 4537 case BC_LEX_KEY_ELSE:
4538 dbg_lex("%s:%d BC_LEX_KEY_ELSE:", __func__, __LINE__);
4538 p->auto_part = false; 4539 p->auto_part = false;
4539 break; 4540 break;
4540 4541
4541 case BC_LEX_LBRACE: 4542 case BC_LEX_LBRACE:
4543 dbg_lex("%s:%d BC_LEX_LBRACE:", __func__, __LINE__);
4542 if (!BC_PARSE_BODY(p)) RETURN_STATUS(bc_error_bad_token()); 4544 if (!BC_PARSE_BODY(p)) RETURN_STATUS(bc_error_bad_token());
4543 ++p->nbraces; 4545 ++p->nbraces;
4544 s = zbc_lex_next(&p->l); 4546 s = zbc_lex_next(&p->l);
@@ -4547,6 +4549,7 @@ static BC_STATUS zbc_parse_stmt(BcParse *p)
4547 RETURN_STATUS(zbc_parse_body(p, true)); 4549 RETURN_STATUS(zbc_parse_body(p, true));
4548 4550
4549 case BC_LEX_KEY_AUTO: 4551 case BC_LEX_KEY_AUTO:
4552 dbg_lex("%s:%d BC_LEX_KEY_AUTO:", __func__, __LINE__);
4550 RETURN_STATUS(zbc_parse_auto(p)); 4553 RETURN_STATUS(zbc_parse_auto(p));
4551 4554
4552 default: 4555 default:
@@ -4660,7 +4663,7 @@ static BC_STATUS zbc_parse_parse(BcParse *p)
4660 4663
4661 dbg_lex_enter("%s:%d entered", __func__, __LINE__); 4664 dbg_lex_enter("%s:%d entered", __func__, __LINE__);
4662 if (p->l.t.t == BC_LEX_EOF) 4665 if (p->l.t.t == BC_LEX_EOF)
4663 s = p->flags.len > 0 ? bc_error("block end could not be found") : bc_error("end of file"); 4666 s = BC_PARSE_FLAG_STACK_EMPTY(p) ? bc_error("end of file") : bc_error("block end could not be found");
4664 else if (p->l.t.t == BC_LEX_KEY_DEFINE) { 4667 else if (p->l.t.t == BC_LEX_KEY_DEFINE) {
4665 dbg_lex("%s:%d p->l.t.t:BC_LEX_KEY_DEFINE", __func__, __LINE__); 4668 dbg_lex("%s:%d p->l.t.t:BC_LEX_KEY_DEFINE", __func__, __LINE__);
4666 if (!BC_PARSE_CAN_EXEC(p)) 4669 if (!BC_PARSE_CAN_EXEC(p))