[git commit] bc: optimize bc_vec_push() usage

Denys Vlasenko vda.linux at googlemail.com
Fri Dec 21 21:16:17 UTC 2018


commit: https://git.busybox.net/busybox/commit/?id=6ed7fb0a877d550428cb289feb3695dcd2812ab8
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
bc_parse_pushNUM                                      87      80      -7
zbc_parse_stmt_possibly_auto                        1697    1689      -8
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-15)             Total: -15 bytes

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 miscutils/bc.c | 58 ++++++++++++++++++++++++++--------------------------------
 1 file changed, 26 insertions(+), 32 deletions(-)

diff --git a/miscutils/bc.c b/miscutils/bc.c
index 441cb0467..abedbdf0b 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -1097,24 +1097,25 @@ static void bc_vec_pop_all(BcVec *v)
 	bc_vec_npop(v, v->len);
 }
 
-//TODO: return index of pushed data - many callers can use that
-static void bc_vec_push(BcVec *v, const void *data)
+static size_t bc_vec_push(BcVec *v, const void *data)
 {
-	if (v->len + 1 > v->cap) bc_vec_grow(v, 1);
-	memmove(v->v + (v->size * v->len), data, v->size);
-	v->len += 1;
+	size_t len = v->len;
+	if (len >= v->cap) bc_vec_grow(v, 1);
+	memmove(v->v + (v->size * len), data, v->size);
+	v->len++;
+	return len;
 }
 
-static void bc_vec_pushByte(BcVec *v, char data)
+static size_t bc_vec_pushByte(BcVec *v, char data)
 {
-	bc_vec_push(v, &data);
+	return bc_vec_push(v, &data);
 }
 
-static void bc_vec_pushZeroByte(BcVec *v)
+static size_t bc_vec_pushZeroByte(BcVec *v)
 {
-	//bc_vec_pushByte(v, '\0');
+	//return bc_vec_pushByte(v, '\0');
 	// better:
-	bc_vec_push(v, &const_int_0);
+	return bc_vec_push(v, &const_int_0);
 }
 
 static void bc_vec_pushAt(BcVec *v, const void *data, size_t idx)
@@ -3548,14 +3549,11 @@ static void bc_parse_pushNUM(BcParse *p)
 {
 	char *num = xstrdup(p->l.t.v.v);
 #if ENABLE_BC && ENABLE_DC
-	size_t idx = IS_BC ? p->func->consts.len : G.prog.consts.len;
-	bc_vec_push(IS_BC ? &p->func->consts : &G.prog.consts, &num);
+	size_t idx = bc_vec_push(IS_BC ? &p->func->consts : &G.prog.consts, &num);
 #elif ENABLE_BC
-	size_t idx = p->func->consts.len;
-	bc_vec_push(&p->func->consts, &num);
+	size_t idx = bc_vec_push(&p->func->consts, &num);
 #else // DC
-	size_t idx = G.prog.consts.len;
-	bc_vec_push(&G.prog.consts, &num);
+	size_t idx = bc_vec_push(&G.prog.consts, &num);
 #endif
 	bc_parse_push(p, BC_INST_NUM);
 	bc_parse_pushIndex(p, idx);
@@ -3652,7 +3650,7 @@ static void bc_program_add_fn(void)
 	//size_t idx;
 	BcFunc f;
 	bc_func_init(&f);
-	//idx = G.prog.fns.len;
+	//idx =
 	bc_vec_push(&G.prog.fns, &f);
 	//return idx;
 }
@@ -4135,12 +4133,13 @@ static BC_STATUS zbc_parse_if(BcParse *p)
 	if (s) RETURN_STATUS(s);
 	s = zbc_parse_expr(p, BC_PARSE_REL);
 	if (s) RETURN_STATUS(s);
-
 	if (p->l.t.t != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token());
 
-	ip_idx = p->func->labels.len;
+	// Encode "if zero, jump to ..."
+	// Pushed value (destination of the jump) is uninitialized,
+	// will be rewritten to be address of "end of if()" or of "else".
+	ip_idx = bc_vec_push(&p->func->labels, &ip_idx);
 	bc_parse_pushJUMP_ZERO(p, ip_idx);
-	bc_vec_push(&p->func->labels, &ip_idx);
 
 	s = zbc_parse_stmt_allow_NLINE_before(p, STRING_if);
 	if (s) RETURN_STATUS(s);
@@ -4149,15 +4148,14 @@ static BC_STATUS zbc_parse_if(BcParse *p)
 	if (p->l.t.t == BC_LEX_KEY_ELSE) {
 		size_t ip2_idx;
 
-		ip2_idx = p->func->labels.len;
-
-		dbg_lex("%s:%d after if() body: BC_INST_JUMP to %zd", __func__, __LINE__, ip2_idx);
+		// Encode "after then_stmt, jump to end of if()"
+		ip2_idx = bc_vec_push(&p->func->labels, &ip2_idx);
+		dbg_lex("%s:%d after if() then_stmt: BC_INST_JUMP to %zd", __func__, __LINE__, ip2_idx);
 		bc_parse_pushJUMP(p, ip2_idx);
 
 		dbg_lex("%s:%d rewriting 'if_zero' label to jump to 'else'-> %zd", __func__, __LINE__, p->func->code.len);
 		rewrite_label_to_current(p, ip_idx);
 
-		bc_vec_push(&p->func->labels, &ip2_idx);
 		ip_idx = ip2_idx;
 
 		s = zbc_parse_stmt_allow_NLINE_before(p, STRING_else);
@@ -4184,10 +4182,8 @@ static BC_STATUS zbc_parse_while(BcParse *p)
 	s = zbc_lex_next(&p->l);
 	if (s) RETURN_STATUS(s);
 
-	cond_idx = p->func->labels.len;
+	cond_idx = bc_vec_push(&p->func->labels, &p->func->code.len);
 	ip_idx = cond_idx + 1;
-
-	bc_vec_push(&p->func->labels, &p->func->code.len);
 	bc_vec_push(&p->conds, &cond_idx);
 
 	bc_vec_push(&p->exits, &ip_idx);
@@ -4240,13 +4236,11 @@ static BC_STATUS zbc_parse_for(BcParse *p)
 	s = zbc_lex_next(&p->l);
 	if (s) RETURN_STATUS(s);
 
-	cond_idx = p->func->labels.len;
+	cond_idx = bc_vec_push(&p->func->labels, &p->func->code.len);
 	update_idx = cond_idx + 1;
 	body_idx = update_idx + 1;
 	exit_idx = body_idx + 1;
 
-	bc_vec_push(&p->func->labels, &p->func->code.len);
-
 	if (p->l.t.t != BC_LEX_SCOLON)
 		s = zbc_parse_expr(p, BC_PARSE_REL);
 	else {
@@ -4272,14 +4266,14 @@ static BC_STATUS zbc_parse_for(BcParse *p)
 
 	if (p->l.t.t != BC_LEX_RPAREN) {
 		s = zbc_parse_expr(p, 0);
-		bc_parse_push(p, BC_INST_POP);
 		if (s) RETURN_STATUS(s);
+		if (p->l.t.t != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token());
+		bc_parse_push(p, BC_INST_POP);
 	} else {
 		s = bc_POSIX_does_not_allow_empty_X_expression_in_for("update");
 		IF_ERROR_RETURN_POSSIBLE(if (s) RETURN_STATUS(s);)
 	}
 
-	if (p->l.t.t != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token());
 	bc_parse_pushJUMP(p, cond_idx);
 	bc_vec_push(&p->func->labels, &p->func->code.len);
 


More information about the busybox-cvs mailing list