From 9d37e157228b3ff30cd8d737bd7f307d3c742a12 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Tue, 23 Nov 2010 22:17:39 +0000 Subject: [PATCH] sh: Code size optimizations to "stack string" memory allocation: * Prefer one CHECKSTRSPACE with multiple USTPUTC to multiple STPUTC. * Add STPUTS macro (based on function) and use it instead of loops that add nul-terminated strings to the stack string. No functional change is intended, but code size is about 1K less on i386. --- bin/sh/cd.c | 12 ++++-------- bin/sh/eval.c | 3 +-- bin/sh/expand.c | 17 ++++++++--------- bin/sh/histedit.c | 3 +-- bin/sh/memalloc.c | 17 +++++++++++++++++ bin/sh/memalloc.h | 4 ++++ bin/sh/miscbltin.c | 11 ++++++----- bin/sh/parser.c | 13 ++++++------- 8 files changed, 47 insertions(+), 33 deletions(-) diff --git a/bin/sh/cd.c b/bin/sh/cd.c index 2ac4b101dd25..068dfb74209f 100644 --- a/bin/sh/cd.c +++ b/bin/sh/cd.c @@ -192,8 +192,7 @@ cdlogical(char *dest) STPUTC('/', p); first = 0; component = q; - while (*q) - STPUTC(*q++, p); + STPUTS(q, p); if (equal(component, "..")) continue; STACKSTRNUL(p); @@ -273,10 +272,8 @@ findcwd(char *dir) scopy(dir, cdcomppath); STARTSTACKSTR(new); if (*dir != '/') { - p = curdir; - while (*p) - STPUTC(*p++, new); - if (p[-1] == '/') + STPUTS(curdir, new); + if (STTOPC(new) == '/') STUNPUTC(new); } while ((p = getcomponent()) != NULL) { @@ -284,8 +281,7 @@ findcwd(char *dir) while (new > stackblock() && (STUNPUTC(new), *new) != '/'); } else if (*p != '\0' && ! equal(p, ".")) { STPUTC('/', new); - while (*p) - STPUTC(*p++, new); + STPUTS(p, new); } } if (new == stackblock()) diff --git a/bin/sh/eval.c b/bin/sh/eval.c index c306e731f316..5bae2f2b2046 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -135,8 +135,7 @@ evalcmd(int argc, char **argv) STARTSTACKSTR(concat); ap = argv + 2; for (;;) { - while (*p) - STPUTC(*p++, concat); + STPUTS(p, concat); if ((p = *ap++) == NULL) break; STPUTC(' ', concat); diff --git a/bin/sh/expand.c b/bin/sh/expand.c index d251ed07bd08..7a3b9d96fe08 100644 --- a/bin/sh/expand.c +++ b/bin/sh/expand.c @@ -225,6 +225,7 @@ argstr(char *p, int flag) if (*p == '~' && (flag & (EXP_TILDE | EXP_VARTILDE))) p = exptilde(p, flag); for (;;) { + CHECKSTRSPACE(2, expdest); switch (c = *p++) { case '\0': case CTLENDVAR: @@ -235,16 +236,16 @@ argstr(char *p, int flag) if (p[0] == CTLVAR && p[2] == '@' && p[3] == '=') break; if ((flag & EXP_FULL) != 0) - STPUTC(c, expdest); + USTPUTC(c, expdest); break; case CTLQUOTEEND: lit_quoted = 0; break; case CTLESC: if (quotes) - STPUTC(c, expdest); + USTPUTC(c, expdest); c = *p++; - STPUTC(c, expdest); + USTPUTC(c, expdest); if (split_lit && !lit_quoted) recordregion(expdest - stackblock() - (quotes ? 2 : 1), @@ -267,7 +268,7 @@ argstr(char *p, int flag) * sort of a hack - expand tildes in variable * assignments (after the first '=' and after ':'s). */ - STPUTC(c, expdest); + USTPUTC(c, expdest); if (split_lit && !lit_quoted) recordregion(expdest - stackblock() - 1, expdest - stackblock(), 0); @@ -279,7 +280,7 @@ argstr(char *p, int flag) } break; default: - STPUTC(c, expdest); + USTPUTC(c, expdest); if (split_lit && !lit_quoted) recordregion(expdest - stackblock() - 1, expdest - stackblock(), 0); @@ -902,8 +903,7 @@ varvalue(char *name, int quoted, int subtype, int flag) STPUTC(*p++, expdest); \ } \ } else \ - while (*p) \ - STPUTC(*p++, expdest); \ + STPUTS(p, expdest); \ } while (0) @@ -1573,8 +1573,7 @@ cvtnum(int num, char *buf) if (neg) *--p = '-'; - while (*p) - STPUTC(*p++, buf); + STPUTS(p, buf); return buf; } diff --git a/bin/sh/histedit.c b/bin/sh/histedit.c index 3fc1782d658e..26d46a8aef9d 100644 --- a/bin/sh/histedit.c +++ b/bin/sh/histedit.c @@ -411,8 +411,7 @@ fc_replace(const char *s, char *p, char *r) STARTSTACKSTR(dest); while (*s) { if (*s == *p && strncmp(s, p, plen) == 0) { - while (*r) - STPUTC(*r++, dest); + STPUTS(r, dest); s += plen; *p = '\0'; /* so no more matches */ } else diff --git a/bin/sh/memalloc.c b/bin/sh/memalloc.c index 91587197f927..d00b4d9afc67 100644 --- a/bin/sh/memalloc.c +++ b/bin/sh/memalloc.c @@ -340,3 +340,20 @@ ungrabstackstr(char *s, char *p) stacknxt = s; sstrnleft = stacknleft - (p - s); } + + +char * +stputbin(const char *data, int len, char *p) +{ + int i; + + for (i = 0; i < len; i++) + STPUTC(data[i], p); + return (p); +} + +char * +stputs(const char *data, char *p) +{ + return (stputbin(data, strlen(data), p)); +} diff --git a/bin/sh/memalloc.h b/bin/sh/memalloc.h index 563927aeb57e..88848ddd63b7 100644 --- a/bin/sh/memalloc.h +++ b/bin/sh/memalloc.h @@ -61,6 +61,8 @@ void grabstackblock(int); char *growstackstr(void); char *makestrspace(void); void ungrabstackstr(char *, char *); +char *stputbin(const char *data, int len, char *p); +char *stputs(const char *data, char *p); @@ -82,3 +84,5 @@ void ungrabstackstr(char *, char *); #define STTOPC(p) p[-1] #define STADJUST(amount, p) (p += (amount), sstrnleft -= (amount)) #define grabstackstr(p) stalloc(stackblocksize() - sstrnleft) +#define STPUTBIN(s, len, p) p = stputbin((s), (len), p) +#define STPUTS(s, p) p = stputs((s), p) diff --git a/bin/sh/miscbltin.c b/bin/sh/miscbltin.c index d9ac8a309c9a..dc200b6d566e 100644 --- a/bin/sh/miscbltin.c +++ b/bin/sh/miscbltin.c @@ -172,11 +172,12 @@ readcmd(int argc __unused, char **argv __unused) } if (c == '\0') continue; + CHECKSTRSPACE(1, p); if (backslash) { backslash = 0; startword = 0; if (c != '\n') - STPUTC(c, p); + USTPUTC(c, p); continue; } if (!rflag && c == '\\') { @@ -194,14 +195,14 @@ readcmd(int argc __unused, char **argv __unused) if (is_ifs == 1) { /* Ignore leading IFS whitespace */ if (saveall) - STPUTC(c, p); + USTPUTC(c, p); continue; } if (is_ifs == 2 && startword == 1) { /* Only one non-whitespace IFS per word */ startword = 2; if (saveall) - STPUTC(c, p); + USTPUTC(c, p); continue; } } @@ -212,7 +213,7 @@ readcmd(int argc __unused, char **argv __unused) if (saveall) /* Not just a spare terminator */ saveall++; - STPUTC(c, p); + USTPUTC(c, p); continue; } @@ -222,7 +223,7 @@ readcmd(int argc __unused, char **argv __unused) if (ap[1] == NULL) { /* Last variable needs all IFS chars */ saveall++; - STPUTC(c, p); + USTPUTC(c, p); continue; } diff --git a/bin/sh/parser.c b/bin/sh/parser.c index 01907e84e9b2..2687003a42df 100644 --- a/bin/sh/parser.c +++ b/bin/sh/parser.c @@ -1017,6 +1017,7 @@ parsebackq(char *out, struct nodelist **pbqlist, setprompt(2); needprompt = 0; } + CHECKSTRSPACE(2, oout); switch (c = pgetc()) { case '`': goto done; @@ -1031,14 +1032,14 @@ parsebackq(char *out, struct nodelist **pbqlist, /* * If eating a newline, avoid putting * the newline into the new character - * stream (via the STPUTC after the + * stream (via the USTPUTC after the * switch). */ continue; } if (c != '\\' && c != '`' && c != '$' && (!dblquote || c != '"')) - STPUTC('\\', oout); + USTPUTC('\\', oout); break; case '\n': @@ -1054,10 +1055,10 @@ parsebackq(char *out, struct nodelist **pbqlist, default: break; } - STPUTC(c, oout); + USTPUTC(c, oout); } done: - STPUTC('\0', oout); + USTPUTC('\0', oout); olen = oout - stackblock(); INTOFF; ostr = ckmalloc(olen); @@ -1444,7 +1445,6 @@ parsesub: { char *p; static const char types[] = "}-+?="; int bracketed_name = 0; /* used to handle ${[0-9]*} variables */ - int i; int linno; int length; @@ -1498,8 +1498,7 @@ parsesub: { linno -= funclinno - 1; snprintf(buf, sizeof(buf), "%d", linno); STADJUST(-6, out); - for (i = 0; buf[i] != '\0'; i++) - STPUTC(buf[i], out); + STPUTS(buf, out); flags |= VSLINENO; } } else if (is_digit(c)) {