[PATCH] Slightly better way to __USE_MALLOC

Loren James Rittle rittle@latour.rsch.comm.mot.com
Thu Oct 17 09:16:00 GMT 2002


In article <20021010150921.J14862@infointeractive.com>,
Brad Spencer<spencer@infointeractive.com> writes:

>>> However, I am afraid that you didn't test well enough the various
>>> cases which exist.  Please try compiling your posted test case at -O2

> I was able to reproduce the problem after all.  The goal has to be to
> emit an undefined symbol into every object file that "tags" it as
> being compiled against one or the other ABI.  I'm trying to work out
> different ways to do this and then choose the one with the minimal
> side effects (i.e. runtime cost, etc).

Hi Brad (and members of the list that care),

Sorry about the long delay in getting back to you.  Your work (BTW,
consider this a response to the actual patch you sent last Thursday as
well) is very helpful even with my comments below.  Actually, if you
are willing, I'd like you to think more radically (to that end, I have
attached such a patch to this e-mail, please tell me if you would
dislike my proposed patch verses your approach).

The primary problem with the current situation, without your patch, is
that the implementation of the ABI changes when a macro is defined;
thus I have to disagree with the goal quoted above.  What we really
want, I think, is the debugging feature and/or the non-caching memory
feature that users sometimes want when that macro is defined (or new
run-time mechanism) *without* changing the published library ABI and
without changing the header-exposed implementation.

With your patch we still have the problem of users compiling objects
with one compiler and trying to match them against an object built
with a compiler configured with the other choice.  In fact, your patch
will make it more likely since users don't even have to go find the
c++config header to edit anymore...

But, I would readily agree that you solved the problem of emitting an
error at link-time when the macro was defined verses not defined
(although, FYI, you appear to have dropped the stl-inst.cc thunk of
the patch).  However, we (at least Phil and I and Gaby?) are on record
as saying that we don't want that situation.  I am sorry if you
thought that was the key issue to solve based on past feedback.  While
explaining what was wrong with the first effort (mismatch of
configuration not caught by the compiler/linker), I may have sent you
on a wild goose chase.

> [...]  I think the runtime invocation of the dummy function makes
> this solution undesirable, even if it is just at startup.  [...]

Instead of that perspective, let's see how to fix this right.  (BTW,
as you know, the exact problem with the header is an undetectable
violation of the one-definition-rule and your current patch just adds
one extra level of checking about the situation but the root violation
would still be present.)  Then, we test a correctly partitioned
version against the current one and see if it matters for real
application code (the code in testsuite/thread/pthread[1-6].cc
stresses the memory allocators; or may be configured to do so, if you
don't believe that they do for your machine).

I would like to see the __USE_MALLOC macro-enabled path completely
gone not renamed.  Although users could get it, that path was never
the "standard" ABI thus I think it is safe to remove.  Then, I would
like to see what we could do to add in the equivalent feature guarded
by a run-time check which defaults to the current "standard" ABI and
behavior (i.e. use the pool allocator).  This way stuff compiled
before the change will still link and run properly against stuff
compiled after the change and vice-verse.  It would only be when the
run-time check (against the presence of an environment variable? how
about GLIBCPP_FORCE_NEW?) is in a non-default state that the non-pool
allocator is used.  If all code was re-compiled, then the run-time
feature to change all allocation on the fly could be used, otherwise
it would be as unsafe to use as when users mixed __USE_MALLOC code
with non-__USE_MALLOC code.

> Is there a cleaner, simpler way to introduce such a symbol?  Are
> either of these acceptable?

I hope this late feedback and alternate patch is helpful without
making you in any way dejected.

Attached is the patch I would want to apply to mainline to address
this issue.  My patch shows 4 additions to the ABI: the new statics
and their guards.  However, I don't believe that they would need to be
exposed for correct operation.  Benjamin, Phil, little help on that
detail (it seems we currently unconditionally globalize all such
statics and their guards)?  Of course, I'm willing to negotiate on any
part of what I did here, e.g. I could add back in the typedef alias
for __mem_interface since it was in the header ABI (but not the binary
library) and perhaps for small embedded targets we really do need to
merge in something like Brad's configuration-time style as well (but I
have the reservations listed above).

