attack the biggest stack users:

-mkfs_minix_main [busybox_unstripped]:                  4288
-mkfs_minix_main [busybox_unstripped]:                  4276
-grave [busybox_unstripped]:                            4260
(bzip2 users too - not listed)

price we pay in code size increase:
mainSort                                            2458    2515     +57
grave                                               1005    1058     +53
sendMTFValues                                       2177    2195     +18
BZ2_blockSort                                        122     125      +3
mkfs_minix_main                                     3070    3022     -48
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/1 up/down: 131/-48)            Total: 83 bytes
This commit is contained in:
Denis Vlasenko 2007-12-02 08:35:37 +00:00
parent 8003e266ed
commit ab801874f8
8 changed files with 85 additions and 20 deletions

View File

@ -90,7 +90,7 @@ objsizes: busybox_unstripped
.PHONY: stksizes .PHONY: stksizes
stksizes: busybox_unstripped stksizes: busybox_unstripped
$(CROSS_COMPILE)objdump -d busybox_unstripped | $(srctree)/scripts/checkstack.pl $(ARCH) $(CROSS_COMPILE)objdump -d busybox_unstripped | $(srctree)/scripts/checkstack.pl $(ARCH) | uniq
.PHONY: bigdata .PHONY: bigdata
bigdata: busybox_unstripped bigdata: busybox_unstripped

View File

@ -721,7 +721,8 @@ void mainQSort3(uint32_t* ptr,
#define CLEARMASK (~(SETMASK)) #define CLEARMASK (~(SETMASK))
static NOINLINE static NOINLINE
void mainSort(uint32_t* ptr, void mainSort(EState* state,
uint32_t* ptr,
uint8_t* block, uint8_t* block,
uint16_t* quadrant, uint16_t* quadrant,
uint32_t* ftab, uint32_t* ftab,
@ -729,13 +730,18 @@ void mainSort(uint32_t* ptr,
int32_t* budget) int32_t* budget)
{ {
int32_t i, j, k, ss, sb; int32_t i, j, k, ss, sb;
int32_t runningOrder[256];
Bool bigDone[256];
int32_t copyStart[256];
int32_t copyEnd [256];
uint8_t c1; uint8_t c1;
int32_t numQSorted; int32_t numQSorted;
uint16_t s; uint16_t s;
Bool bigDone[256];
/* bbox: moved to EState to save stack
int32_t runningOrder[256];
int32_t copyStart[256];
int32_t copyEnd [256];
*/
#define runningOrder (state->mainSort__runningOrder)
#define copyStart (state->mainSort__copyStart)
#define copyEnd (state->mainSort__copyEnd)
/*-- set up the 2-byte frequency table --*/ /*-- set up the 2-byte frequency table --*/
/* was: for (i = 65536; i >= 0; i--) ftab[i] = 0; */ /* was: for (i = 65536; i >= 0; i--) ftab[i] = 0; */
@ -985,6 +991,9 @@ void mainSort(uint32_t* ptr,
AssertH(((bbSize-1) >> shifts) <= 65535, 1002); AssertH(((bbSize-1) >> shifts) <= 65535, 1002);
} }
} }
#undef runningOrder
#undef copyStart
#undef copyEnd
} }
#undef BIGFREQ #undef BIGFREQ
@ -1041,7 +1050,7 @@ void BZ2_blockSort(EState* s)
*/ */
budget = nblock * ((wfact-1) / 3); budget = nblock * ((wfact-1) / 3);
mainSort(ptr, block, quadrant, ftab, nblock, &budget); mainSort(s, ptr, block, quadrant, ftab, nblock, &budget);
if (budget < 0) { if (budget < 0) {
fallbackSort(s->arr1, s->arr2, ftab, nblock); fallbackSort(s->arr1, s->arr2, ftab, nblock);
} }

View File

