This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [v3] locale cache PR 7076,8761
This is locale cache for 3.3, take 3. It passes make check and make
check-abi on i686-pc-gnu-linux.
I found that the new storage in globals.cc didn't have to be exported
at all to keep check-abi happy. This includes facet_cache_vec,
locale_cache_np_c, and locale_cache_np_w. Is this OK or do I need to
add these symbols to the linker map? Aside from this, I think it's
finally ready to go.
Jerry
2003-07-05 Benjamin Kosnik <bkoz@redhat.com>
Jerry Quinn <jlquinn@optonline.net>
* include/bits/ios_base.h (ios_base::_M_getloc): Return reference
to the imbued locale.
* include/bits/locale_classes.h
(__locale_cache_base,__locale_cache): Declare.
(locale,locale::_Impl): Befriend __use_cache.
(locale::_Impl::_M_get_cache): New function.
(locale::_Impl::_M_install_cache): New function.
* include/bits/locale_facets.h (__locale_cache): Declare.
(numpunct): Befriend __locale_cache.
(__locale_cache_base): New class.
(__locale_cache): New class.
* include/bits/locale_facets.tcc (__use_cache): New function.
(num_put::_M_convert_int,_M_convert_float,do_put): Use it.
Use cache data members in place of calls to facet.
(num_put::_M_convert_int): Use _M_getloc.
(num_put::_M_convert_float): Use _M_getloc.
(__locale_cache::__locale_cache(locale&): New.
(__locale_cache::__locale_cache(locale&,bool)): New.
* src/globals.cc (facet_cache_vec): New.
(locale_cache_np_c, locale_cache_np_w): New.
* src/locale-inst.cc
(__locale_cache<numpunct<char> >): Define.
(__locale_cache<numpunct<wchar_t> >): Define.
(__use_cache<numpunct<char> >): Define.
(__use_cache<numpunct<wchar_t> >): Define.
* src/localename.cc (facet_cache_vec): Declare.
(locale_cache_np_c, locale_cache_np_w): Declare.
(locale::_Impl::~Impl): Destroy caches.
(locale::_Impl::Impl): Initialize cache storage. Fill in
static caches.
(locale::_Impl::_M_install_facet): Expand cache storage.
Index: include/bits/ios_base.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/ios_base.h,v
retrieving revision 1.21.2.6
diff -u -r1.21.2.6 ios_base.h
--- include/bits/ios_base.h 2 May 2003 01:08:04 -0000 1.21.2.6
+++ include/bits/ios_base.h 5 Jul 2003 16:22:50 -0000
@@ -604,7 +604,7 @@
/**
* @brief Locale access
- * @return The locale currently in effect.
+ * @return A copy of the current locale.
*
* If @c imbue(loc) has previously been called, then this function
* returns @c loc. Otherwise, it returns a copy of @c std::locale(),
@@ -612,6 +612,16 @@
*/
inline locale
getloc() const { return _M_ios_locale; }
+
+ /**
+ * @brief Locale access
+ * @return A reference to the current locale.
+ *
+ * Like getloc above, but returns a reference instead of
+ * generating a copy.
+ */
+ inline const locale&
+ _M_getloc() const { return _M_ios_locale; }
// [27.4.2.5] ios_base storage functions
/**
Index: include/bits/locale_classes.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/locale_classes.h,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 locale_classes.h
--- include/bits/locale_classes.h 23 Jan 2003 18:56:17 -0000 1.1.2.2
+++ include/bits/locale_classes.h 5 Jul 2003 16:22:50 -0000
@@ -49,6 +49,9 @@
namespace std
{
+ class __locale_cache_base;
+ template<typename _Facet> class __locale_cache;
+
// 22.1.1 Class locale
class locale
{
@@ -72,6 +75,10 @@
friend bool
has_facet(const locale&) throw();
+ template<typename _Facet>
+ friend const __locale_cache<_Facet>&
+ __use_cache(const locale&);
+
// Category values:
// NB: Order must match _S_facet_categories definition in locale.cc
static const category none = 0;
@@ -196,6 +203,10 @@
friend bool
has_facet(const locale&) throw();
+ template<typename _Facet>
+ friend const __locale_cache<_Facet>&
+ __use_cache(const locale&);
+
private:
// Data Members.
_Atomic_word _M_references;
@@ -266,6 +277,25 @@
inline void
_M_init_facet(_Facet* __facet)
{ _M_install_facet(&_Facet::id, __facet); }
+
+ // Retrieve the cache at __index. 0 is returned if the cache is
+ // missing. Cache is actually located at __index +
+ // _M_facets_size. __index must be < _M_facets_size.
+ inline __locale_cache_base*
+ _M_get_cache(size_t __index)
+ {
+ return (__locale_cache_base*)_M_facets[__index + _M_facets_size];
+ }
+
+ // Save the supplied cache at __id. Assumes _M_get_cache has been
+ // called.
+ void
+ _M_install_cache(__locale_cache_base* __cache, int __id)
+ {
+ _M_facets[__id + _M_facets_size] =
+ reinterpret_cast<locale::facet*>(__cache);
+ }
+
};
template<typename _Facet>
Index: include/bits/locale_facets.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/locale_facets.h,v
retrieving revision 1.49.4.7
diff -u -r1.49.4.7 locale_facets.h
--- include/bits/locale_facets.h 2 May 2003 01:08:04 -0000 1.49.4.7
+++ include/bits/locale_facets.h 5 Jul 2003 16:22:51 -0000
@@ -581,6 +581,9 @@
template<typename _CharT>
+ class __locale_cache;
+
+ template<typename _CharT>
class numpunct : public locale::facet
{
public:
@@ -588,6 +591,8 @@
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
+ friend class __locale_cache<numpunct<_CharT> >;
+
static locale::id id;
private:
@@ -1953,6 +1958,93 @@
inline _CharT
tolower(_CharT __c, const locale& __loc)
{ return use_facet<ctype<_CharT> >(__loc).tolower(__c); }
+
+ /**
+ * @if maint
+ * __locale_cache objects hold information extracted from facets in
+ * a form optimized for parsing and formatting. They are stored in
+ * a locale's facet array and accessed via __use_cache<_Facet>.
+ *
+ * The intent twofold: to avoid the costs of creating a locale
+ * object and to avoid calling the virtual functions in a locale's
+ * facet to look up data.
+ * @endif
+ */
+ class __locale_cache_base
+ {
+ friend class std::locale::_Impl;
+ friend class locale;
+
+ public:
+ virtual
+ ~__locale_cache_base() { }
+
+ };
+
+ // This template doesn't really get used for anything except a
+ // placeholder for specializations
+ template<typename _Facet>
+ class __locale_cache : public __locale_cache_base
+ {
+ // ctor
+ __locale_cache(const locale&) {}
+ };
+
+ template<typename _CharT>
+ class __locale_cache<numpunct<_CharT> > : public __locale_cache_base
+ {
+ // Types:
+ typedef _CharT char_type;
+ typedef char_traits<_CharT> traits_type;
+ typedef basic_string<_CharT> string_type;
+
+ public:
+ // Data Members:
+
+ // 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.
+ const _CharT* _M_truename;
+ const _CharT* _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()).
+ const char* _M_grouping;
+
+ // 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().
+
+ // Copied here from __locale_cache<ctype> to save multiple cache
+ // access in num_put functions.
+ _CharT _M_atoms_out[__num_base::_S_end];
+
+ // ctor
+ __locale_cache(const locale& __loc);
+ __locale_cache(const locale& __loc, bool);
+
+ ~__locale_cache()
+ {
+ delete [] _M_truename;
+ delete [] _M_falsename;
+ delete [] _M_grouping;
+ }
+ };
} // namespace std
#endif
Index: include/bits/locale_facets.tcc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/locale_facets.tcc,v
retrieving revision 1.82.4.11
diff -u -r1.82.4.11 locale_facets.tcc
--- include/bits/locale_facets.tcc 5 Jul 2003 03:36:54 -0000 1.82.4.11
+++ include/bits/locale_facets.tcc 5 Jul 2003 16:22:52 -0000
@@ -86,6 +86,23 @@
return (__i < __loc._M_impl->_M_facets_size && __facets[__i]);
}
+ // Routine to access a cache for the locale. If the cache didn't
+ // exist before, it gets constructed on the fly.
+ template<typename _Facet>
+ inline const __locale_cache<_Facet>&
+ __use_cache(const locale& __loc)
+ {
+ size_t __i = _Facet::id._M_id();
+ if (__builtin_expect(__i >= __loc._M_impl->_M_facets_size,false))
+ __throw_bad_cast();
+ __locale_cache_base* __cache = __loc._M_impl->_M_get_cache(__i);
+ if (__builtin_expect(!__cache, false))
+ {
+ __cache = new __locale_cache<_Facet>(__loc);
+ __loc._M_impl->_M_install_cache(__cache, __i);
+ }
+ return static_cast<const __locale_cache<_Facet>&>(*__cache);
+ }
// Stage 1: Determine a conversion specifier.
template<typename _CharT, typename _InIter>
@@ -769,19 +786,16 @@
_M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill,
_ValueT __v) const
{
+ typedef numpunct<_CharT> __facet_type;
+ typedef __locale_cache<numpunct<_CharT> > __cache_type;
+ const locale& __loc = __io._M_getloc();
+ const __cache_type& __lc = __use_cache<__facet_type>(__loc);
+ const _CharT* __lit = __lc._M_atoms_out;
+
// Long enough to hold hex, dec, and octal representations.
int __ilen = 4 * sizeof(_ValueT);
_CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
* __ilen));
- // Buildup list of digits given the current ctype.
- _CharT __lit[_S_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_end, __lit);
- }
-
// [22.2.2.2.2] Stage 1, numeric conversion to character.
// Result is returned right-justified in the buffer.
int __len;
@@ -789,16 +803,14 @@
__cs = __cs + __ilen - __len;
// Add grouping, if necessary.
- const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
- const string __grouping = __np.grouping();
_CharT* __cs2;
- if (__grouping.size())
+ if (__lc._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(__lc._M_grouping, __lc._M_thousands_sep, __io,
__cs2, __cs, __len);
__cs = __cs2;
}
@@ -880,6 +892,11 @@
else if (__prec < static_cast<streamsize>(0))
__prec = static_cast<streamsize>(6);
+ typedef numpunct<_CharT> __facet_type;
+ typedef __locale_cache<numpunct<_CharT> > __cache_type;
+ const locale __loc = __io._M_getloc();
+ const __cache_type& __lc = __use_cache<__facet_type>(__loc);
+
// [22.2.2.2.2] Stage 1, numeric conversion to character.
int __len;
// Long enough for the max format spec.
@@ -923,7 +940,6 @@
// [22.2.2.2.2] Stage 2, convert to char_type, using correct
// numpunct.decimal_point() values for '.' and adding grouping.
- const locale __loc = __io.getloc();
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
_CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
@@ -931,23 +947,21 @@
__ctype.widen(__cs, __cs + __len, __ws);
// Replace decimal point.
- const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
const _CharT __cdec = __ctype.widen('.');
- const _CharT __dec = __np.decimal_point();
+ const _CharT __dec = __lc._M_decimal_point;
const _CharT* __p;
if (__p = char_traits<_CharT>::find(__ws, __len, __cdec))
__ws[__p - __ws] = __dec;
// Add grouping, if necessary.
_CharT* __ws2;
- const string __grouping = __np.grouping();
- if (__grouping.size())
+ if (__lc._M_use_grouping)
{
// Grouping can add (almost) as many separators as the
// number of digits, but no more.
- __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
+ __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
* __len * 2));
- _M_group_float(__grouping, __np.thousands_sep(), __p,
+ _M_group_float(__lc._M_grouping, __lc._M_thousands_sep, __p,
__ws2, __ws, __len);
__ws = __ws2;
}
@@ -981,14 +995,17 @@
}
else
{
- locale __loc = __io.getloc();
- const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+ typedef numpunct<_CharT> __facet_type;
+ typedef __locale_cache<numpunct<_CharT> > __cache_type;
+ const locale __loc = __io._M_getloc();
+ const __cache_type& __lc = __use_cache<__facet_type>(__loc);
+
typedef basic_string<_CharT> __string_type;
__string_type __name;
if (__v)
- __name = __np.truename();
+ __name = __lc._M_truename;
else
- __name = __np.falsename();
+ __name = __lc._M_falsename;
const _CharT* __cs = __name.c_str();
int __len = __name.size();
@@ -2443,6 +2460,69 @@
return __write(__s, __ws, __len);
}
#endif
+
+ template<typename _CharT>
+ __locale_cache<numpunct<_CharT> >::__locale_cache(const locale& __loc)
+ : _M_truename(0), _M_falsename(0), _M_use_grouping(false),
+ _M_grouping(0)
+ {
+ if (has_facet<numpunct<_CharT> >(__loc))
+ {
+ const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+ _M_decimal_point = __np.decimal_point();
+ _M_thousands_sep = __np.thousands_sep();
+
+ string_type __false = __np.falsename();
+ _CharT* __falsename = new _CharT[__false.length() + 1];
+ __false.copy(__falsename, __false.length());
+ __falsename[__false.length()] = _CharT();
+ _M_falsename = __falsename;
+
+ string_type __true = __np.truename();
+ _CharT* __truename = new _CharT[__true.length() + 1];
+ __true.copy(__truename, __true.length());
+ __truename[__true.length()] = _CharT();
+ _M_truename = __truename;
+
+ string __grouping = __np.grouping();
+ char* __group = new char[__grouping.length() + 1];
+ __grouping.copy(__group, __grouping.length());
+ __group[__grouping.length()] = 0;
+ _M_grouping = __group;
+
+ _M_use_grouping = __grouping.length() != 0
+ && __grouping.data()[0] != 0;
+ }
+
+ if (has_facet<ctype<_CharT> >(__loc))
+ {
+ const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
+ __ct.widen(__num_base::_S_atoms_out,
+ __num_base::_S_atoms_out + __num_base::_S_end,
+ _M_atoms_out);
+ }
+ }
+
+ // Static locale cache initialization. Only instantiated with char
+ // and wchar_t, so no need to check has_facet.
+ template<typename _CharT>
+ __locale_cache<numpunct<_CharT> >::
+ __locale_cache(const locale& __loc, bool)
+ {
+ // Grab pointers to numpunct static strings
+ const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+ _M_thousands_sep = __np._M_thousands_sep;
+ _M_decimal_point = __np._M_decimal_point;
+ _M_falsename = __np._M_falsename;
+ _M_truename = __np._M_truename;
+ _M_grouping = __np._M_grouping;
+ _M_use_grouping = false;
+
+ const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
+ __ct.widen(__num_base::_S_atoms_out,
+ __num_base::_S_atoms_out + __num_base::_S_end,
+ _M_atoms_out);
+ }
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
Index: src/globals.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/globals.cc,v
retrieving revision 1.12.4.3
diff -u -r1.12.4.3 globals.cc
--- src/globals.cc 2 May 2003 01:08:04 -0000 1.12.4.3
+++ src/globals.cc 5 Jul 2003 16:22:52 -0000
@@ -84,6 +84,11 @@
fake_facet_vec facet_vec[_GLIBCPP_NUM_FACETS];
_GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx9facet_vecE, _ZSt9facet_vec, GLIBCPP_3.2)
+ // To support combined facets and caches in facet array
+ typedef char fake_facet_cache_vec[sizeof(locale::facet*)]
+ __attribute__ ((aligned(__alignof__(locale::facet*))));
+ fake_facet_cache_vec facet_cache_vec[2 * _GLIBCPP_NUM_FACETS];
+
typedef char fake_ctype_c[sizeof(std::ctype<char>)]
__attribute__ ((aligned(__alignof__(std::ctype<char>))));
fake_ctype_c ctype_c;
@@ -222,6 +227,17 @@
__attribute__ ((aligned(__alignof__(messages<wchar_t>))));
fake_messages_w messages_w;
_GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx10messages_wE, _ZSt10messages_w, GLIBCPP_3.2)
+#endif
+
+ // Storage for static C locale caches
+ typedef char fake_locale_cache_np_c[sizeof(std::__locale_cache<numpunct<char> >)]
+ __attribute__ ((aligned(__alignof__(std::__locale_cache<numpunct<char> >))));
+ fake_locale_cache_np_c locale_cache_np_c;
+
+#ifdef _GLIBCPP_USE_WCHAR_T
+ typedef char fake_locale_cache_np_w[sizeof(std::__locale_cache<numpunct<wchar_t> >)]
+ __attribute__ ((aligned(__alignof__(std::__locale_cache<numpunct<wchar_t> >))));
+ fake_locale_cache_np_w locale_cache_np_w;
#endif
typedef char fake_filebuf[sizeof(stdio_filebuf<char>)]
Index: src/locale-inst.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/locale-inst.cc,v
retrieving revision 1.35.4.4
diff -u -r1.35.4.4 locale-inst.cc
--- src/locale-inst.cc 2 May 2003 01:08:04 -0000 1.35.4.4
+++ src/locale-inst.cc 5 Jul 2003 16:22:52 -0000
@@ -45,6 +45,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<numpunct<char> >;
#ifdef _GLIBCPP_USE_WCHAR_T
template class moneypunct<wchar_t, false>;
@@ -53,6 +54,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<numpunct<wchar_t> >;
#endif
// numpunct, numpunct_byname, num_get, and num_put
@@ -461,6 +463,17 @@
template
bool
has_facet<messages<wchar_t> >(const locale&);
+#endif
+
+ // __use_cache
+ template
+ const __locale_cache<numpunct<char> >&
+ __use_cache<numpunct<char> >(const locale& __loc);
+
+#ifdef _GLIBCPP_USE_WCHAR_T
+ template
+ const __locale_cache<numpunct<wchar_t> >&
+ __use_cache<numpunct<wchar_t> >(const locale& __loc);
#endif
// locale
Index: src/localename.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/localename.cc,v
retrieving revision 1.33.2.3
diff -u -r1.33.2.3 localename.cc
--- src/localename.cc 25 Apr 2003 18:18:05 -0000 1.33.2.3
+++ src/localename.cc 5 Jul 2003 16:22:52 -0000
@@ -36,6 +36,7 @@
// Defined in globals.cc.
extern locale::facet* facet_vec[_GLIBCPP_NUM_FACETS];
+ extern locale::facet* facet_cache_vec[2 * _GLIBCPP_NUM_FACETS];
extern char* facet_name[6 + _GLIBCPP_NUM_CATEGORIES];
extern std::ctype<char> ctype_c;
@@ -68,6 +69,11 @@
extern time_put<wchar_t> time_put_w;
extern std::messages<wchar_t> messages_w;
#endif
+
+ extern std::__locale_cache<numpunct<char> > locale_cache_np_c;
+#ifdef _GLIBCPP_USE_WCHAR_T
+ extern std::__locale_cache<numpunct<wchar_t> > locale_cache_np_w;
+#endif
} // namespace __gnu_cxx
namespace std
@@ -77,9 +83,13 @@
locale::_Impl::
~_Impl() throw()
{
+ // Clean up facets, then caches. No cache refcounts for now.
for (size_t __i = 0; __i < _M_facets_size; ++__i)
if (_M_facets[__i])
_M_facets[__i]->_M_remove_reference();
+ for (size_t __i = _M_facets_size; __i < 2*_M_facets_size; ++__i)
+ if (_M_facets[__i])
+ delete (__locale_cache_base*)_M_facets[__i];
delete [] _M_facets;
for (size_t __i = 0;
@@ -94,8 +104,9 @@
{
try
{
- _M_facets = new facet*[_M_facets_size];
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
+ // Space for facets and matching caches
+ _M_facets = new facet*[2*_M_facets_size];
+ for (size_t __i = 0; __i < 2*_M_facets_size; ++__i)
_M_facets[__i] = 0;
}
catch(...)
@@ -129,9 +140,10 @@
locale::facet::_S_create_c_locale(__cloc, __s);
try
- {
- _M_facets = new facet*[_M_facets_size];
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
+ {
+ // Space for facets and matching caches
+ _M_facets = new facet*[2*_M_facets_size];
+ for (size_t __i = 0; __i < 2*_M_facets_size; ++__i)
_M_facets[__i] = 0;
}
catch(...)
@@ -214,8 +226,9 @@
locale::facet::_S_create_c_locale(locale::facet::_S_c_locale,
locale::facet::_S_c_name);
- _M_facets = new(&facet_vec) facet*[_M_facets_size];
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
+ // Space for facets and matching caches
+ _M_facets = new(&facet_cache_vec) facet*[2*_M_facets_size];
+ for (size_t __i = 0; __i < 2*_M_facets_size; ++__i)
_M_facets[__i] = 0;
// Name all the categories.
@@ -263,6 +276,25 @@
_M_init_facet(new (&time_put_w) time_put<wchar_t>(1));
_M_init_facet(new (&messages_w) std::messages<wchar_t>(1));
#endif
+
+ // Initialize the static locale caches for C locale.
+
+ locale ltmp(this); // Doesn't bump refcount
+ _M_add_reference(); // Bump so destructor doesn't trash us
+
+ // These need to be built in static allocated memory. There must
+ // be a better way to do this!
+ __locale_cache<numpunct<char> >* __lc =
+ new (&locale_cache_np_c) __locale_cache<numpunct<char> >(ltmp, true);
+ _M_facets[numpunct<char>::id._M_id() + _M_facets_size] =
+ reinterpret_cast<locale::facet*>(__lc);
+
+#ifdef _GLIBCPP_USE_WCHAR_T
+ __locale_cache<numpunct<wchar_t> >* __wlc =
+ new (&locale_cache_np_w) __locale_cache<numpunct<wchar_t> >(ltmp, true);
+ _M_facets[numpunct<wchar_t>::id._M_id() + _M_facets_size] =
+ reinterpret_cast<locale::facet*>(__wlc);
+#endif
}
void
@@ -322,11 +354,16 @@
facet** __old = _M_facets;
facet** __new;
const size_t __new_size = __index + 4;
- __new = new facet*[__new_size];
+ __new = new facet*[2 * __new_size];
for (size_t __i = 0; __i < _M_facets_size; ++__i)
__new[__i] = _M_facets[__i];
for (size_t __i2 = _M_facets_size; __i2 < __new_size; ++__i2)
__new[__i2] = 0;
+ // Also copy caches and clear extra space
+ for (size_t __i = 0; __i < _M_facets_size; ++__i)
+ __new[__i + __new_size] = _M_facets[__i + _M_facets_size];
+ for (size_t __i2 = _M_facets_size; __i2 < __new_size; ++__i2)
+ __new[__i2 + __new_size] = 0;
_M_facets_size = __new_size;
_M_facets = __new;