This is the mail archive of the libc-hacker@sourceware.org mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Decrease vfprintf stack usage


Hi!

The recent vfprintf change increased vfprintf's stack usage 3.5x times:
 0000000000000890 <_IO_vfprintf>:
      890:       55                      push   %rbp
      891:       48 89 e5                mov    %rsp,%rbp
      894:       41 57                   push   %r15
      896:       41 56                   push   %r14
      898:       41 55                   push   %r13
      89a:       41 54                   push   %r12
      89c:       53                      push   %rbx
-     89d:       48 81 ec 58 06 00 00    sub    $0x658,%rsp
+     89d:       48 81 ec 58 16 00 00    sub    $0x1658,%rsp

I think that's just too much for something rare (I believe most format
strings don't use precision for %s).  While a VLA is a little bit more
expensive, we'll hit that only when somebody actually uses a precision on
%s and for usual precisions we'll still use less stack.

2007-05-02  Jakub Jelinek  <jakub@redhat.com>

	* stdio-common/vfprintf.c (process_string_arg): Use a VLA rather than
	fixed length array for ignore.

--- libc/stdio-common/vfprintf.c.jj	2007-05-02 08:43:05.000000000 +0200
+++ libc/stdio-common/vfprintf.c	2007-05-02 08:50:17.000000000 +0200
@@ -1162,7 +1162,8 @@ vfprintf (FILE *s, const CHAR_T *format,
 		    /* In case we have a multibyte character set the	      \
 		       situation is more complicated.  We must not copy	      \
 		       bytes at the end which form an incomplete character. */\
-		    wchar_t ignore[1024];				      \
+		    size_t ignore_size = (unsigned) prec > 1024 ? 1024 : prec;\
+		    wchar_t ignore[ignore_size];			      \
 		    const char *str2 = string;				      \
 		    const char *strend = string + prec;			      \
 		    if (strend < string)				      \
@@ -1172,8 +1173,8 @@ vfprintf (FILE *s, const CHAR_T *format,
 		    memset (&ps, '\0', sizeof (ps));			      \
 									      \
 		    while (str2 != NULL && str2 < strend)		      \
-		      if (__mbsnrtowcs (ignore, &str2, strend - str2, 1024,   \
-					&ps) == (size_t) -1)		      \
+		      if (__mbsnrtowcs (ignore, &str2, strend - str2,	      \
+					ignore_size, &ps) == (size_t) -1)     \
 			{						      \
 			  done = -1;					      \
 			  goto all_done;				      \

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]