@ -178,13 +178,22 @@ typedef struct EState {
uint8_t selector [BZ_MAX_SELECTORS]; uint8_t selector [BZ_MAX_SELECTORS];
uint8_t selectorMtf[BZ_MAX_SELECTORS]; uint8_t selectorMtf[BZ_MAX_SELECTORS];
uint8_t len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; uint8_t len[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
int32_t code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
int32_t rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; /* stack-saving measures: these can be local, but they are too big */
int32_t sendMTFValues__code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
int32_t sendMTFValues__rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
#if CONFIG_BZIP2_FEATURE_SPEED >= 5 #if CONFIG_BZIP2_FEATURE_SPEED >= 5
/* second dimension: only 3 needed; 4 makes index calculations faster */ /* second dimension: only 3 needed; 4 makes index calculations faster */
uint32_t len_pack[BZ_MAX_ALPHA_SIZE][4]; uint32_t sendMTFValues__len_pack[BZ_MAX_ALPHA_SIZE][4];
#endif #endif
int32_t BZ2_hbMakeCodeLengths__heap [BZ_MAX_ALPHA_SIZE + 2];
int32_t BZ2_hbMakeCodeLengths__weight[BZ_MAX_ALPHA_SIZE * 2];
int32_t BZ2_hbMakeCodeLengths__parent[BZ_MAX_ALPHA_SIZE * 2];
int32_t mainSort__runningOrder[256];
int32_t mainSort__copyStart[256];
int32_t mainSort__copyEnd[256];
} EState; } EState;
@ -203,7 +212,7 @@ static void
BZ2_hbAssignCodes(int32_t*, uint8_t*, int32_t, int32_t, int32_t); BZ2_hbAssignCodes(int32_t*, uint8_t*, int32_t, int32_t, int32_t);
static void static void
BZ2_hbMakeCodeLengths(uint8_t*, int32_t*, int32_t, int32_t); BZ2_hbMakeCodeLengths(EState*, uint8_t*, int32_t*, int32_t, int32_t);
/*-------------------------------------------------------------*/ /*-------------------------------------------------------------*/
/*--- end bzlib_private.h ---*/ /*--- end bzlib_private.h ---*/

View File

@ -264,13 +264,16 @@ void sendMTFValues(EState* s)
* are also globals only used in this proc. * are also globals only used in this proc.
* Made global to keep stack frame size small. * Made global to keep stack frame size small.
*/ */
#define code sendMTFValues__code
#define rfreq sendMTFValues__rfreq
#define len_pack sendMTFValues__len_pack
uint16_t cost[BZ_N_GROUPS]; uint16_t cost[BZ_N_GROUPS];
int32_t fave[BZ_N_GROUPS]; int32_t fave[BZ_N_GROUPS];
uint16_t* mtfv = s->mtfv; uint16_t* mtfv = s->mtfv;
alphaSize = s->nInUse+2; alphaSize = s->nInUse + 2;
for (t = 0; t < BZ_N_GROUPS; t++) for (t = 0; t < BZ_N_GROUPS; t++)
for (v = 0; v < alphaSize; v++) for (v = 0; v < alphaSize; v++)
s->len[t][v] = BZ_GREATER_ICOST; s->len[t][v] = BZ_GREATER_ICOST;
@ -453,7 +456,7 @@ void sendMTFValues(EState* s)
/* maxLen was changed from 20 to 17 in bzip2-1.0.3. See /* maxLen was changed from 20 to 17 in bzip2-1.0.3. See
* comment in huffman.c for details. */ * comment in huffman.c for details. */
for (t = 0; t < nGroups; t++) for (t = 0; t < nGroups; t++)
BZ2_hbMakeCodeLengths(&(s->len[t][0]), &(s->rfreq[t][0]), alphaSize, 17 /*20*/); BZ2_hbMakeCodeLengths(s, &(s->len[t][0]), &(s->rfreq[t][0]), alphaSize, 17 /*20*/);
} }
AssertH(nGroups < 8, 3002); AssertH(nGroups < 8, 3002);
@ -602,6 +605,9 @@ void sendMTFValues(EState* s)
selCtr++; selCtr++;
} }
AssertH(selCtr == nSelectors, 3007); AssertH(selCtr == nSelectors, 3007);
#undef code
#undef rfreq
#undef len_pack
} }

View File

