ash: [MEMALLOC] Add pushstackmark

Upstream commit:

    Author: Herbert Xu <herbert@gondor.apana.org.au>
    Date:   Sat Oct 6 00:45:52 2007 +0800

    [MEMALLOC] Add pushstackmark

    This patch gets rid of the stack mark tracking hack by allocating a little
    bit of stack memory if we're at risk of planting a stack mark which may be
    grown later.  To do this a new function pushstackmark is added which lets
    the user pick a bigger amount to allocate since some users do that anyway
    after setting a stack mark.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2016-09-30 11:21:21 +02:00
parent 08755f9bcb
commit 60ca834358

View File

@ -1371,13 +1371,11 @@ struct stackmark {
struct stack_block *stackp; struct stack_block *stackp;
char *stacknxt; char *stacknxt;
size_t stacknleft; size_t stacknleft;
struct stackmark *marknext;
}; };
struct globals_memstack { struct globals_memstack {
struct stack_block *g_stackp; // = &stackbase; struct stack_block *g_stackp; // = &stackbase;
struct stackmark *markp;
char *g_stacknxt; // = stackbase.space; char *g_stacknxt; // = stackbase.space;
char *sstrend; // = stackbase.space + MINSIZE; char *sstrend; // = stackbase.space + MINSIZE;
size_t g_stacknleft; // = MINSIZE; size_t g_stacknleft; // = MINSIZE;
@ -1387,7 +1385,6 @@ struct globals_memstack {
extern struct globals_memstack *const ash_ptr_to_globals_memstack; extern struct globals_memstack *const ash_ptr_to_globals_memstack;
#define G_memstack (*ash_ptr_to_globals_memstack) #define G_memstack (*ash_ptr_to_globals_memstack)
#define g_stackp (G_memstack.g_stackp ) #define g_stackp (G_memstack.g_stackp )
#define markp (G_memstack.markp )
#define g_stacknxt (G_memstack.g_stacknxt ) #define g_stacknxt (G_memstack.g_stacknxt )
#define sstrend (G_memstack.sstrend ) #define sstrend (G_memstack.sstrend )
#define g_stacknleft (G_memstack.g_stacknleft) #define g_stacknleft (G_memstack.g_stacknleft)
@ -1478,13 +1475,26 @@ sstrdup(const char *p)
} }
static void static void
setstackmark(struct stackmark *mark) grabstackblock(size_t len)
{
len = SHELL_ALIGN(len);
g_stacknxt += len;
g_stacknleft -= len;
}
static void
pushstackmark(struct stackmark *mark, size_t len)
{ {
mark->stackp = g_stackp; mark->stackp = g_stackp;
mark->stacknxt = g_stacknxt; mark->stacknxt = g_stacknxt;
mark->stacknleft = g_stacknleft; mark->stacknleft = g_stacknleft;
mark->marknext = markp; grabstackblock(len);
markp = mark; }
static void
setstackmark(struct stackmark *mark)
{
pushstackmark(mark, g_stacknxt == g_stackp->space && g_stackp != &stackbase);
} }
static void static void
@ -1496,7 +1506,6 @@ popstackmark(struct stackmark *mark)
return; return;
INT_OFF; INT_OFF;
markp = mark->marknext;
while (g_stackp != mark->stackp) { while (g_stackp != mark->stackp) {
sp = g_stackp; sp = g_stackp;
g_stackp = sp->prev; g_stackp = sp->prev;
@ -1530,7 +1539,6 @@ growstackblock(void)
if (g_stacknxt == g_stackp->space && g_stackp != &stackbase) { if (g_stacknxt == g_stackp->space && g_stackp != &stackbase) {
struct stack_block *oldstackp; struct stack_block *oldstackp;
struct stackmark *xmark;
struct stack_block *sp; struct stack_block *sp;
struct stack_block *prevstackp; struct stack_block *prevstackp;
size_t grosslen; size_t grosslen;
@ -1546,18 +1554,6 @@ growstackblock(void)
g_stacknxt = sp->space; g_stacknxt = sp->space;
g_stacknleft = newlen; g_stacknleft = newlen;
sstrend = sp->space + newlen; sstrend = sp->space + newlen;
/*
* Stack marks pointing to the start of the old block
* must be relocated to point to the new block
*/
xmark = markp;
while (xmark != NULL && xmark->stackp == oldstackp) {
xmark->stackp = g_stackp;
xmark->stacknxt = g_stacknxt;
xmark->stacknleft = g_stacknleft;
xmark = xmark->marknext;
}
INT_ON; INT_ON;
} else { } else {
char *oldspace = g_stacknxt; char *oldspace = g_stacknxt;
@ -1570,14 +1566,6 @@ growstackblock(void)
} }
} }
static void
grabstackblock(size_t len)
{
len = SHELL_ALIGN(len);
g_stacknxt += len;
g_stacknleft -= len;
}
/* /*
* The following routines are somewhat easier to use than the above. * The following routines are somewhat easier to use than the above.
* The user declares a variable of type STACKSTR, which may be declared * The user declares a variable of type STACKSTR, which may be declared
@ -2482,8 +2470,7 @@ setprompt_if(smallint do_set, int whichprompt)
prompt = nullstr; prompt = nullstr;
} }
#if ENABLE_ASH_EXPAND_PRMT #if ENABLE_ASH_EXPAND_PRMT
setstackmark(&smark); pushstackmark(&smark, stackblocksize());
stalloc(stackblocksize());
#endif #endif
putprompt(expandstr(prompt)); putprompt(expandstr(prompt));
#if ENABLE_ASH_EXPAND_PRMT #if ENABLE_ASH_EXPAND_PRMT
@ -5938,10 +5925,8 @@ expbackq(union node *cmd, int flag)
struct stackmark smark; struct stackmark smark;
INT_OFF; INT_OFF;
setstackmark(&smark); startloc = expdest - (char *)stackblock();
dest = expdest; pushstackmark(&smark, startloc);
startloc = dest - (char *)stackblock();
grabstackstr(dest);
evalbackcmd(cmd, &in); evalbackcmd(cmd, &in);
popstackmark(&smark); popstackmark(&smark);