improve density of .rodata (with net win on .text size(1)) via better struct packing

This commit is contained in:
tg
2013-08-11 14:57:11 +00:00
parent 64d828ac07
commit bb0b409a9d
4 changed files with 63 additions and 49 deletions

View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.627 2013/08/10 13:47:16 tg Exp $ # $MirOS: src/bin/mksh/check.t,v 1.628 2013/08/11 14:57:07 tg Exp $
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $ # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
@ -31,7 +31,7 @@
# http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD # http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD
expected-stdout: expected-stdout:
@(#)MIRBSD KSH R48 2013/08/10 @(#)MIRBSD KSH R48 2013/08/11
description: description:
Check version of shell. Check version of shell.
stdin: stdin:
@ -40,7 +40,7 @@ name: KSH_VERSION
category: shell:legacy-no category: shell:legacy-no
--- ---
expected-stdout: expected-stdout:
@(#)LEGACY KSH R48 2013/08/10 @(#)LEGACY KSH R48 2013/08/11
description: description:
Check version of legacy shell. Check version of legacy shell.
stdin: stdin:

72
misc.c
View File

@ -30,7 +30,7 @@
#include <grp.h> #include <grp.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.213 2013/07/21 18:47:20 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/misc.c,v 1.214 2013/08/11 14:57:09 tg Exp $");
#define KSH_CHVT_FLAG #define KSH_CHVT_FLAG
#ifdef MKSH_SMALL #ifdef MKSH_SMALL
@ -123,10 +123,15 @@ Xcheck_grow(XString *xsp, const char *xp, size_t more)
return (xsp->beg + (xp - old_beg)); return (xsp->beg + (xp - old_beg));
} }
#define SHFLAGS_DEFNS #define SHFLAGS_DEFNS
#include "sh_flags.h" #include "sh_flags.h"
const struct shoption options[] = { #define OFC(i) (options[i][-2])
#define OFF(i) (((const unsigned char *)options[i])[-1])
#define OFN(i) (options[i])
const char * const options[] = {
#define SHFLAGS_ITEMS #define SHFLAGS_ITEMS
#include "sh_flags.h" #include "sh_flags.h"
}; };
@ -137,15 +142,20 @@ const struct shoption options[] = {
size_t size_t
option(const char *n) option(const char *n)
{ {
size_t i; size_t i = 0;
if ((n[0] == '-' || n[0] == '+') && n[1] && !n[2]) { if ((n[0] == '-' || n[0] == '+') && n[1] && !n[2])
for (i = 0; i < NELEM(options); i++) while (i < NELEM(options)) {
if (options[i].c == n[1]) if (OFC(i) == n[1])
return (i); return (i);
} else for (i = 0; i < NELEM(options); i++) ++i;
if (options[i].name && strcmp(options[i].name, n) == 0) }
return (i); else
while (i < NELEM(options)) {
if (!strcmp(OFN(i), n))
return (i);
++i;
}
return ((size_t)-1); return ((size_t)-1);
} }
@ -165,7 +175,7 @@ options_fmt_entry(char *buf, size_t buflen, unsigned int i, const void *arg)
const struct options_info *oi = (const struct options_info *)arg; const struct options_info *oi = (const struct options_info *)arg;
shf_snprintf(buf, buflen, "%-*s %s", shf_snprintf(buf, buflen, "%-*s %s",
oi->opt_width, options[oi->opts[i]].name, oi->opt_width, OFN(oi->opts[i]),
Flag(oi->opts[i]) ? "on" : "off"); Flag(oi->opts[i]) ? "on" : "off");
return (buf); return (buf);
} }
@ -184,12 +194,11 @@ printoptions(bool verbose)
oi.opt_width = 0; oi.opt_width = 0;
while (i < NELEM(options)) { while (i < NELEM(options)) {
if (options[i].name) { if ((len = strlen(OFN(i)))) {
oi.opts[n++] = i; oi.opts[n++] = i;
len = strlen(options[i].name);
if (len > octs) if (len > octs)
octs = len; octs = len;
len = utf_mbswidth(options[i].name); len = utf_mbswidth(OFN(i));
if ((int)len > oi.opt_width) if ((int)len > oi.opt_width)
oi.opt_width = (int)len; oi.opt_width = (int)len;
} }
@ -200,10 +209,9 @@ printoptions(bool verbose)
} else { } else {
/* short version like AT&T ksh93 */ /* short version like AT&T ksh93 */
shf_puts(Tset, shl_stdout); shf_puts(Tset, shl_stdout);
while (i < (int)NELEM(options)) { while (i < NELEM(options)) {
if (Flag(i) && options[i].name) if (Flag(i) && OFN(i)[0])
shprintf("%s %s %s", null, "-o", shprintf(" -o %s", OFN(i));
options[i].name);
++i; ++i;
} }
shf_putc('\n', shl_stdout); shf_putc('\n', shl_stdout);
@ -213,13 +221,15 @@ printoptions(bool verbose)
char * char *
getoptions(void) getoptions(void)
{ {
size_t i; size_t i = 0;
char m[(int)FNFLAGS + 1]; char c, m[(int)FNFLAGS + 1];
char *cp = m; char *cp = m;
for (i = 0; i < NELEM(options); i++) while (i < NELEM(options)) {
if (options[i].c && Flag(i)) if ((c = OFC(i)) && Flag(i))
*cp++ = options[i].c; *cp++ = c;
++i;
}
strndupx(cp, m, cp - m, ATEMP); strndupx(cp, m, cp - m, ATEMP);
return (cp); return (cp);
} }
@ -344,7 +354,7 @@ parse_args(const char **argv,
/* First call? Build option strings... */ /* First call? Build option strings... */
if (cmd_opts[0] == '\0') { if (cmd_opts[0] == '\0') {
char *p = cmd_opts, *q = set_opts; char ch, *p = cmd_opts, *q = set_opts;
/* see cmd_opts[] declaration */ /* see cmd_opts[] declaration */
*p++ = 'o'; *p++ = 'o';
@ -361,11 +371,11 @@ parse_args(const char **argv,
*q++ = 's'; *q++ = 's';
for (i = 0; i < NELEM(options); i++) { for (i = 0; i < NELEM(options); i++) {
if (options[i].c) { if ((ch = OFC(i))) {
if (options[i].flags & OF_CMDLINE) if (OFF(i) & OF_CMDLINE)
*p++ = options[i].c; *p++ = ch;
if (options[i].flags & OF_SET) if (OFF(i) & OF_SET)
*q++ = options[i].c; *q++ = ch;
} }
} }
*p = '\0'; *p = '\0';
@ -433,7 +443,7 @@ parse_args(const char **argv,
* if the output of "set +o" is to be used. * if the output of "set +o" is to be used.
*/ */
; ;
else if ((i != (size_t)-1) && (options[i].flags & what)) else if ((i != (size_t)-1) && (OFF(i) & what))
change_flag((enum sh_flag)i, what, set); change_flag((enum sh_flag)i, what, set);
else { else {
bi_errorf("%s: %s", go.optarg, "bad option"); bi_errorf("%s: %s", go.optarg, "bad option");
@ -466,8 +476,8 @@ parse_args(const char **argv,
break; break;
} }
for (i = 0; i < NELEM(options); i++) for (i = 0; i < NELEM(options); i++)
if (optc == options[i].c && if (optc == OFC(i) &&
(what & options[i].flags)) { (what & OFF(i))) {
change_flag((enum sh_flag)i, what, set); change_flag((enum sh_flag)i, what, set);
break; break;
} }

11
sh.h
View File

@ -164,9 +164,9 @@
#endif #endif
#ifdef EXTERN #ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.665 2013/08/10 13:47:18 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/sh.h,v 1.666 2013/08/11 14:57:10 tg Exp $");
#endif #endif
#define MKSH_VERSION "R48 2013/08/10" #define MKSH_VERSION "R48 2013/08/11"
/* arithmetic types: C implementation */ /* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES #if !HAVE_CAN_INTTYPES
@ -771,13 +771,6 @@ EXTERN struct {
#define OF_FIRSTTIME 0x10 /* as early as possible, once */ #define OF_FIRSTTIME 0x10 /* as early as possible, once */
#define OF_ANY (OF_CMDLINE | OF_SET | OF_SPECIAL | OF_INTERNAL) #define OF_ANY (OF_CMDLINE | OF_SET | OF_SPECIAL | OF_INTERNAL)
struct shoption {
const char *name; /* long name of option */
char c; /* character flag (if any) */
unsigned char flags; /* OF_* */
};
extern const struct shoption options[];
/* null value for variable; comparison pointer for unset */ /* null value for variable; comparison pointer for unset */
EXTERN char null[] E_INIT(""); EXTERN char null[] E_INIT("");
/* helpers for string pooling */ /* helpers for string pooling */

View File

@ -1,11 +1,22 @@
#if defined(SHFLAGS_DEFNS) #if defined(SHFLAGS_DEFNS)
__RCSID("$MirOS: src/bin/mksh/sh_flags.h,v 1.15 2013/07/21 18:47:24 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/sh_flags.h,v 1.16 2013/08/11 14:57:11 tg Exp $");
#define FN(sname,cname,ochar,flags) /* nothing */ #define FN(sname,cname,ochar,flags) \
static const struct { \
/* character flag (if any) */ \
char c; \
/* OF_* */ \
unsigned char optflags; \
/* long name of option */ \
char name[sizeof(sname)]; \
} shoptione_ ## cname = { \
ochar, flags, sname \
};
#elif defined(SHFLAGS_ENUMS) #elif defined(SHFLAGS_ENUMS)
#define FN(sname,cname,ochar,flags) cname, #define FN(sname,cname,ochar,flags) cname,
#define F0(sname,cname,ochar,flags) cname = 0, #define F0(sname,cname,ochar,flags) cname = 0,
#elif defined(SHFLAGS_ITEMS) #elif defined(SHFLAGS_ITEMS)
#define FN(sname,cname,ochar,flags) { sname, ochar, flags }, #define FN(sname,cname,ochar,flags) \
((const char *)(&shoptione_ ## cname)) + 2,
#endif #endif
#ifndef F0 #ifndef F0
@ -136,17 +147,17 @@ FN("viraw", FVIRAW, 0, OF_ANY)
FN("xtrace", FXTRACE, 'x', OF_ANY) FN("xtrace", FXTRACE, 'x', OF_ANY)
/* -c (invocation) execute specified command */ /* -c (invocation) execute specified command */
FN(NULL, FCOMMAND, 'c', OF_CMDLINE) FN("", FCOMMAND, 'c', OF_CMDLINE)
/* /*
* anonymous flags: used internally by shell only (not visible to user) * anonymous flags: used internally by shell only (not visible to user)
*/ */
/* ./. direct builtin call (divined from argv[0] multi-call binary) */ /* ./. direct builtin call (divined from argv[0] multi-call binary) */
FN(NULL, FAS_BUILTIN, 0, OF_INTERNAL) FN("", FAS_BUILTIN, 0, OF_INTERNAL)
/* ./. (internal) initial shell was interactive */ /* ./. (internal) initial shell was interactive */
FN(NULL, FTALKING_I, 0, OF_INTERNAL) FN("", FTALKING_I, 0, OF_INTERNAL)
#undef FN #undef FN
#undef F0 #undef F0