This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: libstdc++/include/profile bug fixes and cleanup


All of the changes are either serious bug fixes, cleanup requested by
maintainers or minor features agreed previously by maintainers.
This is the last round of changes for the profile mode for 4.5.
Some of the changes were already reviewed in
http://gcc.gnu.org/ml/libstdc++/2009-12/msg00015.html.

1. Fix bug: Initialization would possibly run more than once on
multithreaded programs due to missing fence.
Fix by using compare_and_swap to set the state.

2. Fix bug: Reentrance guard mechanism was broken since
http://gcc.gnu.org/ml/gcc-patches/2009-11/msg00890.html.
Fix guard logic.

3. Fix bug: Compile time disabling of individual diagnostics was broken.
After this patch, to enable all diagnostics except "vector to list":
g++ -D_GLIBCXX_PROFILE -D_GLIBCXX_PROFILE_NO_VECTOR_TO_LIST

4. Cleanup: Drop support for hash_map and hash_set.
Requested by library maintainer Paolo Carlini.
http://gcc.gnu.org/ml/libstdc++/2010-01/msg00026.html

5. Cleanup: Get rid of templates used only for inline linkage.
Requested by library maintainer Benjamin Kosnik.
http://gcc.gnu.org/ml/libstdc++/2009-12/msg00015.html
Replaced with inline functions containing static members.
See new macros _GLIBCXX_PROFILE_DEFINE_DATA
and _GLIBCXX_PROFILE_DATA.

6. Minor feature: Add support for setting decision weights in config file.
Reviewed by maintainer Benjamin Kosnik.
http://gcc.gnu.org/ml/libstdc++/2009-12/msg00015.html

7. Minor features: Add two simple diagnostics.
list_to_vector and list_to_slist were added.  list_to_set was dropped
from previous patch.
Reviewed by maintainer Benjamin Kosnik.
http://gcc.gnu.org/ml/libstdc++/2009-12/msg00015.html

8. Update docs.
Requested by maintener Benjamin Kosnik.
http://gcc.gnu.org/ml/libstdc++/2009-12/msg00015.html


Tested:
x86_64/linux make check-profile
There were 14 FAILs.  I will make them pass or ask for specific help
before submitting.


Questions to maintainers:

1. Currently, multithreaded execution of the profile mode requires
TLS.  Is this a reasonable way to test TLS support?
#if (defined _GLIBCXX_PROFILE_THREADS) && !(defined HAVE_TLS)
#error profile mode requires either -DHAVE_TLS or -D_GLIBCXX_PROFILE_NO_THREADS

2. I am testing for execinfo.h with #ifdef HAVE_EXECINFO_H.
What is the right way to make sure this gets set in a config file?


Thank you,
Silvius

Attachment: rus-profile-20100107-CL.txt
Description: Text document

Index: doc/xml/manual/profile_mode.xml
===================================================================
--- doc/xml/manual/profile_mode.xml	(revision 155631)
+++ doc/xml/manual/profile_mode.xml	(working copy)
@@ -134,7 +134,7 @@
   </itemizedlist>
   </para>
 
-  <para>Two files are generated.  <code>libstdcxx-profile.txt</code>
+  <para>Three files are generated.  <code>libstdcxx-profile.txt</code>
    contains human readable advice.  <code>libstdcxx-profile.raw</code>
    contains implementation specific data about each diagnostic.
    Their format is not documented.  They are sufficient to generate
@@ -142,6 +142,9 @@
    of keeping this raw format is that traces from multiple executions can
    be aggregated simply by concatenating the raw traces.  We intend to
    offer an external utility program that can issue advice from a trace.
+   <code>libstdcxx-profile.conf.out</code> lists the actual diagnostic
+   parameters used.  To alter parameters, edit this file and rename it to
+   <code>libstdcxx-profile.conf</code>.
   </para>
 
   <para>Advice is given regardless whether the transformation is valid.
@@ -163,8 +166,8 @@
    in the environment where the program is run, before starting execution.
   <itemizedlist>
   <listitem><para>
-   <code>[NO]_GLIBCXX_PROFILE_&lt;diagnostic&gt;</code>:
-   enable/disable specific diagnostics.
+   <code>_GLIBCXX_PROFILE_NO_&lt;diagnostic&gt;</code>:
+   disable specific diagnostics.
    See section Diagnostics for possible values.
    (Environment variables not supported.)
    </para></listitem>
@@ -192,11 +195,12 @@
    live containers are deleted.  The default is 128 MB.
    </para></listitem>
   <listitem><para>
-   <code>GLIBCXX_PROFILE_NOTHREADS</code>:
-   Make the library not use threads.  Otherwise, pthread mutexes are used
-   to protect access to internal data structures.  This should be useful
-   only if the program is single threaded and you want to avoid the overhead
-   of aquiring/releasing locks unnecessarily.
+   <code>GLIBCXX_PROFILE_NO_THREADS and HAVE_TLS</code>:
+   Make the library not use threads.  In multithreaded code, the profile
+   mode requires thread level support.  If -DHAVE_TLS is not set, you
+   will get a preprocessor error asking you to either set -DHAVE_TLS
+   or to alternatively set -DGLIBCXX_PROFILE_NO_THREADS if your program
+   is single-threaded.
    (Environment variable not supported.)
    </para></listitem>
   <listitem><para>
@@ -1320,6 +1324,52 @@
 </itemizedlist>
 </sect3>
 
+<sect3 id="manual.ext.profile_mode.analysis.list_to_slist"
+ xreflabel="List to Forward List">
+<title>List to Forward List (Slist)</title>
+<itemizedlist>
+  <listitem><para><emphasis>Switch:</emphasis>
+  <code>_GLIBCXX_PROFILE_LIST_TO_SLIST</code>.
+  </para></listitem>
+  <listitem><para><emphasis>Goal:</emphasis> Detect cases where 
+  <code>list</code> could be substituted with <code>forward_list</code> for
+  better performance.
+  </para></listitem>
+  <listitem><para><emphasis>Fundamentals:</emphasis>
+  The memory footprint of a forward_list is smaller than that of a list.
+  This has beneficial effects on memory subsystem, e.g., fewer cache misses.
+  </para></listitem>
+  <listitem><para><emphasis>Sample runtime reduction:</emphasis>40%.
+  Note that the reduction is only noticeable if the size of the forward_list
+  node is in fact larger than that of the list node.  For memory allocators
+  with size classes, you will only notice an effect when the two node sizes
+  belong to different allocator size classes.
+  </para></listitem>
+  <listitem><para><emphasis>Recommendation:</emphasis>Replace list with
+  forward_list at site S.</para></listitem>
+  <listitem><para><emphasis>To instrument:</emphasis><code>list</code>
+  operations and iteration methods.</para></listitem>
+  <listitem><para><emphasis>Analysis:</emphasis>
+  Issue the advice if there are no <code>backwards</code> traversals
+  or insertion before a given node.
+  </para></listitem>
+  <listitem><para><emphasis>Cost model:</emphasis>
+  Always true.</para></listitem>
+  <listitem><para><emphasis>Example:</emphasis> 
+<programlisting>
+1  list&lt;int&gt; l;
+...
+2  int sum = 0;
+3  for (list&lt;int&gt;::iterator it = l.begin(); it != l.end(); ++it) {
+4    sum += *it;
+5  }
+
+foo.cc:1: advice: Change "list" to "forward_list".
+</programlisting>
+</para></listitem>
+</itemizedlist>
+</sect3>
+
 <sect3 id="manual.ext.profile_mode.analysis.assoc_ord_to_unord"
  xreflabel="Ordered to Unordered Associative Container">
 <title>Ordered to Unordered Associative Container</title>
Index: include/Makefile.in
===================================================================
--- include/Makefile.in	(revision 155631)
+++ include/Makefile.in	(working copy)
@@ -1026,7 +1026,7 @@
 	${profile_srcdir}/multiset.h \
 	${profile_srcdir}/set \
 	${profile_srcdir}/set.h \
-	${profile_srcdir}/hashtable.h
+	${profile_srcdir}/iterator_tracker.h
 
 profile_impl_srcdir = ${glibcxx_srcdir}/include/profile/impl
 profile_impl_builddir = ./profile/impl
@@ -1040,7 +1040,9 @@
 	${profile_impl_srcdir}/profiler_state.h \
 	${profile_impl_srcdir}/profiler_trace.h \
 	${profile_impl_srcdir}/profiler_vector_size.h \
-	${profile_impl_srcdir}/profiler_vector_to_list.h
+	${profile_impl_srcdir}/profiler_vector_to_list.h \
+	${profile_impl_srcdir}/profiler_list_to_vector.h \
+	${profile_impl_srcdir}/profiler_list_to_slist.h
 
 @GLIBCXX_C_HEADERS_EXTRA_FALSE@c_base_headers_extra = 
 
