diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-09-30 11:21:21 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-09-30 11:21:21 +0200 |
commit | 60ca8343589ff6edb5a447551718e816555af494 (patch) | |
tree | 185d67d64a69966284da66fdfdccf4e365221957 | |
parent | 08755f9bcb2d272ed32687883b410910d34c50dc (diff) | |
download | busybox-w32-60ca8343589ff6edb5a447551718e816555af494.tar.gz busybox-w32-60ca8343589ff6edb5a447551718e816555af494.tar.bz2 busybox-w32-60ca8343589ff6edb5a447551718e816555af494.zip |
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>
-rw-r--r-- | shell/ash.c | 53 |
1 files changed, 19 insertions, 34 deletions
diff --git a/shell/ash.c b/shell/ash.c index 97f8d9377..f7ce698a3 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -1371,13 +1371,11 @@ struct stackmark { | |||
1371 | struct stack_block *stackp; | 1371 | struct stack_block *stackp; |
1372 | char *stacknxt; | 1372 | char *stacknxt; |
1373 | size_t stacknleft; | 1373 | size_t stacknleft; |
1374 | struct stackmark *marknext; | ||
1375 | }; | 1374 | }; |
1376 | 1375 | ||
1377 | 1376 | ||
1378 | struct globals_memstack { | 1377 | struct globals_memstack { |
1379 | struct stack_block *g_stackp; // = &stackbase; | 1378 | struct stack_block *g_stackp; // = &stackbase; |
1380 | struct stackmark *markp; | ||
1381 | char *g_stacknxt; // = stackbase.space; | 1379 | char *g_stacknxt; // = stackbase.space; |
1382 | char *sstrend; // = stackbase.space + MINSIZE; | 1380 | char *sstrend; // = stackbase.space + MINSIZE; |
1383 | size_t g_stacknleft; // = MINSIZE; | 1381 | size_t g_stacknleft; // = MINSIZE; |
@@ -1387,7 +1385,6 @@ struct globals_memstack { | |||
1387 | extern struct globals_memstack *const ash_ptr_to_globals_memstack; | 1385 | extern struct globals_memstack *const ash_ptr_to_globals_memstack; |
1388 | #define G_memstack (*ash_ptr_to_globals_memstack) | 1386 | #define G_memstack (*ash_ptr_to_globals_memstack) |
1389 | #define g_stackp (G_memstack.g_stackp ) | 1387 | #define g_stackp (G_memstack.g_stackp ) |
1390 | #define markp (G_memstack.markp ) | ||
1391 | #define g_stacknxt (G_memstack.g_stacknxt ) | 1388 | #define g_stacknxt (G_memstack.g_stacknxt ) |
1392 | #define sstrend (G_memstack.sstrend ) | 1389 | #define sstrend (G_memstack.sstrend ) |
1393 | #define g_stacknleft (G_memstack.g_stacknleft) | 1390 | #define g_stacknleft (G_memstack.g_stacknleft) |
@@ -1478,13 +1475,26 @@ sstrdup(const char *p) | |||
1478 | } | 1475 | } |
1479 | 1476 | ||
1480 | static void | 1477 | static void |
1481 | setstackmark(struct stackmark *mark) | 1478 | grabstackblock(size_t len) |
1479 | { | ||
1480 | len = SHELL_ALIGN(len); | ||
1481 | g_stacknxt += len; | ||
1482 | g_stacknleft -= len; | ||
1483 | } | ||
1484 | |||
1485 | static void | ||
1486 | pushstackmark(struct stackmark *mark, size_t len) | ||
1482 | { | 1487 | { |
1483 | mark->stackp = g_stackp; | 1488 | mark->stackp = g_stackp; |
1484 | mark->stacknxt = g_stacknxt; | 1489 | mark->stacknxt = g_stacknxt; |
1485 | mark->stacknleft = g_stacknleft; | 1490 | mark->stacknleft = g_stacknleft; |
1486 | mark->marknext = markp; | 1491 | grabstackblock(len); |
1487 | markp = mark; | 1492 | } |
1493 | |||
1494 | static void | ||
1495 | setstackmark(struct stackmark *mark) | ||
1496 | { | ||
1497 | pushstackmark(mark, g_stacknxt == g_stackp->space && g_stackp != &stackbase); | ||
1488 | } | 1498 | } |
1489 | 1499 | ||
1490 | static void | 1500 | static void |
@@ -1496,7 +1506,6 @@ popstackmark(struct stackmark *mark) | |||
1496 | return; | 1506 | return; |
1497 | 1507 | ||
1498 | INT_OFF; | 1508 | INT_OFF; |
1499 | markp = mark->marknext; | ||
1500 | while (g_stackp != mark->stackp) { | 1509 | while (g_stackp != mark->stackp) { |
1501 | sp = g_stackp; | 1510 | sp = g_stackp; |
1502 | g_stackp = sp->prev; | 1511 | g_stackp = sp->prev; |
@@ -1530,7 +1539,6 @@ growstackblock(void) | |||
1530 | 1539 | ||
1531 | if (g_stacknxt == g_stackp->space && g_stackp != &stackbase) { | 1540 | if (g_stacknxt == g_stackp->space && g_stackp != &stackbase) { |
1532 | struct stack_block *oldstackp; | 1541 | struct stack_block *oldstackp; |
1533 | struct stackmark *xmark; | ||
1534 | struct stack_block *sp; | 1542 | struct stack_block *sp; |
1535 | struct stack_block *prevstackp; | 1543 | struct stack_block *prevstackp; |
1536 | size_t grosslen; | 1544 | size_t grosslen; |
@@ -1546,18 +1554,6 @@ growstackblock(void) | |||
1546 | g_stacknxt = sp->space; | 1554 | g_stacknxt = sp->space; |
1547 | g_stacknleft = newlen; | 1555 | g_stacknleft = newlen; |
1548 | sstrend = sp->space + newlen; | 1556 | sstrend = sp->space + newlen; |
1549 | |||
1550 | /* | ||
1551 | * Stack marks pointing to the start of the old block | ||
1552 | * must be relocated to point to the new block | ||
1553 | */ | ||
1554 | xmark = markp; | ||
1555 | while (xmark != NULL && xmark->stackp == oldstackp) { | ||
1556 | xmark->stackp = g_stackp; | ||
1557 | xmark->stacknxt = g_stacknxt; | ||
1558 | xmark->stacknleft = g_stacknleft; | ||
1559 | xmark = xmark->marknext; | ||
1560 | } | ||
1561 | INT_ON; | 1557 | INT_ON; |
1562 | } else { | 1558 | } else { |
1563 | char *oldspace = g_stacknxt; | 1559 | char *oldspace = g_stacknxt; |
@@ -1570,14 +1566,6 @@ growstackblock(void) | |||
1570 | } | 1566 | } |
1571 | } | 1567 | } |
1572 | 1568 | ||
1573 | static void | ||
1574 | grabstackblock(size_t len) | ||
1575 | { | ||
1576 | len = SHELL_ALIGN(len); | ||
1577 | g_stacknxt += len; | ||
1578 | g_stacknleft -= len; | ||
1579 | } | ||
1580 | |||
1581 | /* | 1569 | /* |
1582 | * The following routines are somewhat easier to use than the above. | 1570 | * The following routines are somewhat easier to use than the above. |
1583 | * The user declares a variable of type STACKSTR, which may be declared | 1571 | * The user declares a variable of type STACKSTR, which may be declared |
@@ -2482,8 +2470,7 @@ setprompt_if(smallint do_set, int whichprompt) | |||
2482 | prompt = nullstr; | 2470 | prompt = nullstr; |
2483 | } | 2471 | } |
2484 | #if ENABLE_ASH_EXPAND_PRMT | 2472 | #if ENABLE_ASH_EXPAND_PRMT |
2485 | setstackmark(&smark); | 2473 | pushstackmark(&smark, stackblocksize()); |
2486 | stalloc(stackblocksize()); | ||
2487 | #endif | 2474 | #endif |
2488 | putprompt(expandstr(prompt)); | 2475 | putprompt(expandstr(prompt)); |
2489 | #if ENABLE_ASH_EXPAND_PRMT | 2476 | #if ENABLE_ASH_EXPAND_PRMT |
@@ -5938,10 +5925,8 @@ expbackq(union node *cmd, int flag) | |||
5938 | struct stackmark smark; | 5925 | struct stackmark smark; |
5939 | 5926 | ||
5940 | INT_OFF; | 5927 | INT_OFF; |
5941 | setstackmark(&smark); | 5928 | startloc = expdest - (char *)stackblock(); |
5942 | dest = expdest; | 5929 | pushstackmark(&smark, startloc); |
5943 | startloc = dest - (char *)stackblock(); | ||
5944 | grabstackstr(dest); | ||
5945 | evalbackcmd(cmd, &in); | 5930 | evalbackcmd(cmd, &in); |
5946 | popstackmark(&smark); | 5931 | popstackmark(&smark); |
5947 | 5932 | ||