Rebuilt libstdc++-v3 from scratch on alpha-unknown-freebsd4.7 and
i386-unknown-freebsd4.7.  No regressions.  Also ran `gmake check' with
GLIBCPP_FORCE_NEW=1 in environment.

Funny story, I guess I should be a natural supporter of Brad's
configuration-time patch: On my FreeBSD box, the total time to build
and run the six thread tests drops from 235 seconds to 158 seconds
when GLIBCPP_FORCE_NEW=1 is in the environment.  Time to build and run
those tests before the patch was 235 seconds (i.e. no regression on
tests that slam the allocator interface).  I have known that
__USE_MALLOC configuration was faster on this platform for some time.
(FreeBSD malloc implements a similar pool concept to that which
libstdc++-v3 itself implements; but it is more tightly tuned to the OS
at-hand.)  Timing of all other tests are not really affected much.  I
could strongly support Brad's configuration-time patch if it were
modified to be a property of the port's configuration but not be so
obvious as a configure command line option.

Comments?

Regards,
Loren

	* docs/html/23_containers/howto.html (GLIBCPP_FORCE_NEW): Document
	new environment variable which replaces all uses of __USE_MALLOC
	macro.
	* docs/html/ext/howto.html (GLIBCPP_FORCE_NEW): Likewise.
	(__mem_interface): Remove all references to old internal typedef.
	* include/backward/alloc.h (__USE_MALLOC): Remove it and all
	guarded code.
	* include/bits/c++config (__USE_MALLOC): Update related error
	message and comment.
	* include/bits/stl_alloc.h (__USE_MALLOC): Remove it and all
	guarded code.  Update all related comments.
	(__mem_interface): Unconditionally replace it with __new_alloc.
	(__default_alloc_template<>::allocate, deallocate): Add
	run-time controlled feature similar to what __USE_MALLOC code
	path had provided.  Move out-of-line (to workaround c++/8249).
	* src/stl-inst.cc (__USE_MALLOC): Remove it and all
	guarded code.
	* testsuite/21_strings/capacity.cc: Remove reference to __USE_MALLOC.
	* testsuite/ext/allocators.cc: Likewise.

Index: docs/html/23_containers/howto.html
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/docs/html/23_containers/howto.html,v
retrieving revision 1.24
diff -c -r1.24 howto.html
*** docs/html/23_containers/howto.html	7 Oct 2002 18:11:20 -0000	1.24
--- docs/html/23_containers/howto.html	17 Oct 2002 12:11:18 -0000
***************
*** 253,291 ****
     <p>The STL implementation is currently configured to use the
        high-speed caching memory allocator.  If you absolutely think
        you must change this on a global basis for your platform to better
!       support multi-threading, then please consult all commentary in
!       include/bits/stl_alloc.h and the allocators link below.
     </p> 
-    <blockquote>
-       <p>(Explicit warning since so many people get confused while
-       attempting this:)
-       </p>
-       <p><strong>Adding -D__USE_MALLOC on the command
-       line is almost certainly a bad idea.</strong>  Memory efficiency is
-       almost guaranteed to suffer as a result; this is
-       <a href="http://gcc.gnu.org/ml/libstdc++/2001-05/msg00136.html">why
-       we disabled it for 3.0 in the first place</a>.
-       </p>
-       <p>Related to threading or otherwise, the current recommendation is
-       that users not add any macro defines on the command line to remove or
-       otherwise disable features of libstdc++-v3.  There is
-       no condition under which it will help you without causing other
-       issues to perhaps raise up (possible linkage/ABI problems).  In
-       particular, __USE_MALLOC should only be added to a libstdc++-v3
-       configuration file, include/bits/c++config (where such user
-       action is cautioned against), and the entire library should be
-       rebuilt.  If you do not, then you might be violating the
-       one-definition rule of C/C++ and you might cause yourself untold
-       problems.
-       </p>
-    </blockquote>
-    <p>If you find any platform where gcc reports a
-       threading model other than single, and where libstdc++-v3 builds
-       a buggy container allocator when used with threads unless you
-       define __USE_MALLOC, we want to hear about it ASAP.  In the
-       past, correctness was the main reason people were led to believe
-       that they should define __USE_MALLOC when using threads.
-    </p>
     <p>There is a better way (not standardized yet):  It is possible to
        force the malloc-based allocator on a per-case-basis for some
        application code.  The library team generally believes that this
--- 253,261 ----
     <p>The STL implementation is currently configured to use the
        high-speed caching memory allocator.  If you absolutely think
        you must change this on a global basis for your platform to better
!       support multi-threading, then please add GLIBCPP_FORCE_NEW to
!       your environment before running the program.
     </p> 
     <p>There is a better way (not standardized yet):  It is possible to
        force the malloc-based allocator on a per-case-basis for some
        application code.  The library team generally believes that this
Index: docs/html/ext/howto.html
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/docs/html/ext/howto.html,v
retrieving revision 1.23
diff -c -r1.23 howto.html
*** docs/html/ext/howto.html	7 Oct 2002 18:11:21 -0000	1.23
--- docs/html/ext/howto.html	17 Oct 2002 12:11:18 -0000
***************
*** 280,298 ****
           same as <code>allocator<T></code>.
       </li>
     </ul>
-    <p>An internal typedef, <code> __mem_interface </code>, is defined to be
-       <code>__new_alloc</code> by default.
-    </p>
     <p>Normally,
        <code> __default_alloc_template<bool thr, int inst> </code>
        is also available.  This is the high-speed pool, called the default
        node allocator.  The reusable memory is shared among identical
        instantiations of
!       this type.  It calls through <code>__mem_interface</code> to obtain
        new memory when its lists run out.  If a client container requests a
        block larger than a certain threshold size, then the pool is bypassed,
        and the allocate/deallocate request is passed to
!       <code>__mem_interface</code> directly.
     </p>
     <p>Its <code>inst</code> parameter is described below.  The
        <code>thr</code> boolean determines whether the pool should be
--- 280,295 ----
           same as <code>allocator<T></code>.
       </li>
     </ul>
     <p>Normally,
        <code> __default_alloc_template<bool thr, int inst> </code>
        is also available.  This is the high-speed pool, called the default
        node allocator.  The reusable memory is shared among identical
        instantiations of
!       this type.  It calls through <code>__new_alloc</code> to obtain
        new memory when its lists run out.  If a client container requests a
        block larger than a certain threshold size, then the pool is bypassed,
        and the allocate/deallocate request is passed to
!       <code>__new_alloc</code> directly.
     </p>
     <p>Its <code>inst</code> parameter is described below.  The
        <code>thr</code> boolean determines whether the pool should be
***************
*** 313,329 ****
     </p>
     <h3>A cannon to swat a fly:<code>  __USE_MALLOC</code></h3>
     <p>If you've already read <a href="../23_containers/howto.html#3">this
!       advice</a> and decided to define this macro, then the situation changes
!       thusly:
     </p>
-    <ol>
-      <li><code>__mem_interface</code>, and</li>
-      <li><code>__alloc</code>, and</li>
-      <li><code>__single_client_alloc</code> are all typedef'd to
-          <code>__malloc_alloc_template</code>.</li>
-      <li><code>__default_alloc_template</code> is no longer available.
-          At all.  Anywhere.</li>
-    </ol>
     <h3>Writing your own allocators</h3>
     <p>Depending on your application (a specific program, a generic library,
        etc), allocator classes tend to be one of two styles:  "SGI"
--- 310,322 ----
     </p>
     <h3>A cannon to swat a fly:<code>  __USE_MALLOC</code></h3>
     <p>If you've already read <a href="../23_containers/howto.html#3">this
!       advice</a> but still think you remember how to use this macro from
!       SGI STL days.  Compile normally and set GLIBCPP_FORCE_NEW
!       into your environment before running the program.  You will
!       obtain a similar effect without having to recompile your entire
!       program and the entire library (new in gcc is a light wrapper
!       around malloc).
     </p>
     <h3>Writing your own allocators</h3>
     <p>Depending on your application (a specific program, a generic library,
        etc), allocator classes tend to be one of two styles:  "SGI"
Index: include/backward/alloc.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/backward/alloc.h,v
retrieving revision 1.11
diff -c -r1.11 alloc.h
*** include/backward/alloc.h	6 Dec 2001 20:29:30 -0000	1.11
--- include/backward/alloc.h	17 Oct 2002 12:11:18 -0000
***************
*** 53,62 ****
  using std::__alloc; 
  using std::__single_client_alloc; 
  using std::allocator;
- #ifdef __USE_MALLOC
- using std::malloc_alloc; 
- #else
  using std::__default_alloc_template; 
- #endif
  
  #endif 
--- 53,58 ----
Index: include/bits/c++config
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/c++config,v
retrieving revision 1.516
diff -c -r1.516 c++config
*** include/bits/c++config	17 Oct 2002 07:17:10 -0000	1.516
--- include/bits/c++config	17 Oct 2002 12:11:18 -0000
***************
*** 74,86 ****
  // so, please report any possible issues to libstdc++@gcc.gnu.org .
  // Do not define __USE_MALLOC on the command line.  Enforce it here:
  #ifdef __USE_MALLOC
! #error __USE_MALLOC should only be defined within \
! libstdc++-v3/include/bits/c++config before full recompilation of the library.
  #endif
- // Define __USE_MALLOC after this point in the file in order to aid debugging
- // or globally change allocation policy.  This breaks the ABI, thus
- // completely recompile the library.  A patch to better support
- // changing the global allocator policy would be probably be accepted.
  
  // The remainder of the prewritten config is mostly automatic; all the
  // user hooks are listed above.
--- 74,81 ----
  // so, please report any possible issues to libstdc++@gcc.gnu.org .
  // Do not define __USE_MALLOC on the command line.  Enforce it here:
  #ifdef __USE_MALLOC
! #error __USE_MALLOC should never be defined.  Read the release notes.
  #endif
  
  // The remainder of the prewritten config is mostly automatic; all the
  // user hooks are listed above.
Index: include/bits/stl_alloc.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/stl_alloc.h,v
retrieving revision 1.24
diff -c -r1.24 stl_alloc.h
*** include/bits/stl_alloc.h	23 Aug 2002 16:52:29 -0000	1.24
--- include/bits/stl_alloc.h	17 Oct 2002 12:11:18 -0000
***************
*** 210,224 ****
      }
  #endif
  
- 
-   // Determines the underlying allocator choice for the node allocator.
- #ifdef __USE_MALLOC
-   typedef __malloc_alloc_template<0>  __mem_interface;
- #else
-   typedef __new_alloc                 __mem_interface;
- #endif
- 
- 
    /**
     *  @if maint
     *  This is used primarily (only?) in _Alloc_traits and other places to
--- 210,215 ----
***************
*** 307,329 ****
      };
  
  
- #ifdef __USE_MALLOC
- 
-   typedef __mem_interface __alloc;
-   typedef __mem_interface __single_client_alloc;
- 
- #else
- 
- 
    /**
     *  @if maint
!    *  Default node allocator.  "SGI" style.  Uses __mem_interface for its
!    *  underlying requests (and makes as few requests as possible).
!    *  **** Currently __mem_interface is always __new_alloc, never __malloc*.
     *
     *  Important implementation properties:
     *  1. If the clients request an object of size > _MAX_BYTES, the resulting
!    *     object will be obtained directly from the underlying __mem_interface.
     *  2. In all other cases, we allocate an object of size exactly
     *     _S_round_up(requested_size).  Thus the client has enough size
     *     information that we can return the object to the proper free list
--- 298,314 ----
      };
  
  
    /**
     *  @if maint
!    *  Default node allocator.  "SGI" style.  Uses various allocators to
!    *  fulfill underlying requests (and makes as few requests as possible
!    *  when in default high-speed pool mode).
     *
     *  Important implementation properties:
+    *  0. If globally mandated (and supportable by the port), then
+    *     allocate objects from __malloc_alloc_template<0>
     *  1. If the clients request an object of size > _MAX_BYTES, the resulting
!    *     object will be obtained directly from __new_alloc
     *  2. In all other cases, we allocate an object of size exactly
     *     _S_round_up(requested_size).  Thus the client has enough size
     *     information that we can return the object to the proper free list
***************
*** 397,448 ****
      public:
        // __n must be > 0
        static void*
!       allocate(size_t __n)
!       {
!         void* __ret = 0;
! 
!         if (__n > (size_t) _MAX_BYTES)
!           __ret = __mem_interface::allocate(__n);
!         else
!           {
!             _Obj* volatile* __my_free_list = _S_free_list
!                                              + _S_freelist_index(__n);
!             // Acquire the lock here with a constructor call.  This
!             // ensures that it is released in exit or during stack
!             // unwinding.
!             _Lock __lock_instance;
!             _Obj* __restrict__ __result = *__my_free_list;
!             if (__result == 0)
!               __ret = _S_refill(_S_round_up(__n));
!             else
!               {
!                 *__my_free_list = __result -> _M_free_list_link;
!                 __ret = __result;
!               }
!           }
!         return __ret;
!       };
  
        // __p may not be 0
        static void
!       deallocate(void* __p, size_t __n)
!       {
!         if (__n > (size_t) _MAX_BYTES)
!           __mem_interface::deallocate(__p, __n);
!         else
!           {
!             _Obj* volatile*  __my_free_list = _S_free_list
!               + _S_freelist_index(__n);
!             _Obj* __q = (_Obj*)__p;
! 
!             // Acquire the lock here with a constructor call.  This
!             // ensures that it is released in exit or during stack
!             // unwinding.
!             _Lock __lock_instance;
!             __q -> _M_free_list_link = *__my_free_list;
!             *__my_free_list = __q;
!           }
!       }
  
  #ifdef _GLIBCPP_DEPRECATED
        static void*
--- 382,392 ----
      public:
        // __n must be > 0
        static void*
!       allocate(size_t __n);
  
        // __p may not be 0
        static void
!       deallocate(void* __p, size_t __n);
  
  #ifdef _GLIBCPP_DEPRECATED
        static void*
***************
*** 450,455 ****
--- 394,448 ----
  #endif
      };
  
+   template<bool __threads, int __inst> void*
+   __default_alloc_template<__threads, __inst>::allocate(size_t __n)
+   {
+     static char* __force_new = getenv("GLIBCPP_FORCE_NEW");
+     void* __ret = 0;
+ 
+     if ((__n > (size_t) _MAX_BYTES) || __force_new)
+       __ret = __new_alloc::allocate(__n);
+     else
+       {
+ 	_Obj* volatile* __my_free_list = _S_free_list
+ 	  + _S_freelist_index(__n);
+ 	// Acquire the lock here with a constructor call.  This
+ 	// ensures that it is released in exit or during stack
+ 	// unwinding.
+ 	_Lock __lock_instance;
+ 	_Obj* __restrict__ __result = *__my_free_list;
+ 	if (__result == 0)
+ 	  __ret = _S_refill(_S_round_up(__n));
+ 	else
+ 	  {
+ 	    *__my_free_list = __result -> _M_free_list_link;
+ 	    __ret = __result;
+ 	  }
+       }
+     return __ret;
+   }
+ 
+   template<bool __threads, int __inst> void
+   __default_alloc_template<__threads, __inst>::deallocate(void* __p, size_t __n)
+   {
+     static char* __force_new = getenv("GLIBCPP_FORCE_NEW");
+ 
+     if ((__n > (size_t) _MAX_BYTES) || __force_new)
+       __new_alloc::deallocate(__p, __n);
+     else
+       {
+ 	_Obj* volatile*  __my_free_list = _S_free_list
+ 	  + _S_freelist_index(__n);
+ 	_Obj* __q = (_Obj*)__p;
+ 
+ 	// Acquire the lock here with a constructor call.  This
+ 	// ensures that it is released in exit or during stack
+ 	// unwinding.
+ 	_Lock __lock_instance;
+ 	__q -> _M_free_list_link = *__my_free_list;
+ 	*__my_free_list = __q;
+       }
+   }
  
    template<bool __threads, int __inst>
      inline bool
***************
*** 465,472 ****
  
  
    // We allocate memory in large chunks in order to avoid fragmenting the
!   // malloc heap (or whatever __mem_interface is using) too much.  We assume
!   // that __size is properly aligned.  We hold the allocation lock.
    template<bool __threads, int __inst>
      char*
      __default_alloc_template<__threads, __inst>::
--- 458,465 ----
  
  
    // We allocate memory in large chunks in order to avoid fragmenting the
!   // heap too much.  We assume that __size is properly aligned.  We hold
!   // the allocation lock.
    template<bool __threads, int __inst>
      char*
      __default_alloc_template<__threads, __inst>::
***************
*** 503,509 ****
                ((_Obj*)_S_start_free) -> _M_free_list_link = *__my_free_list;
                *__my_free_list = (_Obj*)_S_start_free;
              }
!           _S_start_free = (char*) __mem_interface::allocate(__bytes_to_get);
            if (0 == _S_start_free)
              {
                size_t __i;
--- 496,502 ----
                ((_Obj*)_S_start_free) -> _M_free_list_link = *__my_free_list;
                *__my_free_list = (_Obj*)_S_start_free;
              }
!           _S_start_free = (char*) __new_alloc::allocate(__bytes_to_get);
            if (0 == _S_start_free)
              {
                size_t __i;
***************
*** 528,534 ****
                      }
                  }
                _S_end_free = 0;        // In case of exception.
!               _S_start_free = (char*)__mem_interface::allocate(__bytes_to_get);
                // This should either throw an exception or remedy the situation.
                // Thus we assume it succeeded.
              }
--- 521,527 ----
                      }
                  }
                _S_end_free = 0;        // In case of exception.
!               _S_start_free = (char*)__new_alloc::allocate(__bytes_to_get);
                // This should either throw an exception or remedy the situation.
                // Thus we assume it succeeded.
              }
***************
*** 618,624 ****
  
    typedef __default_alloc_template<true,0>    __alloc;
    typedef __default_alloc_template<false,0>   __single_client_alloc;
- #endif /* ! __USE_MALLOC */
  
  
    /**
--- 611,616 ----
***************
*** 628,637 ****
     *  of stl_alloc.h.)
     *
     *  The underlying allocator behaves as follows.
-    *  - if __USE_MALLOC then
-    *    - thread safety depends on malloc and is entirely out of our hands
-    *    - __malloc_alloc_template is used for memory requests
-    *  - else (the default)
     *    - __default_alloc_template is used via two typedefs
     *    - "__single_client_alloc" typedef does no locking for threads
     *    - "__alloc" typedef is threadsafe via the locks
--- 620,625 ----
***************
*** 908,914 ****
        typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type;
      };
  
- #ifndef __USE_MALLOC
    template<typename _Tp, bool __threads, int __inst>
      struct _Alloc_traits<_Tp, __default_alloc_template<__threads, __inst> >
      {
--- 896,901 ----
***************
*** 918,924 ****
        typedef __allocator<_Tp, __default_alloc_template<__threads, __inst> >
        allocator_type;
      };
- #endif
  
    template<typename _Tp, typename _Alloc>
      struct _Alloc_traits<_Tp, __debug_alloc<_Alloc> >
--- 905,910 ----
***************
*** 941,947 ****
        typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type;
      };
  
- #ifndef __USE_MALLOC
    template<typename _Tp, typename _Tp1, bool __thr, int __inst>
      struct _Alloc_traits<_Tp, __allocator<_Tp1, __default_alloc_template<__thr, __inst> > >
      {
--- 927,932 ----
***************
*** 951,957 ****
        typedef __allocator<_Tp, __default_alloc_template<__thr,__inst> >
        allocator_type;
      };
- #endif
  
    template<typename _Tp, typename _Tp1, typename _Alloc>
      struct _Alloc_traits<_Tp, __allocator<_Tp1, __debug_alloc<_Alloc> > >
--- 936,941 ----
***************
*** 967,977 ****
    // NB: This syntax is a GNU extension.
    extern template class allocator<char>;
    extern template class allocator<wchar_t>;
- #ifdef __USE_MALLOC
-   extern template class __malloc_alloc_template<0>;
- #else
    extern template class __default_alloc_template<true,0>;
- #endif
  } // namespace std
  
  #endif
--- 951,957 ----
Index: src/stl-inst.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/stl-inst.cc,v
retrieving revision 1.14
diff -c -r1.14 stl-inst.cc
*** src/stl-inst.cc	17 Apr 2002 06:20:19 -0000	1.14
--- src/stl-inst.cc	17 Oct 2002 12:11:18 -0000
***************
*** 39,47 ****
    template class allocator<char>;
    template class allocator<wchar_t>;
  
- #ifdef __USE_MALLOC
-   template class __malloc_alloc_template<0>;
- #else
    template class __default_alloc_template<true, 0>;
- #endif
  } // namespace std
--- 39,43 ----
Index: testsuite/21_strings/capacity.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/21_strings/capacity.cc,v
retrieving revision 1.9
diff -c -r1.9 capacity.cc
*** testsuite/21_strings/capacity.cc	31 Jul 2002 02:47:34 -0000	1.9
--- testsuite/21_strings/capacity.cc	17 Oct 2002 12:11:18 -0000
***************
*** 209,215 ****
    sz02 = str011.length();
    VERIFY( sz02 > sz01 );
      
!   // trickster allocator (__USE_MALLOC, luke) issues involved with these:
    std::string str3 = "8-chars_8-chars_";
    const char* p3 = str3.c_str();
    std::string str4 = str3 + "7-chars";
--- 209,215 ----
    sz02 = str011.length();
    VERIFY( sz02 > sz01 );
      
!   // trickster allocator issues involved with these:
    std::string str3 = "8-chars_8-chars_";
    const char* p3 = str3.c_str();
    std::string str4 = str3 + "7-chars";
Index: testsuite/ext/allocators.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/ext/allocators.cc,v
retrieving revision 1.1
diff -c -r1.1 allocators.cc
*** testsuite/ext/allocators.cc	11 Dec 2001 19:04:58 -0000	1.1
--- testsuite/ext/allocators.cc	17 Oct 2002 12:11:18 -0000
***************
*** 20,26 ****
  
  // 20.4.1.1 allocator members
  
- #undef __USE_MALLOC
  #include <memory>
  #include <cstdlib>
  #include <testsuite_hooks.h>
--- 20,25 ----



More information about the Libstdc++ mailing list