Index: include/profile/hashtable.h
===================================================================
--- include/profile/hashtable.h	(revision 155631)
+++ include/profile/hashtable.h	(working copy)
@@ -1,1151 +0,0 @@
-// Hashtable implementation used by containers -*- C++ -*-
-
-// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
-// Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 2, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING.  If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
-
-// As a special exception, you may use this file as part of a free software
-// library without restriction.  Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License.  This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
-
-/*
- * Copyright (c) 1996,1997
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.  Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied warranty.
- *
- *
- * Copyright (c) 1994
- * Hewlett-Packard Company
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.  Hewlett-Packard Company makes no
- * representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied warranty.
- *
- */
-
-/** @file profile/hashtable.h copied from backward/hashtable.h
- *  This file is a GNU extension to the Standard C++ Library (possibly
- *  containing extensions from the HP/SGI STL subset).
- */
-
-#ifndef _HASHTABLE_H
-#define _HASHTABLE_H 1
-
-// Hashtable class, used to implement the hashed associative containers
-// hash_set, hash_map, hash_multiset, and hash_multimap.
-// Skip instrumentation on vector.
-#include <vector>
-#include <iterator>
-#include <algorithm>
-#include <bits/stl_function.h>
-#include <backward/hash_fun.h>
-#include <profile/base.h>
-
-_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
-
-  using std::size_t;
-  using std::ptrdiff_t;
-  using std::forward_iterator_tag;
-  using std::input_iterator_tag;
-  using std::_Construct;
-  using std::_Destroy;
-  using std::distance;
-  using std::_GLIBCXX_STD_D::vector;
-  using std::pair;
-  using std::__iterator_category;
-
-  template<class _Val>
-    struct _Hashtable_node
-    {
-      _Hashtable_node* _M_next;
-      _Val _M_val;
-    };
-
-  template<class _Val, class _Key, class _HashFcn, class _ExtractKey, 
-	   class _EqualKey, class _Alloc = std::allocator<_Val> >
-    class hashtable;
-
-  template<class _Val, class _Key, class _HashFcn,
-	   class _ExtractKey, class _EqualKey, class _Alloc>
-    struct _Hashtable_iterator;
-
-  template<class _Val, class _Key, class _HashFcn,
-	   class _ExtractKey, class _EqualKey, class _Alloc>
-    struct _Hashtable_const_iterator;
-
-  template<class _Val, class _Key, class _HashFcn,
-	   class _ExtractKey, class _EqualKey, class _Alloc>
-    struct _Hashtable_iterator
-    {
-      typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>
-        _Hashtable;
-      typedef _Hashtable_iterator<_Val, _Key, _HashFcn,
-				  _ExtractKey, _EqualKey, _Alloc>
-        iterator;
-      typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
-					_ExtractKey, _EqualKey, _Alloc>
-        const_iterator;
-      typedef _Hashtable_node<_Val> _Node;
-      typedef forward_iterator_tag iterator_category;
-      typedef _Val value_type;
-      typedef ptrdiff_t difference_type;
-      typedef size_t size_type;
-      typedef _Val& reference;
-      typedef _Val* pointer;
-      
-      _Node* _M_cur;
-      _Hashtable* _M_ht;
-
-      _Hashtable_iterator(_Node* __n, _Hashtable* __tab)
-      : _M_cur(__n), _M_ht(__tab) { }
-
-      _Hashtable_iterator() { }
-
-      reference
-      operator*() const
-      { return _M_cur->_M_val; }
-
-      pointer
-      operator->() const
-      { return &(operator*()); }
-
-      iterator&
-      operator++();
-
-      iterator
-      operator++(int);
-
-      bool
-      operator==(const iterator& __it) const
-      { return _M_cur == __it._M_cur; }
-
-      bool
-      operator!=(const iterator& __it) const
-      { return _M_cur != __it._M_cur; }
-    };
-
-  template<class _Val, class _Key, class _HashFcn,
-	   class _ExtractKey, class _EqualKey, class _Alloc>
-    struct _Hashtable_const_iterator
-    {
-      typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>
-        _Hashtable;
-      typedef _Hashtable_iterator<_Val,_Key,_HashFcn,
-				  _ExtractKey,_EqualKey,_Alloc>
-        iterator;
-      typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
-					_ExtractKey, _EqualKey, _Alloc>
-        const_iterator;
-      typedef _Hashtable_node<_Val> _Node;
-
-      typedef forward_iterator_tag iterator_category;
-      typedef _Val value_type;
-      typedef ptrdiff_t difference_type;
-      typedef size_t size_type;
-      typedef const _Val& reference;
-      typedef const _Val* pointer;
-      
-      const _Node* _M_cur;
-      const _Hashtable* _M_ht;
-
-      _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab)
-      : _M_cur(__n), _M_ht(__tab) { }
-
-      _Hashtable_const_iterator() { }
-
-      _Hashtable_const_iterator(const iterator& __it)
-      : _M_cur(__it._M_cur), _M_ht(__it._M_ht) { }
-
-      reference
-      operator*() const
-      { return _M_cur->_M_val; }
-
-      pointer
-      operator->() const
-      { return &(operator*()); }
-
-      const_iterator&
-      operator++();
-
-      const_iterator
-      operator++(int);
-
-      bool
-      operator==(const const_iterator& __it) const
-      { return _M_cur == __it._M_cur; }
-
-      bool
-      operator!=(const const_iterator& __it) const
-      { return _M_cur != __it._M_cur; }
-    };
-
-  // Note: assumes long is at least 32 bits.
-  enum { _S_num_primes = 28 };
-
-  static const unsigned long __stl_prime_list[_S_num_primes] =
-    {
-      53ul,         97ul,         193ul,       389ul,       769ul,
-      1543ul,       3079ul,       6151ul,      12289ul,     24593ul,
-      49157ul,      98317ul,      196613ul,    393241ul,    786433ul,
-      1572869ul,    3145739ul,    6291469ul,   12582917ul,  25165843ul,
-      50331653ul,   100663319ul,  201326611ul, 402653189ul, 805306457ul,
-      1610612741ul, 3221225473ul, 4294967291ul
-    };
-
-  inline unsigned long
-  __stl_next_prime(unsigned long __n)
-  {
-    const unsigned long* __first = __stl_prime_list;
-    const unsigned long* __last = __stl_prime_list + (int)_S_num_primes;
-    const unsigned long* pos = std::lower_bound(__first, __last, __n);
-    return pos == __last ? *(__last - 1) : *pos;
-  }
-
-  // Forward declaration of operator==.  
-  template<class _Val, class _Key, class _HF, class _Ex,
-	   class _Eq, class _All>
-    class hashtable;
-
-  template<class _Val, class _Key, class _HF, class _Ex,
-	   class _Eq, class _All>
-    bool
-    operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
-	       const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2);
-
-  // Hashtables handle allocators a bit differently than other
-  // containers do.  If we're using standard-conforming allocators, then
-  // a hashtable unconditionally has a member variable to hold its
-  // allocator, even if it so happens that all instances of the
-  // allocator type are identical.  This is because, for hashtables,
-  // this extra storage is negligible.  Additionally, a base class
-  // wouldn't serve any other purposes; it wouldn't, for example,
-  // simplify the exception-handling code.  
-  template<class _Val, class _Key, class _HashFcn,
-	   class _ExtractKey, class _EqualKey, class _Alloc>
-    class hashtable
-    {
-    public:
-      typedef _Key key_type;
-      typedef _Val value_type;
-      typedef _HashFcn hasher;
-      typedef _EqualKey key_equal;
-
-      typedef size_t            size_type;
-      typedef ptrdiff_t         difference_type;
-      typedef value_type*       pointer;
-      typedef const value_type* const_pointer;
-      typedef value_type&       reference;
-      typedef const value_type& const_reference;
-
-      hasher
-      hash_funct() const
-      { return _M_hash; }
-
-      key_equal
-      key_eq() const
-      { return _M_equals; }
-
-    private:
-      typedef _Hashtable_node<_Val> _Node;
-
-    public:
-      typedef typename _Alloc::template rebind<value_type>::other allocator_type;
-      allocator_type
-      get_allocator() const
-      { return _M_node_allocator; }
-
-    private:
-      typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc;
-      typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc;
-      typedef vector<_Node*, _Nodeptr_Alloc> _Vector_type;
-
-      _Node_Alloc _M_node_allocator;
-
-      _Node*
-      _M_get_node()
-      { return _M_node_allocator.allocate(1); }
-
-      void
-      _M_put_node(_Node* __p)
-      { _M_node_allocator.deallocate(__p, 1); }
-
-    private:
-      hasher                _M_hash;
-      key_equal             _M_equals;
-      _ExtractKey           _M_get_key;
-      _Vector_type          _M_buckets;
-      size_type             _M_num_elements;
-      
-    public:
-      typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey,
-				  _EqualKey, _Alloc>
-        iterator;
-      typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
-					_EqualKey, _Alloc>
-        const_iterator;
-
-      friend struct
-      _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>;
-
-      friend struct
-      _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
-				_EqualKey, _Alloc>;
-
-    public:
-      hashtable(size_type __n, const _HashFcn& __hf,
-		const _EqualKey& __eql, const _ExtractKey& __ext,
-		const allocator_type& __a = allocator_type())
-      : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql),
-	_M_get_key(__ext), _M_buckets(__a), _M_num_elements(0)
-      { _M_initialize_buckets(__n); }
-
-      hashtable(size_type __n, const _HashFcn& __hf,
-		const _EqualKey& __eql,
-		const allocator_type& __a = allocator_type())
-      : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql),
-	_M_get_key(_ExtractKey()), _M_buckets(__a), _M_num_elements(0)
-      { _M_initialize_buckets(__n); }
-
-      hashtable(const hashtable& __ht)
-      : _M_node_allocator(__ht.get_allocator()), _M_hash(__ht._M_hash),
-      _M_equals(__ht._M_equals), _M_get_key(__ht._M_get_key),
-      _M_buckets(__ht.get_allocator()), _M_num_elements(0)
-      { _M_copy_from(__ht); }
-
-      hashtable&
-      operator= (const hashtable& __ht)
-      {
-	if (&__ht != this)
-	  {
-	    clear();
-	    _M_hash = __ht._M_hash;
-	    _M_equals = __ht._M_equals;
-	    _M_get_key = __ht._M_get_key;
-	    _M_copy_from(__ht);
-	  }
-	return *this;
-      }
-
-      ~hashtable()
-      { clear(); }
-
-      size_type
-      size() const
-      { return _M_num_elements; }
-
-      size_type
-      max_size() const
-      { return size_type(-1); }
-
-      bool
-      empty() const
-      { return size() == 0; }
-
-      void
-      swap(hashtable& __ht)
-      {
-	std::swap(_M_hash, __ht._M_hash);
-	std::swap(_M_equals, __ht._M_equals);
-	std::swap(_M_get_key, __ht._M_get_key);
-	_M_buckets.swap(__ht._M_buckets);
-	std::swap(_M_num_elements, __ht._M_num_elements);
-      }
-
-      iterator
-      begin()
-      {
-	for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
-	  if (_M_buckets[__n])
-	    return iterator(_M_buckets[__n], this);
-	return end();
-      }
-
-      iterator
-      end()
-      { return iterator(0, this); }
-
-      const_iterator
-      begin() const
-      {
-	for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
-	  if (_M_buckets[__n])
-	    return const_iterator(_M_buckets[__n], this);
-	return end();
-      }
-
-      const_iterator
-      end() const
-      { return const_iterator(0, this); }
-
-      template<class _Vl, class _Ky, class _HF, class _Ex, class _Eq,
-		class _Al>
-        friend bool
-        operator==(const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&,
-		   const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&);
-
-    public:
-      size_type
-      bucket_count() const
-      { return _M_buckets.size(); }
-
-      size_type
-      max_bucket_count() const
-      { return __stl_prime_list[(int)_S_num_primes - 1]; }
-
-      size_type
-      elems_in_bucket(size_type __bucket) const
-      {
-	size_type __result = 0;
-	for (_Node* __n = _M_buckets[__bucket]; __n; __n = __n->_M_next)
-	  __result += 1;
-	return __result;
-      }
-
-      pair<iterator, bool>
-      insert_unique(const value_type& __obj)
-      {
-	resize(_M_num_elements + 1);
-	return insert_unique_noresize(__obj);
-      }
-
-      iterator
-      insert_equal(const value_type& __obj)
-      {
-	resize(_M_num_elements + 1);
-	return insert_equal_noresize(__obj);
-      }
-
-      pair<iterator, bool>
-      insert_unique_noresize(const value_type& __obj);
-
-      iterator
-      insert_equal_noresize(const value_type& __obj);
-
-      template<class _InputIterator>
-        void
-        insert_unique(_InputIterator __f, _InputIterator __l)
-        { insert_unique(__f, __l, __iterator_category(__f)); }
-
-      template<class _InputIterator>
-        void
-        insert_equal(_InputIterator __f, _InputIterator __l)
-        { insert_equal(__f, __l, __iterator_category(__f)); }
-
-      template<class _InputIterator>
-        void
-        insert_unique(_InputIterator __f, _InputIterator __l,
-		      input_iterator_tag)
-        {
-	  for ( ; __f != __l; ++__f)
-	    insert_unique(*__f);
-	}
-
-      template<class _InputIterator>
-        void
-        insert_equal(_InputIterator __f, _InputIterator __l,
-		     input_iterator_tag)
-        {
-	  for ( ; __f != __l; ++__f)
-	    insert_equal(*__f);
-	}
-
-      template<class _ForwardIterator>
-        void
-        insert_unique(_ForwardIterator __f, _ForwardIterator __l,
-		      forward_iterator_tag)
-        {
-	  size_type __n = distance(__f, __l);
-	  resize(_M_num_elements + __n);
-	  for ( ; __n > 0; --__n, ++__f)
-	    insert_unique_noresize(*__f);
-	}
-
-      template<class _ForwardIterator>
-        void
-        insert_equal(_ForwardIterator __f, _ForwardIterator __l,
-		     forward_iterator_tag)
-        {
-	  size_type __n = distance(__f, __l);
-	  resize(_M_num_elements + __n);
-	  for ( ; __n > 0; --__n, ++__f)
-	    insert_equal_noresize(*__f);
-	}
-
-      reference
-      find_or_insert(const value_type& __obj);
-
-      iterator
-      find(const key_type& __key)
-      {
-	size_type __n = _M_bkt_num_key(__key);
-	_Node* __first;
-	for (__first = _M_buckets[__n];
-	     __first && !_M_equals(_M_get_key(__first->_M_val), __key);
-	     __first = __first->_M_next)
-	  { }
-	return iterator(__first, this);
-      }
-
-      const_iterator
-      find(const key_type& __key) const
-      {
-	size_type __n = _M_bkt_num_key(__key);
-	const _Node* __first;
-	for (__first = _M_buckets[__n];
-	     __first && !_M_equals(_M_get_key(__first->_M_val), __key);
-	     __first = __first->_M_next)
-	  { }
-	return const_iterator(__first, this);
-      }
-
-      size_type
-      count(const key_type& __key) const
-      {
-	const size_type __n = _M_bkt_num_key(__key);
-	size_type __result = 0;
-	
-	for (const _Node* __cur = _M_buckets[__n]; __cur;
-	     __cur = __cur->_M_next)
-	  if (_M_equals(_M_get_key(__cur->_M_val), __key))
-	    ++__result;
-	return __result;
-      }
-
-      pair<iterator, iterator>
-      equal_range(const key_type& __key);
-
-      pair<const_iterator, const_iterator>
-      equal_range(const key_type& __key) const;
-
-      size_type
-      erase(const key_type& __key);
-      
-      void
-      erase(const iterator& __it);
-
-      void
-      erase(iterator __first, iterator __last);
-
-      void
-      erase(const const_iterator& __it);
-
-      void
-      erase(const_iterator __first, const_iterator __last);
-
-      void
-      resize(size_type __num_elements_hint);
-
-      void
-      clear();
-
-    private:
-      size_type
-      _M_next_size(size_type __n) const
-      { return __stl_next_prime(__n); }
-
-      void
-      _M_initialize_buckets(size_type __n)
-      {
-	const size_type __n_buckets = _M_next_size(__n);
-	_M_buckets.reserve(__n_buckets);
-	_M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0);
-	_M_num_elements = 0;
-        __profcxx_hashtable_construct(this, __n_buckets);
-        __profcxx_hashtable_construct2(this);
-      }
-
-      size_type
-      _M_bkt_num_key(const key_type& __key) const
-      { return _M_bkt_num_key(__key, _M_buckets.size()); }
-
-      size_type
-      _M_bkt_num(const value_type& __obj) const
-      { return _M_bkt_num_key(_M_get_key(__obj)); }
-
-      size_type
-      _M_bkt_num_key(const key_type& __key, size_t __n) const
-      { return _M_hash(__key) % __n; }
-
-      size_type
-      _M_bkt_num(const value_type& __obj, size_t __n) const
-      { return _M_bkt_num_key(_M_get_key(__obj), __n); }
-
-      _Node*
-      _M_new_node(const value_type& __obj)
-      {
-	_Node* __n = _M_get_node();
-	__n->_M_next = 0;
-	try
-	  {
-	    this->get_allocator().construct(&__n->_M_val, __obj);
-	    return __n;
-	  }
-	catch(...)
-	  {
-	    _M_put_node(__n);
-	    __throw_exception_again;
-	  }
-      }
-
-      void
-      _M_delete_node(_Node* __n)
-      {
-	this->get_allocator().destroy(&__n->_M_val);
-	_M_put_node(__n);
-      }
-      
-      void
-      _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last);
-
-      void
-      _M_erase_bucket(const size_type __n, _Node* __last);
-
-      void
-      _M_copy_from(const hashtable& __ht);
-    };
-
-  template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
-	    class _All>
-    _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>&
-    _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
-    operator++()
-    {
-      const _Node* __old = _M_cur;
-      _M_cur = _M_cur->_M_next;
-      if (!_M_cur)
-	{
-	  size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
-	  while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
-	    _M_cur = _M_ht->_M_buckets[__bucket];
-	}
-      return *this;
-    }
-
-  template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
-	    class _All>
-    inline _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>
-    _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
-    operator++(int)
-    {
-      iterator __tmp = *this;
-      ++*this;
-      return __tmp;
-    }
-
-  template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
-	    class _All>
-    _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>&
-    _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
-    operator++()
-    {
-      const _Node* __old = _M_cur;
-      _M_cur = _M_cur->_M_next;
-      if (!_M_cur)
-	{
-	  size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
-	  while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
-	    _M_cur = _M_ht->_M_buckets[__bucket];
-	}
-      return *this;
-    }
-
-  template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
-	    class _All>
-    inline _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>
-    _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
-    operator++(int)
-    {
-      const_iterator __tmp = *this;
-      ++*this;
-      return __tmp;
-    }
-
-  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-    bool
-    operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
-	       const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2)
-    {
-      typedef typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_Node _Node;
-
-      if (__ht1._M_buckets.size() != __ht2._M_buckets.size())
-	return false;
-
-      for (size_t __n = 0; __n < __ht1._M_buckets.size(); ++__n)
-	{
-	  _Node* __cur1 = __ht1._M_buckets[__n];
-	  _Node* __cur2 = __ht2._M_buckets[__n];
-	  // Check same length of lists
-	  for (; __cur1 && __cur2;
-	       __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next)
-	    { } 
-	  if (__cur1 || __cur2)
-	    return false;
-	  // Now check one's elements are in the other
-	  for (__cur1 = __ht1._M_buckets[__n] ; __cur1;
-	       __cur1 = __cur1->_M_next)
-	    {
-	      bool _found__cur1 = false;
-	      for (__cur2 = __ht2._M_buckets[__n];
-		   __cur2; __cur2 = __cur2->_M_next)
-		{
-		  if (__cur1->_M_val == __cur2->_M_val)
-		    {
-		      _found__cur1 = true;
-		      break;
-		    }
-		}
-	      if (!_found__cur1)
-		return false;
-	    }
-	}
-      return true;
-    }
-
-  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-    inline bool
-    operator!=(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
-	       const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2)
-    { return !(__ht1 == __ht2); }
-
-  template<class _Val, class _Key, class _HF, class _Extract, class _EqKey,
-	    class _All>
-    inline void
-    swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1,
-	 hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2)
-    { __ht1.swap(__ht2); }
-
-  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-    pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator, bool>
-    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
-    insert_unique_noresize(const value_type& __obj)
-    {
-      const size_type __n = _M_bkt_num(__obj);
-      _Node* __first = _M_buckets[__n];
-      
-      for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
-	if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
-	  return pair<iterator, bool>(iterator(__cur, this), false);
-      
-      _Node* __tmp = _M_new_node(__obj);
-      __tmp->_M_next = __first;
-      _M_buckets[__n] = __tmp;
-      ++_M_num_elements;
-      return pair<iterator, bool>(iterator(__tmp, this), true);
-    }
-
-  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-    typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator
-    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
-    insert_equal_noresize(const value_type& __obj)
-    {
-      const size_type __n = _M_bkt_num(__obj);
-      _Node* __first = _M_buckets[__n];
-      
-      for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
-	if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
-	  {
-	    _Node* __tmp = _M_new_node(__obj);
-	    __tmp->_M_next = __cur->_M_next;
-	    __cur->_M_next = __tmp;
-	    ++_M_num_elements;
-	    return iterator(__tmp, this);
-	  }
-
-      _Node* __tmp = _M_new_node(__obj);
-      __tmp->_M_next = __first;
-      _M_buckets[__n] = __tmp;
-      ++_M_num_elements;
-      return iterator(__tmp, this);
-    }
-
-  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-    typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::reference
-    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
-    find_or_insert(const value_type& __obj)
-    {
-      resize(_M_num_elements + 1);
-
-      size_type __n = _M_bkt_num(__obj);
-      _Node* __first = _M_buckets[__n];
-      
-      for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
-	if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
-	  return __cur->_M_val;
-      
-      _Node* __tmp = _M_new_node(__obj);
-      __tmp->_M_next = __first;
-      _M_buckets[__n] = __tmp;
-      ++_M_num_elements;
-      return __tmp->_M_val;
-    }
-
-  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-    pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator,
-	 typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator>
-    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
-    equal_range(const key_type& __key)
-    {
-      typedef pair<iterator, iterator> _Pii;
-      const size_type __n = _M_bkt_num_key(__key);
-
-      for (_Node* __first = _M_buckets[__n]; __first;
-	   __first = __first->_M_next)
-	if (_M_equals(_M_get_key(__first->_M_val), __key))
-	  {
-	    for (_Node* __cur = __first->_M_next; __cur;
-		 __cur = __cur->_M_next)
-	      if (!_M_equals(_M_get_key(__cur->_M_val), __key))
-		return _Pii(iterator(__first, this), iterator(__cur, this));
-	    for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
-	      if (_M_buckets[__m])
-		return _Pii(iterator(__first, this),
-			    iterator(_M_buckets[__m], this));
-	    return _Pii(iterator(__first, this), end());
-	  }
-      return _Pii(end(), end());
-    }
-
-  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-    pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator,
-	 typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator>
-    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
-    equal_range(const key_type& __key) const
-    {
-      typedef pair<const_iterator, const_iterator> _Pii;
-      const size_type __n = _M_bkt_num_key(__key);
-
-      for (const _Node* __first = _M_buckets[__n]; __first;
-	   __first = __first->_M_next)
-	{
-	  if (_M_equals(_M_get_key(__first->_M_val), __key))
-	    {
-	      for (const _Node* __cur = __first->_M_next; __cur;
-		   __cur = __cur->_M_next)
-		if (!_M_equals(_M_get_key(__cur->_M_val), __key))
-		  return _Pii(const_iterator(__first, this),
-			      const_iterator(__cur, this));
-	      for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
-		if (_M_buckets[__m])
-		  return _Pii(const_iterator(__first, this),
-			      const_iterator(_M_buckets[__m], this));
-	      return _Pii(const_iterator(__first, this), end());
-	    }
-	}
-      return _Pii(end(), end());
-    }
-
-  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-    typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::size_type
-    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
-    erase(const key_type& __key)
-    {
-      const size_type __n = _M_bkt_num_key(__key);
-      _Node* __first = _M_buckets[__n];
-      size_type __erased = 0;
-      
-      if (__first)
-	{
-	  _Node* __cur = __first;
-	  _Node* __next = __cur->_M_next;
-	  while (__next)
-	    {
-	      if (_M_equals(_M_get_key(__next->_M_val), __key))
-		{
-		  __cur->_M_next = __next->_M_next;
-		  _M_delete_node(__next);
-		  __next = __cur->_M_next;
-		  ++__erased;
-		  --_M_num_elements;
-		}
-	      else
-		{
-		  __cur = __next;
-		  __next = __cur->_M_next;
-		}
-	    }
-	  if (_M_equals(_M_get_key(__first->_M_val), __key))
-	    {
-	      _M_buckets[__n] = __first->_M_next;
-	      _M_delete_node(__first);
-	      ++__erased;
-	      --_M_num_elements;
-	    }
-	}
-      return __erased;
-    }
-
-  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-    void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
-    erase(const iterator& __it)
-    {
-      _Node* __p = __it._M_cur;
-      if (__p)
-	{
-	  const size_type __n = _M_bkt_num(__p->_M_val);
-	  _Node* __cur = _M_buckets[__n];
-	  
-	  if (__cur == __p)
-	    {
-	      _M_buckets[__n] = __cur->_M_next;
-	      _M_delete_node(__cur);
-	      --_M_num_elements;
-	    }
-	  else
-	    {
-	      _Node* __next = __cur->_M_next;
-	      while (__next)
-		{
-		  if (__next == __p)
-		    {
-		      __cur->_M_next = __next->_M_next;
-		      _M_delete_node(__next);
-		      --_M_num_elements;
-		      break;
-		    }
-		  else
-		    {
-		      __cur = __next;
-		      __next = __cur->_M_next;
-		    }
-		}
-	    }
-	}
-    }
-
-  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-    void
-    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
-    erase(iterator __first, iterator __last)
-    {
-      size_type __f_bucket = __first._M_cur ? _M_bkt_num(__first._M_cur->_M_val)
-	                                    : _M_buckets.size();
-
-      size_type __l_bucket = __last._M_cur ? _M_bkt_num(__last._M_cur->_M_val)
-	                                   : _M_buckets.size();
-
-      if (__first._M_cur == __last._M_cur)
-	return;
-      else if (__f_bucket == __l_bucket)
-	_M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur);
-      else
-	{
-	  _M_erase_bucket(__f_bucket, __first._M_cur, 0);
-	  for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n)
-	    _M_erase_bucket(__n, 0);
-	  if (__l_bucket != _M_buckets.size())
-	    _M_erase_bucket(__l_bucket, __last._M_cur);
-	}
-    }
-
-  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-    inline void
-    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
-    erase(const_iterator __first, const_iterator __last)
-    {
-      erase(iterator(const_cast<_Node*>(__first._M_cur),
-		     const_cast<hashtable*>(__first._M_ht)),
-	    iterator(const_cast<_Node*>(__last._M_cur),
-		     const_cast<hashtable*>(__last._M_ht)));
-    }
-
-  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-    inline void
-    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
-    erase(const const_iterator& __it)
-    { erase(iterator(const_cast<_Node*>(__it._M_cur),
-		     const_cast<hashtable*>(__it._M_ht))); }
-
-  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-    void
-    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
-    resize(size_type __num_elements_hint)
-    {
-      const size_type __old_n = _M_buckets.size();
-      if (__num_elements_hint > __old_n)
-	{
-	  const size_type __n = _M_next_size(__num_elements_hint);
-	  if (__n > __old_n)
-	    {
-	      _Vector_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator());
-	      try
-		{
-		  for (size_type __bucket = 0; __bucket < __old_n; ++__bucket)
-		    {
-		      _Node* __first = _M_buckets[__bucket];
-		      while (__first)
-			{
-			  size_type __new_bucket = _M_bkt_num(__first->_M_val,
-							      __n);
-			  _M_buckets[__bucket] = __first->_M_next;
-			  __first->_M_next = __tmp[__new_bucket];
-			  __tmp[__new_bucket] = __first;
-			  __first = _M_buckets[__bucket];
-			}
-		    }
-		  _M_buckets.swap(__tmp);
-		}
-	      catch(...)
-		{
-		  for (size_type __bucket = 0; __bucket < __tmp.size();
-		       ++__bucket)
-		    {
-		      while (__tmp[__bucket])
-			{
-			  _Node* __next = __tmp[__bucket]->_M_next;
-			  _M_delete_node(__tmp[__bucket]);
-			  __tmp[__bucket] = __next;
-			}
-		    }
-		  __throw_exception_again;
-		}
-        __profcxx_hashtable_resize(this, __num_elements_hint, __n);
-	    }
-	}
-    }
-
-  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-    void
-    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
-    _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last)
-    {
-      _Node* __cur = _M_buckets[__n];
-      if (__cur == __first)
-	_M_erase_bucket(__n, __last);
-      else
-	{
-	  _Node* __next;
-	  for (__next = __cur->_M_next;
-	       __next != __first;
-	       __cur = __next, __next = __cur->_M_next)
-	    ;
-	  while (__next != __last)
-	    {
-	      __cur->_M_next = __next->_M_next;
-	      _M_delete_node(__next);
-	      __next = __cur->_M_next;
-	      --_M_num_elements;
-	    }
-	}
-    }
-
-  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-    void
-    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
-    _M_erase_bucket(const size_type __n, _Node* __last)
-    {
-      _Node* __cur = _M_buckets[__n];
-      while (__cur != __last)
-	{
-	  _Node* __next = __cur->_M_next;
-	  _M_delete_node(__cur);
-	  __cur = __next;
-	  _M_buckets[__n] = __cur;
-	  --_M_num_elements;
-	}
-    }
-
-  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-    void
-    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
-    clear()
-    {
-      size_type __hops=0, __lc = 0, __chain = 0;
-      if (_M_num_elements != 0) 
-         __profcxx_hashtable_destruct(this, _M_buckets.size(), _M_num_elements);
-      
-      for (size_type __i = 0; __i < _M_buckets.size(); ++__i)
-	{
-	  _Node* __cur = _M_buckets[__i];
-	  while (__cur != 0)
-	    {
-	      _Node* __next = __cur->_M_next;
-	      _M_delete_node(__cur);
-	      __cur = __next;
-
-          // Compute the longest chain count.
-          __chain++;
-	    }
-	  _M_buckets[__i] = 0;
-
-      // Collect number of hops.
-      if (__chain > 1) {
-        __lc = __lc > __chain ? __lc : __chain;
-        __hops += (__chain-1) * __chain / 2;
-      }
-      __chain = 0;
-	}
-      if (_M_num_elements) {
-        __profcxx_hashtable_destruct2(this, __lc, _M_num_elements, __hops);
-      }
-      _M_num_elements = 0;
-    }
-
-  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-    void
-    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
-    _M_copy_from(const hashtable& __ht)
-    {
-      _M_buckets.clear();
-      _M_buckets.reserve(__ht._M_buckets.size());
-      _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0);
-      try
-	{
-	  for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) {
-	    const _Node* __cur = __ht._M_buckets[__i];
-	    if (__cur)
-	      {
-		_Node* __local_copy = _M_new_node(__cur->_M_val);
-		_M_buckets[__i] = __local_copy;
-		
-		for (_Node* __next = __cur->_M_next;
-		     __next;
-		     __cur = __next, __next = __cur->_M_next)
-		  {
-		    __local_copy->_M_next = _M_new_node(__next->_M_val);
-		    __local_copy = __local_copy->_M_next;
-		  }
-	      }
-	  }
-	  _M_num_elements = __ht._M_num_elements;
-	}
-      catch(...)
-	{
-	  clear();
-	  __throw_exception_again;
-	}
-    }
-
-_GLIBCXX_END_NAMESPACE
-
-#endif
Index: include/profile/iterator_tracker.h
===================================================================
--- include/profile/iterator_tracker.h	(revision 0)
+++ include/profile/iterator_tracker.h	(revision 0)
@@ -0,0 +1,273 @@
+#ifndef _GLIBCXX_PROFILE_ITERATOR_TRACKER
+#define _GLIBCXX_PROFILE_ITERATOR_TRACKER 1
+
+#include <ext/type_traits.h>
+
+namespace std
+{
+namespace __profile
+{
+
+template<typename _Iterator, typename _Sequence>
+class __iterator_tracker 
+{
+  typedef __iterator_tracker _Self;
+  // The underlying iterator
+  _Iterator _M_current;
+  // The underlying data structure
+  const _Sequence* _M_ds;
+  typedef std::iterator_traits<_Iterator> _Traits;
+
+ public:
+  typedef _Iterator		              _Base_iterator;
+  typedef typename _Traits::iterator_category iterator_category; 
+  typedef typename _Traits::value_type        value_type;
+  typedef typename _Traits::difference_type   difference_type;
+  typedef typename _Traits::reference         reference;
+  typedef typename _Traits::pointer           pointer;
+
+  __iterator_tracker() : _M_current(), _M_ds(0) { }
+  __iterator_tracker(const _Iterator& __i, const _Sequence* seq) 
+      : _M_current(__i), _M_ds(seq) { }
+  __iterator_tracker(const __iterator_tracker& __x) 
+      : _M_current(__x._M_current), _M_ds(__x._M_ds) { }
+  template<typename _MutableIterator>
+  __iterator_tracker(const __iterator_tracker<_MutableIterator, typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator, typename _Sequence::iterator::_Base_iterator>::__value), _Sequence>::__type>& __x)
+      :  _M_current(__x.base()), _M_ds(__x._M_get_sequence()) { }
+
+  _Iterator
+  base() const { return _M_current; }
+  /**
+   * @brief Conversion to underlying non-debug iterator to allow
+   * better interaction with non-profile containers.
+   */
+  operator _Iterator() const { return _M_current; }
+
+  pointer
+  operator->() const { return &*_M_current; }
+
+  __iterator_tracker&
+  operator++()
+  {
+    _M_ds->_M_profile_iterate();
+    ++_M_current;
+    return *this;
+  }
+
+  __iterator_tracker&
+  operator++(int)
+  {
+    _M_ds->_M_profile_iterate();
+    __iterator_tracker __tmp(*this);
+    ++_M_current;
+    return __tmp;
+  }
+
+  __iterator_tracker&
+  operator--()
+  {
+    _M_ds->_M_profile_iterate(1);
+    --_M_current;
+    return *this;
+  }
+
+  __iterator_tracker&
+  operator--(int)
+  {
+    _M_ds->_M_profile_iterate(1);
+    __iterator_tracker __tmp(*this);
+    --_M_current;
+    return __tmp;
+  }
+
+  __iterator_tracker&
+  operator=(const __iterator_tracker& __x)
+  {
+    _M_current = __x._M_current;
+    return *this;
+  }
+
+  reference
+  operator*() const
+  {
+    return *_M_current;
+  }
+
+ // ------ Random access iterator requirements ------
+  reference
+  operator[](const difference_type& __n) const 
+  {
+    return _M_current[__n];
+  }
+
+  __iterator_tracker&
+  operator+=(const difference_type& __n)
+  {
+    _M_current += __n;
+    return *this;
+  }
+
+  __iterator_tracker
+  operator+(const difference_type& __n) const
+  {
+    __iterator_tracker __tmp(*this);
+    __tmp += __n;
+    return __tmp;
+  }
+
+  __iterator_tracker&
+  operator-=(const difference_type& __n)
+  {
+    _M_current += -__n;
+    return *this;
+  }
+
+  __iterator_tracker
+  operator-(const difference_type& __n) const
+  {
+    __iterator_tracker __tmp(*this);
+    __tmp -= __n;
+    return __tmp;
+  }
+
+  void
+  _M_find()
+  {
+    _M_ds->_M_profile_find();
+  }
+
+  const _Sequence*
+  _M_get_sequence() const
+  {
+    return static_cast<const _Sequence*>(_M_ds);
+  }
+};
+
+template<typename _IteratorL, typename _IteratorR, typename _Sequence>
+inline bool
+operator==(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
+           const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
+{
+  return __lhs.base() == __rhs.base();
+}
+
+template<typename _Iterator, typename _Sequence>
+inline bool
+operator==(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
+           const __iterator_tracker<_Iterator, _Sequence>& __rhs)
+{
+  return __lhs.base() == __rhs.base();
+}
+
+template<typename _IteratorL, typename _IteratorR, typename _Sequence>
+inline bool
+operator!=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
+           const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
+{
+  return __lhs.base() != __rhs.base();
+}
+
+template<typename _Iterator, typename _Sequence>
+inline bool
+operator!=(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
+               const __iterator_tracker<_Iterator, _Sequence>& __rhs)
+{
+  return __lhs.base() != __rhs.base();
+}
+
+template<typename _IteratorL, typename _IteratorR, typename _Sequence>
+inline bool
+operator<(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
+          const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
+{
+  return __lhs.base() < __rhs.base();
+}
+
+template<typename _Iterator, typename _Sequence>
+inline bool
+operator<(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
+          const __iterator_tracker<_Iterator, _Sequence>& __rhs)
+{
+  return __lhs.base() < __rhs.base();
+}
+
+template<typename _IteratorL, typename _IteratorR, typename _Sequence>
+inline bool
+operator<=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
+           const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
+{
+  return __lhs.base() <= __rhs.base();
+}
+
+template<typename _Iterator, typename _Sequence>
+inline bool
+operator<=(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
+           const __iterator_tracker<_Iterator, _Sequence>& __rhs)
+{
+  return __lhs.base() <= __rhs.base();
+}
+
+template<typename _IteratorL, typename _IteratorR, typename _Sequence>
+inline bool
+operator>(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
+          const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
+{
+  return __lhs.base() > __rhs.base();
+}
+
+template<typename _Iterator, typename _Sequence>
+inline bool
+operator>(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
+          const __iterator_tracker<_Iterator, _Sequence>& __rhs)
+{
+  return __lhs.base() > __rhs.base();
+}
+
+template<typename _IteratorL, typename _IteratorR, typename _Sequence>
+inline bool
+operator>=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
+           const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
+{
+  return __lhs.base() >= __rhs.base();
+}
+
+template<typename _Iterator, typename _Sequence>
+inline bool
+operator>=(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
+           const __iterator_tracker<_Iterator, _Sequence>& __rhs)
+{
+  return __lhs.base() >= __rhs.base();
+}
+
+// _GLIBCXX_RESOLVE_LIB_DEFECTS
+// According to the resolution of DR179 not only the various comparison
+// operators but also operator- must accept mixed iterator/const_iterator
+// parameters.
+  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
+  inline typename __iterator_tracker<_IteratorL, _Sequence>::difference_type
+  operator-(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
+            const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
+{
+  return __lhs.base() - __rhs.base();
+}
+
+template<typename _Iterator, typename _Sequence>
+inline typename __iterator_tracker<_Iterator, _Sequence>::difference_type
+operator-(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
+          const __iterator_tracker<_Iterator, _Sequence>& __rhs)
+{
+  return __lhs.base() - __rhs.base();
+}
+
+template<typename _Iterator, typename _Sequence>
+inline __iterator_tracker<_Iterator, _Sequence>
+operator+(typename __iterator_tracker<_Iterator,_Sequence>::difference_type
+          __n,
+          const __iterator_tracker<_Iterator, _Sequence>& __i)
+{
+  return __i + __n;
+}
+		
+}  // namespace __profile
+}  // namespace std
+#endif
Index: include/profile/impl/profiler_list_to_slist.h
===================================================================
--- include/profile/impl/profiler_list_to_slist.h	(revision 0)
+++ include/profile/impl/profiler_list_to_slist.h	(revision 0)
@@ -0,0 +1,182 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License as published by the Free Software
+// Foundation; either version 2, or (at your option) any later
+// version.
+
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/** @file profile/impl/profiler_list_to_slist.h
+ *  @brief Diagnostics for list to slist.
+ */
+
+// Written by Changhee Jung.
+
+#ifndef _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H
+#define _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H 1
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#endif
+#include "profile/impl/profiler.h"
+#include "profile/impl/profiler_node.h"
+#include "profile/impl/profiler_trace.h"
+
+namespace __gnu_profile
+{
+
+class __list2slist_info: public __object_info_base
+{
+ public:
+  __list2slist_info() : _M_rewind(false), _M_operations(0) {}
+  __list2slist_info(__stack_t __stack) 
+      : _M_rewind(false), _M_operations(0),__object_info_base(__stack) {}
+  virtual ~__list2slist_info() {}
+  __list2slist_info(const __list2slist_info& __o) : __object_info_base(__o)
+  { _M_rewind = __o._M_rewind; _M_operations = __o._M_operations; }
+  // XXX: the magnitude should be multiplied with a constant factor F,
+  // where F is 1 when the malloc size class of list nodes is different
+  // from the malloc size class of slist nodes.  When they fall into the same
+  // class, the only slist benefit is from having to set fewer links, so
+  // the factor F should be much smaller, closer to 0 than to 1.
+  // This could be implemented by passing the size classes in the config file.
+  // For now, we always assume F to be 1.
+  float __magnitude() const
+  { if (!_M_rewind) return _M_operations; else return 0; }
+  void __merge(const __list2slist_info& __o) {};
+  void __write(FILE* __f) const;
+  const char* __advice() const
+  { return strdup("change std::list to std::forward_list"); }
+  void __opr_rewind() { _M_rewind = true; _M_valid = false;}
+  void __record_operation() { _M_operations++; }
+  bool __has_rewind() { return _M_rewind; }
+
+private:
+  bool _M_rewind;
+  size_t _M_operations;
+};
+
+class __list2slist_stack_info: public __list2slist_info {
+ public:
+  __list2slist_stack_info(const __list2slist_info& __o) 
+      : __list2slist_info(__o) {}
+};
+
+class __trace_list_to_slist
+    : public __trace_base<__list2slist_info, __list2slist_stack_info> 
+{
+ public:
+  ~__trace_list_to_slist() {}
+  __trace_list_to_slist() 
+      : __trace_base<__list2slist_info, __list2slist_stack_info>()
+  { __id = "list-to-slist"; }
+  void __opr_rewind(const void* __obj);
+  void __record_operation(const void* __obj);
+  void __insert(const __object_t __obj, __stack_t __stack)
+  { __add_object(__obj, __list2slist_info(__stack)); }
+  void __destruct(const void* __obj);
+};
+
+inline void __list2slist_info::__write(FILE* __f) const
+{
+  fprintf(__f, "%s\n", _M_rewind ? "invalid" : "valid");
+}
+
+inline void __trace_list_to_slist::__destruct(const void* __obj)
+{
+  if (!__is_on())
+    return;
+
+  __list2slist_info* __res = __get_object_info(__obj);
+  if (!__res)
+    return;
+
+  __retire_object(__obj);
+}
+
+inline void __trace_list_to_slist_init()
+{
+  _GLIBCXX_PROFILE_DATA(_S_list_to_slist) = new __trace_list_to_slist();
+}
+
+inline void __trace_list_to_slist_report(FILE* __f, 
+                                       __warning_vector_t& __warnings)
+{
+  if (_GLIBCXX_PROFILE_DATA(_S_list_to_slist)) {
+    _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__collect_warnings(__warnings);
+    _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__write(__f);
+  }
+}
+
+inline void __trace_list_to_slist::__opr_rewind(const void* __obj)
+{
+  __list2slist_info* __res = __get_object_info(__obj);
+  if (__res)
+    __res->__opr_rewind();
+}
+
+inline void __trace_list_to_slist::__record_operation(const void* __obj)
+{
+  __list2slist_info* __res = __get_object_info(__obj);
+  if (__res)
+    __res->__record_operation();
+}
+
+inline void __trace_list_to_slist_rewind(const void* __obj) 
+{
+  if (!__profcxx_init()) return;
+
+  _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__opr_rewind(__obj);
+}
+
+inline void __trace_list_to_slist_operation(const void* __obj) 
+{
+  if (!__profcxx_init()) return;
+
+  _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__record_operation(__obj);
+}
+
+inline void __trace_list_to_slist_construct(const void* __obj)
+{
+  if (!__profcxx_init()) return;
+
+  _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__insert(__obj, __get_stack());
+}
+
+inline void __trace_list_to_slist_destruct(const void* __obj)
+{
+  if (!__profcxx_init()) return;
+
+  _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__destruct(__obj);
+}
+
+} // namespace __gnu_profile
+#endif /* _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H */
Index: include/profile/impl/profiler_container_size.h
===================================================================
--- include/profile/impl/profiler_container_size.h	(revision 155631)
+++ include/profile/impl/profiler_container_size.h	(working copy)
@@ -47,214 +47,196 @@
 #include <string.h>
 #endif
 
+#include <sstream>
+
 #include "profile/impl/profiler.h"
 #include "profile/impl/profiler_node.h"
 #include "profile/impl/profiler_trace.h"
 
 namespace __gnu_profile
 {
-  /** @brief A container size instrumentation line in the object table.  */
-  class __container_size_info: public __object_info_base
-  {
-  public:
-    __container_size_info();
-    __container_size_info(const __container_size_info& __o);
-    __container_size_info(__stack_t __stack, size_t __num);
-    virtual ~__container_size_info() { }
 
-    void __write(FILE* f) const;
-    float __magnitude() const { return static_cast<float>(_M_cost); }
-    const char* __advice() const;
+/** @brief A container size instrumentation line in the object table.  */
+class __container_size_info: public __object_info_base 
+{
+ public:
+  __container_size_info();
+  __container_size_info(const __container_size_info& __o);
+  __container_size_info(__stack_t __stack, size_t __num);
+  virtual ~__container_size_info() {}
 
-    void __merge(const __container_size_info& __o);
+  void __write(FILE* f) const;
+  float __magnitude() const { return static_cast<float>(_M_cost); }
+  const char* __advice() const;
 
-    // Call if a container is destructed or cleaned.
-    void __destruct(size_t __num, size_t __inum);
+  void __merge(const __container_size_info& __o);
+  // Call if a container is destructed or cleaned.
+  void __destruct(size_t __num, size_t __inum);
+  // Estimate the cost of resize/rehash. 
+  float __resize_cost(size_t __from, size_t __to) { return __from; }
+  // Call if container is resized.
+  void __resize(size_t __from, size_t __to);
 
-    // Estimate the cost of resize/rehash.
-    float __resize_cost(size_t __from, size_t __to) { return __from; }
+ private:
+  size_t _M_init;
+  size_t _M_max;  // range of # buckets
+  size_t _M_min;
+  size_t _M_total;
+  size_t _M_item_min;  // range of # items
+  size_t _M_item_max;
+  size_t _M_item_total;
+  size_t _M_count;
+  size_t _M_resize;
+  size_t _M_cost;
+};
 
-    // Call if container is resized.
-    void __resize(size_t __from, size_t __to);
+inline const char* __container_size_info::__advice() const
+{
+  std::stringstream __message;
+  if (_M_init < _M_item_max)
+    __message << "change initial container size from " << _M_init
+              << " to " << _M_item_max;
 
-  private:
-    size_t _M_init;
-    size_t _M_max;  // Range of # buckets.
-    size_t _M_min;
-    size_t _M_total;
-    size_t _M_item_min;  // Range of # items.
-    size_t _M_item_max;
-    size_t _M_item_total;
-    size_t _M_count;
-    size_t _M_resize;
-    size_t _M_cost;
-  };
+  return strdup(__message.str().c_str());
+}
 
-  inline const char* 
-  __container_size_info::__advice() const
-  {
-    const size_t __max_chars_size_t_printed = 20;
-    const char* __message_pattern =
-      "change initial container size from %d to %d";
-    size_t __message_size = (strlen(__message_pattern)
-			     + 2 * __max_chars_size_t_printed
-			     - 2 * 2);
-    char* __message = new char[__message_size + 1];
-
-    if (_M_init < _M_item_max)
-      snprintf(__message, __message_size, __message_pattern, _M_init,
-	       _M_item_max);
-    else
-      snprintf(__message, __message_size, __message_pattern, _M_init,
-	       _M_item_max);
-
-    return __message;
+inline void __container_size_info::__destruct(size_t __num, size_t __inum) 
+{
+  _M_max = __max(_M_max, __num);
+  _M_item_max = __max(_M_item_max, __inum);
+  if (_M_min == 0) {
+    _M_min = __num; 
+    _M_item_min = __inum;
+  } else {
+    _M_min = __min(_M_min, __num);
+    _M_item_min = __min(_M_item_min, __inum);
   }
+  _M_total += __num;
+  _M_item_total += __inum;
+  _M_count += 1;
+}
 
-  inline void 
-  __container_size_info::__destruct(size_t __num, size_t __inum)
-  {
-    _M_max = __max(_M_max, __num);
-    _M_item_max = __max(_M_item_max, __inum);
-    if (_M_min == 0) 
-      {
-	_M_min = __num;
-	_M_item_min = __inum;
-      } 
-    else 
-      {
-	_M_min = __min(_M_min, __num);
-	_M_item_min = __min(_M_item_min, __inum);
-      }
-    _M_total += __num;
-    _M_item_total += __inum;
-    _M_count += 1;
-  }
+inline void __container_size_info::__resize(size_t __from, size_t __to) 
+{
+  _M_cost += this->__resize_cost(__from, __to);
+  _M_resize += 1;
+  _M_max = __max(_M_max, __to);
+}
 
-  inline void 
-  __container_size_info::__resize(size_t __from, size_t __to)
-  {
-    _M_cost += this->__resize_cost(__from, __to);
-    _M_resize += 1;
-    _M_max = __max(_M_max, __to);
-  }
+inline __container_size_info::__container_size_info(__stack_t __stack, 
+                                                    size_t __num)
+    : __object_info_base(__stack), _M_init(0), _M_max(0), _M_item_max(0), 
+      _M_min(0), _M_item_min(0), _M_total(0), _M_item_total(0), _M_cost(0), 
+      _M_count(0), _M_resize(0)
+{
+  _M_init = _M_max = __num;
+  _M_item_min = _M_item_max = _M_item_total = _M_total = 0;
+  _M_min = 0;
+  _M_count = 0;
+  _M_resize = 0;
+}
 
-  inline void 
-  __container_size_info::__merge(const __container_size_info& __o)
-  {
-    _M_init        = __max(_M_init, __o._M_init);
-    _M_max         = __max(_M_max, __o._M_max);
-    _M_item_max    = __max(_M_item_max, __o._M_item_max);
-    _M_min         = __min(_M_min, __o._M_min);
-    _M_item_min    = __min(_M_item_min, __o._M_item_min);
-    _M_total      += __o._M_total;
-    _M_item_total += __o._M_item_total;
-    _M_count      += __o._M_count;
-    _M_cost       += __o._M_cost;
-    _M_resize     += __o._M_resize;
-  }
+inline void __container_size_info::__merge(const __container_size_info& __o)
+{
+  _M_init        = __max(_M_init, __o._M_init);
+  _M_max         = __max(_M_max, __o._M_max);
+  _M_item_max    = __max(_M_item_max, __o._M_item_max);
+  _M_min         = __min(_M_min, __o._M_min);
+  _M_item_min    = __min(_M_item_min, __o._M_item_min);
+  _M_total      += __o._M_total;
+  _M_item_total += __o._M_item_total;
+  _M_count      += __o._M_count;
+  _M_cost       += __o._M_cost;
+  _M_resize     += __o._M_resize;
+}
 
-  inline __container_size_info::__container_size_info()
-  : _M_init(0), _M_max(0), _M_item_max(0), _M_min(0), _M_item_min(0),
-    _M_total(0), _M_item_total(0), _M_cost(0), _M_count(0), _M_resize(0)
-  { }
+inline __container_size_info::__container_size_info()
+    : _M_init(0), _M_max(0), _M_item_max(0), _M_min(0), _M_item_min(0),
+      _M_total(0), _M_item_total(0), _M_cost(0), _M_count(0), _M_resize(0)
+{
+}
 
-  inline __container_size_info::__container_size_info(__stack_t __stack,
-						      size_t __num)
-  : __object_info_base(__stack), _M_init(0), _M_max(0), _M_item_max(0),
-    _M_min(0), _M_item_min(0), _M_total(0), _M_item_total(0), _M_cost(0),
-    _M_count(0), _M_resize(0)
-  {
-    _M_init = _M_max = __num;
-    _M_item_min = _M_item_max = _M_item_total = _M_total = 0;
-    _M_min = 0;
-    _M_count = 0;
-    _M_resize = 0;
-  }
-
-  inline __container_size_info::__container_size_info(const __container_size_info& __o)
+inline __container_size_info::__container_size_info(
+    const __container_size_info& __o)
     : __object_info_base(__o)
-  {
-    _M_init        = __o._M_init;
-    _M_max         = __o._M_max;
-    _M_item_max    = __o._M_item_max;
-    _M_min         = __o._M_min;
-    _M_item_min    = __o._M_item_min;
-    _M_total       = __o._M_total;
-    _M_item_total  = __o._M_item_total;
-    _M_cost        = __o._M_cost;
-    _M_count       = __o._M_count;
-    _M_resize      = __o._M_resize;
-  }
+{
+  _M_init        = __o._M_init;
+  _M_max         = __o._M_max;
+  _M_item_max    = __o._M_item_max;
+  _M_min         = __o._M_min;
+  _M_item_min    = __o._M_item_min;
+  _M_total       = __o._M_total;
+  _M_item_total  = __o._M_item_total;
+  _M_cost        = __o._M_cost;
+  _M_count       = __o._M_count;
+  _M_resize      = __o._M_resize;
+}
 
-  /** @brief A container size instrumentation line in the stack table.  */
-  class __container_size_stack_info: public __container_size_info
-  {
-  public:
-    __container_size_stack_info(const __container_size_info& __o)
-    : __container_size_info(__o) { }
-  };
+/** @brief A container size instrumentation line in the stack table.  */
+class __container_size_stack_info: public __container_size_info
+{
+ public:
+  __container_size_stack_info(const __container_size_info& __o)
+      : __container_size_info(__o) {}
+};
 
-  /** @brief Container size instrumentation trace producer.  */
-  class __trace_container_size
-  : public __trace_base<__container_size_info, __container_size_stack_info>
-  {
-  public:
-    __trace_container_size()
-    : __trace_base<__container_size_info, __container_size_stack_info>() { };
+/** @brief Container size instrumentation trace producer.  */
+class __trace_container_size
+    : public __trace_base<__container_size_info, __container_size_stack_info> 
+{
+ public:
+  ~__trace_container_size() {}
+  __trace_container_size()
+      : __trace_base<__container_size_info, __container_size_stack_info>() {};
 
-    ~__trace_container_size() { }
+  // Insert a new node at construct with object, callstack and initial size. 
+  void __insert(const __object_t __obj, __stack_t __stack, size_t __num);
+  // Call at destruction/clean to set container final size.
+  void __destruct(const void* __obj, size_t __num, size_t __inum);
+  void __construct(const void* __obj, size_t __inum);
+  // Call at resize to set resize/cost information.
+  void __resize(const void* __obj, int __from, int __to);
+};
 
-    // Insert a new node at construct with object, callstack and initial size.
-    void __insert(const __object_t __obj, __stack_t __stack, size_t __num);
+inline void __trace_container_size::__insert(const __object_t __obj,
+                                             __stack_t __stack, size_t __num)
+{
+  __add_object(__obj, __container_size_info(__stack, __num));
+}
 
-    // Call at destruction/clean to set container final size.
-    void __destruct(const void* __obj, size_t __num, size_t __inum);
-    void __construct(const void* __obj, size_t __inum);
+inline void __container_size_info::__write(FILE* __f) const
+{
+  fprintf(__f, "%Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu\n", 
+          _M_init, _M_count, _M_cost, _M_resize, _M_min, _M_max, _M_total,
+          _M_item_min, _M_item_max, _M_item_total);
+}
 
-    // Call at resize to set resize/cost information.
-    void __resize(const void* __obj, int __from, int __to);
-  };
+inline void __trace_container_size::__destruct(const void* __obj, 
+                                               size_t __num, size_t __inum)
+{
+  if (!__is_on()) return;
 
-  inline void 
-  __trace_container_size::__insert(const __object_t __obj,
-				   __stack_t __stack, size_t __num)
-  { __add_object(__obj, __container_size_info(__stack, __num)); }
+  __object_t __obj_handle = static_cast<__object_t>(__obj);
 
-  inline void 
-  __container_size_info::__write(FILE* __f) const
-  {
-    fprintf(__f, "%Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu\n",
-	    _M_init, _M_count, _M_cost, _M_resize, _M_min, _M_max, _M_total,
-	    _M_item_min, _M_item_max, _M_item_total);
-  }
+  __container_size_info* __object_info = __get_object_info(__obj_handle);
+  if (!__object_info)
+    return;
 
-  inline void 
-  __trace_container_size::__destruct(const void* __obj, size_t __num, 
-				     size_t __inum)
-  {
-    if (!__is_on()) return;
+  __object_info->__destruct(__num, __inum);
+  __retire_object(__obj_handle);
+}
 
-    __object_t __obj_handle = static_cast<__object_t>(__obj);
+inline void __trace_container_size::__resize(const void* __obj, int __from, 
+                                             int __to)
+{
+  if (!__is_on()) return;
 
-    __container_size_info* __object_info = __get_object_info(__obj_handle);
-    if (!__object_info)
-      return;
+  __container_size_info* __object_info = __get_object_info(__obj);
+  if (!__object_info)
+    return;
 
-    __object_info->__destruct(__num, __inum);
-    __retire_object(__obj_handle);
-  }
+  __object_info->__resize(__from, __to);
+}
 
-  inline void 
-  __trace_container_size::__resize(const void* __obj, int __from, int __to)
-  {
-    if (!__is_on()) return;
-
-    __container_size_info* __object_info = __get_object_info(__obj);
-    if (!__object_info)
-      return;
-
-    __object_info->__resize(__from, __to);
-  }
 } // namespace __gnu_profile
 #endif /* _GLIBCXX_PROFILE_PROFILER_CONTAINER_SIZE_H */
Index: include/profile/impl/profiler_vector_size.h
===================================================================
--- include/profile/impl/profiler_vector_size.h	(revision 155631)
+++ include/profile/impl/profiler_vector_size.h	(working copy)
@@ -54,49 +54,51 @@
 
 namespace __gnu_profile
 {
-  /** @brief Hashtable size instrumentation trace producer.  */
-  class __trace_vector_size : public __trace_container_size
-  {
-  public:
-    __trace_vector_size() : __trace_container_size() { __id = "vector-size"; }
-  };
 
-  // Initialization and report.
-  inline void 
-  __trace_vector_size_init()
-  { __tables<0>::_S_vector_size = new __trace_vector_size(); }
+/** @brief Hashtable size instrumentation trace producer.  */
+class __trace_vector_size : public __trace_container_size
+{
+ public:
+  __trace_vector_size() : __trace_container_size() { __id = "vector-size"; }
+};
 
-  inline void 
-  __trace_vector_size_report(FILE* __f, __warning_vector_t& __warnings)
-  {
-    if (__tables<0>::_S_vector_size) 
-      {
-	__tables<0>::_S_vector_size->__collect_warnings(__warnings);
-	__tables<0>::_S_vector_size->__write(__f);
-      }
-  }
+inline void __trace_vector_size_init()
+{
+  _GLIBCXX_PROFILE_DATA(_S_vector_size) = new __trace_vector_size();
+}
 
-  // Implementations of instrumentation hooks.
-  inline void 
-  __trace_vector_size_construct(const void* __obj, size_t __num)
-  {
-    if (!__profcxx_init()) return;
-    __tables<0>::_S_vector_size->__insert(__obj, __get_stack(), __num);
+inline void __trace_vector_size_report(FILE* __f, 
+                                       __warning_vector_t& __warnings)
+{
+  if (_GLIBCXX_PROFILE_DATA(_S_vector_size)) {
+    _GLIBCXX_PROFILE_DATA(_S_vector_size)->__collect_warnings(__warnings);
+    _GLIBCXX_PROFILE_DATA(_S_vector_size)->__write(__f);
   }
+}
 
-  inline void 
-  __trace_vector_size_destruct(const void* __obj, size_t __num, size_t __inum)
-  {
-    if (!__profcxx_init()) return;
-    __tables<0>::_S_vector_size->__destruct(__obj, __num, __inum);
-  }
+inline void __trace_vector_size_construct(const void* __obj, size_t __num)
+{
+  if (!__profcxx_init()) return;
 
-  inline void
-  __trace_vector_size_resize(const void* __obj, size_t __from, size_t __to)
-  {
-    if (!__profcxx_init()) return;
-    __tables<0>::_S_vector_size->__resize(__obj, __from, __to);
-  }
+  _GLIBCXX_PROFILE_DATA(_S_vector_size)->__insert(__obj, __get_stack(), __num);
+}
+
+inline void __trace_vector_size_destruct(const void* __obj, size_t __num,
+                                         size_t __inum)
+{
+  if (!__profcxx_init()) return;
+
+  _GLIBCXX_PROFILE_DATA(_S_vector_size)->__destruct(__obj, __num, __inum);
+}
+
+inline void __trace_vector_size_resize(const void* __obj, size_t __from,
+                                       size_t __to)
+{
+  if (!__profcxx_init()) return;
+
+  _GLIBCXX_PROFILE_DATA(_S_vector_size)->__resize(__obj, __from, __to);
+}
+
 } // namespace __gnu_profile
 
 #endif /* _GLIBCXX_PROFILE_PROFILER_VECTOR_SIZE_H */
Index: include/profile/impl/profiler_hash_func.h
===================================================================
--- include/profile/impl/profiler_hash_func.h	(revision 155631)
+++ include/profile/impl/profiler_hash_func.h	(working copy)
@@ -52,143 +52,134 @@
 
 namespace __gnu_profile
 {
-  /** @brief A hash performance instrumentation line in the object table.  */
-  class __hashfunc_info: public __object_info_base
-  {
-  public:
-    __hashfunc_info() :_M_longest_chain(0), _M_accesses(0), _M_hops(0) { }
 
-    __hashfunc_info(const __hashfunc_info& o);
+/** @brief A hash performance instrumentation line in the object table.  */
+class __hashfunc_info: public __object_info_base
+{
+ public:
+  __hashfunc_info()
+      :_M_longest_chain(0), _M_accesses(0), _M_hops(0) {}
+  __hashfunc_info(const __hashfunc_info& o);
+  __hashfunc_info(__stack_t __stack)
+      : __object_info_base(__stack),
+        _M_longest_chain(0), _M_accesses(0), _M_hops(0){} 
+  virtual ~__hashfunc_info() {}
 
-    __hashfunc_info(__stack_t __stack) 
-    : __object_info_base(__stack), _M_longest_chain(0), 
-      _M_accesses(0), _M_hops(0) { }
+  void __merge(const __hashfunc_info& __o);
+  void __destruct(size_t __chain, size_t __accesses, size_t __hops);
+  void __write(FILE* __f) const;
+  float __magnitude() const { return static_cast<float>(_M_hops); }
+  const char* __advice() const { return strdup("change hash function"); }
 
-    virtual ~__hashfunc_info() { }
+private:
+  size_t _M_longest_chain;
+  size_t _M_accesses;
+  size_t _M_hops;
+};
 
-    void __merge(const __hashfunc_info& __o);
-    void __destruct(size_t __chain, size_t __accesses, size_t __hops);
-    void __write(FILE* __f) const;
-    float __magnitude() const { return static_cast<float>(_M_hops); }
-    const char* __advice() const { return "change hash function"; }
+inline __hashfunc_info::__hashfunc_info(const __hashfunc_info& __o)
+    : __object_info_base(__o)
+{
+  _M_longest_chain = __o._M_longest_chain;
+  _M_accesses      = __o._M_accesses;
+  _M_hops          = __o._M_hops;
+}
 
-  private:
-    size_t _M_longest_chain;
-    size_t _M_accesses;
-    size_t _M_hops;
-  };
+inline void __hashfunc_info::__merge(const __hashfunc_info& __o)
+{
+  _M_longest_chain  = __max(_M_longest_chain, __o._M_longest_chain);
+  _M_accesses      += __o._M_accesses;
+  _M_hops          += __o._M_hops;
+}
 
-  inline __hashfunc_info::__hashfunc_info(const __hashfunc_info& __o)
-  : __object_info_base(__o)
-  {
-    _M_longest_chain = __o._M_longest_chain;
-    _M_accesses      = __o._M_accesses;
-    _M_hops          = __o._M_hops;
-  }
+inline void __hashfunc_info::__destruct(size_t __chain, size_t __accesses, 
+                                        size_t __hops)
+{ 
+  _M_longest_chain  = __max(_M_longest_chain, __chain);
+  _M_accesses      += __accesses;
+  _M_hops          += __hops;
+}
 
-  inline void 
-  __hashfunc_info::__merge(const __hashfunc_info& __o)
-  {
-    _M_longest_chain  = __max(_M_longest_chain, __o._M_longest_chain);
-    _M_accesses      += __o._M_accesses;
-    _M_hops          += __o._M_hops;
-  }
+/** @brief A hash performance instrumentation line in the stack table.  */
+class __hashfunc_stack_info: public __hashfunc_info {
+ public:
+  __hashfunc_stack_info(const __hashfunc_info& __o) : __hashfunc_info(__o) {}
+};
 
-  inline void 
-  __hashfunc_info::__destruct(size_t __chain, size_t __accesses, size_t __hops)
-  {
-    _M_longest_chain  = __max(_M_longest_chain, __chain);
-    _M_accesses      += __accesses;
-    _M_hops          += __hops;
-  }
+/** @brief Hash performance instrumentation producer.  */
+class __trace_hash_func
+    : public __trace_base<__hashfunc_info, __hashfunc_stack_info> 
+{
+ public:
+  __trace_hash_func();
+  ~__trace_hash_func() {}
 
-  /** @brief A hash performance instrumentation line in the stack table.  */
-  class __hashfunc_stack_info: public __hashfunc_info 
-  {
-  public:
-    __hashfunc_stack_info(const __hashfunc_info& __o) : __hashfunc_info(__o) { }
-  };
+  // Insert a new node at construct with object, callstack and initial size. 
+  void __insert(__object_t __obj, __stack_t __stack);
+  // Call at destruction/clean to set container final size.
+  void __destruct(const void* __obj, size_t __chain,
+                  size_t __accesses, size_t __hops);
+};
 
-  /** @brief Hash performance instrumentation producer.  */
-  class __trace_hash_func
-  : public __trace_base<__hashfunc_info, __hashfunc_stack_info>
-  {
-  public:
-    __trace_hash_func();
-    ~__trace_hash_func() { }
+inline __trace_hash_func::__trace_hash_func()
+    : __trace_base<__hashfunc_info, __hashfunc_stack_info>()
+{
+  __id = "hash-distr";
+}
 
-    // Insert a new node at construct with object, callstack and initial size.
-    void __insert(__object_t __obj, __stack_t __stack);
+inline void __trace_hash_func::__insert(__object_t __obj, __stack_t __stack)
+{
+  __add_object(__obj, __hashfunc_info(__stack));
+}
 
-    // Call at destruction/clean to set container final size.
-    void __destruct(const void* __obj, size_t __chain, size_t __accesses, 
-		    size_t __hops);
-  };
+inline void __hashfunc_info::__write(FILE* __f) const
+{
+  fprintf(__f, "%Zu %Zu %Zu\n", _M_hops, _M_accesses, _M_longest_chain);
+}
 
-  inline __trace_hash_func::__trace_hash_func()
-  : __trace_base<__hashfunc_info, __hashfunc_stack_info>()
-  { __id = "hash-distr"; }
+inline void __trace_hash_func::__destruct(const void* __obj, size_t __chain,
+                                          size_t __accesses, size_t __hops)
+{
+  if (!__is_on()) return;
 
-  inline void 
-  __trace_hash_func::__insert(__object_t __obj, __stack_t __stack)
-  { __add_object(__obj, __hashfunc_info(__stack)); }
+  // First find the item from the live objects and update the informations.
+  __hashfunc_info* __objs = __get_object_info(__obj);
+  if (!__objs)
+    return;
 
-  inline void 
-  __hashfunc_info::__write(FILE* __f) const
-  { fprintf(__f, "%Zu %Zu %Zu\n", _M_hops, _M_accesses, _M_longest_chain); }
+  __objs->__destruct(__chain, __accesses, __hops);
+  __retire_object(__obj);
+}
 
-  inline void 
-  __trace_hash_func::__destruct(const void* __obj, size_t __chain,
-				size_t __accesses, size_t __hops)
-  {
-    if (!__is_on()) 
-      return;
+inline void __trace_hash_func_init()
+{
+  _GLIBCXX_PROFILE_DATA(_S_hash_func) = new __trace_hash_func();
+}
 
-    // First find the item from the live objects and update the informations.
-    __hashfunc_info* __objs = __get_object_info(__obj);
-    if (!__objs)
-      return;
-
-    __objs->__destruct(__chain, __accesses, __hops);
-    __retire_object(__obj);
+inline void __trace_hash_func_report(FILE* __f,
+                                     __warning_vector_t& __warnings)
+{
+  if (_GLIBCXX_PROFILE_DATA(_S_hash_func)) {
+    _GLIBCXX_PROFILE_DATA(_S_hash_func)->__collect_warnings(__warnings);
+    _GLIBCXX_PROFILE_DATA(_S_hash_func)->__write(__f);
   }
+}
 
+inline void __trace_hash_func_construct(const void* __obj)
+{
+  if (!__profcxx_init()) return;
 
-  // Initialization and report.
-  inline void 
-  __trace_hash_func_init()
-  { __tables<0>::_S_hash_func = new __trace_hash_func(); }
+  _GLIBCXX_PROFILE_DATA(_S_hash_func)->__insert(__obj, __get_stack());
+}
 
-  inline void 
-  __trace_hash_func_report(FILE* __f, __warning_vector_t& __warnings)
-  {
-    if (__tables<0>::_S_hash_func) 
-      {
-	__tables<0>::_S_hash_func->__collect_warnings(__warnings);
-	__tables<0>::_S_hash_func->__write(__f);
-      }
-  }
+inline void __trace_hash_func_destruct(const void* __obj, size_t __chain,
+                                       size_t __accesses, size_t __hops)
+{
+  if (!__profcxx_init()) return;
 
+  _GLIBCXX_PROFILE_DATA(_S_hash_func)->__destruct(__obj, __chain, __accesses, 
+                                                  __hops);
+}
 
-  // Implementations of instrumentation hooks.
-  inline void 
-  __trace_hash_func_construct(const void* __obj)
-  {
-    if (!__profcxx_init()) 
-      return;
-
-    __tables<0>::_S_hash_func->__insert(__obj, __get_stack());
-  }
-
-  inline void 
-  __trace_hash_func_destruct(const void* __obj, size_t __chain,
-			     size_t __accesses, size_t __hops)
-  {
-    if (!__profcxx_init()) 
-      return;
-
-    __tables<0>::_S_hash_func->__destruct(__obj, __chain, __accesses, __hops);
-  }
-
 } // namespace __gnu_profile
 #endif /* _GLIBCXX_PROFILE_PROFILER_HASH_FUNC_H */
Index: include/profile/impl/profiler_trace.h
===================================================================
--- include/profile/impl/profiler_trace.h	(revision 155631)
+++ include/profile/impl/profiler_trace.h	(working copy)
@@ -54,8 +54,14 @@
 #endif
 
 #include <algorithm>
+#include <fstream>
+#include <string>
 #include <utility>
 
+#if (defined _GLIBCXX_PROFILE_THREADS) && !(defined HAVE_TLS)
+#error profile mode requires either -DHAVE_TLS or -D_GLIBCXX_PROFILE_NO_THREADS
+#endif
+
 #if defined _GLIBCXX_PROFILE_THREADS && defined HAVE_TLS
 #include <pthread.h>
 #endif
@@ -65,528 +71,611 @@
 
 namespace __gnu_profile
 {
+
 #if defined _GLIBCXX_PROFILE_THREADS && defined HAVE_TLS
 #define _GLIBCXX_IMPL_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
-  typedef pthread_mutex_t __mutex_t;
-
-  /** @brief Pthread mutex wrapper.  */
-  template<int _Unused=0>
-    class __mutex 
-    {
-    public:
-      static __mutex_t __global_lock;
-      static void __lock(__mutex_t& __m) { pthread_mutex_lock(&__m); }
-      static void __unlock(__mutex_t& __m) { pthread_mutex_unlock(&__m); }
-    };
+typedef pthread_mutex_t __mutex_t;
+/** @brief Pthread mutex wrapper.  */
+_GLIBCXX_PROFILE_DEFINE_DATA(__mutex_t, __global_lock, 
+                             PTHREAD_MUTEX_INITIALIZER);
+inline void __lock(__mutex_t& __m) { pthread_mutex_lock(&__m); }
+inline void __unlock(__mutex_t& __m) { pthread_mutex_unlock(&__m); }
 #else
+typedef int __mutex_t;
+/** @brief Mock mutex interface.  */
 #define _GLIBCXX_IMPL_MUTEX_INITIALIZER 0
-  typedef int __mutex_t;
-
-  /** @brief Mock mutex interface.  */
-  template<int _Unused=0>
-    class __mutex 
-    {
-    public:
-      static __mutex_t __global_lock;
-      static void __lock(__mutex_t& __m) { }
-      static void __unlock(__mutex_t& __m) { }
-    };
+_GLIBCXX_PROFILE_DEFINE_DATA(__mutex_t, __global_lock, 0);
+inline void __lock(__mutex_t& __m) {}
+inline void __unlock(__mutex_t& __m) {}
 #endif
 
-  template<int _Unused>
-    __mutex_t __mutex<_Unused>::__global_lock = _GLIBCXX_IMPL_MUTEX_INITIALIZER;
+/** @brief Representation of a warning.  */
+struct __warning_data
+{
+  float __magnitude;
+  __stack_t __context;
+  const char* __warning_id;
+  const char* __warning_message;
+  __warning_data();
+  __warning_data(float __m, __stack_t __c, const char* __id, 
+                 const char* __msg);
+  bool operator>(const struct __warning_data& other) const;
+};
 
-  /** @brief Representation of a warning.  */
-  struct __warning_data
-  {
-    float __magnitude;
-    __stack_t __context;
-    const char* __warning_id;
-    const char* __warning_message;
-    __warning_data();
-    __warning_data(float __m, __stack_t __c, const char* __id,
-		   const char* __msg);
-    bool operator>(const struct __warning_data& other) const;
-  };
+inline __warning_data::__warning_data()
+    : __magnitude(0.0), __context(NULL), __warning_id(NULL),
+      __warning_message(NULL)
+{
+}
 
-  inline __warning_data::__warning_data()
-  : __magnitude(0.0), __context(NULL), __warning_id(NULL),
-    __warning_message(NULL)
-  { }
+inline __warning_data::__warning_data(float __m, __stack_t __c, 
+                                      const char* __id, const char* __msg)
+    : __magnitude(__m), __context(__c), __warning_id(__id),
+      __warning_message(__msg)
+{
+}
 
-  inline __warning_data::__warning_data(float __m, __stack_t __c,
-					const char* __id, const char* __msg)
-  : __magnitude(__m), __context(__c), __warning_id(__id),
-    __warning_message(__msg)
-  { }
+inline bool __warning_data::operator>(const struct __warning_data& other) const
+{
+  return __magnitude > other.__magnitude;
+}
 
-  inline bool 
-  __warning_data::operator>(const struct __warning_data& other) const
-  { return __magnitude > other.__magnitude; }
+typedef std::_GLIBCXX_STD_PR::vector<__warning_data> __warning_vector_t;
 
-  typedef std::_GLIBCXX_STD_PR::vector<__warning_data> __warning_vector_t;
+// Defined in profiler_<diagnostic name>.h.
+class __trace_hash_func;
+class __trace_hashtable_size;
+class __trace_map2umap;
+class __trace_vector_size;
+class __trace_vector_to_list;
+class __trace_list_to_slist; 
+class __trace_list_to_vector; 
+void __trace_vector_size_init();
+void __trace_hashtable_size_init();
+void __trace_hash_func_init();
+void __trace_vector_to_list_init();
+void __trace_list_to_slist_init();  
+void __trace_list_to_vector_init();  
+void __trace_map_to_unordered_map_init();
+void __trace_vector_size_report(FILE*, __warning_vector_t&);
+void __trace_hashtable_size_report(FILE*, __warning_vector_t&);
+void __trace_hash_func_report(FILE*, __warning_vector_t&);
+void __trace_vector_to_list_report(FILE*, __warning_vector_t&);
+void __trace_list_to_slist_report(FILE*, __warning_vector_t&); 
+void __trace_list_to_vector_report(FILE*, __warning_vector_t&);
+void __trace_map_to_unordered_map_report(FILE*, __warning_vector_t&);
 
-  // Defined in profiler_<diagnostic name>.h.
-  class __trace_hash_func;
-  class __trace_hashtable_size;
-  class __trace_map2umap;
-  class __trace_vector_size;
-  class __trace_vector_to_list;
-  void __trace_vector_size_init();
-  void __trace_hashtable_size_init();
-  void __trace_hash_func_init();
-  void __trace_vector_to_list_init();
-  void __trace_map_to_unordered_map_init();
-  void __trace_vector_size_report(FILE*, __warning_vector_t&);
-  void __trace_hashtable_size_report(FILE*, __warning_vector_t&);
-  void __trace_hash_func_report(FILE*, __warning_vector_t&);
-  void __trace_vector_to_list_report(FILE*, __warning_vector_t&);
-  void __trace_map_to_unordered_map_report(FILE*, __warning_vector_t&);
+// Utility functions.
+inline size_t __max(size_t __a, size_t __b)
+{
+  return __a >= __b ? __a : __b;
+}
 
-  // Utility functions.
-  inline size_t 
-  __max(size_t __a, size_t __b) { return __a >= __b ? __a : __b; }
+inline size_t __min(size_t __a, size_t __b)
+{
+  return __a <= __b ? __a : __b;
+}
 
-  inline size_t 
-  __min(size_t __a, size_t __b)  { return __a <= __b ? __a : __b; }
+struct __cost_factor
+{
+  const char* __env_var;
+  float __value;
+};
 
-  /** @brief Storage for diagnostic table entries.  Has only static fields.  */
-  template<int _Unused=0>
-    class __tables
-    {
-    public:
-      static __trace_hash_func*        	_S_hash_func;
-      static __trace_hashtable_size* 	_S_hashtable_size;
-      static __trace_map2umap* 		_S_map2umap;
-      static __trace_vector_size* 	_S_vector_size;
-      static __trace_vector_to_list* 	_S_vector_to_list;
-    };
+typedef std::_GLIBCXX_STD_PR::vector<__cost_factor*> __cost_factor_vector;
 
-  template<int _Unused>
-    __trace_hash_func* __tables<_Unused>::_S_hash_func = NULL;
+_GLIBCXX_PROFILE_DEFINE_DATA(__trace_hash_func*, _S_hash_func, NULL);
+_GLIBCXX_PROFILE_DEFINE_DATA(__trace_hashtable_size*, _S_hashtable_size, NULL);
+_GLIBCXX_PROFILE_DEFINE_DATA(__trace_map2umap*, _S_map2umap, NULL);
+_GLIBCXX_PROFILE_DEFINE_DATA(__trace_vector_size*, _S_vector_size, NULL);
+_GLIBCXX_PROFILE_DEFINE_DATA(__trace_vector_to_list*, _S_vector_to_list, NULL);
+_GLIBCXX_PROFILE_DEFINE_DATA(__trace_list_to_slist*, _S_list_to_slist, NULL); 
+_GLIBCXX_PROFILE_DEFINE_DATA(__trace_list_to_vector*, _S_list_to_vector, NULL);
 
-  template<int _Unused>
-    __trace_hashtable_size* __tables<_Unused>::_S_hashtable_size = NULL;
+_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_shift_cost_factor, 
+                             {"__vector_shift_cost_factor", 1.0});
+_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_iterate_cost_factor,
+                             {"__vector_iterate_cost_factor", 1.0});
+_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_resize_cost_factor,
+                             {"__vector_resize_cost_factor", 1.0}); 
+_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_shift_cost_factor,
+                             {"__list_shift_cost_factor", 0.0});
+_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_iterate_cost_factor,
+                             {"__list_iterate_cost_factor", 10.0}); 
+_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_resize_cost_factor,
+                             {"__list_resize_cost_factor", 0.0}); 
+_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_insert_cost_factor,
+                             {"__map_insert_cost_factor", 1.5});
+_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_erase_cost_factor,
+                             {"__map_erase_cost_factor", 1.5});
+_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_find_cost_factor,
+                             {"__map_find_cost_factor", 1});
+_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_iterate_cost_factor,
+                             {"__map_iterate_cost_factor", 2.3});
+_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_insert_cost_factor,
+                             {"__umap_insert_cost_factor", 12.0});
+_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_erase_cost_factor,
+                             {"__umap_erase_cost_factor", 12.0});
+_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_find_cost_factor,
+                             {"__umap_find_cost_factor", 10.0});
+_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_iterate_cost_factor,
+                             {"__umap_iterate_cost_factor", 1.7});
+_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor_vector*, __cost_factors, NULL);
 
