Dead code (was: Re: Good numbers from Ritter's new string allocator)

Paolo Carlini pcarlini@unitus.it
Tue Nov 13 15:18:00 GMT 2001


Benjamin, libstdc++ maintainers and gurus,

>There is a bunch of stuff in std::string::_Rep to do with allocations. Is it
>supposed to handle this kind of tuning gracefully? If so, how? It seems
>obvious to me that the default allocation strategy is way off, and should
>be fixed.

all that stuff in std::string::_Rep is in fact just ****dead code**** !!!

I have just bootstrapped and made check (i686-pc-linux-gnu) with the following updated
patch, which also get rid of that "garbage".

What remains to be done IMO is at least getting rid the patch of the magic number 4096,
the pagesize: the test is already in configure, AFAICT, but I don't know :( how to use
it...

Cheers,
Paolo.


diff -urN gcc-vanilla/libstdc++-v3/include/bits/basic_string.h
gcc/libstdc++-v3/include/bits/basic_string.h
--- gcc-vanilla/libstdc++-v3/include/bits/basic_string.h Fri Nov  2 18:38:10 2001
+++ gcc/libstdc++-v3/include/bits/basic_string.h Thu Nov 22 22:42:52 2001
@@ -197,21 +197,6 @@
  _CharT*
  _M_clone(const _Alloc&, size_type __res = 0);

-#if _GLIBCPP_ALLOC_CONTROL
- // These function pointers allow you to modify the allocation
- // policy used by the string classes.  By default they expand by
- // powers of two, but this may be excessive for space-critical
- // applications.
-
- // Returns true if ALLOCATED is too much larger than LENGTH
- static bool (*_S_excess_slop) (size_t __length, size_t __allocated);
-
- inline static bool
- __default_excess(size_t, size_t);
-#else
- inline static bool
- _S_excess_slop(size_t, size_t);
-#endif
       };

       // Use empty-base optimization: http://www.cantrip.org/emptyopt.html
diff -urN gcc-vanilla/libstdc++-v3/include/bits/basic_string.tcc
gcc/libstdc++-v3/include/bits/basic_string.tcc
--- gcc-vanilla/libstdc++-v3/include/bits/basic_string.tcc Thu Nov 22 00:54:51 2001
+++ gcc/libstdc++-v3/include/bits/basic_string.tcc Thu Nov 22 23:09:16 2001
@@ -349,13 +349,6 @@
  }
     }

-#ifdef _GLIBCPP_ALLOC_CONTROL
-  template<typename _CharT, typename _Traits, typename _Alloc>
-    bool (*basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_excess_slop)
-    (size_t, size_t) =
-    basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_default_excess;
-#endif
-
   template<typename _CharT, typename _Traits, typename _Alloc>
     typename basic_string<_CharT, _Traits, _Alloc>::_Rep*
     basic_string<_CharT, _Traits, _Alloc>::_Rep::
@@ -374,6 +367,37 @@
       // terminating null char_type() element, plus enough for the
       // _Rep data structure. Whew. Seemingly so needy, yet so elemental.
       size_t __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
+
+      // The standard places no restriction on allocating more memory
+      // than is strictly needed within this layer at the moment or
+      // requested by an explicit application call to reserve().  Many
+      // malloc implementations perform quite poorly when an
+      // application attempts to allocate memory in a stepwise fashion
+      // growing each allocation size by only 1 char.  Additionally,
+      // it makes little sense to allocate less linear memory than the
+      // natural resolution size of a malloc implementation.
+
+      // This version assumes the malloc implementation prefers to
+      // align allocations over the size of a page to a page boundary
+      // and under the size of a page to a power of 2.
+      const size_t __pagesize = 4096; // This magic constant, from OS.
+      const size_t __malloc_header_size = 4*sizeof(void*);
+      if ((__size + __malloc_header_size) > __pagesize)
+      {
+        size_t __extra =
+          (__pagesize - ((__size + __malloc_header_size) % __pagesize))
+          % __pagesize;
+        __capacity += __extra / sizeof(_CharT);
+        __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
+      }
+      else if (__size > 128) // This magic constant is from stl_alloc.h.
+      {
+        size_t __extra =
+          (256 - ((__size + __malloc_header_size) % 256)) % 256;
+        __capacity += __extra / sizeof(_CharT);
+        __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
+      }
+
       // NB: Might throw, but no worries about a leak, mate: _Rep()
       // does not throw.
       void* __place = _Raw_bytes_alloc(__alloc).allocate(__size);
@@ -402,19 +426,6 @@
  }
       __r->_M_length = _M_length;
       return __r->_M_refdata();
-    }
-
-  template<typename _CharT, typename _Traits, typename _Alloc>
-  inline bool
-#ifdef _GLIBCPP_ALLOC_CONTROL
-    basic_string<_CharT, _Traits, _Alloc>::_Rep::
-    _S_default_excess(size_t __s, size_t __r)
-#else
-    basic_string<_CharT, _Traits, _Alloc>::_Rep::
-    _S_excess_slop(size_t __s, size_t __r)
-#endif
-    {
-      return 2 * (__s <= 16 ? 16 : __s) < __r;
     }

   template<typename _CharT, typename _Traits, typename _Alloc>




More information about the Libstdc++ mailing list