@ -98,7 +98,8 @@ void DOWNHEAP1(int32_t *heap, int32_t *weight, int32_t nHeap)
/*---------------------------------------------------*/ /*---------------------------------------------------*/
static static
void BZ2_hbMakeCodeLengths(uint8_t *len, void BZ2_hbMakeCodeLengths(EState *s,
uint8_t *len,
int32_t *freq, int32_t *freq,
int32_t alphaSize, int32_t alphaSize,
int32_t maxLen) int32_t maxLen)
@ -110,9 +111,14 @@ void BZ2_hbMakeCodeLengths(uint8_t *len,
int32_t nNodes, nHeap, n1, n2, i, j, k; int32_t nNodes, nHeap, n1, n2, i, j, k;
Bool tooLong; Bool tooLong;
/* bbox: moved to EState to save stack
int32_t heap [BZ_MAX_ALPHA_SIZE + 2]; int32_t heap [BZ_MAX_ALPHA_SIZE + 2];
int32_t weight[BZ_MAX_ALPHA_SIZE * 2]; int32_t weight[BZ_MAX_ALPHA_SIZE * 2];
int32_t parent[BZ_MAX_ALPHA_SIZE * 2]; int32_t parent[BZ_MAX_ALPHA_SIZE * 2];
*/
#define heap (s->BZ2_hbMakeCodeLengths__heap)
#define weight (s->BZ2_hbMakeCodeLengths__weight)
#define parent (s->BZ2_hbMakeCodeLengths__parent)
for (i = 0; i < alphaSize; i++) for (i = 0; i < alphaSize; i++)
weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8; weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
@ -189,6 +195,9 @@ void BZ2_hbMakeCodeLengths(uint8_t *len,
weight[i] = j << 8; weight[i] = j << 8;
} }
} }
#undef heap
#undef weight
#undef parent
} }

View File

