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.
This commit is contained in:
Jilles Tjoelker 2010-11-23 22:17:39 +00:00
parent 7a9417182e
commit 9d37e15722
8 changed files with 47 additions and 33 deletions

View File

@ -192,8 +192,7 @@ cdlogical(char *dest)
STPUTC('/', p); STPUTC('/', p);
first = 0; first = 0;
component = q; component = q;
while (*q) STPUTS(q, p);
STPUTC(*q++, p);
if (equal(component, "..")) if (equal(component, ".."))
continue; continue;
STACKSTRNUL(p); STACKSTRNUL(p);
@ -273,10 +272,8 @@ findcwd(char *dir)
scopy(dir, cdcomppath); scopy(dir, cdcomppath);
STARTSTACKSTR(new); STARTSTACKSTR(new);
if (*dir != '/') { if (*dir != '/') {
p = curdir; STPUTS(curdir, new);
while (*p) if (STTOPC(new) == '/')
STPUTC(*p++, new);
if (p[-1] == '/')
STUNPUTC(new); STUNPUTC(new);
} }
while ((p = getcomponent()) != NULL) { while ((p = getcomponent()) != NULL) {
@ -284,8 +281,7 @@ findcwd(char *dir)
while (new > stackblock() && (STUNPUTC(new), *new) != '/'); while (new > stackblock() && (STUNPUTC(new), *new) != '/');
} else if (*p != '\0' && ! equal(p, ".")) { } else if (*p != '\0' && ! equal(p, ".")) {
STPUTC('/', new); STPUTC('/', new);
while (*p) STPUTS(p, new);
STPUTC(*p++, new);
} }
} }
if (new == stackblock()) if (new == stackblock())

View File

@ -135,8 +135,7 @@ evalcmd(int argc, char **argv)
STARTSTACKSTR(concat); STARTSTACKSTR(concat);
ap = argv + 2; ap = argv + 2;
for (;;) { for (;;) {
while (*p) STPUTS(p, concat);
STPUTC(*p++, concat);
if ((p = *ap++) == NULL) if ((p = *ap++) == NULL)
break; break;
STPUTC(' ', concat); STPUTC(' ', concat);

View File

@ -225,6 +225,7 @@ argstr(char *p, int flag)
if (*p == '~' && (flag & (EXP_TILDE | EXP_VARTILDE))) if (*p == '~' && (flag & (EXP_TILDE | EXP_VARTILDE)))
p = exptilde(p, flag); p = exptilde(p, flag);
for (;;) { for (;;) {
CHECKSTRSPACE(2, expdest);
switch (c = *p++) { switch (c = *p++) {
case '\0': case '\0':
case CTLENDVAR: case CTLENDVAR:
@ -235,16 +236,16 @@ argstr(char *p, int flag)
if (p[0] == CTLVAR && p[2] == '@' && p[3] == '=') if (p[0] == CTLVAR && p[2] == '@' && p[3] == '=')
break; break;
if ((flag & EXP_FULL) != 0) if ((flag & EXP_FULL) != 0)
STPUTC(c, expdest); USTPUTC(c, expdest);
break; break;
case CTLQUOTEEND: case CTLQUOTEEND:
lit_quoted = 0; lit_quoted = 0;
break; break;
case CTLESC: case CTLESC:
if (quotes) if (quotes)
STPUTC(c, expdest); USTPUTC(c, expdest);
c = *p++; c = *p++;
STPUTC(c, expdest); USTPUTC(c, expdest);
if (split_lit && !lit_quoted) if (split_lit && !lit_quoted)
recordregion(expdest - stackblock() - recordregion(expdest - stackblock() -
(quotes ? 2 : 1), (quotes ? 2 : 1),
@ -267,7 +268,7 @@ argstr(char *p, int flag)
* sort of a hack - expand tildes in variable * sort of a hack - expand tildes in variable
* assignments (after the first '=' and after ':'s). * assignments (after the first '=' and after ':'s).
*/ */
STPUTC(c, expdest); USTPUTC(c, expdest);
if (split_lit && !lit_quoted) if (split_lit && !lit_quoted)
recordregion(expdest - stackblock() - 1, recordregion(expdest - stackblock() - 1,
expdest - stackblock(), 0); expdest - stackblock(), 0);
@ -279,7 +280,7 @@ argstr(char *p, int flag)
} }
break; break;
default: default:
STPUTC(c, expdest); USTPUTC(c, expdest);
if (split_lit && !lit_quoted) if (split_lit && !lit_quoted)
recordregion(expdest - stackblock() - 1, recordregion(expdest - stackblock() - 1,
expdest - stackblock(), 0); expdest - stackblock(), 0);
@ -902,8 +903,7 @@ varvalue(char *name, int quoted, int subtype, int flag)
STPUTC(*p++, expdest); \ STPUTC(*p++, expdest); \
} \ } \
} else \ } else \
while (*p) \ STPUTS(p, expdest); \
STPUTC(*p++, expdest); \
} while (0) } while (0)
@ -1573,8 +1573,7 @@ cvtnum(int num, char *buf)
if (neg) if (neg)
*--p = '-'; *--p = '-';
while (*p) STPUTS(p, buf);
STPUTC(*p++, buf);
return buf; return buf;
} }

View File

