[v3] pr 8761 and 7076, caching bits

Jerry Quinn jlquinn@optonline.net
Fri Feb 14 06:11:00 GMT 2003


After doing a couple of revisions to the IO speedups for libstdc++ that have
not gone in yet, here is another round for this patch.

This is the format cache, now renamed the locale cache, on the theory that it
will be more generally applicable.  The dummy reserved functions in the
interface have been removed since they are currently problematic.

Hopefully this is the final version :-)

This patch is against mainline.

2003-02-13  Jerry Quinn  <jlquinn@optonline.net>

	* include/bits/basic_ios.h (__locale_cache::_M_cache): Declare.
	* include/bits/basic_ios.tcc (basic_ios::copyfmt): Rebuild locale cache.
	(basic_ios::imbue): Force locale cache to be built.
	(basic_ios::_M_init): Create and initialize locale cache.
	* include/bits/ios_base.h (__locale_cache_base): Declare.
	(ios_base::_M_locale_cache): New.
	(ios_base::_M_cache): Define.
	* include/bits/locale_facets.h:	(__num_base): Fix comment.  Add
	_S_end.
        (__locale_cache_base,__locale_cache<_CharT>):  New classes.
	(__locale_cache<char>, __locale_cache<wchar_t>): New specializations.
	* include/bits/locale_facets.tcc (num_put::_M_convert_int): Use locale
	cache literal string, grouping flag, thousands separator.
	(__locale_cache<_CharT>::__locale_cache): New.
	(__locale_cache<_CharT>::_M_init): New.
	(__locale_cache<_CharT>::_M_populate): New.
	* src/ios.cc: Clear _M_locale_cache in constructor.
	* src/locale-inst.cc (__locale_cache<char>, __locale_cache<_char_t>):
	New.
	* src/localenames.cc: (__locale_cache<char>::__locale_cache,
	__locale_cache<wchar_t>::__locale_cache): New.



Index: include/bits/basic_ios.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/basic_ios.h,v
retrieving revision 1.16
diff -u -r1.16 basic_ios.h
--- include/bits/basic_ios.h	22 Jan 2003 16:51:51 -0000	1.16
+++ include/bits/basic_ios.h	13 Feb 2003 14:03:24 -0000
@@ -1,6 +1,6 @@
 // Iostreams base classes -*- C++ -*-
 
-// Copyright (C) 1997, 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
+// Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -439,6 +439,10 @@
 
       void
       _M_cache_facets(const locale& __loc);
+
+      __locale_cache<_CharT>&
+      _M_cache()
+      { return *static_cast<__locale_cache<_CharT>*>(_M_locale_cache.get()); }
     };
 } // namespace std
 
Index: include/bits/basic_ios.tcc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/basic_ios.tcc,v
retrieving revision 1.17
diff -u -r1.17 basic_ios.tcc
--- include/bits/basic_ios.tcc	1 Nov 2002 17:30:35 -0000	1.17
+++ include/bits/basic_ios.tcc	13 Feb 2003 14:03:24 -0000
@@ -1,6 +1,6 @@
 // basic_ios locale and locale-related member functions -*- C++ -*-
 
-// Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+// Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -99,6 +99,9 @@
       this->exceptions(__rhs.exceptions());
       
       _M_call_callbacks(copyfmt_event);
+
+      _M_cache()._M_populate(*this);
+
       return *this;
     }
 
@@ -130,6 +133,8 @@
       locale __old(this->getloc());
       ios_base::imbue(__loc);
       _M_cache_facets(__loc);
+      // Force the cache to be rebuilt.
+      _M_cache()._M_populate(*this);
       if (this->rdbuf() != 0)
 	this->rdbuf()->pubimbue(__loc);
       return __old;
@@ -142,6 +147,12 @@
       // NB: This may be called more than once on the same object.
       ios_base::_M_init();
       _M_cache_facets(_M_ios_locale);
+      if (!_M_locale_cache.get())
+	{
+	  this->_M_locale_cache = auto_ptr<__locale_cache_base>(new __locale_cache<_CharT>);
+	  __locale_cache<_CharT>& __fc = (__locale_cache<_CharT>&)_M_cache();
+	  __fc._M_init(*this);
+	}
       _M_tie = 0;
 
       // NB: The 27.4.4.1 Postconditions Table specifies requirements