-  template<int _Unused>
-    __trace_map2umap* __tables<_Unused>::_S_map2umap = NULL;
+_GLIBCXX_PROFILE_DEFINE_DATA(const char*, _S_trace_file_name,
+                             _GLIBCXX_PROFILE_TRACE_PATH_ROOT);
+_GLIBCXX_PROFILE_DEFINE_DATA(size_t, _S_max_warn_count,
+                             _GLIBCXX_PROFILE_MAX_WARN_COUNT);
+_GLIBCXX_PROFILE_DEFINE_DATA(size_t, _S_max_stack_depth,
+                             _GLIBCXX_PROFILE_MAX_STACK_DEPTH);
+_GLIBCXX_PROFILE_DEFINE_DATA(size_t, _S_max_mem,
+                             _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC);
 
-  template<int _Unused>
-    __trace_vector_size* __tables<_Unused>::_S_vector_size = NULL;
+inline size_t __stack_max_depth()
+{
+  return _GLIBCXX_PROFILE_DATA(_S_max_stack_depth);
+}
 
-  template<int _Unused>
-    __trace_vector_to_list* __tables<_Unused>::_S_vector_to_list = NULL;
+inline size_t __max_mem()
+{
+  return _GLIBCXX_PROFILE_DATA(_S_max_mem);
+}
 
