zero-alloc cache (was Re: [v3] Fix PR libstdc++/10276)

Jerry Quinn jlquinn@optonline.net
Tue Apr 29 15:47:00 GMT 2003


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@optonline.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;



More information about the Gcc-patches mailing list