@ -126,7 +126,8 @@ while (my $line = <STDIN>) {
$addr =~ s/ /0/g; $addr =~ s/ /0/g;
$addr = "0x$addr"; $addr = "0x$addr";
my $intro = "$addr $func [$file]:"; # bbox: was: my $intro = "$addr $func [$file]:";
my $intro = "$func [$file]:";
my $padlen = 56 - length($intro); my $padlen = 56 - length($intro);
while ($padlen > 0) { while ($padlen > 0) {
$intro .= ' '; $intro .= ' ';

View File

@ -735,6 +735,9 @@ struct globals {
char filechar_cmdbuf[BUFSIZ]; char filechar_cmdbuf[BUFSIZ];
char line[LINELIM]; char line[LINELIM];
char child_cmd[LINELIM]; char child_cmd[LINELIM];
char grave__var_name[LINELIM];
char grave__alt_value[LINELIM];
}; };
#define G (*ptr_to_globals) #define G (*ptr_to_globals)
@ -746,6 +749,9 @@ struct globals {
#define filechar_cmdbuf (G.filechar_cmdbuf) #define filechar_cmdbuf (G.filechar_cmdbuf)
#define line (G.line ) #define line (G.line )
#define child_cmd (G.child_cmd ) #define child_cmd (G.child_cmd )
#define INIT_G() do { \
PTR_TO_GLOBALS = xzalloc(sizeof(G)); \
} while (0)
#ifdef MSHDEBUG #ifdef MSHDEBUG
@ -4042,8 +4048,12 @@ static int grave(int quoted)
ignore_once = 1; ignore_once = 1;
if (*src == '$' && !ignore && !ignore_once) { if (*src == '$' && !ignore && !ignore_once) {
struct var *vp; struct var *vp;
/* moved to G to reduce stack usage
char var_name[LINELIM]; char var_name[LINELIM];
char alt_value[LINELIM]; char alt_value[LINELIM];
*/
#define var_name (G.grave__var_name)
#define alt_value (G.grave__alt_value)
int var_index = 0; int var_index = 0;
int alt_index = 0; int alt_index = 0;
char operator = 0; char operator = 0;
@ -4131,6 +4141,8 @@ static int grave(int quoted)
count++; count++;
} }
} }
#undef var_name
#undef alt_value
} else { } else {
*dest++ = *src++; *dest++ = *src++;
count++; count++;
@ -5173,7 +5185,8 @@ int msh_main(int argc, char **argv)
char *name, **ap; char *name, **ap;
int (*iof) (struct ioarg *); int (*iof) (struct ioarg *);
PTR_TO_GLOBALS = xzalloc(sizeof(G)); INIT_G();
sharedbuf.id = AFID_NOBUF; sharedbuf.id = AFID_NOBUF;
mainbuf.id = AFID_NOBUF; mainbuf.id = AFID_NOBUF;
e.linep = line; e.linep = line;

View File

@ -109,16 +109,22 @@ struct globals {
unsigned long req_nr_inodes; unsigned long req_nr_inodes;
unsigned currently_testing; unsigned currently_testing;
char root_block[BLOCK_SIZE]; char root_block[BLOCK_SIZE];
char super_block_buffer[BLOCK_SIZE]; char super_block_buffer[BLOCK_SIZE];
char boot_block_buffer[512]; char boot_block_buffer[512];
unsigned short good_blocks_table[MAX_GOOD_BLOCKS]; unsigned short good_blocks_table[MAX_GOOD_BLOCKS];
/* check_blocks(): buffer[] was the biggest static in entire bbox */ /* check_blocks(): buffer[] was the biggest static in entire bbox */
char check_blocks_buffer[BLOCK_SIZE * TEST_BUFFER_BLOCKS]; char check_blocks_buffer[BLOCK_SIZE * TEST_BUFFER_BLOCKS];
};
unsigned short ind_block1[BLOCK_SIZE >> 1];
unsigned short dind_block1[BLOCK_SIZE >> 1];
unsigned long ind_block2[BLOCK_SIZE >> 2];
unsigned long dind_block2[BLOCK_SIZE >> 2];
};
#define G (*ptr_to_globals) #define G (*ptr_to_globals)
#define INIT_G() do { \
PTR_TO_GLOBALS = xzalloc(sizeof(G)); \
} while (0)
static ALWAYS_INLINE unsigned div_roundup(unsigned size, unsigned n) static ALWAYS_INLINE unsigned div_roundup(unsigned size, unsigned n)
{ {
@ -306,8 +312,12 @@ static void make_bad_inode(void)
struct minix1_inode *inode = &INODE_BUF1[MINIX_BAD_INO]; struct minix1_inode *inode = &INODE_BUF1[MINIX_BAD_INO];
int i, j, zone; int i, j, zone;
int ind = 0, dind = 0; int ind = 0, dind = 0;
/* moved to globals to reduce stack usage
unsigned short ind_block[BLOCK_SIZE >> 1]; unsigned short ind_block[BLOCK_SIZE >> 1];
unsigned short dind_block[BLOCK_SIZE >> 1]; unsigned short dind_block[BLOCK_SIZE >> 1];
*/
#define ind_block (G.ind_block1)
#define dind_block (G.dind_block1)
#define NEXT_BAD (zone = next(zone)) #define NEXT_BAD (zone = next(zone))
@ -351,6 +361,8 @@ static void make_bad_inode(void)
write_block(ind, (char *) ind_block); write_block(ind, (char *) ind_block);
if (dind) if (dind)
write_block(dind, (char *) dind_block); write_block(dind, (char *) dind_block);
#undef ind_block
#undef dind_block
} }
#if ENABLE_FEATURE_MINIX2 #if ENABLE_FEATURE_MINIX2
@ -359,8 +371,12 @@ static void make_bad_inode2(void)
struct minix2_inode *inode = &INODE_BUF2[MINIX_BAD_INO]; struct minix2_inode *inode = &INODE_BUF2[MINIX_BAD_INO];
int i, j, zone; int i, j, zone;
int ind = 0, dind = 0; int ind = 0, dind = 0;
/* moved to globals to reduce stack usage
unsigned long ind_block[BLOCK_SIZE >> 2]; unsigned long ind_block[BLOCK_SIZE >> 2];
unsigned long dind_block[BLOCK_SIZE >> 2]; unsigned long dind_block[BLOCK_SIZE >> 2];
*/
#define ind_block (G.ind_block2)
#define dind_block (G.dind_block2)
if (!G.badblocks) if (!G.badblocks)
return; return;
@ -401,6 +417,8 @@ static void make_bad_inode2(void)
write_block(ind, (char *) ind_block); write_block(ind, (char *) ind_block);
if (dind) if (dind)
write_block(dind, (char *) dind_block); write_block(dind, (char *) dind_block);
#undef ind_block
#undef dind_block
} }
#else #else
void make_bad_inode2(void); void make_bad_inode2(void);
@ -613,7 +631,7 @@ int mkfs_minix_main(int argc, char **argv)
char *str_i, *str_n; char *str_i, *str_n;
char *listfile = NULL; char *listfile = NULL;
PTR_TO_GLOBALS = xzalloc(sizeof(G)); INIT_G();
/* default (changed to 30, per Linus's suggestion, Sun Nov 21 08:05:07 1993) */ /* default (changed to 30, per Linus's suggestion, Sun Nov 21 08:05:07 1993) */
G.namelen = 30; G.namelen = 30;
G.dirsize = 32; G.dirsize = 32;