-  /** @brief Storage for user defined parameters.  Has only static fields.  */
-  template<int _Unused=0>
-    class __settings 
-    {
-    public:
-      static const char* 	_S_trace_file_name;
-      static size_t 		_S_max_warn_count;
-      static size_t 		_S_max_stack_depth;
-      static size_t 		_S_max_mem;
-  };
+/** @brief Base class for all trace producers.  */
+template <typename __object_info, typename __stack_info>
+class __trace_base
+{
+ public:
+  __trace_base();
+  virtual ~__trace_base() {}
 
-  template<int _Unused>
-    const char* __settings<_Unused>::_S_trace_file_name =
-    _GLIBCXX_PROFILE_TRACE_PATH_ROOT;
+  void __add_object(__object_t object, __object_info __info);
+  __object_info* __get_object_info(__object_t __object);
+  void __retire_object(__object_t __object);
+  void __write(FILE* f);
+  void __collect_warnings(__warning_vector_t& __warnings);
 
-  template<int _Unused>
-    size_t __settings<_Unused>::_S_max_warn_count =
-    _GLIBCXX_PROFILE_MAX_WARN_COUNT;
+  void __lock_object_table();
+  void __lock_stack_table();
+  void __unlock_object_table();
+  void __unlock_stack_table();
 
-  template<int _Unused>
-    size_t __settings<_Unused>::_S_max_stack_depth =
-    _GLIBCXX_PROFILE_MAX_STACK_DEPTH;
+ private:
+  __mutex_t __object_table_lock;
+  __mutex_t __stack_table_lock;
+  typedef _GLIBCXX_IMPL_UNORDERED_MAP<__object_t, 
+                                      __object_info> __object_table_t;
+  typedef _GLIBCXX_IMPL_UNORDERED_MAP<__stack_t, __stack_info, __stack_hash, 
+                                      __stack_hash> __stack_table_t;
+  __object_table_t __object_table;
+  __stack_table_t __stack_table;
+  size_t __stack_table_byte_size;
 
-  template<int _Unused>
-    size_t __settings<_Unused>::_S_max_mem =
-    _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC;
+ protected:
+  const char* __id;
+};
 
-  inline size_t 
-  __stack_max_depth() { return __settings<0>::_S_max_stack_depth; }
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__collect_warnings(
+    __warning_vector_t& __warnings)
+{
+  typename __stack_table_t::iterator __i = __stack_table.begin();
+  for ( ; __i != __stack_table.end(); ++__i )
+  {
+    __warnings.push_back(__warning_data((*__i).second.__magnitude(), 
+                                        (*__i).first, 
+                                        __id,
+                                        (*__i).second.__advice()));
+  }
+}
 
-  inline size_t 
-  __max_mem() { return __settings<0>::_S_max_mem; }
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__lock_object_table()
+{
+  __lock(this->__object_table_lock);
+}
 
-  /** @brief Base class for all trace producers.  */
-  template<typename __object_info, typename __stack_info>
-    class __trace_base
-    {
-    public:
-      __trace_base();
-      virtual ~__trace_base() { }
-      
-      void __add_object(__object_t object, __object_info __info);
-      __object_info* __get_object_info(__object_t __object);
-      void __retire_object(__object_t __object);
-      void __write(FILE* f);
-      void __collect_warnings(__warning_vector_t& warnings);
-      
-      void __lock_object_table();
-      void __lock_stack_table();
-      void __unlock_object_table();
-      void __unlock_stack_table();
-      
-    private:
-      __mutex_t __object_table_lock;
-      __mutex_t __stack_table_lock;
-      typedef _GLIBCXX_IMPL_UNORDERED_MAP<__object_t,
-					  __object_info> __object_table_t;
-      typedef _GLIBCXX_IMPL_UNORDERED_MAP<__stack_t, __stack_info, __stack_hash,
-					  __stack_hash> __stack_table_t;
-      __object_table_t __object_table;
-      __stack_table_t __stack_table;
-      size_t __stack_table_byte_size;
-      
-    protected:
-      const char* __id;
-    };
-  
-  template<typename __object_info, typename __stack_info>
-    void 
-    __trace_base<__object_info, __stack_info>::__collect_warnings(__warning_vector_t& warnings)
-    {
-      typename __stack_table_t::iterator __i = __stack_table.begin();
-      for ( ; __i != __stack_table.end(); ++__i)
-	{
-	  warnings.push_back(__warning_data((*__i).second.__magnitude(),
-					    (*__i).first,
-					    __id,
-					    (*__i).second.__advice()));
-	}
-    }
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__lock_stack_table()
+{
+  __lock(this->__stack_table_lock);
+}
 
-  template<typename __object_info, typename __stack_info>
-    void 
-    __trace_base<__object_info, __stack_info>::__lock_object_table()
-    { __mutex<0>::__lock(this->__object_table_lock); }
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__unlock_object_table()
+{
+  __unlock(this->__object_table_lock);
+}
 
-  template<typename __object_info, typename __stack_info>
-    void
-    __trace_base<__object_info, __stack_info>::__lock_stack_table()
-    { __mutex<0>::__lock(this->__stack_table_lock); }
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__unlock_stack_table()
+{
+  __unlock(this->__stack_table_lock);
+}
 
-  template<typename __object_info, typename __stack_info>
-    void __trace_base<__object_info, __stack_info>::__unlock_object_table()
-    { __mutex<0>::__unlock(this->__object_table_lock); }
+template <typename __object_info, typename __stack_info>
+__trace_base<__object_info, __stack_info>::__trace_base()
+{
+  // Do not pick the initial size too large, as we don't know which diagnostics
+  // are more active.
+  __object_table.rehash(10000);
+  __stack_table.rehash(10000);
+  __stack_table_byte_size = 0;
+  __id = NULL;
+  __object_table_lock = __stack_table_lock = _GLIBCXX_IMPL_MUTEX_INITIALIZER;
+}
 
