ash: [REDIR] Move null redirect checks into caller

Upstream commit:

    Date: Thu, 27 May 2010 14:21:17 +0800
    [REDIR] Move null redirect checks into caller

    The null redirect checks were added as an optimisation to avoid
    unnecessary memory allocations.  However, we could avoid this
    completely by simply making the caller avoid making a redirection
    unless it is not null.

    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

function                                             old     new   delta
evaltree                                             784     809     +25
evalcommand                                         1251    1261     +10
hashvar                                               59      62      +3
dotcmd                                               321     319      -2
clearredir                                            37      30      -7
popredir                                             183     162     -21
redirect                                            1264    1233     -31
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/4 up/down: 63/-61)            Total: -23 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2016-10-25 21:46:03 +02:00
parent 2a6d29ad5c
commit eaf9436b08

View File

@ -1951,7 +1951,6 @@ struct redirtab;
struct globals_var { struct globals_var {
struct shparam shellparam; /* $@ current positional parameters */ struct shparam shellparam; /* $@ current positional parameters */
struct redirtab *redirlist; struct redirtab *redirlist;
int g_nullredirs;
int preverrout_fd; /* save fd2 before print debug if xflag is set. */ int preverrout_fd; /* save fd2 before print debug if xflag is set. */
struct var *vartab[VTABSIZE]; struct var *vartab[VTABSIZE];
struct var varinit[ARRAY_SIZE(varinit_data)]; struct var varinit[ARRAY_SIZE(varinit_data)];
@ -1960,7 +1959,6 @@ extern struct globals_var *const ash_ptr_to_globals_var;
#define G_var (*ash_ptr_to_globals_var) #define G_var (*ash_ptr_to_globals_var)
#define shellparam (G_var.shellparam ) #define shellparam (G_var.shellparam )
//#define redirlist (G_var.redirlist ) //#define redirlist (G_var.redirlist )
#define g_nullredirs (G_var.g_nullredirs )
#define preverrout_fd (G_var.preverrout_fd) #define preverrout_fd (G_var.preverrout_fd)
#define vartab (G_var.vartab ) #define vartab (G_var.vartab )
#define varinit (G_var.varinit ) #define varinit (G_var.varinit )
@ -5216,7 +5214,6 @@ struct two_fd_t {
}; };
struct redirtab { struct redirtab {
struct redirtab *next; struct redirtab *next;
int nullredirs;
int pair_count; int pair_count;
struct two_fd_t two_fd[]; struct two_fd_t two_fd[];
}; };
@ -5295,7 +5292,6 @@ redirect(union node *redir, int flags)
int newfd; int newfd;
int copied_fd2 = -1; int copied_fd2 = -1;
g_nullredirs++;
if (!redir) { if (!redir) {
return; return;
} }
@ -5317,8 +5313,6 @@ redirect(union node *redir, int flags)
sv->next = redirlist; sv->next = redirlist;
sv->pair_count = sv_pos; sv->pair_count = sv_pos;
redirlist = sv; redirlist = sv;
sv->nullredirs = g_nullredirs - 1;
g_nullredirs = 0;
while (sv_pos > 0) { while (sv_pos > 0) {
sv_pos--; sv_pos--;
sv->two_fd[sv_pos].orig = sv->two_fd[sv_pos].copy = EMPTY; sv->two_fd[sv_pos].orig = sv->two_fd[sv_pos].copy = EMPTY;
@ -5430,7 +5424,7 @@ popredir(int drop, int restore)
struct redirtab *rp; struct redirtab *rp;
int i; int i;
if (--g_nullredirs >= 0 || redirlist == NULL) if (redirlist == NULL)
return; return;
INT_OFF; INT_OFF;
rp = redirlist; rp = redirlist;
@ -5452,7 +5446,6 @@ popredir(int drop, int restore)
} }
} }
redirlist = rp->next; redirlist = rp->next;
g_nullredirs = rp->nullredirs;
free(rp); free(rp);
INT_ON; INT_ON;
} }
@ -5467,12 +5460,8 @@ popredir(int drop, int restore)
static void static void
clearredir(int drop) clearredir(int drop)
{ {
for (;;) { while (redirlist)
g_nullredirs = 0;
if (!redirlist)
break;
popredir(drop, /*restore:*/ 0); popredir(drop, /*restore:*/ 0);
}
} }
static int static int
@ -8573,7 +8562,8 @@ evaltree(union node *n, int flags)
if (!status) { if (!status) {
status = evaltree(n->nredir.n, flags & EV_TESTED); status = evaltree(n->nredir.n, flags & EV_TESTED);
} }
popredir(/*drop:*/ 0, /*restore:*/ 0 /* not sure */); if (n->nredir.redirect)
popredir(/*drop:*/ 0, /*restore:*/ 0 /* not sure */);
goto setstatus; goto setstatus;
case NCMD: case NCMD:
evalfn = evalcommand; evalfn = evalcommand;
@ -9645,7 +9635,8 @@ evalcommand(union node *cmd, int flags)
} /* switch */ } /* switch */
out: out:
popredir(/*drop:*/ cmd_is_exec, /*restore:*/ cmd_is_exec); if (cmd->ncmd.redirect)
popredir(/*drop:*/ cmd_is_exec, /*restore:*/ cmd_is_exec);
if (lastarg) { if (lastarg) {
/* dsl: I think this is intended to be used to support /* dsl: I think this is intended to be used to support
* '_' in 'vi' command mode during line editing... * '_' in 'vi' command mode during line editing...