This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


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

Re: [v3] libstdc++/28277: collate bits


Paolo Carlini wrote:

2006-07-11 Paolo Carlini <pcarlini@suse.de>

PR libstdc++/28277 (partial: collate bits)
* include/bits/locale_facets.tcc (collate<>::do_transform(
const _CharT*, const _CharT*)): Avoid __builtin_alloca with no
limit; also avoid multiple calls (in a loop).


Actually, we can go with something much simpler (and always correct). Tested x86-linux, committed to mainline.

Paolo.

///////////////////
2006-07-11  Paolo Carlini  <pcarlini@suse.de>

	* include/bits/locale_facets.tcc (collate<>::do_transform(
	const _CharT*, const _CharT*)): Simplify previous fix for
	libstdc++/28277, always allocate memory dynamically.
Index: include/bits/locale_facets.tcc
===================================================================
--- include/bits/locale_facets.tcc	(revision 115354)
+++ include/bits/locale_facets.tcc	(working copy)
@@ -2457,28 +2457,18 @@
     {
       string_type __ret;
 
-      // Use alloca for an _M_transform temporary buffer up to an arbitrary,
-      // but limited, asize, to avoid abusing the stack.  Otherwise fall back
-      // to dynamic memory allocation.  This means splitting the computation
-      // itself in hunks:  a size <= 8k (thus <= 16k asize) appear sufficient
-      // for optimal performance.
-      const size_t __size = std::min(size_t(__hi - __lo), size_t(8192));
-      const size_t __asize = 2 * __size;
+      // strxfrm assumes zero-terminated strings so we make a copy
+      const string_type __str(__lo, __hi);
 
-      size_t __len = __asize;
+      const _CharT* __p = __str.c_str();
+      const _CharT* __pend = __str.data() + __str.length();
 
-      _CharT* __c =
-	static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len));
+      size_t __len = (__hi - __lo) * 2;
 
-      for (size_t __hunk = __size; __lo < __hi;
-	   __lo += __hunk, __hunk = std::min(size_t(__hi - __lo), __hunk))
-	{
-	  // strxfrm assumes zero-terminated strings so we make a copy
-	  const string_type __str(__lo, __lo + __hunk);
+      _CharT* __c = new _CharT[__len];
 
-	  const _CharT* __p = __str.c_str();
-	  const _CharT* __pend = __str.data() + __hunk;
-
+      try
+	{
 	  // strxfrm stops when it sees a nul character so we break
 	  // the string into zero-terminated substrings and pass those
 	  // to strxfrm.
@@ -2490,9 +2480,8 @@
 	      // correct size.
 	      if (__res >= __len)
 		{
-		  if (__len > __asize)
-		    delete [] __c;
 		  __len = __res + 1;
+		  delete [] __c, __c = 0;
 		  __c = new _CharT[__len];
 		  __res = _M_transform(__c, __p, __len);
 		}
@@ -2506,9 +2495,13 @@
 	      __ret.push_back(_CharT());
 	    }
 	}
+      catch(...)
+	{
+	  delete [] __c;
+	  __throw_exception_again;
+	}
 
-      if (__len > __asize)
-	delete [] __c;
+      delete [] __c;
 
       return __ret;
     }

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