-  template<typename __object_info, typename __stack_info>
-    void __trace_base<__object_info, __stack_info>::__unlock_stack_table()
-    { __mutex<0>::__unlock(this->__stack_table_lock); }
-
-  template<typename __object_info, typename __stack_info>
-    __trace_base<__object_info, __stack_info>::__trace_base()
-    {
-      // Do not pick the initial size too large, as we don't know which
-      // diagnostics are more active.
-      __object_table.rehash(10000);
-      __stack_table.rehash(10000);
-      __stack_table_byte_size = 0;
-      __id = NULL;
-      __stack_table_lock = _GLIBCXX_IMPL_MUTEX_INITIALIZER;
-      __object_table_lock = __stack_table_lock;
-    }
-
-  template<typename __object_info, typename __stack_info>
-    void 
-    __trace_base<__object_info, __stack_info>::__add_object(__object_t __object, __object_info __info)
-  {
-    typedef typename __object_table_t::value_type value_type;
-    if (__max_mem() == 0
-	|| __object_table.size() * sizeof(__object_info) <= __max_mem()) 
-      {
-	__lock_object_table();
-	__object_table.insert(value_type(__object, __info));
-      __unlock_object_table();
-    }
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__add_object(
+    __object_t __object, __object_info __info)
+{
+  if (__max_mem() == 0 
+      || __object_table.size() * sizeof(__object_info) <= __max_mem()) {
+    __lock_object_table();
+    __object_table.insert(
+        typename __object_table_t::value_type(__object, __info));
+    __unlock_object_table();
   }
+}
 
-  template<typename __object_info, typename __stack_info>
-    __object_info* 
-   __trace_base<__object_info, __stack_info>::__get_object_info(__object_t __object)
-  {
-    // XXX: Revisit this to see if we can decrease mutex spans.
-    // Without this mutex, the object table could be rehashed during an
-    // insertion on another thread, which could result in a segfault.
-    __lock_object_table();
-    typename __object_table_t::iterator __object_it =
+template <typename __object_info, typename __stack_info>
+__object_info* __trace_base<__object_info, __stack_info>::__get_object_info(
+    __object_t __object)
+{
+  // XXX: Revisit this to see if we can decrease mutex spans.
+  // Without this mutex, the object table could be rehashed during an
+  // insertion on another thread, which could result in a segfault.
+  __lock_object_table();
+  typename __object_table_t::iterator __object_it = 
       __object_table.find(__object);
-
-    if (__object_it == __object_table.end())
-      {
-	__unlock_object_table();
-	return NULL;
-      } 
-    else 
-      {
-	__unlock_object_table();
-	return &__object_it->second;
-      }
+  if (__object_it == __object_table.end()){
+    __unlock_object_table();
+    return NULL;
+  } else {
+    __unlock_object_table();
+    return &__object_it->second;
   }
+}
 
-  template<typename __object_info, typename __stack_info>
-    void 
-    __trace_base<__object_info, __stack_info>::__retire_object(__object_t __object)
-  {
-    __lock_object_table();
-    __lock_stack_table();
-    typename __object_table_t::iterator __object_it =
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__retire_object(
+    __object_t __object)
+{
+  __lock_object_table();
+  __lock_stack_table();
+  typename __object_table_t::iterator __object_it =
       __object_table.find(__object);
-
-    if (__object_it != __object_table.end())
-      {
-	const __object_info& __info = __object_it->second;
-	const __stack_t& __stack = __info.__stack();
-	typename __stack_table_t::iterator __stack_it =
-	__stack_table.find(__stack);
-
-	if (__stack_it == __stack_table.end()) 
-	  {
-	    // First occurence of this call context.
-	    if (__max_mem() == 0 || __stack_table_byte_size < __max_mem()) 
-	      {
-		__stack_table_byte_size +=
-		  (sizeof(__instruction_address_t) * __size(__stack)
-		   + sizeof(__stack) + sizeof(__stack_info));
-		__stack_table.insert(make_pair(__stack, __stack_info(__info)));
-	      }
-	  } 
-	else 
-	  {
-	    // Merge object info into info summary for this call context.
-	    __stack_it->second.__merge(__info);
-	    delete __stack;
-	  }
-	__object_table.erase(__object);
+  if (__object_it != __object_table.end()){
+    const __object_info& __info = __object_it->second;
+    const __stack_t& __stack = __info.__stack();
+    typename __stack_table_t::iterator __stack_it = 
+        __stack_table.find(__stack);
+    if (__stack_it == __stack_table.end()) {
+      // First occurence of this call context.
+      if (__max_mem() == 0 || __stack_table_byte_size < __max_mem()) {
+        __stack_table_byte_size += 
+            (sizeof(__instruction_address_t) * __size(__stack)
+             + sizeof(__stack) + sizeof(__stack_info));
+        __stack_table.insert(make_pair(__stack, __stack_info(__info)));
       }
-    __unlock_stack_table();
-    __unlock_object_table();
+    } else {
+      // Merge object info into info summary for this call context.
+      __stack_it->second.__merge(__info);
+      delete __stack;
+    }
+    __object_table.erase(__object);
   }
+  __unlock_stack_table();
+  __unlock_object_table();
+}
 
-  template<typename __object_info, typename __stack_info>
-  void 
-  __trace_base<__object_info, __stack_info>::__write(FILE* __f)
-  {
-    typename __stack_table_t::iterator __it;
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__write(FILE* __f)
+{
+  typename __stack_table_t::iterator __it;
 
-    for (__it = __stack_table.begin(); __it != __stack_table.end(); __it++) 
-      {
-	if (__it->second.__is_valid()) 
-	  {
-	    fprintf(__f, __id);
-	    fprintf(__f, "|");
-	    __gnu_profile::__write(__f, __it->first);
-	    fprintf(__f, "|");
-	    __it->second.__write(__f);
-	  }
-      }
+  for (__it = __stack_table.begin(); __it != __stack_table.end(); __it++) {
+    if (__it->second.__is_valid()) {
+      fprintf(__f, __id);
+      fprintf(__f, "|");
+      __gnu_profile::__write(__f, __it->first);
+      fprintf(__f, "|");
+      __it->second.__write(__f);
+    }
   }
+}
 
-  inline size_t 
-  __env_to_size_t(const char* __env_var, size_t __default_value)
-  {
-    char* __env_value = getenv(__env_var);
-    if (__env_value) 
-      {
-	long int __converted_value = strtol(__env_value, NULL, 10);
-	if (errno || __converted_value < 0) 
-	  {
-	    fprintf(stderr, "Bad value for environment variable '%s'.",
-		    __env_var);
-	    abort();
-	  } 
-	else 
-	  {
-	    return static_cast<size_t>(__converted_value);
-	  }
-      } 
-    else 
-      {
-	return __default_value;
-      }
+inline size_t __env_to_size_t(const char* __env_var, size_t __default_value)
+{
+  char* __env_value = getenv(__env_var);
+  if (__env_value) {
+    long int __converted_value = strtol(__env_value, NULL, 10);
+    if (errno || __converted_value < 0) {
+      fprintf(stderr, "Bad value for environment variable '%s'.\n", __env_var);
+      abort();
+    } else {
+      return static_cast<size_t>(__converted_value);
+    }
+  } else {
+    return __default_value;
   }
+}
 
-  inline void 
-  __set_max_stack_trace_depth()
-  {
-    __settings<0>::_S_max_stack_depth = __env_to_size_t(_GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR, __settings<0>::_S_max_stack_depth);
+inline void __set_max_stack_trace_depth()
+{
+  _GLIBCXX_PROFILE_DATA(_S_max_stack_depth) = __env_to_size_t(
+      _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR,
+      _GLIBCXX_PROFILE_DATA(_S_max_stack_depth));
+}
+
+inline void __set_max_mem()
+{
+  _GLIBCXX_PROFILE_DATA(_S_max_mem) = __env_to_size_t(
+      _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR,
+      _GLIBCXX_PROFILE_DATA(_S_max_mem));
+}
+
+inline int __log_magnitude(float f)
+{
+  const float log_base = 10.0;
+  int result = 0;
+  int sign = 1;
+  if (f < 0) {
+    f = -f;
+    sign = -1;
   }
+  while (f > log_base) {
+    ++result;
+    f /= 10.0;
+  }
+  return sign * result;
+}
 
-  inline void 
-  __set_max_mem()
+struct __warn
+{
+  FILE* __file;
+  __warn(FILE* __f) { __file = __f; }
+  void operator() (const __warning_data& __info)
   {
-    __settings<0>::_S_max_mem = __env_to_size_t(_GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR, __settings<0>::_S_max_mem);
+    fprintf(__file,  __info.__warning_id);
+    fprintf(__file, ": improvement = %d", __log_magnitude(__info.__magnitude));
+    fprintf(__file, ": call stack = ");
+    __gnu_profile::__write(__file, __info.__context);
+    fprintf(__file, ": advice = %s\n", __info.__warning_message);
+    free(
+        const_cast<void*>(
+            reinterpret_cast<const void*>(__info.__warning_message)));
   }
+};
 
-  inline int 
-  __log_magnitude(float f)
-  {
-    const float log_base = 10.0;
-    int result = 0;
-    int sign = 1;
-    if (f < 0) 
-      {
-	f = -f;
-	sign = -1;
-      }
-    while (f > log_base) 
-      {
-	++result;
-	f /= 10.0;
-      }
-    return sign * result;
+inline FILE* __open_output_file(const char* extension)
+{
+  // The path is made of _S_trace_file_name + "." + extension.
+  size_t root_len = strlen(_GLIBCXX_PROFILE_DATA(_S_trace_file_name));
+  size_t ext_len = strlen(extension);
+  char* file_name = new char[root_len + 1 + ext_len + 1];
+  memcpy(file_name, _GLIBCXX_PROFILE_DATA(_S_trace_file_name), root_len);
+  *(file_name + root_len) = '.';
+  memcpy(file_name + root_len + 1, extension, ext_len + 1);
+  FILE* out_file = fopen(file_name, "w");
+  if (out_file) {
+    return out_file;
+  } else {
+    fprintf(stderr, "Could not open trace file '%s'.\n", file_name);
+    abort();
   }
+}
 
-  struct __warn
-  {
-    FILE* __file;
+/** @brief Final report method, registered with "atexit".
+ *
+ * This can also be called directly by user code, including signal handlers.
+ * It is protected against deadlocks by the reentrance guard in profiler.h.
+ * However, when called from a signal handler that triggers while within
+ * __gnu_profile (under the guarded zone), no output will be produced.
+ */
+inline void __report(void)
+{
+  __lock(_GLIBCXX_PROFILE_DATA(__global_lock));
 
-    __warn(FILE* __f) { __file = __f; }
+  __warning_vector_t __warnings;
 
-    void operator() (const __warning_data& __info)
-    {
-      fprintf(__file,  __info.__warning_id);
-      fprintf(__file, ": improvement = %d", 
-	      __log_magnitude(__info.__magnitude));
-      fprintf(__file, ": call stack = ");
-      __gnu_profile::__write(__file, __info.__context);
-      fprintf(__file, ": advice = %s\n", __info.__warning_message);
-    }
-  };
+  FILE* __raw_file = __open_output_file("raw");
+  __trace_vector_size_report(__raw_file, __warnings);
+  __trace_hashtable_size_report(__raw_file, __warnings);
+  __trace_hash_func_report(__raw_file, __warnings);
+  __trace_vector_to_list_report(__raw_file, __warnings);
+  __trace_list_to_slist_report(__raw_file, __warnings);
+  __trace_list_to_vector_report(__raw_file, __warnings);
+  __trace_map_to_unordered_map_report(__raw_file, __warnings);
+  fclose(__raw_file);
 
-  inline FILE* 
-  __open_output_file(const char* extension)
-  {
-    // The path is made of _S_trace_file_name + "." + extension.
-    size_t root_len = strlen(__settings<0>::_S_trace_file_name);
-    size_t ext_len = strlen(extension);
-    char* file_name = new char[root_len + 1 + ext_len + 1];
-    char* p = file_name;
-    memcpy(file_name, __settings<0>::_S_trace_file_name, root_len);
-    *(file_name + root_len) = '.';
-    memcpy(file_name + root_len + 1, extension, ext_len + 1);
-    FILE* out_file = fopen(file_name, "w");
-    if (out_file) 
-      return out_file;
-    else 
-      {
-	fprintf(stderr, "Could not open trace file '%s'.", file_name);
-	abort();
-      }
-  }
+  // Sort data by magnitude.
+  // XXX: instead of sorting, should collect only top N for better performance.
+  size_t __cutoff = __min(_GLIBCXX_PROFILE_DATA(_S_max_warn_count),
+                          __warnings.size());
 
-  /** @brief Final report method, registered with "atexit".
-   *
-   * This can also be called directly by user code, including signal handlers.
-   * It is protected against deadlocks by the reentrance guard in profiler.h.
-   * However, when called from a signal handler that triggers while within
-   * __gnu_profile (under the guarded zone), no output will be produced.
-   */
-  inline void 
-  __report(void)
-  {
-    __mutex<0>::__lock(__mutex<0>::__global_lock);
+  std::sort(__warnings.begin(), __warnings.end(),
+            std::greater<__warning_vector_t::value_type>());
+  __warnings.resize(__cutoff);
 
-    __warning_vector_t __warnings;
+  FILE* __warn_file = __open_output_file("txt");
+  std::for_each(__warnings.begin(), __warnings.end(), __warn(__warn_file));
+  fclose(__warn_file);
 
-    FILE* __raw_file = __open_output_file("raw");
-    __trace_vector_size_report(__raw_file, __warnings);
-    __trace_hashtable_size_report(__raw_file, __warnings);
-    __trace_hash_func_report(__raw_file, __warnings);
-    __trace_vector_to_list_report(__raw_file, __warnings);
-    __trace_map_to_unordered_map_report(__raw_file, __warnings);
-    fclose(__raw_file);
+  __unlock(_GLIBCXX_PROFILE_DATA(__global_lock));
+}
 
-    // Sort data by magnitude.
+inline void __set_trace_path()
+{
+  char* __env_trace_file_name = getenv(_GLIBCXX_PROFILE_TRACE_ENV_VAR);
 
-    // XXX: instead of sorting, should collect only top N for better
-    // performance.
-    size_t __cutoff = __min(__settings<0>::_S_max_warn_count,
-			    __warnings.size());
+  if (__env_trace_file_name) { 
+    _GLIBCXX_PROFILE_DATA(_S_trace_file_name) = __env_trace_file_name; 
+  }
 
-    std::sort(__warnings.begin(), __warnings.end(),
-	      std::greater<__warning_vector_t::value_type>());
-    __warnings.resize(__cutoff);
+  // Make sure early that we can create the trace file.
+  fclose(__open_output_file("txt"));
+}
 
-    FILE* __warn_file = __open_output_file("txt");
-    std::for_each(__warnings.begin(), __warnings.end(), __warn(__warn_file));
-    fclose(__warn_file);
+inline void __set_max_warn_count()
+{
+  char* __env_max_warn_count_str = getenv(
+      _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR);
 
-    __mutex<0>::__unlock(__mutex<0>::__global_lock);
+  if (__env_max_warn_count_str) {
+    _GLIBCXX_PROFILE_DATA(_S_max_warn_count) = static_cast<size_t>(
+        atoi(__env_max_warn_count_str));
   }
+}
 
-  inline void 
-  __set_trace_path()
-  {
-    char* __env_trace_file_name = getenv(_GLIBCXX_PROFILE_TRACE_ENV_VAR);
+inline void __read_cost_factors()
+{
+  std::string __conf_file_name(_GLIBCXX_PROFILE_DATA(_S_trace_file_name));
+  __conf_file_name += ".conf";
 
-    if (__env_trace_file_name) 
-      __settings<0>::_S_trace_file_name = __env_trace_file_name;
+  std::ifstream __conf_file(__conf_file_name.c_str());
 
-    // Make sure early that we can create the trace file.
-    fclose(__open_output_file("txt"));
-  }
+  if (__conf_file.is_open()) {
+    std::string __line;
 
-  inline void 
-  __set_max_warn_count()
-  {
-    char* __env_max_warn_count_str = getenv(_GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR);
+    while (getline(__conf_file, __line)) {
+      std::string::size_type __i = __line.find_first_not_of(" \t\n\v");
 
-    if (__env_max_warn_count_str) 
-      {
-	int i = atoi(__env_max_warn_count_str);
-	__settings<0>::_S_max_warn_count = static_cast<size_t>(i);
+      if (__line.length() <= 0 || __line[__i] == '#') {
+        // Skip empty lines or comments.
+        continue;
+      }
+
+      // Trim.
+      __line.erase(std::remove(__line.begin(), __line.end(), ' '), 
+                   __line.end());
+      std::string::size_type __pos = __line.find("=");
+      std::string __factor_name = __line.substr(0, __pos);
+      std::string::size_type __end = __line.find_first_of(";\n");
+      std::string __factor_value = __line.substr(__pos + 1, __end - __pos);
+
+      setenv(__factor_name.c_str(), __factor_value.c_str(), 0);
     }
+  } 
+}
+
+struct __cost_factor_writer
+{
+  FILE* __file;
+  __cost_factor_writer(FILE* __f) : __file(__f) {}
+  void operator() (const __cost_factor* __factor)
+  {
+    fprintf(__file, "%s = %f\n", __factor->__env_var, __factor->__value);
   }
+};
 
-  inline void 
-  __profcxx_init_unconditional()
+inline void __write_cost_factors()
+{
+  FILE* __file = __open_output_file("conf.out");
+  std::for_each(_GLIBCXX_PROFILE_DATA(__cost_factors)->begin(),
+                _GLIBCXX_PROFILE_DATA(__cost_factors)->end(),
+                __cost_factor_writer(__file));
+  fclose(__file);
+}
+
+struct __cost_factor_setter
+{
+  void operator() (__cost_factor* __factor)
   {
-    __mutex<0>::__lock(__mutex<0>::__global_lock);
+    char* __env_cost_factor;
+    if (__env_cost_factor = getenv(__factor->__env_var))
+      __factor->__value = atof(__env_cost_factor);
+  }
+};
 
+inline void __set_cost_factors()
+{
+  _GLIBCXX_PROFILE_DATA(__cost_factors) = new __cost_factor_vector;
+  _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
+      &_GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor));
+  _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
+      &_GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor));
+  _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
+      &_GLIBCXX_PROFILE_DATA(__vector_resize_cost_factor));
+  _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
+      &_GLIBCXX_PROFILE_DATA(__list_shift_cost_factor));
+  _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
+      &_GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor));
+  _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
+      &_GLIBCXX_PROFILE_DATA(__list_resize_cost_factor));
+  _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
+      &_GLIBCXX_PROFILE_DATA(__map_insert_cost_factor));
+  _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
+      &_GLIBCXX_PROFILE_DATA(__map_erase_cost_factor));
+  _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
+      &_GLIBCXX_PROFILE_DATA(__map_find_cost_factor));
+  _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
+      &_GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor));
+  _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
+      &_GLIBCXX_PROFILE_DATA(__umap_insert_cost_factor));
+  _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
+      &_GLIBCXX_PROFILE_DATA(__umap_erase_cost_factor));
+  _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
+      &_GLIBCXX_PROFILE_DATA(__umap_find_cost_factor));
+  _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
+      &_GLIBCXX_PROFILE_DATA(__umap_iterate_cost_factor));
+  std::for_each(_GLIBCXX_PROFILE_DATA(__cost_factors)->begin(),
+                _GLIBCXX_PROFILE_DATA(__cost_factors)->end(),
+                __cost_factor_setter());
+}
+
+inline void __profcxx_init_unconditional()
+{
+  __lock(_GLIBCXX_PROFILE_DATA(__global_lock));
+
+  if (__is_invalid()) {
+
     __set_max_warn_count();
 
-    if (__is_invalid()) 
-      {
-      if (__settings<0>::_S_max_warn_count == 0) 
-	{
-	  __turn_off();
-	} 
-      else 
-	{
-	__set_max_stack_trace_depth();
-	__set_max_mem();
-	__set_trace_path();
+    if (_GLIBCXX_PROFILE_DATA(_S_max_warn_count) == 0) {
 
-	__trace_vector_size_init();
-	__trace_hashtable_size_init();
-	__trace_hash_func_init();
-	__trace_vector_to_list_init();
-	__trace_map_to_unordered_map_init();
+      __turn_off();
 
-	atexit(__report);
+    } else {
 
-	__turn_on();
-	}
-      }
+      __set_max_stack_trace_depth();
+      __set_max_mem();
+      __set_trace_path();
+      __read_cost_factors(); 
+      __set_cost_factors();
+      __write_cost_factors();
 
-    __mutex<0>::__unlock(__mutex<0>::__global_lock);
+      __trace_vector_size_init();
+      __trace_hashtable_size_init();
+      __trace_hash_func_init();
+      __trace_vector_to_list_init();
+      __trace_list_to_slist_init(); 
+      __trace_list_to_vector_init();
+      __trace_map_to_unordered_map_init();
+
+      atexit(__report);
+
+      __turn_on();
+
+    }
   }
 
-  /** @brief This function must be called by each instrumentation point.
-   *
-   * The common path is inlined fully.
-   */
-  inline bool 
-  __profcxx_init(void)
-  {
-    if (__is_invalid())
-      __profcxx_init_unconditional();
-    return __is_on();
+  __unlock(_GLIBCXX_PROFILE_DATA(__global_lock));
+}
+
+/** @brief This function must be called by each instrumentation point.
+ *
+ * The common path is inlined fully.
+ */
+inline bool __profcxx_init(void)
+{
+  if (__is_invalid()) {
+    __profcxx_init_unconditional();
   }
 
+  return __is_on();
+}
+
 } // namespace __gnu_profile
 
 #endif /* _GLIBCXX_PROFILE_PROFILER_TRACE_H */
Index: include/profile/impl/profiler_vector_to_list.h
===================================================================
--- include/profile/impl/profiler_vector_to_list.h	(revision 155631)
+++ include/profile/impl/profiler_vector_to_list.h	(working copy)
@@ -28,8 +28,8 @@
 // reasons why the executable file might be covered by the GNU General
 // Public License.
 
-/** @file profile/impl/profiler_trace.h
- *  @brief Data structures to represent profiling traces.
+/** @file profile/impl/profiler_vector_to_list.h
+ *  @brief diagnostics for vector to list.
  */
 
 // Written by Lixia Liu and Silvius Rus.
@@ -52,258 +52,285 @@
 
 namespace __gnu_profile
 {
-  /** @brief A vector-to-list instrumentation line in the object table.  */
-  class __vector2list_info: public __object_info_base
-  {
-  public:
-    __vector2list_info()
-    :_M_shift_count(0), _M_iterate(0), _M_resize(0), _M_list_cost(0),
-     _M_vector_cost(0), _M_valid(true) { }
 
-    __vector2list_info(__stack_t __stack)
-    : __object_info_base(__stack), _M_shift_count(0), _M_iterate(0),
-      _M_resize(0), _M_list_cost(0), _M_vector_cost(0), _M_valid(true) { } 
+/** @brief A vector-to-list instrumentation line in the object table.  */
+class __vector2list_info: public __object_info_base
+{
+ public:
+  __vector2list_info()
+      :_M_shift_count(0), _M_iterate(0), _M_resize(0), _M_list_cost(0),
+       _M_vector_cost(0), _M_valid(true) {}
+  __vector2list_info(__stack_t __stack)
+      : __object_info_base(__stack), _M_shift_count(0), _M_iterate(0),
+        _M_resize(0), _M_list_cost(0), _M_vector_cost(0), _M_valid(true) {} 
+  virtual ~__vector2list_info() {}
+  __vector2list_info(const __vector2list_info& __o);
+  void __merge(const __vector2list_info& __o);
+  void __write(FILE* __f) const;
+  float __magnitude() const { return _M_vector_cost - _M_list_cost; }
+  const char* __advice() const 
+  { return strdup("change std::vector to std::list"); }
 
-    virtual ~__vector2list_info() { }
-    __vector2list_info(const __vector2list_info& __o);
+  size_t __shift_count() { return _M_shift_count; }
+  size_t __iterate()   { return _M_iterate; }
+  float __list_cost() { return _M_list_cost; }
+  size_t __resize() { return _M_resize; }
+  void __set_list_cost(float __lc) { _M_list_cost = __lc; }
+  void __set_vector_cost(float __vc) { _M_vector_cost = __vc; }
+  bool __is_valid() { return _M_valid; }
+  void __set_invalid() { _M_valid = false; }
 
-    void __merge(const __vector2list_info& __o);
-    void __write(FILE* __f) const;
-    float __magnitude() const { return _M_vector_cost - _M_list_cost; }
-    const char* __advice() const { return "change std::vector to std::list"; }
+  void __opr_insert(size_t __pos, size_t __num);
+  void __opr_iterate(size_t __num);
+  void __resize(size_t __from, size_t __to);
+  void __opr_find(size_t __size);
 
-    size_t __shift_count() { return _M_shift_count; }
-    size_t __iterate()   { return _M_iterate; }
-    float __list_cost() { return _M_list_cost; }
-    size_t __resize() { return _M_resize; }
-    void __set_list_cost(float __lc) { _M_list_cost = __lc; }
-    void __set_vector_cost(float __vc) { _M_vector_cost = __vc; }
-    bool __is_valid() { return _M_valid; }
-    void __set_invalid() { _M_valid = false; }
+private:
+  size_t _M_shift_count;
+  size_t _M_iterate;
+  size_t _M_resize;
+  float _M_list_cost;
+  float _M_vector_cost;
+  bool  _M_valid;
+};
 
-    void __opr_insert(size_t __pos, size_t __num);
-    void __opr_iterate(size_t __num) { _M_iterate += __num; }
-    void __resize(size_t __from, size_t __to);
+inline __vector2list_info::__vector2list_info(const __vector2list_info& __o)
+    : __object_info_base(__o)
+{
+  _M_shift_count  = __o._M_shift_count;
+  _M_iterate      = __o._M_iterate;
+  _M_vector_cost  = __o._M_vector_cost;
+  _M_list_cost    = __o._M_list_cost;
+  _M_valid        = __o._M_valid;
+  _M_resize       = __o._M_resize;
+}
 
-  private:
-    size_t _M_shift_count;
-    size_t _M_iterate;
-    size_t _M_resize;
-    float _M_list_cost;
-    float _M_vector_cost;
-    bool  _M_valid;
-  };
+inline void __vector2list_info::__merge(const __vector2list_info& __o)
+{
+  _M_shift_count  += __o._M_shift_count;
+  _M_iterate      += __o._M_iterate;
+  _M_vector_cost  += __o._M_vector_cost;
+  _M_list_cost    += __o._M_list_cost;
+  _M_valid        &= __o._M_valid;
+  _M_resize       += __o._M_resize;
+}
 
-  inline __vector2list_info::__vector2list_info(const __vector2list_info& __o)
-  : __object_info_base(__o)
-  {
-    _M_shift_count  = __o._M_shift_count;
-    _M_iterate      = __o._M_iterate;
-    _M_vector_cost  = __o._M_vector_cost;
-    _M_list_cost    = __o._M_list_cost;
-    _M_valid        = __o._M_valid;
-    _M_resize       = __o._M_resize;
-  }
+inline void __vector2list_info::__opr_insert(size_t __pos, size_t __num)
+{
+  _M_shift_count += __num - __pos;
+}
 
-  inline void 
-  __vector2list_info::__merge(const __vector2list_info& __o)
-  {
-    _M_shift_count  += __o._M_shift_count;
-    _M_iterate      += __o._M_iterate;
-    _M_vector_cost  += __o._M_vector_cost;
-    _M_list_cost    += __o._M_list_cost;
-    _M_valid        &= __o._M_valid;
-    _M_resize       += __o._M_resize;
-  }
+inline void __vector2list_info::__resize(size_t __from, size_t __to)
+{
+  _M_resize += __from;
+}
 
-  inline void 
-  __vector2list_info::__opr_insert(size_t __pos, size_t __num)
-  { _M_shift_count += __num - __pos; }
+inline void __vector2list_info::__opr_iterate(size_t __num)
+{ 
+  _M_iterate += __num; 
+}
 
-  inline void 
-  __vector2list_info::__resize(size_t __from, size_t __to)
-  { _M_resize += __from; }
+inline void __vector2list_info::__opr_find(size_t __size)
+{
+  // Use average case complexity.
+  _M_iterate += 3.0 / 4.0 * __size;
+}
 
-  /** @brief A vector-to-list instrumentation line in the stack table.  */
-  class __vector2list_stack_info: public __vector2list_info 
-  {
-  public:
-    __vector2list_stack_info(const __vector2list_info& __o) 
-    : __vector2list_info(__o) { }
-  };
+/** @brief A vector-to-list instrumentation line in the stack table.  */
+class __vector2list_stack_info: public __vector2list_info {
+ public:
+  __vector2list_stack_info(const __vector2list_info& __o) 
+      : __vector2list_info(__o) {}
+};
 
-  /** @brief Vector-to-list instrumentation producer.  */
-  class __trace_vector_to_list
-  : public __trace_base<__vector2list_info, __vector2list_stack_info> 
-  {
-  public:
-    __trace_vector_to_list();
-    ~__trace_vector_to_list() { }
+/** @brief Vector-to-list instrumentation producer.  */
+class __trace_vector_to_list
+    : public __trace_base<__vector2list_info, __vector2list_stack_info> 
+{
+ public:
+  __trace_vector_to_list();
+  ~__trace_vector_to_list() {}
 
-    // Insert a new node at construct with object, callstack and initial size. 
-    void __insert(__object_t __obj, __stack_t __stack);
+  // Insert a new node at construct with object, callstack and initial size. 
+  void __insert(__object_t __obj, __stack_t __stack);
+  // Call at destruction/clean to set container final size.
+  void __destruct(const void* __obj);
 
-    // Call at destruction/clean to set container final size.
-    void __destruct(const void* __obj);
+  // Find the node in the live map.
+  __vector2list_info* __find(const void* __obj);
 
-    // Find the node in the live map.
-    __vector2list_info* __find(const void* __obj);
+  // Collect cost of operations.
+  void __opr_insert(const void* __obj, size_t __pos, size_t __num);
+  void __opr_iterate(const void* __obj, size_t __num);
+  void __invalid_operator(const void* __obj);
+  void __resize(const void* __obj, size_t __from, size_t __to);
+  float __vector_cost(size_t __shift, size_t __iterate, size_t __resize);
+  float __list_cost(size_t __shift, size_t __iterate, size_t __resize);
+  void __opr_find(const void* __obj, size_t __size);
+};
 
-    // Collect cost of operations.
-    void __opr_insert(const void* __obj, size_t __pos, size_t __num);
-    void __opr_iterate(const void* __obj, size_t __num);
-    void __invalid_operator(const void* __obj);
-    void __resize(const void* __obj, size_t __from, size_t __to);
-    float __vector_cost(size_t __shift, size_t __iterate, size_t __resize);
-    float __list_cost(size_t __shift, size_t __iterate, size_t __resize);
-  };
+inline __trace_vector_to_list::__trace_vector_to_list()
+    : __trace_base<__vector2list_info, __vector2list_stack_info>()
+{
+  __id = "vector-to-list";
+}
 
-  inline __trace_vector_to_list::__trace_vector_to_list()
-  : __trace_base<__vector2list_info, __vector2list_stack_info>()
-  { __id = "vector-to-list"; }
+inline void __trace_vector_to_list::__insert(__object_t __obj,
+                                             __stack_t __stack)
+{
+  __add_object(__obj, __vector2list_info(__stack));
+}
 
-  inline void 
-  __trace_vector_to_list::__insert(__object_t __obj, __stack_t __stack)
-  { __add_object(__obj, __vector2list_info(__stack)); }
+inline void __vector2list_info::__write(FILE* __f) const
+{
+  fprintf(__f, "%Zu %Zu %Zu %.0f %.0f\n",
+          _M_shift_count, _M_resize, _M_iterate, _M_vector_cost, _M_list_cost);
+}
 
-  inline void 
-  __vector2list_info::__write(FILE* __f) const
-  {
-    fprintf(__f, "%Zu %Zu %Zu %.0f %.0f\n", _M_shift_count, _M_resize, 
-	    _M_iterate, _M_vector_cost, _M_list_cost);
-  }
+inline float __trace_vector_to_list::__vector_cost(size_t __shift, 
+                                                   size_t __iterate,
+                                                   size_t __resize)
+{
+  return (
+      __shift * _GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor).__value
+      + __iterate * _GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor).__value
+      + __resize * _GLIBCXX_PROFILE_DATA(__vector_resize_cost_factor).__value
+      );
+}
 
-  // Cost model.  
-  //  Vector operation cost:
-  //   - Cost per shift: 1
-  //   - Cost per access: 1
-  //   - Cost per resize: 1
-  //  List operation cost:
-  //   - Cost per shift: 0
-  //   - Cost per access: 10
-  //   - Cost per resize: 0
-  // XXX: get this from the cost model database instead.
-  inline float 
-  __trace_vector_to_list::__vector_cost(size_t __shift, size_t __iterate,
-					size_t __resize)
-  { return __shift * 1 + __iterate * 1 + __resize * 1; }
+inline float __trace_vector_to_list::__list_cost(size_t __shift, 
+                                                 size_t __iterate,
+                                                 size_t __resize)
+{
+  return (
+      __shift * _GLIBCXX_PROFILE_DATA(__list_shift_cost_factor).__value
+      + __iterate * _GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor).__value
+      + __resize * _GLIBCXX_PROFILE_DATA(__list_resize_cost_factor).__value);
+}
 
-  inline float 
-  __trace_vector_to_list::__list_cost(size_t __shift, size_t __iterate,
-				      size_t __resize)
-  { return __shift * 0 + __iterate * 10 + __resize * 0; }
+inline void __trace_vector_to_list::__destruct(const void* __obj)
+{
+  if (!__is_on())
+    return;
 
-  inline void 
-  __trace_vector_to_list::__destruct(const void* __obj)
-  {
-    if (!__is_on())
-      return;
+ __vector2list_info* __res = __get_object_info(__obj);
+  if (!__res)
+    return;
 
-    __vector2list_info* __res = __get_object_info(__obj);
-    if (!__res)
-      return;
+  float __vc = __vector_cost(__res->__shift_count(), __res->__iterate(),
+                             __res->__resize());
+  float __lc = __list_cost(__res->__shift_count(), __res->__iterate(),
+                           __res->__resize());
+  __res->__set_vector_cost(__vc);
+  __res->__set_list_cost(__lc);
 
-    float __vc = __vector_cost(__res->__shift_count(), __res->__iterate(),
-			       __res->__resize());
-    float __lc = __list_cost(__res->__shift_count(), __res->__iterate(),
-			     __res->__resize());
-    __res->__set_vector_cost(__vc);
-    __res->__set_list_cost(__lc);
+  __retire_object(__obj);
+}
 
-    __retire_object(__obj);
-  }
+inline void __trace_vector_to_list::__opr_insert(const void* __obj, 
+                                                 size_t __pos, size_t __num)
+{
+  __vector2list_info* __res = __get_object_info(__obj);
+  if (__res)
+    __res->__opr_insert(__pos, __num);
+}
 
-  inline void 
-  __trace_vector_to_list::__opr_insert(const void* __obj, size_t __pos, 
-				       size_t __num)
-  {
-    __vector2list_info* __res = __get_object_info(__obj);
-    if (__res)
-      __res->__opr_insert(__pos, __num);
-  }
+inline void __trace_vector_to_list::__opr_iterate(const void* __obj,
+                                                  size_t __num)
+{
+  __vector2list_info* __res = __get_object_info(__obj);
+  if (__res)
+    __res->__opr_iterate(__num);
+}
 
-  inline void 
-  __trace_vector_to_list::__opr_iterate(const void* __obj, size_t __num)
-  {
-    __vector2list_info* __res = __get_object_info(__obj);
-    if (__res)
-      __res->__opr_iterate(__num);
-  }
+inline void __trace_vector_to_list::__invalid_operator(const void* __obj)
+{
+  __vector2list_info* __res = __get_object_info(__obj);
+  if (__res)
+    __res->__set_invalid();
+}
 
-  inline void 
-  __trace_vector_to_list::__invalid_operator(const void* __obj)
-  {
-    __vector2list_info* __res = __get_object_info(__obj);
-    if (__res)
-      __res->__set_invalid();
-  }
+inline void __trace_vector_to_list::__resize(const void* __obj, size_t __from, 
+                                             size_t __to)
+{
+  __vector2list_info* __res = __get_object_info(__obj);
+  if (__res)
+    __res->__resize(__from, __to);
+}
 
