svn commit: r214599 - head/bin/sh
Jilles Tjoelker
jilles at FreeBSD.org
Sun Oct 31 12:06:03 UTC 2010
Author: jilles
Date: Sun Oct 31 12:06:02 2010
New Revision: 214599
URL: http://svn.freebsd.org/changeset/base/214599
Log:
sh: Use iteration instead of recursion to evaluate semicolon lists.
This reduces CPU and memory usage when executing long lists (such
as long functions).
Modified:
head/bin/sh/eval.c
head/bin/sh/parser.c
Modified: head/bin/sh/eval.c
==============================================================================
--- head/bin/sh/eval.c Sun Oct 31 12:05:37 2010 (r214598)
+++ head/bin/sh/eval.c Sun Oct 31 12:06:02 2010 (r214599)
@@ -196,6 +196,7 @@ void
evaltree(union node *n, int flags)
{
int do_etest;
+ union node *next;
do_etest = 0;
if (n == NULL) {
@@ -203,6 +204,8 @@ evaltree(union node *n, int flags)
exitstatus = 0;
goto out;
}
+ do {
+ next = NULL;
#ifndef NO_HISTORY
displayhist = 1; /* show history substitutions done with fc */
#endif
@@ -212,20 +215,20 @@ evaltree(union node *n, int flags)
evaltree(n->nbinary.ch1, flags & ~EV_EXIT);
if (evalskip)
goto out;
- evaltree(n->nbinary.ch2, flags);
+ next = n->nbinary.ch2;
break;
case NAND:
evaltree(n->nbinary.ch1, EV_TESTED);
if (evalskip || exitstatus != 0) {
goto out;
}
- evaltree(n->nbinary.ch2, flags);
+ next = n->nbinary.ch2;
break;
case NOR:
evaltree(n->nbinary.ch1, EV_TESTED);
if (evalskip || exitstatus == 0)
goto out;
- evaltree(n->nbinary.ch2, flags);
+ next = n->nbinary.ch2;
break;
case NREDIR:
evalredir(n, flags);
@@ -242,9 +245,9 @@ evaltree(union node *n, int flags)
if (evalskip)
goto out;
if (exitstatus == 0)
- evaltree(n->nif.ifpart, flags);
+ next = n->nif.ifpart;
else if (n->nif.elsepart)
- evaltree(n->nif.elsepart, flags);
+ next = n->nif.elsepart;
else
exitstatus = 0;
break;
@@ -281,6 +284,8 @@ evaltree(union node *n, int flags)
flushout(&output);
break;
}
+ n = next;
+ } while (n != NULL);
out:
if (pendingsigs)
dotrap();
Modified: head/bin/sh/parser.c
==============================================================================
--- head/bin/sh/parser.c Sun Oct 31 12:05:37 2010 (r214598)
+++ head/bin/sh/parser.c Sun Oct 31 12:06:02 2010 (r214599)
@@ -227,13 +227,13 @@ parsecmd(int interact)
static union node *
list(int nlflag, int erflag)
{
- union node *n1, *n2, *n3;
+ union node *ntop, *n1, *n2, *n3;
int tok;
checkkwd = 2;
if (!nlflag && !erflag && tokendlist[peektoken()])
return NULL;
- n1 = NULL;
+ ntop = n1 = NULL;
for (;;) {
n2 = andor();
tok = readtoken();
@@ -250,14 +250,21 @@ list(int nlflag, int erflag)
n2 = n3;
}
}
- if (n1 == NULL) {
- n1 = n2;
+ if (ntop == NULL)
+ ntop = n2;
+ else if (n1 == NULL) {
+ n1 = (union node *)stalloc(sizeof (struct nbinary));
+ n1->type = NSEMI;
+ n1->nbinary.ch1 = ntop;
+ n1->nbinary.ch2 = n2;
+ ntop = n1;
}
else {
n3 = (union node *)stalloc(sizeof (struct nbinary));
n3->type = NSEMI;
- n3->nbinary.ch1 = n1;
+ n3->nbinary.ch1 = n1->nbinary.ch2;
n3->nbinary.ch2 = n2;
+ n1->nbinary.ch2 = n3;
n1 = n3;
}
switch (tok) {
@@ -269,28 +276,28 @@ list(int nlflag, int erflag)
if (tok == TNL) {
parseheredoc();
if (nlflag)
- return n1;
+ return ntop;
} else if (tok == TEOF && nlflag) {
parseheredoc();
- return n1;
+ return ntop;
} else {
tokpushback++;
}
checkkwd = 2;
if (!nlflag && !erflag && tokendlist[peektoken()])
- return n1;
+ return ntop;
break;
case TEOF:
if (heredoclist)
parseheredoc();
else
pungetc(); /* push back EOF on input */
- return n1;
+ return ntop;
default:
if (nlflag || erflag)
synexpect(-1);
tokpushback++;
- return n1;
+ return ntop;
}
}
}
More information about the svn-src-all
mailing list