Index: include/bits/ios_base.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/ios_base.h,v
retrieving revision 1.23
diff -u -r1.23 ios_base.h
--- include/bits/ios_base.h	6 Feb 2003 05:58:10 -0000	1.23
+++ include/bits/ios_base.h	13 Feb 2003 14:03:24 -0000
@@ -146,6 +146,8 @@
 
   enum _Ios_Seekdir { _M_ios_seekdir_end = 1L << 16 };
 
+  class __locale_cache_base;
+
   // 27.4.2  Class ios_base
   /**
    *  @brief  The very top of the I/O class hierarchy.
@@ -430,6 +432,9 @@
     // Members for locale and locale caching.
     locale 		_M_ios_locale;
 
+    // Access to the locale cache.  Cast this to __locale_cache<_CharT>*
+    auto_ptr<__locale_cache_base>	_M_locale_cache;
+
     void 
     _M_init();
 
@@ -635,6 +640,11 @@
 			? _M_word[__ix] : _M_grow_words(__ix);
       return __word._M_pword;
     }
+
+    // Access to the cache.  Not safe to call until basic_ios::_M_init() has
+    // happened.
+    __locale_cache_base&
+    _M_cache() { return *_M_locale_cache; }
 
     // Destructor
     /**
Index: include/bits/locale_facets.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/locale_facets.h,v
retrieving revision 1.55
diff -u -r1.55 locale_facets.h
--- include/bits/locale_facets.h	11 Feb 2003 21:55:48 -0000	1.55
+++ include/bits/locale_facets.h	13 Feb 2003 14:03:25 -0000
@@ -531,8 +531,8 @@
   class __num_base 
   {
   public:
-    // NB: Code depends on the order of _M_atoms_out elements.
-    // Below are the indices into _M_atoms_out.
+    // NB: Code depends on the order of _S_atoms_out elements.
+    // Below are the indices into _S_atoms_out.
     enum 
       {  
         _S_minus, 
@@ -543,14 +543,15 @@
         _S_digits_end = _S_digits + 16,
         _S_udigits = _S_digits_end,  
         _S_udigits_end = _S_udigits + 16,
-        _S_e = _S_digits + 14, // For scientific notation, 'e'
-        _S_E = _S_udigits + 14 // For scientific notation, 'E'
+        _S_e = _S_digits + 14,  // For scientific notation, 'e'
+        _S_E = _S_udigits + 14, // For scientific notation, 'E'
+	_S_end = _S_udigits_end
       };
     
-    // A list of valid numeric literals for output. 
-    // This array contains the chars after having been passed through
-    // the current locale's ctype<_CharT>.widen().
-    // For the standard "C" locale, this is 
+    // A list of valid numeric literals for output.  This array contains chars
+    // that will be passed through the current locale's ctype<_CharT>.widen()
+    // and then used to render numbers.
+    // For the standard "C" locale, this is
     // "-+xX0123456789abcdef0123456789ABCDEF".
     static const char* _S_atoms_out;
 
@@ -1931,6 +1932,88 @@
     inline _CharT 
     tolower(_CharT __c, const locale& __loc)
     { return use_facet<ctype<_CharT> >(__loc).tolower(__c); }
+
+
+  // Pseudo pointer machinery for transparent casting from void* to
+  // __locale_cache<_CharT>
+  template<typename _CharT>
+    class __locale_cache;
+
+  class __locale_cache_base
+  {
+  public:
+    virtual
+    ~__locale_cache_base() {}
+  };
+
+  // __locale_cache holds the information extracted from the numpunct<> and
+  // moneypunct<> facets in a form optimized for parsing and formatting.  It
+  // is stored as a member of basic_ios and accessed via a void* pointer in
+  // the ios_base object passed to the _get and _put facets.
+
+  // Its intent is to avoid the cost of creating a locale object and
+  // calling the virtual functions in locale facets.
+  template<typename _CharT>
+    class __locale_cache : public __locale_cache_base
+    {
+      // Types:
+      typedef _CharT               	char_type;
+      typedef char_traits<_CharT>       traits_type;
+      typedef basic_string<_CharT>	string_type;
+
+
+    public: 
+      // Data Members:
+
+      // A list of valid numeric literals: for the standard "C" locale, this
+      // is "-+xX0123456789abcdef0123456789ABCDEF".  This array contains the
+      // chars after having been passed through the current locale's
+      // ctype<_CharT>.widen().
+      _CharT                    _M_literals[__num_base::_S_udigits_end];
+
+     
+      // The sign used to separate decimal values: for standard US
+      // locales, this would usually be: "."
+      // Abstracted from numpunct::decimal_point().
+      _CharT                    _M_decimal_point;
+
+      // The sign used to separate groups of digits into smaller
+      // strings that the eye can parse with less difficulty: for
+      // standard US locales, this would usually be: ","
+      // Abstracted from numpunct::thousands_sep().
+      _CharT                    _M_thousands_sep;
+      
+      // However the US's "false" and "true" are translated.
+      // From numpunct::truename() and numpunct::falsename(), respectively.
+      string_type 		_M_truename;
+      string_type 		_M_falsename;
+
+      // If we are checking groupings. This should be equivalent to 
+      // numpunct::groupings().size() != 0
+      bool                      _M_use_grouping;
+
+      // If we are using numpunct's groupings, this is the current grouping
+      // string in effect (from numpunct::grouping()).
+      string                    _M_grouping;
+
+      __locale_cache();
+
+      __locale_cache& operator=(const __locale_cache& __fc);
+
+
+      // Make sure the cache is built before the first use.
+      void _M_init(ios_base&);
+
+      void 
+      _M_populate(ios_base&);
+    };
+
+  template<>
+    __locale_cache<char>::__locale_cache();
+#ifdef _GLIBCPP_USE_WCHAR_T
+  template<>
+    __locale_cache<wchar_t>::__locale_cache();
+#endif
 } // namespace std
 
 #endif
Index: include/bits/locale_facets.tcc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/locale_facets.tcc,v
retrieving revision 1.89
diff -u -r1.89 locale_facets.tcc
--- include/bits/locale_facets.tcc	11 Feb 2003 21:55:48 -0000	1.89
+++ include/bits/locale_facets.tcc	13 Feb 2003 14:03:25 -0000
@@ -768,20 +768,13 @@
       _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill, 
 		     _ValueT __v) const
       {
-	// Buildup list of digits given the current ctype.
-	_CharT __lit[_S_udigits_end];
-	const locale __loc = __io.getloc();
-	if (__builtin_expect(has_facet< ctype<_CharT> >(__loc), true))
-	  {
-	    const ctype<_CharT>& __ct = use_facet< ctype<_CharT> >(__loc);
-	    __ct.widen(_S_atoms_out, _S_atoms_out + _S_udigits_end, __lit);
-	  }
+	__locale_cache<_CharT>& __fc = (__locale_cache<_CharT>&) __io._M_cache();
+	_CharT* __lit = __fc._M_literals;
 
 	// Long enough to hold hex, dec, and octal representations.
 	int __ilen = 4 * sizeof(_ValueT);
 	_CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
 							     * __ilen));
-
 	// [22.2.2.2.2] Stage 1, numeric conversion to character.
 	// Result is returned right-justified in the buffer.
 	int __len;
@@ -790,15 +783,13 @@
 	
 	// Add grouping, if necessary. 
 	_CharT* __cs2;
-	const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
-	const string __grouping = __np.grouping();
-	if (__grouping.size())
+	if (__fc._M_use_grouping)
 	  {
 	    // Grouping can add (almost) as many separators as the
 	    // number of digits, but no more.
 	    __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
 							  * __len * 2));
-	    _M_group_int(__grouping, __np.thousands_sep(), __io, 
+	    _M_group_int(__fc._M_grouping, __fc._M_thousands_sep, __io, 
 			 __cs2, __cs, __len);
 	    __cs = __cs2;
 	  }
@@ -2215,6 +2206,62 @@
       while (__first != __last);
       return __s;
     }
+
+  template<typename _CharT>
+    inline
+    __locale_cache<_CharT>::__locale_cache()
+    : _M_use_grouping(false)
+    { }
+
+  // Cache initialization
+  template<typename _CharT>
+    inline
+    void
+    __locale_cache<_CharT>::_M_init(ios_base& __io)
+    { _M_populate(__io); }
+
+  // char and wchar_t specializations start out valid, so no need to call
+  // _M_populate
+  template<>
+    inline
+    void
+    __locale_cache<char>::_M_init(ios_base&)
+    { }
+#ifdef _GLIBCPP_USE_WCHAR_T
+  template<>
+    inline
+    void
+    __locale_cache<wchar_t>::_M_init(ios_base&)
+    { }
+#endif
+
+
+  template<typename _CharT>
+    void
+    __locale_cache<_CharT>::_M_populate(ios_base& __io)
+    {
+      static const char _S_numeric_literals[] = "-+xX0123456789abcdef0123456789ABCDEF";
+      static const int _S_literal_count = sizeof(_S_numeric_literals) - 1;
+
+      locale __loc = __io.getloc();
+      if (__builtin_expect(has_facet<numpunct<_CharT> >(__loc), true))
+	{
+	  numpunct<_CharT> const& __np = use_facet<numpunct<_CharT> >(__loc);
+	  _M_falsename = __np.falsename();
+	  _M_truename = __np.truename();
+	  _M_thousands_sep = __np.thousands_sep();
+	  _M_decimal_point = __np.decimal_point();
+	  _M_grouping = __np.grouping();
+	  _M_use_grouping = _M_grouping.size() != 0 && _M_grouping.data()[0] != 0;
+	}
+      if (__builtin_expect(has_facet< ctype<_CharT> >(__loc), true))
+	{
+	  ctype<_CharT> const& __ct = use_facet< ctype<_CharT> >(__loc);
+	  __ct.widen(__num_base::_S_atoms_out,
+		     __num_base::_S_atoms_out + __num_base::_S_end, _M_literals);
+	}
+    }
+
 
   // Inhibit implicit instantiations for required instantiations,
   // which are defined via explicit instantiations elsewhere.  
Index: src/ios.cc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/src/ios.cc,v
retrieving revision 1.34
diff -u -r1.34 ios.cc
--- src/ios.cc	11 Feb 2003 10:43:49 -0000	1.34
+++ src/ios.cc	13 Feb 2003 14:03:27 -0000
@@ -1,6 +1,6 @@
 // Iostreams base classes -*- C++ -*-
 
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -302,7 +302,7 @@
     return __old;
   }
 
-  ios_base::ios_base() : _M_callbacks(0), _M_word(0)
+  ios_base::ios_base() : _M_callbacks(0), _M_word(0), _M_locale_cache(0)
   {
     // Do nothing: basic_ios::init() does it.  
     // NB: _M_callbacks and _M_word must be zero for non-initialized
Index: src/locale-inst.cc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/src/locale-inst.cc,v
retrieving revision 1.36
diff -u -r1.36 locale-inst.cc
--- src/locale-inst.cc	11 Feb 2003 21:55:49 -0000	1.36
+++ src/locale-inst.cc	13 Feb 2003 14:03:27 -0000
@@ -46,6 +46,7 @@
   template class moneypunct_byname<char, true>;
   template class money_get<char, istreambuf_iterator<char> >;
   template class money_put<char, ostreambuf_iterator<char> >;
+  template class __locale_cache<char>;
 
 #ifdef _GLIBCPP_USE_WCHAR_T
   template class moneypunct<wchar_t, false>;
@@ -54,6 +55,7 @@
   template class moneypunct_byname<wchar_t, true>;
   template class money_get<wchar_t, istreambuf_iterator<wchar_t> >;
   template class money_put<wchar_t, ostreambuf_iterator<wchar_t> >;
+  template class __locale_cache<wchar_t>;
 #endif
 
   // numpunct, numpunct_byname, num_get, and num_put
Index: src/localename.cc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/src/localename.cc,v
retrieving revision 1.35
diff -u -r1.35 localename.cc
--- src/localename.cc	1 Feb 2003 16:37:20 -0000	1.35
+++ src/localename.cc	13 Feb 2003 14:03:29 -0000
@@ -1,4 +1,4 @@
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -350,4 +350,28 @@
 	  }
       }
   }
+
+  template<>
+    __locale_cache<char>::__locale_cache()
+    : _M_decimal_point('.'), _M_thousands_sep(','),
+      _M_truename("true"), _M_falsename("false"), _M_use_grouping(false)
+    {
+      static const char _S_numeric_literals[] = "-+xX0123456789abcdef0123456789ABCDEF";
+      static const int _S_literal_count = sizeof(_S_numeric_literals) - 1;
+
+      copy(_S_numeric_literals, _S_numeric_literals + _S_literal_count, _M_literals);
+    }
+ 
+#ifdef  _GLIBCPP_USE_WCHAR_T
+  template<>
+    __locale_cache<wchar_t>::__locale_cache()
+    : _M_decimal_point(L'.'), _M_thousands_sep(L','),
+      _M_truename(L"true"), _M_falsename(L"false"), _M_use_grouping(false)
+    {
+      static const wchar_t _S_numeric_literals[] = L"-+xX0123456789abcdef0123456789ABCDEF";
+      static const int _S_literal_count = (sizeof(_S_numeric_literals) - 1) / sizeof(wchar_t);
+
+      copy(_S_numeric_literals, _S_numeric_literals + _S_literal_count, _M_literals);
+    }
+#endif
 } // namespace std



More information about the Libstdc++ mailing list