-  inline void 
-  __trace_vector_to_list::__resize(const void* __obj, size_t __from, 
-				   size_t __to)
-  {
-    __vector2list_info* __res = __get_object_info(__obj);
-    if (__res)
-      __res->__resize(__from, __to);
+inline void __trace_vector_to_list::__opr_find(const void* __obj,
+                                               size_t __size)
+{
+  __vector2list_info* __res = __get_object_info(__obj);
+  if (__res)
+    __res->__opr_find(__size);
+}
+
+inline void __trace_vector_to_list_init()
+{
+  _GLIBCXX_PROFILE_DATA(_S_vector_to_list) = new __trace_vector_to_list();
+}
+
+inline void __trace_vector_to_list_report(FILE* __f, 
+                                          __warning_vector_t& __warnings)
+{
+  if (_GLIBCXX_PROFILE_DATA(_S_vector_to_list)) {
+    _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__collect_warnings(__warnings);
+    _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__write(__f);
   }
+}
 
+inline void __trace_vector_to_list_construct(const void* __obj)
+{
+  if (!__profcxx_init()) return;
 
-  // Initialization and report.
-  inline void 
-  __trace_vector_to_list_init()
-  { __tables<0>::_S_vector_to_list = new __trace_vector_to_list(); }
+  _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__insert(__obj, __get_stack());
+}
 
-  inline void 
-  __trace_vector_to_list_report(FILE* __f, __warning_vector_t& __warnings)
-  {
-    if (__tables<0>::_S_vector_to_list) 
-      {
-	__tables<0>::_S_vector_to_list->__collect_warnings(__warnings);
-	__tables<0>::_S_vector_to_list->__write(__f);
-      }
-  }
+inline void __trace_vector_to_list_destruct(const void* __obj)
+{
+  if (!__profcxx_init()) return;
 
-  // Implementations of instrumentation hooks.
-  inline void 
-  __trace_vector_to_list_construct(const void* __obj)
-  {
-    if (!__profcxx_init()) return;
-    __tables<0>::_S_vector_to_list->__insert(__obj, __get_stack());
-  }
+  _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__destruct(__obj);
+}
 
-  inline void 
-  __trace_vector_to_list_destruct(const void* __obj)
-  {
-    if (!__profcxx_init()) return;
-    __tables<0>::_S_vector_to_list->__destruct(__obj);
-  }
+inline void __trace_vector_to_list_insert(const void* __obj, 
+                                          size_t __pos, size_t __num)
+{
+  if (!__profcxx_init()) return;
 
-  inline void 
-  __trace_vector_to_list_insert(const void* __obj, size_t __pos, size_t __num)
-  {
-    if (!__profcxx_init()) return;
-    __tables<0>::_S_vector_to_list->__opr_insert(__obj, __pos, __num);
-  }
+  _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_insert(__obj, __pos, __num);
+}
 
-  inline void 
-  __trace_vector_to_list_iterate(const void* __obj, size_t __num)
-  {
-    if (!__profcxx_init()) return;
-    __tables<0>::_S_vector_to_list->__opr_iterate(__obj, __num);
-  }
 
-  inline void 
-  __trace_vector_to_list_invalid_operator(const void* __obj)
-  {
-    if (!__profcxx_init()) return;
-    __tables<0>::_S_vector_to_list->__invalid_operator(__obj);
-  }
+inline void __trace_vector_to_list_iterate(const void* __obj, size_t __num = 1)
+{
+  if (!__profcxx_init()) return;
 
-  inline void 
-  __trace_vector_to_list_resize(const void* __obj, size_t __from, size_t __to)
-  {
-    if (!__profcxx_init()) return;
-    __tables<0>::_S_vector_to_list->__resize(__obj, __from, __to);
-  }
+  _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_iterate(__obj, __num);
+}
+
+inline void __trace_vector_to_list_invalid_operator(const void* __obj)
+{
+  if (!__profcxx_init()) return;
+
+  _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__invalid_operator(__obj);
+}
+
+inline void __trace_vector_to_list_resize(const void* __obj, 
+                                          size_t __from, size_t __to)
+{
+  if (!__profcxx_init()) return;
+
+  _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__resize(__obj, __from, __to);
+}
+
+inline void __trace_vector_to_list_find(const void* __obj, size_t __size)
+{
+  if (!__profcxx_init()) return;
+
+  _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_find(__obj, __size);
+}
+
 } // namespace __gnu_profile
 #endif /* _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H */
Index: include/profile/impl/profiler_list_to_vector.h
===================================================================
--- include/profile/impl/profiler_list_to_vector.h	(revision 0)
+++ include/profile/impl/profiler_list_to_vector.h	(revision 0)
@@ -0,0 +1,313 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License as published by the Free Software
+// Foundation; either version 2, or (at your option) any later
+// version.
+
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/** @file profile/impl/profiler_list_to_vector.h
+ *  @brief diagnostics for list to vector.
+ */
+
+// Written by Changhee Jung.
+
+#ifndef _GLIBCXX_PROFILE_PROFILER_LIST_TO_VECTOR_H
+#define _GLIBCXX_PROFILE_PROFILER_LIST_TO_VECTOR_H 1
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#else
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#endif
+#include <string>
+#include <sstream>
+#include "profile/impl/profiler.h"
+#include "profile/impl/profiler_node.h"
+#include "profile/impl/profiler_trace.h"
+
+namespace __gnu_profile
+{
+
+/** @brief A list-to-vector instrumentation line in the object table.  */
+class __list2vector_info: public __object_info_base
+{
+ public:
+  __list2vector_info()
+      :_M_shift_count(0), _M_iterate(0), _M_resize(0), _M_list_cost(0),
+       _M_vector_cost(0), _M_valid(true), _M_max_size(0) {}
+  __list2vector_info(__stack_t __stack)
+      : __object_info_base(__stack), _M_shift_count(0), _M_iterate(0),
+        _M_resize(0), _M_list_cost(0), _M_vector_cost(0), _M_valid(true),
+        _M_max_size(0) {}
+  virtual ~__list2vector_info() {}
+  __list2vector_info(const __list2vector_info& __o);
+  void __merge(const __list2vector_info& __o);
+  void __write(FILE* __f) const;
+  float __magnitude() const { return _M_list_cost - _M_vector_cost; }
+  const char* __advice() const;
+  size_t __shift_count() { return _M_shift_count; }
+  size_t __iterate()   { return _M_iterate; }
+  float __list_cost() { return _M_list_cost; }
+  size_t __resize() { return _M_resize; }
+  void __set_list_cost(float __lc) { _M_list_cost = __lc; }
+  void __set_vector_cost(float __vc) { _M_vector_cost = __vc; }
+  bool __is_valid() { return _M_valid; }
+  void __set_invalid() { _M_valid = false; }
+
+  void __opr_insert(size_t __shift, size_t __size);
+  void __opr_iterate(size_t __num) { _M_iterate += __num;}
+
+  void __resize(size_t __from, size_t __to);
+
+private:
+  size_t _M_shift_count;
+  size_t _M_iterate;
+  size_t _M_resize;
+  float _M_list_cost;
+  float _M_vector_cost;
+  bool  _M_valid;
+  size_t _M_max_size;
+};
+
+inline __list2vector_info::__list2vector_info(const __list2vector_info& __o)
+    : __object_info_base(__o)
+{
+  _M_shift_count  = __o._M_shift_count;
+  _M_iterate      = __o._M_iterate;
+  _M_vector_cost  = __o._M_vector_cost;
+  _M_list_cost    = __o._M_list_cost;
+  _M_valid        = __o._M_valid;
+  _M_resize       = __o._M_resize;
+  _M_max_size     = __o._M_max_size;
+}
+
+inline const char* __list2vector_info::__advice() const {
+  std::stringstream __sstream;
+  __sstream 
+      << "change std::list to std::vector and its initial size from 0 to "
+      << _M_max_size;
+  return strdup(__sstream.str().c_str());
+}
+
+inline void __list2vector_info::__merge(const __list2vector_info& __o)
+{
+  _M_shift_count  += __o._M_shift_count;
+  _M_iterate      += __o._M_iterate;
+  _M_vector_cost  += __o._M_vector_cost;
+  _M_list_cost    += __o._M_list_cost;
+  _M_valid        &= __o._M_valid;
+  _M_resize       += __o._M_resize;
+  _M_max_size     = __max( _M_max_size, __o._M_max_size);
+}
+
+inline void __list2vector_info::__opr_insert(size_t __shift, size_t __size) 
+{
+  _M_shift_count += __shift;
+  _M_max_size = __max(_M_max_size, __size);
+}
+
+inline void __list2vector_info::__resize(size_t __from, size_t __to)
+{
+  _M_resize += __from;
+}
+
+class __list2vector_stack_info: public __list2vector_info {
+ public:
+  __list2vector_stack_info(const __list2vector_info& __o) 
+      : __list2vector_info(__o) {}
+};
+
+class __trace_list_to_vector
+    : public __trace_base<__list2vector_info, __list2vector_stack_info> 
+{
+ public:
+  __trace_list_to_vector();
+  ~__trace_list_to_vector() {}
+
+  // Insert a new node at construct with object, callstack and initial size. 
+  void __insert(__object_t __obj, __stack_t __stack);
+  // Call at destruction/clean to set container final size.
+  void __destruct(const void* __obj);
+
+  // Find the node in the live map.
+  __list2vector_info* __find(const void* __obj);
+
+  // Collect cost of operations.
+  void __opr_insert(const void* __obj, size_t __shift, size_t __size);
+  void __opr_iterate(const void* __obj, size_t __num);
+  void __invalid_operator(const void* __obj);
+  void __resize(const void* __obj, size_t __from, size_t __to);
+  float __vector_cost(size_t __shift, size_t __iterate);
+  float __list_cost(size_t __shift, size_t __iterate);
+};
+
+inline __trace_list_to_vector::__trace_list_to_vector()
+    : __trace_base<__list2vector_info, __list2vector_stack_info>()
+{
+  __id = "list-to-vector";
+}
+
+inline void __trace_list_to_vector::__insert(__object_t __obj,
+                                             __stack_t __stack)
+{
+  __add_object(__obj, __list2vector_info(__stack));
+}
+
+inline void __list2vector_info::__write(FILE* __f) const
+{
+  fprintf(__f, "%Zu %Zu %Zu %.0f %.0f\n",
+          _M_shift_count, _M_resize, _M_iterate, _M_vector_cost, _M_list_cost);
+}
+
+inline float __trace_list_to_vector::__vector_cost(size_t __shift, 
+                                                   size_t __iterate)
+{
+  // The resulting vector will use a 'reserve' method.
+  return __shift * _GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor).__value + 
+      __iterate * _GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor).__value; 
+}
+
+inline float __trace_list_to_vector::__list_cost(size_t __shift, 
+                                                 size_t __iterate)
+{
+  return __shift * _GLIBCXX_PROFILE_DATA(__list_shift_cost_factor).__value + 
+      __iterate * _GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor).__value; 
+}
+
+inline void __trace_list_to_vector::__destruct(const void* __obj)
+{
+  if (!__is_on())
+    return;
+
+ __list2vector_info* __res = __get_object_info(__obj);
+  if (!__res)
+    return;
+
+  float __vc = __vector_cost(__res->__shift_count(), __res->__iterate());
+  float __lc = __list_cost(__res->__shift_count(), __res->__iterate());
+  __res->__set_vector_cost(__vc);
+  __res->__set_list_cost(__lc);
+  __retire_object(__obj);
+}
+
+inline void __trace_list_to_vector::__opr_insert(const void* __obj, 
+                                                 size_t __shift, size_t __size)
+{
+  __list2vector_info* __res = __get_object_info(__obj);
+  if (__res)
+    __res->__opr_insert(__shift, __size);
+}
+
+inline void __trace_list_to_vector::__opr_iterate(const void* __obj,
+                                                  size_t __num)
+{
+  __list2vector_info* __res = __get_object_info(__obj);
+  if (__res) {
+    __res->__opr_iterate(__num);
+  }
+}
+
+inline void __trace_list_to_vector::__invalid_operator(const void* __obj)
+{
+  __list2vector_info* __res = __get_object_info(__obj);
+  if (__res)
+    __res->__set_invalid();
+}
+
+inline void __trace_list_to_vector::__resize(const void* __obj, size_t __from, 
+                                             size_t __to)
+{
+  __list2vector_info* __res = __get_object_info(__obj);
+  if (__res)
+    __res->__resize(__from, __to);
+}
+
+inline void __trace_list_to_vector_init()
+{
+  _GLIBCXX_PROFILE_DATA(_S_list_to_vector) = new __trace_list_to_vector();
+}
+
+inline void __trace_list_to_vector_report(FILE* __f, 
+                                          __warning_vector_t& __warnings)
+{
+  if (_GLIBCXX_PROFILE_DATA(_S_list_to_vector)) {
+    _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__collect_warnings(__warnings);
+    _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__write(__f);
+  }
+}
+
+inline void __trace_list_to_vector_construct(const void* __obj)
+{
+  if (!__profcxx_init()) return;
+
+  _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__insert(__obj, __get_stack());
+}
+
+inline void __trace_list_to_vector_destruct(const void* __obj)
+{
+  if (!__profcxx_init()) return;
+
+  _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__destruct(__obj);
+}
+
+inline void __trace_list_to_vector_insert(const void* __obj, 
+                                          size_t __shift, size_t __size)
+{
+  if (!__profcxx_init()) return;
+
+  _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__opr_insert(__obj, __shift, 
+                                                         __size);
+}
+
+
+inline void __trace_list_to_vector_iterate(const void* __obj, size_t __num = 1)
+{
+  if (!__profcxx_init()) return;
+
+  _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__opr_iterate(__obj, __num);
+}
+
+inline void __trace_list_to_vector_invalid_operator(const void* __obj)
+{
+  if (!__profcxx_init()) return;
+
+  _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__invalid_operator(__obj);
+}
+
+inline void __trace_list_to_vector_resize(const void* __obj, 
+                                          size_t __from, size_t __to)
+{
+  if (!__profcxx_init()) return;
+
+  _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__resize(__obj, __from, __to);
+}
+
+} // namespace __gnu_profile
+#endif /* _GLIBCXX_PROFILE_PROFILER_LIST_TO_VECTOR_H__ */
Index: include/profile/impl/profiler.h
===================================================================
--- include/profile/impl/profiler.h	(revision 155631)
+++ include/profile/impl/profiler.h	(working copy)
@@ -43,6 +43,20 @@
 #include <stddef.h>
 #endif
 
+// Mechanism to define data with inline linkage.
+#define _GLIBCXX_PROFILE_DEFINE_DATA(__type, __name, __initial_value...) \
+  inline __type& __get_##__name() {                                      \
+    static __type __name(__initial_value);                               \
+    return __name;                                                       \
+  }
+#define _GLIBCXX_PROFILE_DATA(__name) \
+  __get_##__name()
+
+/**
+ * @namespace std::__cxxprof_guard
+ * @brief Mechanism to protect all __gnu_profile operations against
+ * multithreaded and exception reentrance.
+ */
 namespace __gnu_profile
 {
   /** @brief Reentrance guard.
@@ -53,80 +67,127 @@
   struct __reentrance_guard
   {
     static bool
-    _S_set_in()
+    __get_in()
     {
-      if (_S_get_in())
+      if (__inside() == true)
 	return false;
       else
 	{
-	  _S_get_in() = true;
+	  __inside() = true;
 	  return true;
 	}
     }
 
     static bool&
-    _S_get_in()
+    __inside()
     {
       static __thread bool _S_inside(false);
       return _S_inside;
     }
 
     __reentrance_guard() { }
-    ~__reentrance_guard() { _S_get_in() = false; }
+    ~__reentrance_guard() { __inside() = false; }
   };
 
 #define _GLIBCXX_PROFILE_REENTRANCE_GUARD(__x...)	      	\
   {                                                             \
-    if (__gnu_profile::__reentrance_guard::_S_get_in())	 	\
+    if (__gnu_profile::__reentrance_guard::__get_in())          \
     {                                                           \
       __gnu_profile::__reentrance_guard __get_out; 		\
       __x;                                                      \
     }                                                           \
   }
+}
 
+/**
+ * @namespace std::__gnu_profile
+ * @brief Implementation of profile extension.
+ */
+namespace __gnu_profile
+{
+// Forward declarations of implementation functions.
+// Don't use any __gnu_profile:: in user code.
+// Instead, use the __profcxx... macros, which offer guarded access.
+bool __turn_on();
+bool __turn_off();
+bool __is_invalid();
+bool __is_on();
+bool __is_off();
+void __report(void);
+void __trace_hashtable_size_resize(const void*, size_t, size_t);
+void __trace_hashtable_size_destruct(const void*, size_t, size_t);
+void __trace_hashtable_size_construct(const void*, size_t);
+void __trace_vector_size_resize(const void*, size_t, size_t);
+void __trace_vector_size_destruct(const void*, size_t, size_t);
+void __trace_vector_size_construct(const void*, size_t);
+void __trace_hash_func_destruct(const void*, size_t, size_t, size_t);
+void __trace_hash_func_construct(const void*);
+void __trace_vector_to_list_destruct(const void*);
+void __trace_vector_to_list_construct(const void*);
+void __trace_vector_to_list_insert(const void*, size_t, size_t);
+void __trace_vector_to_list_iterate(const void*, size_t);
+void __trace_vector_to_list_invalid_operator(const void*);
+void __trace_vector_to_list_resize(const void*, size_t, size_t);
+void __trace_vector_to_list_find(const void*, size_t);
 
-  // Forward declarations of implementation functions.
-  // Don't use any __gnu_profile:: in user code.
-  // Instead, use the __profcxx... macros, which offer guarded access.
-  void __turn_on();
-  void __turn_off();
-  bool __is_invalid();
-  bool __is_on();
-  bool __is_off();
-  void __report(void);
-  void __trace_hashtable_size_resize(const void*, size_t, size_t);
-  void __trace_hashtable_size_destruct(const void*, size_t, size_t);
-  void __trace_hashtable_size_construct(const void*, size_t);
-  void __trace_vector_size_resize(const void*, size_t, size_t);
-  void __trace_vector_size_destruct(const void*, size_t, size_t);
-  void __trace_vector_size_construct(const void*, size_t);
-  void __trace_hash_func_destruct(const void*, size_t, size_t, size_t);
-  void __trace_hash_func_construct(const void*);
-  void __trace_vector_to_list_destruct(const void*);
-  void __trace_vector_to_list_construct(const void*);
-  void __trace_vector_to_list_insert(const void*, size_t, size_t);
-  void __trace_vector_to_list_iterate(const void*, size_t);
-  void __trace_vector_to_list_invalid_operator(const void*);
-  void __trace_vector_to_list_resize(const void*, size_t, size_t);
-  void __trace_map_to_unordered_map_construct(const void*);
-  void __trace_map_to_unordered_map_invalidate(const void*);
-  void __trace_map_to_unordered_map_insert(const void*, size_t, size_t);
-  void __trace_map_to_unordered_map_erase(const void*, size_t, size_t);
-  void __trace_map_to_unordered_map_iterate(const void*, size_t);
-  void __trace_map_to_unordered_map_find(const void*, size_t);
-  void __trace_map_to_unordered_map_destruct(const void*);
+void __trace_list_to_slist_destruct(const void*);
+void __trace_list_to_slist_construct(const void*);
+void __trace_list_to_slist_rewind(const void*); 
+void __trace_list_to_slist_operation(const void*);
+
+void __trace_list_to_vector_destruct(const void*);
+void __trace_list_to_vector_construct(const void*);
+void __trace_list_to_vector_insert(const void*, size_t, size_t); 
+void __trace_list_to_vector_iterate(const void*, size_t);
+void __trace_list_to_vector_invalid_operator(const void*);
+void __trace_list_to_vector_resize(const void*, size_t, size_t); 
+
+void __trace_list_to_set_destruct(const void*);
+void __trace_list_to_set_construct(const void*);
+void __trace_list_to_set_insert(const void*, size_t, size_t); 
+void __trace_list_to_set_iterate(const void*, size_t);
+void __trace_list_to_set_invalid_operator(const void*);
+void __trace_list_to_set_find(const void*, size_t); 
+
+void __trace_map_to_unordered_map_construct(const void*);
+void __trace_map_to_unordered_map_invalidate(const void*);
+void __trace_map_to_unordered_map_insert(const void*, size_t, size_t);
+void __trace_map_to_unordered_map_erase(const void*, size_t, size_t);
+void __trace_map_to_unordered_map_iterate(const void*, size_t);
+void __trace_map_to_unordered_map_find(const void*, size_t);
+void __trace_map_to_unordered_map_destruct(const void*);
 } // namespace __gnu_profile
 
-// Master switch turns on all diagnostics.
+// Master switch turns on all diagnostics that are not explicitly turned off.
 #ifdef _GLIBCXX_PROFILE
+#ifndef _GLIBCXX_PROFILE_NO_HASHTABLE_TOO_SMALL
 #define _GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL
+#endif
+#ifndef _GLIBCXX_PROFILE_NO_HASHTABLE_TOO_LARGE
 #define _GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE
+#endif
+#ifndef _GLIBCXX_PROFILE_NO_VECTOR_TOO_SMALL
 #define _GLIBCXX_PROFILE_VECTOR_TOO_SMALL
+#endif
+#ifndef _GLIBCXX_PROFILE_NO_VECTOR_TOO_LARGE
 #define _GLIBCXX_PROFILE_VECTOR_TOO_LARGE
+#endif
+#ifndef _GLIBCXX_PROFILE_NO_INEFFICIENT_HASH
 #define _GLIBCXX_PROFILE_INEFFICIENT_HASH
+#endif
+#ifndef _GLIBCXX_PROFILE_NO_VECTOR_TO_LIST
 #define _GLIBCXX_PROFILE_VECTOR_TO_LIST
+#endif
+#ifndef _GLIBCXX_PROFILE_NO_LIST_TO_SLIST
+#define _GLIBCXX_PROFILE_LIST_TO_SLIST
+#endif
+#ifndef _GLIBCXX_PROFILE_NO_LIST_TO_VECTOR
+#define _GLIBCXX_PROFILE_LIST_TO_VECTOR
+#endif
+#ifndef _GLIBCXX_PROFILE_NO_MAP_TO_UNORDERED_MAP
 #define _GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP
 #endif
+#endif
 
 // Expose global management routines to user code.
 #ifdef _GLIBCXX_PROFILE
@@ -152,10 +213,8 @@
 #endif
 
 // Turn on/off instrumentation for HASHTABLE_TOO_SMALL and HASHTABLE_TOO_LARGE.
-#if ((defined(_GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL) \
-      && !defined(_NO_GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL)) \
-     || (defined(_GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE) \
-	 && !defined(_NO_GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE)))
+#if (defined(_GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL) \
+     || defined(_GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE))
 #define __profcxx_hashtable_resize(__x...) \
   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
       __gnu_profile::__trace_hashtable_size_resize(__x))
@@ -166,16 +225,14 @@
   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
       __gnu_profile::__trace_hashtable_size_construct(__x))
 #else
-#define __profcxx_hashtable_resize(__x...)
-#define __profcxx_hashtable_destruct(__x...)
-#define __profcxx_hashtable_construct(__x...)
+#define __profcxx_hashtable_resize(__x...)  
+#define __profcxx_hashtable_destruct(__x...) 
+#define __profcxx_hashtable_construct(__x...)  
 #endif
 
 // Turn on/off instrumentation for VECTOR_TOO_SMALL and VECTOR_TOO_LARGE.
-#if ((defined(_GLIBCXX_PROFILE_VECTOR_TOO_SMALL) \
-      && !defined(_NO_GLIBCXX_PROFILE_VECTOR_TOO_SMALL)) \
-     || (defined(_GLIBCXX_PROFILE_VECTOR_TOO_LARGE) \
-	 && !defined(_NO_GLIBCXX_PROFILE_VECTOR_TOO_LARGE)))
+#if (defined(_GLIBCXX_PROFILE_VECTOR_TOO_SMALL) \
+     || defined(_GLIBCXX_PROFILE_VECTOR_TOO_LARGE))
 #define __profcxx_vector_resize(__x...) \
   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
       __gnu_profile::__trace_vector_size_resize(__x))
@@ -186,14 +243,13 @@
   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
       __gnu_profile::__trace_vector_size_construct(__x))
 #else
-#define __profcxx_vector_resize(__x...)
-#define __profcxx_vector_destruct(__x...)
-#define __profcxx_vector_construct(__x...)
-#endif
+#define __profcxx_vector_resize(__x...)  
+#define __profcxx_vector_destruct(__x...) 
+#define __profcxx_vector_construct(__x...)  
+#endif 
 
 // Turn on/off instrumentation for INEFFICIENT_HASH.
-#if (defined(_GLIBCXX_PROFILE_INEFFICIENT_HASH) \
-     && !defined(_NO_GLIBCXX_PROFILE_INEFFICIENT_HASH))
+#if defined(_GLIBCXX_PROFILE_INEFFICIENT_HASH)
 #define __profcxx_hashtable_construct2(__x...) \
   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
       __gnu_profile::__trace_hash_func_construct(__x))
@@ -201,13 +257,12 @@
   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
       __gnu_profile::__trace_hash_func_destruct(__x))
 #else
-#define __profcxx_hashtable_destruct2(__x...)
-#define __profcxx_hashtable_construct2(__x...)
+#define __profcxx_hashtable_destruct2(__x...) 
+#define __profcxx_hashtable_construct2(__x...)  
 #endif
 
 // Turn on/off instrumentation for VECTOR_TO_LIST.
-#if (defined(_GLIBCXX_PROFILE_VECTOR_TO_LIST) \
-     && !defined(_NO_GLIBCXX_PROFILE_VECTOR_TO_LIST))
+#if defined(_GLIBCXX_PROFILE_VECTOR_TO_LIST)
 #define __profcxx_vector_construct2(__x...) \
   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
       __gnu_profile::__trace_vector_to_list_construct(__x))
@@ -226,6 +281,9 @@
 #define __profcxx_vector_resize2(__x...) \
   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
       __gnu_profile::__trace_vector_to_list_resize(__x))
+#define __profcxx_vector_find(__x...) \
+  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+      __gnu_profile::__trace_vector_to_list_find(__x))
 #else
 #define __profcxx_vector_destruct2(__x...)
 #define __profcxx_vector_construct2(__x...)
@@ -233,11 +291,57 @@
 #define __profcxx_vector_iterate(__x...)
 #define __profcxx_vector_invalid_operator(__x...)
 #define __profcxx_vector_resize2(__x...)
+#define __profcxx_vector_find(__x...)
 #endif
 