@ -411,8 +411,7 @@ fc_replace(const char *s, char *p, char *r)
STARTSTACKSTR(dest); STARTSTACKSTR(dest);
while (*s) { while (*s) {
if (*s == *p && strncmp(s, p, plen) == 0) { if (*s == *p && strncmp(s, p, plen) == 0) {
while (*r) STPUTS(r, dest);
STPUTC(*r++, dest);
s += plen; s += plen;
*p = '\0'; /* so no more matches */ *p = '\0'; /* so no more matches */
} else } else

View File

@ -340,3 +340,20 @@ ungrabstackstr(char *s, char *p)
stacknxt = s; stacknxt = s;
sstrnleft = stacknleft - (p - 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));
}

View File

@ -61,6 +61,8 @@ void grabstackblock(int);
char *growstackstr(void); char *growstackstr(void);
char *makestrspace(void); char *makestrspace(void);
void ungrabstackstr(char *, char *); 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 STTOPC(p) p[-1]
#define STADJUST(amount, p) (p += (amount), sstrnleft -= (amount)) #define STADJUST(amount, p) (p += (amount), sstrnleft -= (amount))
#define grabstackstr(p) stalloc(stackblocksize() - sstrnleft) #define grabstackstr(p) stalloc(stackblocksize() - sstrnleft)
#define STPUTBIN(s, len, p) p = stputbin((s), (len), p)
#define STPUTS(s, p) p = stputs((s), p)

View File

@ -172,11 +172,12 @@ readcmd(int argc __unused, char **argv __unused)
} }
if (c == '\0') if (c == '\0')
continue; continue;
CHECKSTRSPACE(1, p);
if (backslash) { if (backslash) {
backslash = 0; backslash = 0;
startword = 0; startword = 0;
if (c != '\n') if (c != '\n')
STPUTC(c, p); USTPUTC(c, p);
continue; continue;
} }
if (!rflag && c == '\\') { if (!rflag && c == '\\') {
@ -194,14 +195,14 @@ readcmd(int argc __unused, char **argv __unused)
if (is_ifs == 1) { if (is_ifs == 1) {
/* Ignore leading IFS whitespace */ /* Ignore leading IFS whitespace */
if (saveall) if (saveall)
STPUTC(c, p); USTPUTC(c, p);
continue; continue;
} }
if (is_ifs == 2 && startword == 1) { if (is_ifs == 2 && startword == 1) {
/* Only one non-whitespace IFS per word */ /* Only one non-whitespace IFS per word */
startword = 2; startword = 2;
if (saveall) if (saveall)
STPUTC(c, p); USTPUTC(c, p);
continue; continue;
} }
} }
@ -212,7 +213,7 @@ readcmd(int argc __unused, char **argv __unused)
if (saveall) if (saveall)
/* Not just a spare terminator */ /* Not just a spare terminator */
saveall++; saveall++;
STPUTC(c, p); USTPUTC(c, p);
continue; continue;
} }
@ -222,7 +223,7 @@ readcmd(int argc __unused, char **argv __unused)
if (ap[1] == NULL) { if (ap[1] == NULL) {
/* Last variable needs all IFS chars */ /* Last variable needs all IFS chars */
saveall++; saveall++;
STPUTC(c, p); USTPUTC(c, p);
continue; continue;
} }

View File

@ -1017,6 +1017,7 @@ parsebackq(char *out, struct nodelist **pbqlist,
setprompt(2); setprompt(2);
needprompt = 0; needprompt = 0;
} }
CHECKSTRSPACE(2, oout);
switch (c = pgetc()) { switch (c = pgetc()) {
case '`': case '`':
goto done; goto done;
@ -1031,14 +1032,14 @@ parsebackq(char *out, struct nodelist **pbqlist,
/* /*
* If eating a newline, avoid putting * If eating a newline, avoid putting
* the newline into the new character * the newline into the new character
* stream (via the STPUTC after the * stream (via the USTPUTC after the
* switch). * switch).
*/ */
continue; continue;
} }
if (c != '\\' && c != '`' && c != '$' if (c != '\\' && c != '`' && c != '$'
&& (!dblquote || c != '"')) && (!dblquote || c != '"'))
STPUTC('\\', oout); USTPUTC('\\', oout);
break; break;
case '\n': case '\n':
@ -1054,10 +1055,10 @@ parsebackq(char *out, struct nodelist **pbqlist,
default: default:
break; break;
} }
STPUTC(c, oout); USTPUTC(c, oout);
} }
done: done:
STPUTC('\0', oout); USTPUTC('\0', oout);
olen = oout - stackblock(); olen = oout - stackblock();
INTOFF; INTOFF;
ostr = ckmalloc(olen); ostr = ckmalloc(olen);
@ -1444,7 +1445,6 @@ parsesub: {
char *p; char *p;
static const char types[] = "}-+?="; static const char types[] = "}-+?=";
int bracketed_name = 0; /* used to handle ${[0-9]*} variables */ int bracketed_name = 0; /* used to handle ${[0-9]*} variables */
int i;
int linno; int linno;
int length; int length;
@ -1498,8 +1498,7 @@ parsesub: {
linno -= funclinno - 1; linno -= funclinno - 1;
snprintf(buf, sizeof(buf), "%d", linno); snprintf(buf, sizeof(buf), "%d", linno);
STADJUST(-6, out); STADJUST(-6, out);
for (i = 0; buf[i] != '\0'; i++) STPUTS(buf, out);
STPUTC(buf[i], out);
flags |= VSLINENO; flags |= VSLINENO;
} }
} else if (is_digit(c)) { } else if (is_digit(c)) {