Date: Sun, 31 Oct 2010 12:06:02 +0000 (UTC) From: Jilles Tjoelker <jilles@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r214599 - head/bin/sh Message-ID: <201010311206.o9VC62qv086927@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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; } } }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201010311206.o9VC62qv086927>