+// Turn on/off instrumentation for LIST_TO_VECTOR. 
+#if defined(_GLIBCXX_PROFILE_LIST_TO_VECTOR)
+#define __profcxx_list_construct2(__x...) \
+  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+      __gnu_profile::__trace_list_to_vector_construct(__x))
+#define __profcxx_list_destruct2(__x...) \
+  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+      __gnu_profile::__trace_list_to_vector_destruct(__x))
+#define __profcxx_list_insert(__x...) \
+  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+      __gnu_profile::__trace_list_to_vector_insert(__x))
+#define __profcxx_list_iterate(__x...) \
+  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+      __gnu_profile::__trace_list_to_vector_iterate(__x))
+#define __profcxx_list_invalid_operator(__x...) \
+  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+      __gnu_profile::__trace_list_to_vector_invalid_operator(__x))
+#else
+#define __profcxx_list_destruct2(__x...)
+#define __profcxx_list_construct2(__x...)
+#define __profcxx_list_insert(__x...)
+#define __profcxx_list_iterate(__x...)
+#define __profcxx_list_invalid_operator(__x...)
+#endif
+
+// Turn on/off instrumentation for LIST_TO_SLIST.  
+#if defined(_GLIBCXX_PROFILE_LIST_TO_SLIST)
+#define __profcxx_list_rewind(__x...) \
+  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+      __gnu_profile::__trace_list_to_slist_rewind(__x))
+#define __profcxx_list_operation(__x...) \
+  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+      __gnu_profile::__trace_list_to_slist_operation(__x))
+#define __profcxx_list_destruct(__x...) \
+  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+      __gnu_profile::__trace_list_to_slist_destruct(__x))
+#define __profcxx_list_construct(__x...) \
+  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+      __gnu_profile::__trace_list_to_slist_construct(__x))
+#else
+#define __profcxx_list_rewind(__x...)  
+#define __profcxx_list_operation(__x...)
+#define __profcxx_list_destruct(__x...) 
+#define __profcxx_list_construct(__x...)  
+#endif 
+
 // Turn on/off instrumentation for MAP_TO_UNORDERED_MAP.
-#if (defined(_GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP) \
-     && !defined(_NO_GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP))
+#if defined(_GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP)
 #define __profcxx_map_to_unordered_map_construct(__x...) \
   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
       __gnu_profile::__trace_map_to_unordered_map_construct(__x))
@@ -261,7 +365,7 @@
       __gnu_profile::__trace_map_to_unordered_map_find(__x))
 #else
 #define __profcxx_map_to_unordered_map_construct(__x...) \
-
+  
 #define __profcxx_map_to_unordered_map_destruct(__x...)
 #define __profcxx_map_to_unordered_map_insert(__x...)
 #define __profcxx_map_to_unordered_map_erase(__x...)
@@ -271,7 +375,7 @@
 #endif
 
 // Run multithreaded unless instructed not to do so.
-#ifndef _GLIBCXX_PROFILE_NOTHREADS
+#ifndef _GLIBCXX_PROFILE_NO_THREADS
 #define _GLIBCXX_PROFILE_THREADS
 #endif
 
@@ -310,5 +414,7 @@
 #include "profile/impl/profiler_map_to_unordered_map.h"
 #include "profile/impl/profiler_vector_size.h"
 #include "profile/impl/profiler_vector_to_list.h"
+#include "profile/impl/profiler_list_to_slist.h"
+#include "profile/impl/profiler_list_to_vector.h"
 
 #endif // _GLIBCXX_PROFILE_PROFILER_H
Index: include/profile/impl/profiler_state.h
===================================================================
--- include/profile/impl/profiler_state.h	(revision 155631)
+++ include/profile/impl/profiler_state.h	(working copy)
@@ -37,72 +37,34 @@
 #ifndef _GLIBCXX_PROFILE_PROFILER_STATE_H
 #define _GLIBCXX_PROFILE_PROFILER_STATE_H 1
 
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
-#include <cstdio>
-#else
-#include <stdio.h>
-#endif
-
 namespace __gnu_profile
 {
-  /** @brief Profiling mode on/off state.  */
-  template<int _Unused=0>
-    class __state
-    {
-    private:
-      enum __state_type { __ON, __OFF, __INVALID };
 
-      __state_type 		_M_state;
+enum __state_type { __ON, __OFF, __INVALID };
 
-    public:
-      static __state<_Unused>* 	_S_diag_state;
+_GLIBCXX_PROFILE_DEFINE_DATA(__state_type, __state, __INVALID);
 
-      __state() : _M_state(__INVALID) { }
-      ~__state() { }
+inline bool __turn(__state_type __s)
+{
+  return (_GLIBCXX_PROFILE_DATA(__state)
+          == __sync_val_compare_and_swap(&_GLIBCXX_PROFILE_DATA(__state),
+                                         __INVALID, __s));
+}
 
-      bool __is_on() { return _M_state == __ON; }
-      bool __is_off() { return _M_state == __OFF; }
-      bool __is_invalid() { return _M_state == __INVALID; }
-      void __turn_on() { _M_state = __ON; }
-      void __turn_off() { _M_state = __OFF; }
-    };
+inline bool __turn_on()
+{ return __turn(__ON); }
 
-  template<int _Unused>
-    __state<_Unused>* __state<_Unused>::_S_diag_state = NULL;
+inline bool __turn_off()
+{ return __turn(__OFF); }
 
-  inline bool 
-  __is_on()
-  {
-    return __state<0>::_S_diag_state && __state<0>::_S_diag_state->__is_on();
-  }
+inline bool __is_on()
+{ return _GLIBCXX_PROFILE_DATA(__state) == __ON; }
 
-  inline bool 
-  __is_off()
-  {
-    return __state<0>::_S_diag_state && __state<0>::_S_diag_state->__is_off();
-  }
+inline bool __is_off()
+{ return _GLIBCXX_PROFILE_DATA(__state) == __OFF; }
 
-  inline bool 
-  __is_invalid()
-  {
-    return (!__state<0>::_S_diag_state || __state<0>::_S_diag_state->__is_invalid());
-  }
+inline bool __is_invalid()
+{ return _GLIBCXX_PROFILE_DATA(__state) == __INVALID; }
 
-  inline void 
-  __turn_on()
-  {
-    if (!__state<0>::_S_diag_state)
-      __state<0>::_S_diag_state = new __state<0>();
-    __state<0>::_S_diag_state->__turn_on();
-  }
-
-  inline void 
-  __turn_off()
-  {
-    if (!__state<0>::_S_diag_state)
-      __state<0>::_S_diag_state = new __state<0>();
-    __state<0>::_S_diag_state->__turn_off();
-  }
-
 } // end namespace __gnu_profile
 #endif /* _GLIBCXX_PROFILE_PROFILER_STATE_H */
Index: include/profile/impl/profiler_map_to_unordered_map.h
===================================================================
--- include/profile/impl/profiler_map_to_unordered_map.h	(revision 155631)
+++ include/profile/impl/profiler_map_to_unordered_map.h	(working copy)
@@ -52,275 +52,241 @@
 
 namespace __gnu_profile
 {
-  // Cost model. 
-  //  Map operations:
-  //   - insert: 1.5 * log(size)
-  //   - erase: 1.5 * log(size)
-  //   - find: log(size)
-  //   - iterate: 2.3
-  //  Unordered map operations:
-  //   - insert: 12
-  //   - erase: 12
-  //   - find: 10
-  //   - iterate: 1.7
-  // XXX: this must be taken from the machine model instead.
-  const float __map_insert_cost_factor = 1.5;
-  const float __map_erase_cost_factor = 1.5;
-  const float __map_find_cost_factor = 1;
-  const float __map_iterate_cost = 2.3;
 
-  const float __umap_insert_cost = 12.0;
-  const float __umap_erase_cost = 12.0;
-  const float __umap_find_cost = 10.0;
-  const float __umap_iterate_cost = 1.7;
-
-  inline int 
-  __log2(size_t __size)
+inline int __log2(size_t __size)
+{
+  for (int __bit_count = sizeof(size_t) - 1; __bit_count >= 0; -- __bit_count) 
   {
-    int __bit_count = sizeof(size_t) - 1;
-    for (; __bit_count >= 0; --__bit_count) 
-      {
-	if ((2 << __bit_count) & __size)
-	  return __bit_count;
-      }
-    return 0;
+    if ((2 << __bit_count) & __size) {
+      return __bit_count;
+    }
   }
+  return 0;
+}
 
-  inline float 
-  __map_insert_cost(size_t __size)
-  { return __map_insert_cost_factor * static_cast<float>(__log2(__size)); }
+inline float __map_insert_cost(size_t __size)
+{
+  return (_GLIBCXX_PROFILE_DATA(__map_insert_cost_factor).__value 
+          * static_cast<float>(__log2(__size)));
+}
 
-  inline float 
-  __map_erase_cost(size_t __size)
-  { return __map_erase_cost_factor * static_cast<float>(__log2(__size)); }
+inline float __map_erase_cost(size_t __size)
+{
+  return (_GLIBCXX_PROFILE_DATA(__map_erase_cost_factor).__value
+          * static_cast<float>(__log2(__size)));
+}
 
-  inline float 
-  __map_find_cost(size_t __size)
-  { return __map_find_cost_factor * static_cast<float>(__log2(__size)); }
+inline float __map_find_cost(size_t __size)
+{
+  return (_GLIBCXX_PROFILE_DATA(__map_find_cost_factor).__value
+          * static_cast<float>(__log2(__size)));
+}
 
-  /** @brief A map-to-unordered_map instrumentation line in the object table. */
-  class __map2umap_info: public __object_info_base
-  {
-  public:
-    __map2umap_info()
-    : _M_insert(0), _M_erase(0), _M_find(0), _M_iterate(0),
-      _M_map_cost(0.0), _M_umap_cost(0.0), _M_valid(true) { }
+/** @brief A map-to-unordered_map instrumentation line in the object table.  */
+class __map2umap_info: public __object_info_base
+{
+ public:
+  __map2umap_info()
+      : _M_insert(0), _M_erase(0), _M_find(0), _M_iterate(0),
+        _M_map_cost(0.0), _M_umap_cost(0.0), _M_valid(true) {}
+  __map2umap_info(__stack_t __stack)
+      : __object_info_base(__stack), _M_insert(0), _M_erase(0), _M_find(0), 
+        _M_iterate(0), _M_map_cost(0.0), _M_umap_cost(0.0), _M_valid(true) {} 
+  virtual ~__map2umap_info() {}
+  __map2umap_info(const __map2umap_info& o);
+  void __merge(const __map2umap_info& o);
+  void __write(FILE* __f) const;
+  float __magnitude() const { return _M_map_cost - _M_umap_cost; }
+  const char* __advice() const;
 
-    __map2umap_info(__stack_t __stack)
-    : __object_info_base(__stack), _M_insert(0), _M_erase(0), _M_find(0), 
-      _M_iterate(0), _M_map_cost(0.0), _M_umap_cost(0.0), _M_valid(true) { } 
+  void __record_insert(size_t __size, size_t __count);
+  void __record_erase(size_t __size, size_t __count);
+  void __record_find(size_t __size);
+  void __record_iterate(size_t __count);
+  void __record_invalidate();
 
-    virtual ~__map2umap_info() { }
+ private:
+  size_t _M_insert;
+  size_t _M_erase;
+  size_t _M_find;
+  size_t _M_iterate;
+  float _M_umap_cost;
+  float _M_map_cost;
+  bool  _M_valid;
+};
 
-    __map2umap_info(const __map2umap_info& o);
+inline const char* __map2umap_info::__advice() const
+{
+  return strdup("change std::map to std::unordered_map");
+}
 
-    void __merge(const __map2umap_info& o);
-    void __write(FILE* __f) const;
-    float __magnitude() const { return _M_map_cost - _M_umap_cost; }
-    const char* __advice() const;
+inline __map2umap_info::__map2umap_info(const __map2umap_info& __o)
+    : __object_info_base(__o), 
+      _M_insert(__o._M_insert),
+      _M_erase(__o._M_erase),
+      _M_find(__o._M_find),
+      _M_iterate(__o._M_iterate),
+      _M_map_cost(__o._M_map_cost),
+      _M_umap_cost(__o._M_umap_cost),
+      _M_valid(__o._M_valid)
+{}
 
-    void __record_insert(size_t __size, size_t __count);
-    void __record_erase(size_t __size, size_t __count);
-    void __record_find(size_t __size);
-    void __record_iterate(size_t __count);
-    void __record_invalidate();
+inline void __map2umap_info::__merge(const __map2umap_info& __o)
+{
+  _M_insert    += __o._M_insert;
+  _M_erase     += __o._M_erase;
+  _M_find      += __o._M_find;
+  _M_map_cost  += __o._M_map_cost;
+  _M_umap_cost += __o._M_umap_cost;
+  _M_valid     &= __o._M_valid;
+}
 
-  private:
-    size_t _M_insert;
-    size_t _M_erase;
-    size_t _M_find;
-    size_t _M_iterate;
-    float _M_umap_cost;
-    float _M_map_cost;
-    bool  _M_valid;
-  };
+inline void __map2umap_info:: __record_insert(size_t __size, size_t __count)
+{
+  _M_insert += __count;
+  _M_map_cost += __count * __map_insert_cost(__size);
+  _M_umap_cost += (__count
+                   * _GLIBCXX_PROFILE_DATA(__umap_insert_cost_factor).__value);
+}
 
-  inline __map2umap_info::__map2umap_info(const __map2umap_info& __o)
-  : __object_info_base(__o), 
-    _M_insert(__o._M_insert),
-    _M_erase(__o._M_erase),
-    _M_find(__o._M_find),
-    _M_iterate(__o._M_iterate),
-    _M_map_cost(__o._M_map_cost),
-    _M_umap_cost(__o._M_umap_cost),
-    _M_valid(__o._M_valid)
-  { }
+inline void __map2umap_info:: __record_erase(size_t __size, size_t __count)
+{
+  _M_erase += __count;
+  _M_map_cost += __count * __map_erase_cost(__size);
+  _M_umap_cost += (__count
+                   * _GLIBCXX_PROFILE_DATA(__umap_erase_cost_factor).__value);
+}
 
-  inline const char* 
-  __map2umap_info::__advice() const
-  { return "change std::map to std::unordered_map"; }
+inline void __map2umap_info:: __record_find(size_t __size)
+{
+  _M_find += 1;
+  _M_map_cost += __map_find_cost(__size);
+  _M_umap_cost += _GLIBCXX_PROFILE_DATA(__umap_find_cost_factor).__value;
+}
 
-  inline void 
-  __map2umap_info::__merge(const __map2umap_info& __o)
-  {
-    _M_insert    += __o._M_insert;
-    _M_erase     += __o._M_erase;
-    _M_find      += __o._M_find;
-    _M_map_cost  += __o._M_map_cost;
-    _M_umap_cost += __o._M_umap_cost;
-    _M_valid     &= __o._M_valid;
-  }
+inline void __map2umap_info:: __record_iterate(size_t __count)
+{
+  _M_iterate += __count;
+  _M_map_cost += (__count
+                  * _GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor).__value);
+  _M_umap_cost += (
+      __count * _GLIBCXX_PROFILE_DATA(__umap_iterate_cost_factor).__value);
+}
 
-  inline void 
-  __map2umap_info:: __record_insert(size_t __size, size_t __count)
-  {
-    _M_insert += __count;
-    _M_map_cost += __count * __map_insert_cost(__size);
-    _M_umap_cost += __count * __umap_insert_cost;
-  }
+inline void __map2umap_info:: __record_invalidate()
+{
+  _M_valid = false;
+}
 
-  inline void 
-  __map2umap_info:: __record_erase(size_t __size, size_t __count)
-  {
-    _M_erase += __count;
-    _M_map_cost += __count * __map_erase_cost(__size);
-    _M_umap_cost += __count * __umap_erase_cost;
-  }
+inline void __map2umap_info::__write(FILE* __f) const
+{
+  fprintf(__f, "%Zu %Zu %Zu %Zu %.0f %.0f %s\n",
+          _M_insert, _M_erase, _M_find, _M_iterate, _M_map_cost, _M_umap_cost,
+          _M_valid ? "valid" : "invalid");
+}
 
-  inline void 
-  __map2umap_info:: __record_find(size_t __size)
-  {
-    _M_find += 1;
-    _M_map_cost += __map_find_cost(__size);
-    _M_umap_cost += __umap_find_cost;
-  }
+/** @brief A map-to-unordered_map instrumentation line in the stack table.  */
+class __map2umap_stack_info: public __map2umap_info
+{
+ public:
+  __map2umap_stack_info(const __map2umap_info& o) : __map2umap_info(o) {}
+};
 
-  inline void 
-  __map2umap_info:: __record_iterate(size_t __count)
-  {
-    _M_iterate += __count;
-    _M_map_cost += __count * __map_iterate_cost;
-    _M_umap_cost += __count * __umap_iterate_cost;
-  }
+/** @brief Map-to-unordered_map instrumentation producer.  */
+class __trace_map2umap
+    : public __trace_base<__map2umap_info, __map2umap_stack_info> 
+{
+ public:
+  __trace_map2umap();
+};
 
-  inline void 
-  __map2umap_info:: __record_invalidate()
-  {
-    _M_valid = false;
-  }
+inline __trace_map2umap::__trace_map2umap()
+    : __trace_base<__map2umap_info, __map2umap_stack_info>()
+{
+  __id = "map-to-unordered-map";
+}
 
-  inline void 
-  __map2umap_info::__write(FILE* __f) const
-  {
-    fprintf(__f, "%Zu %Zu %Zu %Zu %.0f %.0f %s\n",
-	    _M_insert, _M_erase, _M_find, _M_iterate, _M_map_cost, _M_umap_cost,
-	    _M_valid ? "valid" : "invalid");
-  }
+inline void __trace_map_to_unordered_map_init()
+{
+  _GLIBCXX_PROFILE_DATA(_S_map2umap) = new __trace_map2umap();
+}
 
-  /** @brief A map-to-unordered_map instrumentation line in the stack table.  */
-  class __map2umap_stack_info: public __map2umap_info
-  {
-  public:
-    __map2umap_stack_info(const __map2umap_info& o) : __map2umap_info(o) { }
-  };
-
-  /** @brief Map-to-unordered_map instrumentation producer.  */
-  class __trace_map2umap
-  : public __trace_base<__map2umap_info, __map2umap_stack_info> 
-  {
-  public:
-    __trace_map2umap();
-  };
-
-  inline __trace_map2umap::__trace_map2umap()
-  : __trace_base<__map2umap_info, __map2umap_stack_info>()
-  { __id = "map-to-unordered-map"; }
-
-  inline void 
-  __trace_map_to_unordered_map_init()
-  { __tables<0>::_S_map2umap = new __trace_map2umap(); }
-
-  inline void 
-  __trace_map_to_unordered_map_report(FILE* __f, __warning_vector_t& __warnings)
-  {
-    if (__tables<0>::_S_map2umap) 
-      {
-	__tables<0>::_S_map2umap->__collect_warnings(__warnings);
-	__tables<0>::_S_map2umap->__write(__f);
-      }
+inline void __trace_map_to_unordered_map_report(
+    FILE* __f, __warning_vector_t& __warnings)
+{
+  if (_GLIBCXX_PROFILE_DATA(_S_map2umap)) {
+    _GLIBCXX_PROFILE_DATA(_S_map2umap)->__collect_warnings(__warnings);
+    _GLIBCXX_PROFILE_DATA(_S_map2umap)->__write(__f);
   }
+}
 
-  // Implementations of instrumentation hooks.
-  inline void 
-  __trace_map_to_unordered_map_construct(const void* __obj)
-  {
-    if (!__profcxx_init()) 
-      return;
+inline void __trace_map_to_unordered_map_construct(const void* __obj)
+{
+  if (!__profcxx_init()) return;
 
-    __tables<0>::_S_map2umap->__add_object(__obj, 
-					   __map2umap_info(__get_stack()));
-  }
+  _GLIBCXX_PROFILE_DATA(_S_map2umap)->__add_object(
+      __obj, __map2umap_info(__get_stack()));
+}
 
-  inline void 
-  __trace_map_to_unordered_map_destruct(const void* __obj)
-  {
-    if (!__profcxx_init()) 
-      return;
+inline void __trace_map_to_unordered_map_destruct(const void* __obj)
+{
+  if (!__profcxx_init()) return;
 
-    __tables<0>::_S_map2umap->__retire_object(__obj);
-  }
+  _GLIBCXX_PROFILE_DATA(_S_map2umap)->__retire_object(__obj);
+}
 
-  inline void 
-  __trace_map_to_unordered_map_insert(const void* __obj, size_t __size, 
-				      size_t __count)
-  {
-    if (!__profcxx_init()) 
-      return;
+inline void __trace_map_to_unordered_map_insert(const void* __obj, 
+                                                size_t __size, size_t __count)
+{
+  if (!__profcxx_init()) return;
 
-    __map2umap_info* __info = __tables<0>::_S_map2umap->__get_object_info(__obj);
+  __map2umap_info* __info =
+      _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
 
-    if (__info) 
-      __info->__record_insert(__size, __count);
-  }
+  if (__info) __info->__record_insert(__size, __count);
+}
 
-  inline void 
-  __trace_map_to_unordered_map_erase(const void* __obj, size_t __size, 
-				     size_t __count)
-  {
-    if (!__profcxx_init())
-      return;
+inline void __trace_map_to_unordered_map_erase(const void* __obj, 
+                                               size_t __size, size_t __count)
+{
+  if (!__profcxx_init()) return;
 
-    __map2umap_info* __info = __tables<0>::_S_map2umap->__get_object_info(__obj);
+  __map2umap_info* __info =
+      _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
 
-    if (__info) 
-      __info->__record_erase(__size, __count);
-  }
+  if (__info) __info->__record_erase(__size, __count);
+}
 
-  inline void 
-  __trace_map_to_unordered_map_find(const void* __obj, size_t __size)
-  {
-    if (!__profcxx_init()) 
-      return;
+inline void __trace_map_to_unordered_map_find(const void* __obj, size_t __size)
+{
+  if (!__profcxx_init()) return;
 
-    __map2umap_info* __info = __tables<0>::_S_map2umap->__get_object_info(__obj);
+  __map2umap_info* __info =
+      _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
 
-    if (__info) 
-      __info->__record_find(__size);
-  }
+  if (__info) __info->__record_find(__size);
+}
 
-  inline void 
-  __trace_map_to_unordered_map_iterate(const void* __obj, size_t __count)
-  {
-    if (!__profcxx_init()) 
-      return;
+inline void __trace_map_to_unordered_map_iterate(const void* __obj, 
+                                                 size_t __count)
+{
+  if (!__profcxx_init()) return;
 
-    __map2umap_info* __info = __tables<0>::_S_map2umap->__get_object_info(__obj);
+  __map2umap_info* __info =
+      _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
 
-    if (__info) 
-      __info->__record_iterate(__count);
-  }
+  if (__info) __info->__record_iterate(__count);
+}
 
-  inline void 
-  __trace_map_to_unordered_map_invalidate(const void* __obj)
-  {
-    if (!__profcxx_init()) 
-      return;
+inline void __trace_map_to_unordered_map_invalidate(const void* __obj)
+{
+  if (!__profcxx_init()) return;
 
-    __map2umap_info* __info = __tables<0>::_S_map2umap->__get_object_info(__obj);
+  __map2umap_info* __info =
+      _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
 
-    if (__info) 
-      __info->__record_invalidate();
-  }
+  if (__info) __info->__record_invalidate();
+}
 
 } // namespace __gnu_profile
 #endif /* _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H */
