This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: zero-alloc cache (was Re: [v3] Fix PR libstdc++/10276)
B. Kosnik writes:
> Jerry, I'm taking this as your white flag.
I think I'm not done yet, but will certainly accept help, since my
work rate isn't very fast.
> >In addition, there are strings in the cache. How do these avoid
> >allocating? There is also another issue flagged by valgrind, but I
> >don't know what it is from:
>
> This is the internal string memory managment. You'll need to use an
> allocator in your strings that is pre-allocated, or not use strings.
Which do you recommend here? I'm not familiar with custom
allocators. I also see potential difficulties, because you probably
only want the preallocated strings for the static standard streams,
no?
I'm going to work up a char buffer approach for now.
Here's a solution for the _Callback_list objects. It seems to work,
but it's not pretty. This is against 3.3.
Opinions?
2003-04-29 Jerry Quinn <jlquinn at optonline dot net>
* config/linker-map.gnu (basic_ios::init(basic_streambuf,
__locale_cache)): Export new symbol.
* include/bits/basic_ios.[h,tcc] (basic_ios::init(basic_streambuf,
__locale_cache)): Replace default argument with overloaded
function.
* include/bits/ios_base.h (ios_base): Make friends with
__locale_cache_base.
* include/bits/locale_facets.h
(__locale_cache_base::_M_static_cblist): New member.
* include/std/std_istream.h
(basic_istream::basic_istream(__streambuf_type*,
__locale_cache*)): New.
* include/std/std_ostream.h
(basic_ostream::basic_ostream(__streambuf_type*,
__locale_cache*)): New.
* src/ios.cc (cout, cin, cerr, clog, wcout, wcin, wcerr,
wclog): Change initialization of __locale_cache.
(ios_base::register_callback): Use buffer in locale cache for
static _Callback_list objects.
(ios_base::dispose_callbacks): Don't delete _Callback_list for
static locale caches.
Index: config/linker-map.gnu
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/config/linker-map.gnu,v)
retrieving revision 1.25.2.7
diff -u -r1.25.2.7 linker-map.gnu
--- config/linker-map.gnu 7 Mar 2003 22:04:18 -0000 1.25.2.7
+++ config/linker-map.gnu 29 Apr 2003 15:31:26 -0000
@@ -374,6 +374,9 @@
_ZNKSt7num_putI[wc]St19ostreambuf_iteratorI[wc]St11char_traitsI[wc]EEE12_M_group_int*;
+ _ZNSt9basic_iosI[cw]St11char_traitsI[cw]EE4initEPSt15basic_streambufI[cw]S1_EPSt14__locale_cacheI[cw]E;
+
+
# vtable
_ZTVSt19__locale_cache_base;
_ZTVSt14__locale_cacheI[cw]E;
Index: include/bits/basic_ios.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/basic_ios.h,v
retrieving revision 1.14.2.4
diff -u -r1.14.2.4 basic_ios.h
--- include/bits/basic_ios.h 22 Apr 2003 15:40:34 -0000 1.14.2.4
+++ include/bits/basic_ios.h 29 Apr 2003 15:31:27 -0000
@@ -425,8 +425,11 @@
* memory.
*/
void
+ init(basic_streambuf<_CharT, _Traits>* __sb);
+
+ void
init(basic_streambuf<_CharT, _Traits>* __sb,
- __locale_cache<_CharT>* __cache=0);
+ __locale_cache<_CharT>* __cache);
bool
_M_check_facet(const locale::facet* __f) const
Index: include/bits/basic_ios.tcc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/basic_ios.tcc,v
retrieving revision 1.17.4.3
diff -u -r1.17.4.3 basic_ios.tcc
--- include/bits/basic_ios.tcc 22 Apr 2003 15:40:34 -0000 1.17.4.3
+++ include/bits/basic_ios.tcc 29 Apr 2003 15:31:27 -0000
@@ -144,6 +144,11 @@
template<typename _CharT, typename _Traits>
void
+ basic_ios<_CharT, _Traits>::init(basic_streambuf<_CharT, _Traits>* __sb)
+ { init(__sb, 0); }
+
+ template<typename _CharT, typename _Traits>
+ void
basic_ios<_CharT, _Traits>::init(basic_streambuf<_CharT, _Traits>* __sb,
__locale_cache<_CharT>* __cache)
{
Index: include/bits/ios_base.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/ios_base.h,v
retrieving revision 1.21.2.5
diff -u -r1.21.2.5 ios_base.h
--- include/bits/ios_base.h 5 Mar 2003 19:09:45 -0000 1.21.2.5
+++ include/bits/ios_base.h 29 Apr 2003 15:31:27 -0000
@@ -376,6 +376,8 @@
iostate _M_streambuf_state;
//@}
+ friend class __locale_cache_base;
+
// 27.4.2.6 Members for callbacks
// 27.4.2.6 ios_base callbacks
struct _Callback_list
Index: include/bits/locale_facets.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/locale_facets.h,v
retrieving revision 1.49.4.6
diff -u -r1.49.4.6 locale_facets.h
--- include/bits/locale_facets.h 5 Mar 2003 04:40:07 -0000 1.49.4.6
+++ include/bits/locale_facets.h 29 Apr 2003 15:31:27 -0000
@@ -1964,6 +1964,11 @@
// calling the virtual functions in locale facets.
class __locale_cache_base
{
+ friend class ios_base;
+
+ // Used to provide space for a callback list entry for static caches.
+ char _M_static_cblist[sizeof(ios_base::_Callback_list)];
+
public:
virtual
~__locale_cache_base() {}
Index: include/std/std_istream.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/std/std_istream.h,v
retrieving revision 1.5.2.2
diff -u -r1.5.2.2 std_istream.h
--- include/std/std_istream.h 23 Apr 2003 16:44:15 -0000 1.5.2.2
+++ include/std/std_istream.h 29 Apr 2003 15:31:28 -0000
@@ -107,6 +107,12 @@
_M_gcount = streamsize(0);
}
+ basic_istream(__streambuf_type* __sb, __locale_cache<_CharT>* __lc)
+ {
+ this->init(__sb, __lc);
+ _M_gcount = streamsize(0);
+ }
+
/**
* @brief Base destructor.
*
Index: include/std/std_ostream.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/std/std_ostream.h,v
retrieving revision 1.5.2.1
diff -u -r1.5.2.1 std_ostream.h
--- include/std/std_ostream.h 9 Mar 2003 02:00:53 -0000 1.5.2.1
+++ include/std/std_ostream.h 29 Apr 2003 15:31:28 -0000
@@ -105,6 +105,9 @@
basic_ostream(__streambuf_type* __sb)
{ this->init(__sb); }
+ basic_ostream(__streambuf_type* __sb, __locale_cache<_CharT>* __lc)
+ { this->init(__sb, __lc); }
+
/**
* @brief Base destructor.
*
Index: src/ios.cc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/src/ios.cc,v
retrieving revision 1.33.2.6
diff -u -r1.33.2.6 ios.cc
--- src/ios.cc 22 Apr 2003 15:40:34 -0000 1.33.2.6
+++ src/ios.cc 29 Apr 2003 15:31:28 -0000
@@ -182,14 +182,10 @@
new (&buf_cin) stdio_filebuf<char>(stdin, ios_base::in, __in_size);
new (&buf_cerr) stdio_filebuf<char>(stderr, ios_base::out, __out_size);
- new (&cout) ostream(&buf_cout);
- new (&cin) istream(&buf_cin);
- new (&cerr) ostream(&buf_cerr);
- new (&clog) ostream(&buf_cerr);
- cout.init(&buf_cout, &locale_cache_cout);
- cin.init(&buf_cin, &locale_cache_cin);
- cerr.init(&buf_cerr, &locale_cache_cerr);
- clog.init(&buf_cerr, &locale_cache_clog);
+ new (&cout) ostream(&buf_cout, &locale_cache_cout);
+ new (&cin) istream(&buf_cin, &locale_cache_cin);
+ new (&cerr) ostream(&buf_cerr, &locale_cache_cerr);
+ new (&clog) ostream(&buf_cerr, &locale_cache_clog);
cin.tie(&cout);
cerr.flags(ios_base::unitbuf);
@@ -197,14 +193,10 @@
new (&buf_wcout) stdio_filebuf<wchar_t>(stdout, ios_base::out, __out_size);
new (&buf_wcin) stdio_filebuf<wchar_t>(stdin, ios_base::in, __in_size);
new (&buf_wcerr) stdio_filebuf<wchar_t>(stderr, ios_base::out, __out_size);
- new (&wcout) wostream(&buf_wcout);
- new (&wcin) wistream(&buf_wcin);
- new (&wcerr) wostream(&buf_wcerr);
- new (&wclog) wostream(&buf_wcerr);
- wcout.init(&buf_wcout, &locale_cache_wcout);
- wcin.init(&buf_wcin, &locale_cache_wcin);
- wcerr.init(&buf_wcerr, &locale_cache_wcerr);
- wclog.init(&buf_wcerr, &locale_cache_wclog);
+ new (&wcout) wostream(&buf_wcout, &locale_cache_wcout);
+ new (&wcin) wistream(&buf_wcin, &locale_cache_wcin);
+ new (&wcerr) wostream(&buf_wcerr, &locale_cache_wcerr);
+ new (&wclog) wostream(&buf_wcerr, &locale_cache_wclog);
wcin.tie(&wcout);
wcerr.flags(ios_base::unitbuf);
#endif
@@ -339,7 +331,18 @@
void
ios_base::register_callback(event_callback __fn, int __index)
- { _M_callbacks = new _Callback_list(__fn, __index, _M_callbacks); }
+ {
+ // Deal with static standard streams. For these, we didn't want
+ // Callback_list objects to be created on the heap. Instead we
+ // use the buffer in the cache.
+ if (__index == 0 && iword(0) == 1)
+ {
+ char* __cb_array = _M_cache()._M_static_cblist;
+ _M_callbacks = new (__cb_array) _Callback_list(__fn, __index, _M_callbacks);
+ }
+ else
+ _M_callbacks = new _Callback_list(__fn, __index, _M_callbacks);
+ }
void
ios_base::_M_call_callbacks(event __e) throw()
@@ -362,7 +365,9 @@
while (__p && __p->_M_remove_reference() == 0)
{
_Callback_list* __next = __p->_M_next;
- delete __p;
+ // Don't delete _Callback_list that is part of a static cache.
+ if (!(__p->_M_index == 0 && iword(0) == 1))
+ delete __p;
__p = __next;
}
_M_callbacks = 0;