From owner-svn-src-all@freebsd.org Sat Jan 30 21:21:27 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 6E4AFA728A7; Sat, 30 Jan 2016 21:21:27 +0000 (UTC) (envelope-from jilles@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1CA491137; Sat, 30 Jan 2016 21:21:27 +0000 (UTC) (envelope-from jilles@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u0ULLQsJ074932; Sat, 30 Jan 2016 21:21:26 GMT (envelope-from jilles@FreeBSD.org) Received: (from jilles@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u0ULLQRA074931; Sat, 30 Jan 2016 21:21:26 GMT (envelope-from jilles@FreeBSD.org) Message-Id: <201601302121.u0ULLQRA074931@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jilles set sender to jilles@FreeBSD.org using -f From: Jilles Tjoelker Date: Sat, 30 Jan 2016 21:21:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r295085 - head/bin/sh X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 30 Jan 2016 21:21:27 -0000 Author: jilles Date: Sat Jan 30 21:21:25 2016 New Revision: 295085 URL: https://svnweb.freebsd.org/changeset/base/295085 Log: sh: Don't allocate a redirtab if there are no redirections. Builtins (including variable assignments without command word), function calls and redirected compound commands need to restore file descriptors to their original state after execution. This is handled by allocating a redirtab structure. These mallocs and frees show up heavily in pmcstat. Only allocate a redirtab if there are actually redirections and maintain a count of how many levels of REDIR_PUSH there are without redirtabs. A simple loop without external programs like sh -c 'i=0; w=$(printf %0100d 7); while [ "$i" -lt 1000000 ]; do i=$((i+1)); done' is over 25% faster on an amd64 bhyve VM. Modified: head/bin/sh/redir.c Modified: head/bin/sh/redir.c ============================================================================== --- head/bin/sh/redir.c Sat Jan 30 20:48:45 2016 (r295084) +++ head/bin/sh/redir.c Sat Jan 30 21:21:25 2016 (r295085) @@ -70,6 +70,7 @@ struct redirtab { struct redirtab *next; int renamed[10]; int fd0_redirected; + unsigned int empty_redirs; }; @@ -82,6 +83,9 @@ static struct redirtab *redirlist; */ static int fd0_redirected = 0; +/* Number of redirtabs that have not been allocated. */ +static unsigned int empty_redirs = 0; + static void openredirect(union node *, char[10 ]); static int openhere(union node *); @@ -115,12 +119,17 @@ redirect(union node *redir, int flags) memory[i] = 0; memory[1] = flags & REDIR_BACKQ; if (flags & REDIR_PUSH) { - sv = ckmalloc(sizeof (struct redirtab)); - for (i = 0 ; i < 10 ; i++) - sv->renamed[i] = EMPTY; - sv->fd0_redirected = fd0_redirected; - sv->next = redirlist; - redirlist = sv; + empty_redirs++; + if (redir != NULL) { + sv = ckmalloc(sizeof (struct redirtab)); + for (i = 0 ; i < 10 ; i++) + sv->renamed[i] = EMPTY; + sv->fd0_redirected = fd0_redirected; + sv->empty_redirs = empty_redirs - 1; + sv->next = redirlist; + redirlist = sv; + empty_redirs = 0; + } } for (n = redir ; n ; n = n->nfile.next) { fd = n->nfile.fd; @@ -303,6 +312,12 @@ popredir(void) struct redirtab *rp = redirlist; int i; + INTOFF; + if (empty_redirs > 0) { + empty_redirs--; + INTON; + return; + } for (i = 0 ; i < 10 ; i++) { if (rp->renamed[i] != EMPTY) { if (rp->renamed[i] >= 0) { @@ -313,8 +328,8 @@ popredir(void) } } } - INTOFF; fd0_redirected = rp->fd0_redirected; + empty_redirs = rp->empty_redirs; redirlist = rp->next; ckfree(rp); INTON;