Index: include/profile/impl/profiler_hashtable_size.h
===================================================================
--- include/profile/impl/profiler_hashtable_size.h	(revision 155631)
+++ include/profile/impl/profiler_hashtable_size.h	(working copy)
@@ -54,58 +54,55 @@
 
 namespace __gnu_profile
 {
-  /** @brief Hashtable size instrumentation trace producer.  */
-  class __trace_hashtable_size : public __trace_container_size
-  {
-  public:
-    __trace_hashtable_size() : __trace_container_size()
-    { __id = "hashtable-size"; }
-  };
 
-  // Initialization and report.
-  inline void
-  __trace_hashtable_size_init()
-  { __tables<0>::_S_hashtable_size = new __trace_hashtable_size(); }
-
-  inline void
-  __trace_hashtable_size_report(FILE* __f, __warning_vector_t& __warnings)
+/** @brief Hashtable size instrumentation trace producer.  */
+class __trace_hashtable_size : public __trace_container_size
+{
+ public:
+  __trace_hashtable_size() : __trace_container_size()
   {
-    if (__tables<0>::_S_hashtable_size)
-      {
-	__tables<0>::_S_hashtable_size->__collect_warnings(__warnings);
-	__tables<0>::_S_hashtable_size->__write(__f);
-      }
+    __id = "hashtable-size";
   }
+};
 
-  // Implementations of instrumentation hooks.
-  inline void
-  __trace_hashtable_size_construct(const void* __obj, size_t __num)
-  {
-    if (!__profcxx_init())
-      return;
+inline void __trace_hashtable_size_init()
+{
+  _GLIBCXX_PROFILE_DATA(_S_hashtable_size) = new __trace_hashtable_size();
+}
 
-    __tables<0>::_S_hashtable_size->__insert(__obj, __get_stack(), __num);
+inline void __trace_hashtable_size_report(FILE* __f, 
+                                          __warning_vector_t& __warnings)
+{
+  if (_GLIBCXX_PROFILE_DATA(_S_hashtable_size)) {
+    _GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__collect_warnings(__warnings);
+    _GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__write(__f);
   }
+}
 
-  inline void
-  __trace_hashtable_size_destruct(const void* __obj, size_t __num,
-				  size_t __inum)
-  {
-    if (!__profcxx_init())
-      return;
+inline void __trace_hashtable_size_construct(const void* __obj, size_t __num)
+{
+  if (!__profcxx_init()) return;
+  
+  _GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__insert(__obj, __get_stack(),
+                                                     __num);
+}
 
-    __tables<0>::_S_hashtable_size->__destruct(__obj, __num, __inum);
-  }
+inline void __trace_hashtable_size_destruct(const void* __obj, size_t __num, 
+                                            size_t __inum)
+{
+  if (!__profcxx_init()) return;
 
-  inline void
-  __trace_hashtable_size_resize(const void* __obj, size_t __from, size_t __to)
-  {
-    if (!__profcxx_init())
-      return;
+  _GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__destruct(__obj, __num, __inum);
+}
 
-    __tables<0>::_S_hashtable_size->__resize(__obj, __from, __to);
-  }
+inline void __trace_hashtable_size_resize(const void* __obj, size_t __from, 
+                                          size_t __to)
+{
+  if (!__profcxx_init()) return;
 
+  _GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__resize(__obj, __from, __to);
+}
+
 } // namespace __gnu_profile
 
 #endif /* _GLIBCXX_PROFILE_PROFILER_HASHTABLE_SIZE_H */
Index: include/profile/impl/profiler_node.h
===================================================================
--- include/profile/impl/profiler_node.h	(revision 155631)
+++ include/profile/impl/profiler_node.h	(working copy)
@@ -53,116 +53,120 @@
 
 namespace __gnu_profile
 {
-  typedef const void* __object_t;
-  typedef void* __instruction_address_t;
-  typedef std::_GLIBCXX_STD_PR::vector<__instruction_address_t> __stack_npt;
-  typedef __stack_npt* __stack_t;
+typedef const void* __object_t;
+typedef void* __instruction_address_t;
+typedef std::_GLIBCXX_STD_PR::vector<__instruction_address_t> __stack_npt;
+typedef __stack_npt* __stack_t;
 
-  size_t __stack_max_depth();
+size_t __stack_max_depth();
 
-  inline __stack_t __get_stack()
-  {
+inline __stack_t __get_stack()
+{
 #if defined HAVE_EXECINFO_H
-    size_t __max_depth = __stack_max_depth();
-    if (__max_depth == 0)
-      return NULL;
-    __stack_npt __buffer(__max_depth);
-    int __depth = backtrace(&__buffer[0], __max_depth);
-    __stack_t __stack = new __stack_npt(__depth);
-    memcpy(&(*__stack)[0], &__buffer[0], __depth * sizeof(__object_t));
-    return __stack;
+  size_t __max_depth = __stack_max_depth();
+  if (__max_depth == 0)
+    return NULL;
+  __stack_npt __buffer(__max_depth);
+  int __depth = backtrace(&__buffer[0], __max_depth);
+  __stack_t __stack = new __stack_npt(__depth);
+  memcpy(&(*__stack)[0], &__buffer[0], __depth * sizeof(__object_t));
+  return __stack;
 #else
-    return NULL;
+  return NULL;
 #endif
+}
+
+inline __size(const __stack_t& __stack)
+{
+  if (!__stack) {
+    return 0;
+  } else {
+    return __stack->size();
   }
+}
 
-  inline __size(const __stack_t& __stack)
-  {
-    if (!__stack)
-      return 0;
-    else
-      return __stack->size();
+inline void __write(FILE* __f, const __stack_t __stack)
+{
+  if (!__stack) {
+    return;
   }
 
-  inline void __write(FILE* __f, const __stack_t __stack)
+  __stack_npt::const_iterator __it;
+  for (__it = __stack->begin(); __it != __stack->end(); ++__it) {
+    fprintf(__f, "%p ", *__it);
+  }
+}
+
+/** @brief Hash function for summary trace using call stack as index.  */
+class __stack_hash 
+{
+ public:
+  size_t operator()(const __stack_t __s) const
   {
-    if (!__stack)
-      return;
+    if (!__s) {
+      return 0;
+    }
 
+    uintptr_t __index = 0;
     __stack_npt::const_iterator __it;
-    for (__it = __stack->begin(); __it != __stack->end(); ++__it)
-      fprintf(__f, "%p ", *__it);
+    for (__it = __s->begin(); __it != __s->end(); ++__it) {
+      __index += reinterpret_cast<uintptr_t>(*__it);
+    } 
+    return __index;
   }
 
-  /** @brief Hash function for summary trace using call stack as index.  */
-  class __stack_hash
+  bool operator() (const __stack_t __stack1, const __stack_t __stack2) const
   {
-  public:
-    size_t operator()(const __stack_t __s) const
-    {
-      if (!__s)
-	return 0;
-      
-      uintptr_t __index = 0;
-      __stack_npt::const_iterator __it;
-      for (__it = __s->begin(); __it != __s->end(); ++__it) 
-	{
-	  __index += reinterpret_cast<uintptr_t>(*__it);
-	}
-      return __index;
-    }
+    if (!__stack1 && !__stack2) return true;
+    if (!__stack1 || !__stack2) return false;
+    if (__stack1->size() != __stack2->size()) return false;
 
-    bool operator() (const __stack_t __stack1, const __stack_t __stack2) const
-    {
-      if (!__stack1 && !__stack2) return true;
-      if (!__stack1 || !__stack2) return false;
-      if (__stack1->size() != __stack2->size()) return false;
+    size_t __byte_size = __stack1->size() * sizeof(__stack_npt::value_type);
+    return memcmp(&(*__stack1)[0], &(*__stack2)[0], __byte_size) == 0;
+  }
+};
 
-      size_t __byte_size = __stack1->size() * sizeof(__stack_npt::value_type);
-      return memcmp(&(*__stack1)[0], &(*__stack2)[0], __byte_size) == 0;
-    }
-  };
+/** @brief Base class for a line in the object table.  */
+class __object_info_base
+{
+ public:
+  __object_info_base() {}
+  __object_info_base(__stack_t __stack);
+  __object_info_base(const __object_info_base& o);
+  virtual ~__object_info_base() {}
+  bool __is_valid() const { return _M_valid; }
+  __stack_t __stack() const { return _M_stack; }
+  virtual void __write(FILE* f) const = 0;
 
-  /** @brief Base class for a line in the object table.  */
-  class __object_info_base
-  {
-  public:
-    __object_info_base() { }
-    __object_info_base(__stack_t __stack);
-    __object_info_base(const __object_info_base& o);
-    virtual ~__object_info_base() { }
-    bool __is_valid() const { return _M_valid; }
-    __stack_t __stack() const { return _M_stack; }
-    virtual void __write(FILE* f) const = 0;
+ protected:
+  __stack_t _M_stack;
+  bool _M_valid;
+};
 
-  protected:
-    __stack_t _M_stack;
-    bool _M_valid;
-  };
+inline __object_info_base::__object_info_base(__stack_t __stack)
+{
+  _M_stack = __stack;
+  _M_valid = true;
+}
 
-  inline __object_info_base::__object_info_base(__stack_t __stack)
-  {
-    _M_stack = __stack;
-    _M_valid = true;
-  }
+inline __object_info_base::__object_info_base(const __object_info_base& __o)
+{
+  _M_stack = __o._M_stack;
+  _M_valid = __o._M_valid;
+}
 
-  inline __object_info_base::__object_info_base(const __object_info_base& __o)
-  {
-    _M_stack = __o._M_stack;
-    _M_valid = __o._M_valid;
-  }
+/** @brief Base class for a line in the stack table.  */
+template<typename __object_info>
+class __stack_info_base
+{
+ public:
+  __stack_info_base() {}
+  __stack_info_base(const __object_info& __info) = 0;
+  virtual ~__stack_info_base() {}
+  void __merge(const __object_info& __info) = 0;
+  virtual float __magnitude() const = 0;
+  virtual const char* __get_id() const = 0;
+};
 
-  /** @brief Base class for a line in the stack table.  */
-  template<typename __object_info>
-    class __stack_info_base
-    {
-    public:
-      __stack_info_base() { }
-      __stack_info_base(const __object_info& __info) = 0;
-      virtual ~__stack_info_base() { }
-      void __merge(const __object_info& __info) = 0;
-      virtual float __magnitude() const = 0;
-      virtual const char* __get_id() const = 0;
-    };
 } // namespace __gnu_profile
 #endif /* _GLIBCXX_PROFILE_PROFILER_NODE_H */
Index: include/profile/vector
===================================================================
--- include/profile/vector	(revision 155631)
+++ include/profile/vector	(working copy)
@@ -37,12 +37,12 @@
 #include <vector>
 #include <utility>
 #include <profile/base.h>
+#include <profile/iterator_tracker.h>
 
 namespace std
 {
 namespace __profile
 {
-  /// Class std::vector wrapper with performance instrumentation.
   template<typename _Tp,
 	   typename _Allocator = std::allocator<_Tp> >
     class vector
@@ -54,17 +54,21 @@
       typedef typename _Base::reference             reference;
       typedef typename _Base::const_reference       const_reference;
 
-      typedef typename _Base::iterator iterator;
-      typedef typename _Base::const_iterator const_iterator;
+      typedef __iterator_tracker<typename _Base::iterator, vector>
+                                                    iterator;
+      typedef __iterator_tracker<typename _Base::const_iterator, vector>
+				                    const_iterator;
 
       typedef typename _Base::size_type             size_type;
       typedef typename _Base::difference_type       difference_type;
 
-      typedef _Tp				                    value_type;
-      typedef _Allocator			                allocator_type;
+      typedef _Tp				    value_type;
+      typedef _Allocator			    allocator_type;
       typedef typename _Base::pointer               pointer;
       typedef typename _Base::const_pointer         const_pointer;
-
+      typedef std::reverse_iterator<iterator>       reverse_iterator;
+      typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+      
       _Base&
       _M_base()       { return *this; }
 
@@ -157,6 +161,58 @@
       using _Base::assign;
       using _Base::get_allocator;
 
+
+      // iterators:
+      iterator
+      begin()
+      { return iterator(_Base::begin(), this); }
+
+      const_iterator
+      begin() const
+      { return const_iterator(_Base::begin(), this); }
+
+      iterator
+      end()
+      { return iterator(_Base::end(), this); }
+
+      const_iterator
+      end() const
+      { return const_iterator(_Base::end(), this); }
+
+      reverse_iterator
+      rbegin()
+      { return reverse_iterator(end()); }
+
+      const_reverse_iterator
+      rbegin() const
+      { return const_reverse_iterator(end()); }
+
+      reverse_iterator
+      rend()
+      { return reverse_iterator(begin()); }
+
+      const_reverse_iterator
+      rend() const
+      { return const_reverse_iterator(begin()); }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      const_iterator
+      cbegin() const
+      { return const_iterator(_Base::begin(), this); }
+
+      const_iterator
+      cend() const
+      { return const_iterator(_Base::end(), this); }
+
+      const_reverse_iterator
+      crbegin() const
+      { return const_reverse_iterator(end()); }
+
+      const_reverse_iterator
+      crend() const
+      { return const_reverse_iterator(begin()); }
+#endif
+
       // 23.2.4.2 capacity:
       using _Base::size;
       using _Base::max_size;
@@ -238,22 +294,24 @@
       iterator
       insert(iterator __position, const _Tp& __x)
       {
-        __profcxx_vector_insert(this,  __position-_Base::begin(), this->size());
+        __profcxx_vector_insert(this, __position.base() - _Base::begin(),
+                                this->size());
         size_type __old_size = this->capacity();
-	typename _Base::iterator __res = _Base::insert(__position,__x);
+	typename _Base::iterator __res = _Base::insert(__position.base(), __x);
         _M_profile_resize(this, __old_size, this->capacity());
-	return __res;
+	return iterator(__res, this);
       }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       iterator
       insert(iterator __position, _Tp&& __x)
       {
-        __profcxx_vector_insert(this,  __position-_Base::begin(), this->size());
+        __profcxx_vector_insert(this, __position.base() - _Base::begin(),
+                                this->size());
         size_type __old_size = this->capacity();
-	typename _Base::iterator __res = _Base::insert(__position,__x);
+	typename _Base::iterator __res = _Base::insert(__position.base(), __x);
         _M_profile_resize(this, __old_size, this->capacity());
-	return __res;
+	return iterator(__res, this);
       }
 
       void
@@ -262,8 +320,11 @@
 #endif
 
       void
-
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      swap(vector&& __x)
+#else
       swap(vector& __x)
+#endif
       {
         _Base::swap(__x);
       }
@@ -272,9 +333,10 @@
       void
       insert(iterator __position, size_type __n, const _Tp& __x)
       {
-        __profcxx_vector_insert(this,  __position-_Base::begin(), this->size());
+        __profcxx_vector_insert(this, __position.base() - _Base::begin(),
+                                this->size());
         size_type __old_size = this->capacity();
-	    _Base::insert(__position, __n, __x);
+        _Base::insert(__position, __n, __x);
         _M_profile_resize(this, __old_size, this->capacity());
       }
 
@@ -283,12 +345,31 @@
       insert(iterator __position,
              _InputIterator __first, _InputIterator __last)
       {
-        __profcxx_vector_insert(this,  __position-_Base::begin(), this->size());
+        __profcxx_vector_insert(this, __position.base()-_Base::begin(),
+                                this->size());
         size_type __old_size = this->capacity();
         _Base::insert(__position, __first, __last);
         _M_profile_resize(this, __old_size, this->capacity());
       }
 
+
+      iterator
+      erase(iterator __position)
+      {
+	typename _Base::iterator __res = _Base::erase(__position.base());
+	return iterator(__res, this);
+      }
+
+      iterator
+      erase(iterator __first, iterator __last)
+      {
+	// _GLIBCXX_RESOLVE_LIB_DEFECTS
+	// 151. can't currently clear() empty container
+	typename _Base::iterator __res = _Base::erase(__first.base(),
+                                                      __last.base());
+	return iterator(__res, this);
+      }
+
       void
       clear()
       {
@@ -297,17 +378,14 @@
         _Base::clear();
       }
 
-      // iterators:
-      iterator
-      begin()
+      inline void _M_profile_find() const 
       { 
-        return _Base::begin(); 
+        __profcxx_vector_find(this, size()); 
       }
 
-      const_iterator
-      begin() const
+      inline void _M_profile_iterate(int __rewind = 0) const 
       { 
-        return _Base::begin(); 
+        __profcxx_vector_iterate(this); 
       }
 
     private:
@@ -362,6 +440,18 @@
     swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
     { __lhs.swap(__rhs); }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+  template<typename _Tp, typename _Alloc>
+    inline void
+    swap(vector<_Tp, _Alloc>&& __lhs, vector<_Tp, _Alloc>& __rhs)
+    { __lhs.swap(__rhs); }
+
+  template<typename _Tp, typename _Alloc>
+    inline void
+    swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>&& __rhs)
+    { __lhs.swap(__rhs); }
+#endif
+
 } // namespace __profile
   using _GLIBCXX_STD_D::_S_word_bit;
 } // namespace std
Index: include/profile/list
===================================================================
--- include/profile/list	(revision 155631)
+++ include/profile/list	(working copy)
@@ -30,13 +30,15 @@
 #define _GLIBCXX_PROFILE_LIST 1
 
 #include <list>
+#include <profile/base.h> 
+#include <profile/iterator_tracker.h> 
 
 namespace std
 {
 namespace __profile
 {
-  /// Class std::list wrapper with performance instrumentation.
-  template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
+  /** @brief List wrapper with performance instrumentation.  */
+template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
     class list
     : public _GLIBCXX_STD_D::list<_Tp, _Allocator>
     {
@@ -46,8 +48,10 @@
       typedef typename _Base::reference             reference;
       typedef typename _Base::const_reference       const_reference;
 
-      typedef typename _Base::iterator              iterator;
-      typedef typename _Base::const_iterator        const_iterator;
+      typedef __iterator_tracker<typename _Base::iterator, list>        
+				                    iterator;
+      typedef __iterator_tracker<typename _Base::const_iterator, list>  
+                                                    const_iterator;
 
       typedef typename _Base::size_type             size_type;
       typedef typename _Base::difference_type       difference_type;
@@ -61,35 +65,60 @@
 
       // 23.2.2.1 construct/copy/destroy:
       explicit list(const _Allocator& __a = _Allocator())
-      : _Base(__a) { }
+      : _Base(__a) 
+      { 
+        __profcxx_list_construct(this); 	// list2slist
+        __profcxx_list_construct2(this); 	// list2vector
+      }
 
       explicit list(size_type __n, const _Tp& __value = _Tp(),
 		    const _Allocator& __a = _Allocator())
-      : _Base(__n, __value, __a) { }
+      : _Base(__n, __value, __a) 
+      { 
+        __profcxx_list_construct(this); 
+        __profcxx_list_construct2(this); 
+      }
 
       template<class _InputIterator>
       list(_InputIterator __first, _InputIterator __last,
 	   const _Allocator& __a = _Allocator())
       : _Base(__first, __last, __a)
-      { }
+      {	 
+        __profcxx_list_construct(this); 
+        __profcxx_list_construct2(this); 
+      }
 
       list(const list& __x)
-      : _Base(__x) { }
+      : _Base(__x) 
+      { 
+        __profcxx_list_construct(this); 
+        __profcxx_list_construct2(this); 
+      }
 
       list(const _Base& __x)
-      : _Base(__x) { }
+      : _Base(__x) 
+      { 	
+        __profcxx_list_construct(this); 
+        __profcxx_list_construct2(this); 
+      }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       list(list&& __x)
       : _Base(std::forward<list>(__x))
-      { }
+      { 
+        __profcxx_list_construct(this); 
+        __profcxx_list_construct2(this); 
+      }
 
       list(initializer_list<value_type> __l,
            const allocator_type& __a = allocator_type())
         : _Base(__l, __a) { }
 #endif
 
-      ~list() { }
+      ~list() { 
+        __profcxx_list_destruct(this); 
+        __profcxx_list_destruct2(this); 
+      }
 
       list&
       operator=(const list& __x)
@@ -117,7 +146,7 @@
 
       void
       assign(initializer_list<value_type> __l)
-      { _Base::assign(__l); }
+      {	_Base::assign(__l); }
 #endif
 
       template<class _InputIterator>
@@ -127,34 +156,46 @@
 
       void
       assign(size_type __n, const _Tp& __t)
-      { _Base::assign(__n, __t); }
+      {	_Base::assign(__n, __t); }
 
       using _Base::get_allocator;
 
       // iterators:
       iterator
       begin()
-      { return iterator(_Base::begin()); }
+      { return iterator(_Base::begin(), this); }
 
       const_iterator
       begin() const
-      { return const_iterator(_Base::begin()); }
+      { return const_iterator(_Base::begin(), this); }
 
       iterator
       end()
-      { return iterator(_Base::end()); }
+      {
+        __profcxx_list_rewind(this);
+        return iterator(_Base::end(), this);
+      }
 
       const_iterator
       end() const
-      { return const_iterator(_Base::end()); }
+      {
+        __profcxx_list_rewind(this);
+        return const_iterator(_Base::end(), this);
+      }
 
       reverse_iterator
       rbegin()
-      { return reverse_iterator(end()); }
+      {
+        __profcxx_list_rewind(this);
+        return reverse_iterator(end());
+      }
 
       const_reverse_iterator
       rbegin() const
-      { return const_reverse_iterator(end()); }
+      { 
+        __profcxx_list_rewind(this);
+        return const_reverse_iterator(end());
+      }
 
       reverse_iterator
       rend()
@@ -167,11 +208,11 @@
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       const_iterator
       cbegin() const
-      { return const_iterator(_Base::begin()); }
+      { return const_iterator(_Base::begin(), this); }
 
       const_iterator
       cend() const
-      { return const_iterator(_Base::end()); }
+      { return const_iterator(_Base::end(), this); }
 
       const_reverse_iterator
       crbegin() const
@@ -202,14 +243,26 @@
 
       reference
       back()
-      { return _Base::back(); }
+      {
+        __profcxx_list_rewind(this);
+	return _Base::back();
+      }
 
       const_reference
       back() const
-      { return _Base::back(); }
+      {
+        __profcxx_list_rewind(this);
+	return _Base::back();
+      }
 
       // 23.2.2.3 modifiers:
-      using _Base::push_front;
+      void
+      push_front(const value_type& __x)
+      {
+        __profcxx_list_invalid_operator(this);
+        __profcxx_list_operation(this);
+        _Base::push_front(__x);
+      }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       using _Base::emplace_front;
@@ -218,7 +271,7 @@
       void
       pop_front()
       {
-	iterator __victim = begin();
+        __profcxx_list_operation(this);
 	_Base::pop_front();
       }
 
@@ -234,6 +287,7 @@
 	iterator __victim = end();
 	--__victim;
 	_Base::pop_back();
+        __profcxx_list_rewind(this);
       }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
@@ -241,54 +295,70 @@
         iterator
         emplace(iterator __position, _Args&&... __args)
 	{
-	  return iterator(_Base::emplace(__position,
-					std::forward<_Args>(__args)...));
+	  return iterator(_Base::emplace(__position.base(),
+                                         std::forward<_Args>(__args)...));
 	}
 #endif
 
       iterator
       insert(iterator __position, const _Tp& __x)
-      { return iterator(_Base::insert(__position, __x)); }
+      {
+        size_type __size = size();
+        _M_profile_insert(this, __position, __size);
+        return iterator(_Base::insert(__position.base(), __x), this);
+      }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       iterator
       insert(iterator __position, _Tp&& __x)
-      { return emplace(__position, std::move(__x)); }
+      { 
+        size_type __size = size();
+        _M_profile_insert(this, __position, __size);
+        return emplace(__position.base(), std::move(__x)); 
+      }
 
       void
       insert(iterator __p, initializer_list<value_type> __l)
-      { _Base::insert(__p, __l); }
+      {	_Base::insert(__p, __l); }
 #endif
 
       void
       insert(iterator __position, size_type __n, const _Tp& __x)
-      { _Base::insert(__position, __n, __x); }
+      {
+        size_type __size = size();
+        _M_profile_insert(this, __position, __size);
+	_Base::insert(__position.base(), __n, __x);
+      }
 
       template<class _InputIterator>
         void
         insert(iterator __position, _InputIterator __first,
 	       _InputIterator __last)
-        { _Base::insert(__position, __first, __last); }
+      {
+        size_type __size = size();
+        _M_profile_insert(this, __position, __size);
+        _Base::insert(__position.base(), __first, __last);
+      }
 
       iterator
       erase(iterator __position)
-      { return iterator(_Base::erase(__position)); }
+      {	return iterator(_Base::erase(__position.base()), this); }
 
       iterator
       erase(iterator __position, iterator __last)
       {
 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
 	// 151. can't currently clear() empty container
-	return iterator(_Base::erase(__position, __last));
+	return iterator(_Base::erase(__position.base(), __last.base()), this);
       }
 
       void
       swap(list& __x)
-      { _Base::swap(__x); }
+      {	_Base::swap(__x); }
 
       void
       clear()
-      { _Base::clear(); }
+      {	_Base::clear(); }
 
       // 23.2.2.4 list operations:
       void
@@ -305,7 +375,13 @@
       { this->splice(__position, std::move(__x)); }
 #endif
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
       void
+      splice(iterator __position, list& __x, iterator __i)
+      { this->splice(__position, std::move(__x), __i); }
+#endif
+
+      void
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       splice(iterator __position, list&& __x, iterator __i)
 #else
@@ -316,17 +392,11 @@
 	// after implementing the relevant bits of N1599.
 
 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
-	_Base::splice(__position, _GLIBCXX_MOVE(__x._M_base()),
-		      __i);
+	_Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
+		      __i.base());
       }
 
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
       void
-      splice(iterator __position, list& __x, iterator __i)
-      { this->splice(__position, std::move(__x), __i); }
-#endif
-
-      void
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       splice(iterator __position, list&& __x, iterator __first,
 	     iterator __last)
@@ -338,8 +408,8 @@
 	// We used to perform the splice_alloc check:  not anymore, redundant
 	// after implementing the relevant bits of N1599.
 
-	_Base::splice(__position, _GLIBCXX_MOVE(__x._M_base()),
-		      __first, __last);
+	_Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
+		      __first.base(), __last.base());
       }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
@@ -366,6 +436,7 @@
         {
 	  for (iterator __x = begin(); __x != _Base::end(); )
 	    {
+              __profcxx_list_operation(this);
 	      if (__pred(*__x))
 		__x = erase(__x);
 	      else
@@ -383,6 +454,7 @@
 	iterator __next = __first;
 	while (++__next != __last)
 	  {
+            __profcxx_list_operation(this);
 	    if (*__first == *__next)
 	      erase(__next);
 	    else
@@ -402,6 +474,7 @@
 	  iterator __next = __first;
 	  while (++__next != __last)
 	    {
+              __profcxx_list_operation(this);
 	      if (__binary_pred(*__first, *__next))
 		erase(__next);
 	      else
@@ -420,7 +493,7 @@
 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
 	// 300. list::merge() specification incomplete
 	if (this != &__x)
-	  _Base::merge(_GLIBCXX_MOVE(__x._M_base()));
+	  { _Base::merge(_GLIBCXX_MOVE(__x._M_base())); }
       }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
@@ -428,7 +501,7 @@
       merge(list& __x)
       { this->merge(std::move(__x)); }
 #endif
- 
+
       template<class _Compare>
         void
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
@@ -440,7 +513,7 @@
 	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
 	  // 300. list::merge() specification incomplete
 	  if (this != &__x)
-	    _Base::merge(_GLIBCXX_MOVE(__x._M_base()), __comp);
+	    { _Base::merge(_GLIBCXX_MOVE(__x._M_base()), __comp); }
 	}
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
@@ -465,6 +538,28 @@
       const _Base&
       _M_base() const { return *this; }
 
+      inline void _M_profile_find() const 
+      { }
+
+      inline void _M_profile_iterate(int __rewind = 0) const 
+      {
+        __profcxx_list_operation(this);
+        __profcxx_list_iterate(this); 
+        if (__rewind)
+          __profcxx_list_rewind(this);
+      }
+
+    private:
+      size_type _M_profile_insert(void* obj, iterator __pos, size_type __size)
+      {
+        size_type __shift = 0;
+        typename _Base::iterator __it = __pos.base();
+        for ( ; __it!=_Base::end(); __it++)
+          __shift++;
+        __profcxx_list_rewind(this);
+        __profcxx_list_operation(this);
+        __profcxx_list_insert(this, __shift, __size);
+      }
     };
 
   template<typename _Tp, typename _Alloc>
Index: include/Makefile.am
===================================================================
--- include/Makefile.am	(revision 155631)
+++ include/Makefile.am	(working copy)
@@ -793,7 +793,7 @@
 	${profile_srcdir}/multiset.h \
 	${profile_srcdir}/set \
 	${profile_srcdir}/set.h \
-	${profile_srcdir}/hashtable.h
+	${profile_srcdir}/iterator_tracker.h
 profile_impl_srcdir = ${glibcxx_srcdir}/include/profile/impl
 profile_impl_builddir = ./profile/impl
 profile_impl_headers = \
@@ -806,7 +806,9 @@
 	${profile_impl_srcdir}/profiler_state.h \
 	${profile_impl_srcdir}/profiler_trace.h \
 	${profile_impl_srcdir}/profiler_vector_size.h \
-	${profile_impl_srcdir}/profiler_vector_to_list.h
+	${profile_impl_srcdir}/profiler_vector_to_list.h \
+	${profile_impl_srcdir}/profiler_list_to_vector.h \
+	${profile_impl_srcdir}/profiler_list_to_slist.h
 
 # Some of the different "C" header models need extra files.
 # Some "C" header schemes require the "C" compatibility headers.
Index: include/backward/hash_map
===================================================================
--- include/backward/hash_map	(revision 155631)
+++ include/backward/hash_map	(working copy)
@@ -58,11 +58,7 @@
 
 #include "backward_warning.h"
 #include <bits/c++config.h>
-#ifdef _GLIBCXX_PROFILE
-#include <profile/hashtable.h>
-#else
 #include <backward/hashtable.h>
-#endif
 #include <bits/concept_check.h>
 
 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
Index: include/backward/hash_set
===================================================================
--- include/backward/hash_set	(revision 155631)
+++ include/backward/hash_set	(working copy)
@@ -58,11 +58,7 @@
 
 #include "backward_warning.h"
 #include <bits/c++config.h>
-#ifdef _GLIBCXX_PROFILE
-#include <profile/hashtable.h>
-#else
 #include <backward/hashtable.h>
-#endif
 #include <bits/concept_check.h>
 
 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]