OSDN Git Service

libstdc++ profile mode bug fixes and minor updates
authorrus <rus@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 10 Jan 2010 08:25:23 +0000 (08:25 +0000)
committerrus <rus@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 10 Jan 2010 08:25:23 +0000 (08:25 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@155786 138bc75d-0d04-0410-961f-82ee72b054a4

27 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/config.h.in
libstdc++-v3/configure
libstdc++-v3/configure.ac
libstdc++-v3/doc/xml/manual/profile_mode.xml
libstdc++-v3/include/Makefile.am
libstdc++-v3/include/Makefile.in
libstdc++-v3/include/backward/hash_map
libstdc++-v3/include/backward/hash_set
libstdc++-v3/include/profile/hashtable.h [deleted file]
libstdc++-v3/include/profile/impl/profiler.h
libstdc++-v3/include/profile/impl/profiler_container_size.h
libstdc++-v3/include/profile/impl/profiler_hash_func.h
libstdc++-v3/include/profile/impl/profiler_hashtable_size.h
libstdc++-v3/include/profile/impl/profiler_list_to_slist.h [new file with mode: 0644]
libstdc++-v3/include/profile/impl/profiler_list_to_vector.h [new file with mode: 0644]
libstdc++-v3/include/profile/impl/profiler_map_to_unordered_map.h
libstdc++-v3/include/profile/impl/profiler_node.h
libstdc++-v3/include/profile/impl/profiler_state.h
libstdc++-v3/include/profile/impl/profiler_trace.h
libstdc++-v3/include/profile/impl/profiler_vector_size.h
libstdc++-v3/include/profile/impl/profiler_vector_to_list.h
libstdc++-v3/include/profile/iterator_tracker.h [new file with mode: 0644]
libstdc++-v3/include/profile/list
libstdc++-v3/include/profile/vector
libstdc++-v3/testsuite/ext/throw_allocator/deallocate_global.cc
libstdc++-v3/testsuite/ext/throw_allocator/deallocate_local.cc

index e0fe569..a45c735 100644 (file)
@@ -1,3 +1,37 @@
+2010-01-10  Silvius Rus  <rus@google.com>
+
+       * configure.ac: Add detection of execinfo.h.
+       * configure: Same.
+       * config.h.in: Same.
+       * doc/xml/manual/profile_mode.xml: Add list_to_slist manual.
+       Also, correct user interface mistakes.
+       * include/Makefile.in: Add references to new include files.
+       * include/Makefile.am: Add references to new include files.
+       * include/backward/hash_map: Remove profile include.
+       * include/backward/hash_set: Remove profile include.
+       * include/profile/hashtable.h: Delete file.
+       * include/profile/iterator_tracker.h: New file.
+       * include/profile/vector: Add instrumentation for tracked iterator.
+       * include/profile/list: Same.
+       * include/profile/impl/profiler_list_to_slist.h: New file.
+       * include/profile/impl/profiler_list_to_vector.h: Same.
+       * include/profile/impl/profiler.h: Add list_to_slist and
+       list_to_vector instrumentation hook interfaces.  Fixed broken
+       diagnostic disabling mechanism.
+       (_GLIBCXX_PROFILE_DEFINE_DATA,_GLIBCXX_PROFILE_DATA) New macros.
+       (__reentrance_guard) Fix bug.
+       * include/profile/impl/profiler_trace.h: Replace dummy templates
+       with _GLIBCXX_PROFILE_DEFINE_DATA.
+       * include/profile/impl/profiler_container_size.h: Same.
+       * include/profile/impl/profiler_vector_size.h: Same.
+       * include/profile/impl/profiler_hash_func.h: Same.
+       * include/profile/impl/profiler_vector_to_list.h: Same.
+       * include/profile/impl/profiler_map_to_unordered_map.h: Same.
+       * include/profile/impl/profiler_hashtable_size.h: Same.
+       * include/profile/impl/profiler_node.h: Same.
+       * include/profile/impl/profiler_state.h: Same.  Also, remove
+       class __state. Also, use __sync_val_compare_and_swap to set state.
+
 2010-01-09  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR other/42230
 2010-01-09  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR other/42230
index 8041960..c39f423 100644 (file)
@@ -66,6 +66,9 @@
 /* Define to 1 if you have the <endian.h> header file. */
 #undef HAVE_ENDIAN_H
 
 /* Define to 1 if you have the <endian.h> header file. */
 #undef HAVE_ENDIAN_H
 
+/* Define to 1 if you have the <execinfo.h> header file. */
+#undef HAVE_EXECINFO_H
+
 /* Define if ENODATA exists. */
 #undef HAVE_ENODATA
 
 /* Define if ENODATA exists. */
 #undef HAVE_ENODATA
 
index 82f7f59..2abdfc2 100755 (executable)
@@ -19449,8 +19449,8 @@ fi
 
 
 # Check for available headers.
 
 
 # Check for available headers.
-for ac_header in endian.h float.h fp.h ieeefp.h inttypes.h locale.h \
-machine/endian.h machine/param.h nan.h stdint.h stdlib.h string.h \
+for ac_header in endian.h execinfo.h float.h fp.h ieeefp.h inttypes.h \
+locale.h machine/endian.h machine/param.h nan.h stdint.h stdlib.h string.h \
 strings.h sys/ipc.h sys/isa_defs.h sys/machine.h sys/param.h \
 sys/resource.h sys/sem.h sys/stat.h sys/time.h sys/types.h unistd.h \
 wchar.h wctype.h
 strings.h sys/ipc.h sys/isa_defs.h sys/machine.h sys/param.h \
 sys/resource.h sys/sem.h sys/stat.h sys/time.h sys/types.h unistd.h \
 wchar.h wctype.h
index 2ee2bdb..0137f0a 100644 (file)
@@ -165,8 +165,8 @@ GLIBCXX_CHECK_GTHREADS
 AC_LC_MESSAGES
 
 # Check for available headers.
 AC_LC_MESSAGES
 
 # Check for available headers.
-AC_CHECK_HEADERS([endian.h float.h fp.h ieeefp.h inttypes.h locale.h \
-machine/endian.h machine/param.h nan.h stdint.h stdlib.h string.h \
+AC_CHECK_HEADERS([endian.h execinfo.h float.h fp.h ieeefp.h inttypes.h \
+locale.h machine/endian.h machine/param.h nan.h stdint.h stdlib.h string.h \
 strings.h sys/ipc.h sys/isa_defs.h sys/machine.h sys/param.h \
 sys/resource.h sys/sem.h sys/stat.h sys/time.h sys/types.h unistd.h \
 wchar.h wctype.h])
 strings.h sys/ipc.h sys/isa_defs.h sys/machine.h sys/param.h \
 sys/resource.h sys/sem.h sys/stat.h sys/time.h sys/types.h unistd.h \
 wchar.h wctype.h])
index 5e8e82e..5396e15 100644 (file)
@@ -134,7 +134,7 @@ vector-size: improvement = 3: call stack = 0x804842c ...
   </itemizedlist>
   </para>
 
   </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
    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 @@ vector-size: improvement = 3: call stack = 0x804842c ...
    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.
    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.
   </para>
 
   <para>Advice is given regardless whether the transformation is valid.
@@ -163,19 +166,19 @@ vector-size: improvement = 3: call stack = 0x804842c ...
    in the environment where the program is run, before starting execution.
   <itemizedlist>
   <listitem><para>
    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>
   <listitem><para>
    See section Diagnostics for possible values.
    (Environment variables not supported.)
    </para></listitem>
   <listitem><para>
-   <code>GLIBCXX_PROFILE_TRACE_PATH_ROOT</code>: set an alternative root
+   <code>_GLIBCXX_PROFILE_TRACE_PATH_ROOT</code>: set an alternative root
    path for the output files.
    </para></listitem>
    path for the output files.
    </para></listitem>
-  <listitem><para>GLIBCXX_PROFILE_MAX_WARN_COUNT: set it to the maximum
+  <listitem><para>_GLIBCXX_PROFILE_MAX_WARN_COUNT: set it to the maximum
    number of warnings desired.  The default value is 10.</para></listitem>
   <listitem><para>
    number of warnings desired.  The default value is 10.</para></listitem>
   <listitem><para>
-   <code>GLIBCXX_PROFILE_MAX_STACK_DEPTH</code>: if set to 0, 
+   <code>_GLIBCXX_PROFILE_MAX_STACK_DEPTH</code>: if set to 0, 
    the advice will
    be collected and reported for the program as a whole, and not for each
    call context.
    the advice will
    be collected and reported for the program as a whole, and not for each
    call context.
@@ -184,7 +187,7 @@ vector-size: improvement = 3: call stack = 0x804842c ...
    The default value is 32.
    </para></listitem>
   <listitem><para>
    The default value is 32.
    </para></listitem>
   <listitem><para>
-   <code>GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC</code>:
+   <code>_GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC</code>:
    set a limit on how much memory to use for the accounting tables for each
    diagnostic type.  When this limit is reached, new events are ignored
    until the memory usage decreases under the limit.  Generally, this means
    set a limit on how much memory to use for the accounting tables for each
    diagnostic type.  When this limit is reached, new events are ignored
    until the memory usage decreases under the limit.  Generally, this means
@@ -192,16 +195,16 @@ vector-size: improvement = 3: call stack = 0x804842c ...
    live containers are deleted.  The default is 128 MB.
    </para></listitem>
   <listitem><para>
    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</code>:
+   Make the library not use threads.  If thread local storage (TLS) is not 
+   available, you will get a preprocessor error asking you to set
+   -D_GLIBCXX_PROFILE_NO_THREADS if your program is single-threaded.
+   Multithreded execution without TLS is not supported.
    (Environment variable not supported.)
    </para></listitem>
   <listitem><para>
    (Environment variable not supported.)
    </para></listitem>
   <listitem><para>
-   <code>HAVE_EXECINFO_H</code>:
-   This name should be defined at library configuration time.
+   <code>_GLIBCXX_HAVE_EXECINFO_H</code>:
+   This name should be defined automatically at library configuration time.
    If your library was configured without <code>execinfo.h</code>, but
    you have it in your include path, you can define it explicitly.  Without
    it, advice is collected for the program as a whole, and not for each
    If your library was configured without <code>execinfo.h</code>, but
    you have it in your include path, you can define it explicitly.  Without
    it, advice is collected for the program as a whole, and not for each
@@ -1320,6 +1323,52 @@ memory references.
 </itemizedlist>
 </sect3>
 
 </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>
 <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 69f90a4..ee7696b 100644 (file)
@@ -793,7 +793,7 @@ profile_headers = \
        ${profile_srcdir}/multiset.h \
        ${profile_srcdir}/set \
        ${profile_srcdir}/set.h \
        ${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 = \
 profile_impl_srcdir = ${glibcxx_srcdir}/include/profile/impl
 profile_impl_builddir = ./profile/impl
 profile_impl_headers = \
@@ -806,7 +806,9 @@ profile_impl_headers = \
        ${profile_impl_srcdir}/profiler_state.h \
        ${profile_impl_srcdir}/profiler_trace.h \
        ${profile_impl_srcdir}/profiler_vector_size.h \
        ${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.
 
 # Some of the different "C" header models need extra files.
 # Some "C" header schemes require the "C" compatibility headers.
index 1a25e1e..62a8daf 100644 (file)
@@ -1026,7 +1026,7 @@ profile_headers = \
        ${profile_srcdir}/multiset.h \
        ${profile_srcdir}/set \
        ${profile_srcdir}/set.h \
        ${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_srcdir = ${glibcxx_srcdir}/include/profile/impl
 profile_impl_builddir = ./profile/impl
@@ -1040,7 +1040,9 @@ profile_impl_headers = \
        ${profile_impl_srcdir}/profiler_state.h \
        ${profile_impl_srcdir}/profiler_trace.h \
        ${profile_impl_srcdir}/profiler_vector_size.h \
        ${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 = 
 
 
 @GLIBCXX_C_HEADERS_EXTRA_FALSE@c_base_headers_extra = 
 
index cb31687..469429c 100644 (file)
 
 #include "backward_warning.h"
 #include <bits/c++config.h>
 
 #include "backward_warning.h"
 #include <bits/c++config.h>
-#ifdef _GLIBCXX_PROFILE
-#include <profile/hashtable.h>
-#else
 #include <backward/hashtable.h>
 #include <backward/hashtable.h>
-#endif
 #include <bits/concept_check.h>
 
 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
 #include <bits/concept_check.h>
 
 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
index d2bd03b..32fa220 100644 (file)
 
 #include "backward_warning.h"
 #include <bits/c++config.h>
 
 #include "backward_warning.h"
 #include <bits/c++config.h>
-#ifdef _GLIBCXX_PROFILE
-#include <profile/hashtable.h>
-#else
 #include <backward/hashtable.h>
 #include <backward/hashtable.h>
-#endif
 #include <bits/concept_check.h>
 
 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
 #include <bits/concept_check.h>
 
 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
diff --git a/libstdc++-v3/include/profile/hashtable.h b/libstdc++-v3/include/profile/hashtable.h
deleted file mode 100644 (file)
index 2089187..0000000
+++ /dev/null
@@ -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 c9db6cd..81d8dba 100644 (file)
 #include <stddef.h>
 #endif
 
 #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.
 namespace __gnu_profile
 {
   /** @brief Reentrance guard.
@@ -53,80 +67,127 @@ namespace __gnu_profile
   struct __reentrance_guard
   {
     static bool
   struct __reentrance_guard
   {
     static bool
-    _S_set_in()
+    __get_in()
     {
     {
-      if (_S_get_in())
+      if (__inside() == true)
        return false;
       else
        {
        return false;
       else
        {
-         _S_get_in() = true;
+         __inside() = true;
          return true;
        }
     }
 
     static bool&
          return true;
        }
     }
 
     static bool&
-    _S_get_in()
+    __inside()
     {
       static __thread bool _S_inside(false);
       return _S_inside;
     }
 
     __reentrance_guard() { }
     {
       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...)              \
   {                                                             \
   };
 
 #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;                                                      \
     }                                                           \
   }
     {                                                           \
       __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);
+
+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); 
 
 
-  // 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_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
 
 } // namespace __gnu_profile
 
-// Master switch turns on all diagnostics.
+// Master switch turns on all diagnostics that are not explicitly turned off.
 #ifdef _GLIBCXX_PROFILE
 #ifdef _GLIBCXX_PROFILE
+#ifndef _GLIBCXX_PROFILE_NO_HASHTABLE_TOO_SMALL
 #define _GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL
 #define _GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL
+#endif
+#ifndef _GLIBCXX_PROFILE_NO_HASHTABLE_TOO_LARGE
 #define _GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE
 #define _GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE
+#endif
+#ifndef _GLIBCXX_PROFILE_NO_VECTOR_TOO_SMALL
 #define _GLIBCXX_PROFILE_VECTOR_TOO_SMALL
 #define _GLIBCXX_PROFILE_VECTOR_TOO_SMALL
+#endif
+#ifndef _GLIBCXX_PROFILE_NO_VECTOR_TOO_LARGE
 #define _GLIBCXX_PROFILE_VECTOR_TOO_LARGE
 #define _GLIBCXX_PROFILE_VECTOR_TOO_LARGE
+#endif
+#ifndef _GLIBCXX_PROFILE_NO_INEFFICIENT_HASH
 #define _GLIBCXX_PROFILE_INEFFICIENT_HASH
 #define _GLIBCXX_PROFILE_INEFFICIENT_HASH
+#endif
+#ifndef _GLIBCXX_PROFILE_NO_VECTOR_TO_LIST
 #define _GLIBCXX_PROFILE_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
 #define _GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP
 #endif
+#endif
 
 // Expose global management routines to user code.
 #ifdef _GLIBCXX_PROFILE
 
 // Expose global management routines to user code.
 #ifdef _GLIBCXX_PROFILE
@@ -152,10 +213,8 @@ namespace __gnu_profile
 #endif
 
 // Turn on/off instrumentation for HASHTABLE_TOO_SMALL and HASHTABLE_TOO_LARGE.
 #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))
 #define __profcxx_hashtable_resize(__x...) \
   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
       __gnu_profile::__trace_hashtable_size_resize(__x))
@@ -166,16 +225,14 @@ namespace __gnu_profile
   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
       __gnu_profile::__trace_hashtable_size_construct(__x))
 #else
   _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.
 #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))
 #define __profcxx_vector_resize(__x...) \
   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
       __gnu_profile::__trace_vector_size_resize(__x))
@@ -186,14 +243,13 @@ namespace __gnu_profile
   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
       __gnu_profile::__trace_vector_size_construct(__x))
 #else
   _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.
 
 // 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))
 #define __profcxx_hashtable_construct2(__x...) \
   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
       __gnu_profile::__trace_hash_func_construct(__x))
@@ -201,13 +257,12 @@ namespace __gnu_profile
   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
       __gnu_profile::__trace_hash_func_destruct(__x))
 #else
   _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.
 #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))
 #define __profcxx_vector_construct2(__x...) \
   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
       __gnu_profile::__trace_vector_to_list_construct(__x))
@@ -226,6 +281,9 @@ namespace __gnu_profile
 #define __profcxx_vector_resize2(__x...) \
   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
       __gnu_profile::__trace_vector_to_list_resize(__x))
 #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...)
 #else
 #define __profcxx_vector_destruct2(__x...)
 #define __profcxx_vector_construct2(__x...)
@@ -233,11 +291,57 @@ namespace __gnu_profile
 #define __profcxx_vector_iterate(__x...)
 #define __profcxx_vector_invalid_operator(__x...)
 #define __profcxx_vector_resize2(__x...)
 #define __profcxx_vector_iterate(__x...)
 #define __profcxx_vector_invalid_operator(__x...)
 #define __profcxx_vector_resize2(__x...)
+#define __profcxx_vector_find(__x...)
 #endif
 
 #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.
 // 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))
 #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 @@ namespace __gnu_profile
       __gnu_profile::__trace_map_to_unordered_map_find(__x))
 #else
 #define __profcxx_map_to_unordered_map_construct(__x...) \
       __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...)
 #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 @@ namespace __gnu_profile
 #endif
 
 // Run multithreaded unless instructed not to do so.
 #endif
 
 // Run multithreaded unless instructed not to do so.
-#ifndef _GLIBCXX_PROFILE_NOTHREADS
+#ifndef _GLIBCXX_PROFILE_NO_THREADS
 #define _GLIBCXX_PROFILE_THREADS
 #endif
 
 #define _GLIBCXX_PROFILE_THREADS
 #endif
 
@@ -280,11 +384,11 @@ namespace __gnu_profile
 #define _GLIBCXX_PROFILE_TRACE_PATH_ROOT "libstdcxx-profile"
 #endif
 #ifndef _GLIBCXX_PROFILE_TRACE_ENV_VAR
 #define _GLIBCXX_PROFILE_TRACE_PATH_ROOT "libstdcxx-profile"
 #endif
 #ifndef _GLIBCXX_PROFILE_TRACE_ENV_VAR
-#define _GLIBCXX_PROFILE_TRACE_ENV_VAR "GLIBCXX_PROFILE_TRACE_PATH_ROOT"
+#define _GLIBCXX_PROFILE_TRACE_ENV_VAR "_GLIBCXX_PROFILE_TRACE_PATH_ROOT"
 #endif
 #ifndef _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR
 #define _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR \
 #endif
 #ifndef _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR
 #define _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR \
-  "GLIBCXX_PROFILE_MAX_WARN_COUNT"
+  "_GLIBCXX_PROFILE_MAX_WARN_COUNT"
 #endif
 #ifndef _GLIBCXX_PROFILE_MAX_WARN_COUNT
 #define _GLIBCXX_PROFILE_MAX_WARN_COUNT 10
 #endif
 #ifndef _GLIBCXX_PROFILE_MAX_WARN_COUNT
 #define _GLIBCXX_PROFILE_MAX_WARN_COUNT 10
@@ -294,14 +398,14 @@ namespace __gnu_profile
 #endif
 #ifndef _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR
 #define _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR \
 #endif
 #ifndef _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR
 #define _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR \
-  "GLIBCXX_PROFILE_MAX_STACK_DEPTH"
+  "_GLIBCXX_PROFILE_MAX_STACK_DEPTH"
 #endif
 #ifndef _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC
 #define _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC 2 << 27
 #endif
 #ifndef _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR
 #define _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR \
 #endif
 #ifndef _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC
 #define _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC 2 << 27
 #endif
 #ifndef _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR
 #define _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR \
-  "GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC"
+  "_GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC"
 #endif
 
 // Instrumentation hook implementations.
 #endif
 
 // Instrumentation hook implementations.
@@ -310,5 +414,7 @@ namespace __gnu_profile
 #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_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
 
 #endif // _GLIBCXX_PROFILE_PROFILER_H
index 71f5556..bfbab85 100644 (file)
 #include <string.h>
 #endif
 
 #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
 {
 #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;
-
-    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);
-
-  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;
-  };
-
-  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;
-  }
+/** @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;
+
+  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);
+
+ 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;
+};
+
+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;
 
 
-  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);
-  }
+  return strdup(__message.str().c_str());
+}
 
 
-  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::__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 __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 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 __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(const __container_size_info& __o)
+inline __container_size_info::__container_size_info(
+    const __container_size_info& __o)
     : __object_info_base(__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 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>() {};
+
+  // 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);
+};
+
+inline void __trace_container_size::__insert(const __object_t __obj,
+                                             __stack_t __stack, size_t __num)
+{
+  __add_object(__obj, __container_size_info(__stack, __num));
+}
 
 
-  /** @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>() { };
-
-    ~__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);
-  };
-
-  inline void 
-  __trace_container_size::__insert(const __object_t __obj,
-                                  __stack_t __stack, size_t __num)
-  { __add_object(__obj, __container_size_info(__stack, __num)); }
-
-  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);
-  }
+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);
+}
 
 
-  inline void 
-  __trace_container_size::__destruct(const void* __obj, size_t __num, 
-                                    size_t __inum)
-  {
-    if (!__is_on()) return;
+inline void __trace_container_size::__destruct(const void* __obj, 
+                                               size_t __num, size_t __inum)
+{
+  if (!__is_on()) return;
 
 
-    __object_t __obj_handle = static_cast<__object_t>(__obj);
+  __object_t __obj_handle = static_cast<__object_t>(__obj);
 
 
-    __container_size_info* __object_info = __get_object_info(__obj_handle);
-    if (!__object_info)
-      return;
+  __container_size_info* __object_info = __get_object_info(__obj_handle);
+  if (!__object_info)
+    return;
 
 
-    __object_info->__destruct(__num, __inum);
-    __retire_object(__obj_handle);
-  }
+  __object_info->__destruct(__num, __inum);
+  __retire_object(__obj_handle);
+}
 
 
-  inline void 
-  __trace_container_size::__resize(const void* __obj, int __from, int __to)
-  {
-    if (!__is_on()) return;
+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;
+  __container_size_info* __object_info = __get_object_info(__obj);
+  if (!__object_info)
+    return;
+
+  __object_info->__resize(__from, __to);
+}
 
 
-    __object_info->__resize(__from, __to);
-  }
 } // namespace __gnu_profile
 #endif /* _GLIBCXX_PROFILE_PROFILER_CONTAINER_SIZE_H */
 } // namespace __gnu_profile
 #endif /* _GLIBCXX_PROFILE_PROFILER_CONTAINER_SIZE_H */
index 86859e5..95fad19 100644 (file)
 
 namespace __gnu_profile
 {
 
 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);
-
-    __hashfunc_info(__stack_t __stack) 
-    : __object_info_base(__stack), _M_longest_chain(0), 
-      _M_accesses(0), _M_hops(0) { }
-
-    virtual ~__hashfunc_info() { }
-
-    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"; }
-
-  private:
-    size_t _M_longest_chain;
-    size_t _M_accesses;
-    size_t _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::__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 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() {}
+
+  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"); }
+
+private:
+  size_t _M_longest_chain;
+  size_t _M_accesses;
+  size_t _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;
+}
+
+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 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) {}
+};
+
+/** @brief Hash performance instrumentation producer.  */
+class __trace_hash_func
+    : public __trace_base<__hashfunc_info, __hashfunc_stack_info> 
+{
+ public:
+  __trace_hash_func();
+  ~__trace_hash_func() {}
+
+  // 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);
+};
+
+inline __trace_hash_func::__trace_hash_func()
+    : __trace_base<__hashfunc_info, __hashfunc_stack_info>()
+{
+  __id = "hash-distr";
+}
 
 
-  /** @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) { }
-  };
-
-  /** @brief Hash performance instrumentation producer.  */
-  class __trace_hash_func
-  : public __trace_base<__hashfunc_info, __hashfunc_stack_info>
-  {
-  public:
-    __trace_hash_func();
-    ~__trace_hash_func() { }
-
-    // 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);
-  };
-
-  inline __trace_hash_func::__trace_hash_func()
-  : __trace_base<__hashfunc_info, __hashfunc_stack_info>()
-  { __id = "hash-distr"; }
-
-  inline void 
-  __trace_hash_func::__insert(__object_t __obj, __stack_t __stack)
-  { __add_object(__obj, __hashfunc_info(__stack)); }
-
-  inline void 
-  __hashfunc_info::__write(FILE* __f) const
-  { fprintf(__f, "%Zu %Zu %Zu\n", _M_hops, _M_accesses, _M_longest_chain); }
-
-  inline void 
-  __trace_hash_func::__destruct(const void* __obj, size_t __chain,
-                               size_t __accesses, size_t __hops)
-  {
-    if (!__is_on()) 
-      return;
-
-    // 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::__insert(__object_t __obj, __stack_t __stack)
+{
+  __add_object(__obj, __hashfunc_info(__stack));
+}
 
 
+inline void __hashfunc_info::__write(FILE* __f) const
+{
+  fprintf(__f, "%Zu %Zu %Zu\n", _M_hops, _M_accesses, _M_longest_chain);
+}
 
 
-  // Initialization and report.
-  inline void 
-  __trace_hash_func_init()
-  { __tables<0>::_S_hash_func = new __trace_hash_func(); }
+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_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);
-      }
-  }
+  // 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);
+}
 
 
-  // Implementations of instrumentation hooks.
-  inline void 
-  __trace_hash_func_construct(const void* __obj)
-  {
-    if (!__profcxx_init()) 
-      return;
+inline void __trace_hash_func_init()
+{
+  _GLIBCXX_PROFILE_DATA(_S_hash_func) = new __trace_hash_func();
+}
 
 
-    __tables<0>::_S_hash_func->__insert(__obj, __get_stack());
+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_destruct(const void* __obj, size_t __chain,
-                            size_t __accesses, size_t __hops)
-  {
-    if (!__profcxx_init()) 
-      return;
+inline void __trace_hash_func_construct(const void* __obj)
+{
+  if (!__profcxx_init()) return;
 
 
-    __tables<0>::_S_hash_func->__destruct(__obj, __chain, __accesses, __hops);
-  }
+  _GLIBCXX_PROFILE_DATA(_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;
+
+  _GLIBCXX_PROFILE_DATA(_S_hash_func)->__destruct(__obj, __chain, __accesses, 
+                                                  __hops);
+}
 
 } // namespace __gnu_profile
 #endif /* _GLIBCXX_PROFILE_PROFILER_HASH_FUNC_H */
 
 } // namespace __gnu_profile
 #endif /* _GLIBCXX_PROFILE_PROFILER_HASH_FUNC_H */
index da89c07..8248f47 100644 (file)
 
 namespace __gnu_profile
 {
 
 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);
+}
+
+inline void __trace_hashtable_size_destruct(const void* __obj, size_t __num, 
+                                            size_t __inum)
+{
+  if (!__profcxx_init()) return;
 
 
-    __tables<0>::_S_hashtable_size->__destruct(__obj, __num, __inum);
-  }
+  _GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__destruct(__obj, __num, __inum);
+}
 
 
-  inline void
-  __trace_hashtable_size_resize(const void* __obj, size_t __from, size_t __to)
-  {
-    if (!__profcxx_init())
-      return;
+inline void __trace_hashtable_size_resize(const void* __obj, size_t __from, 
+                                          size_t __to)
+{
+  if (!__profcxx_init()) return;
 
 
-    __tables<0>::_S_hashtable_size->__resize(__obj, __from, __to);
-  }
+  _GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__resize(__obj, __from, __to);
+}
 
 } // namespace __gnu_profile
 
 
 } // namespace __gnu_profile
 
diff --git a/libstdc++-v3/include/profile/impl/profiler_list_to_slist.h b/libstdc++-v3/include/profile/impl/profiler_list_to_slist.h
new file mode 100644 (file)
index 0000000..073bdf2
--- /dev/null
@@ -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 */
diff --git a/libstdc++-v3/include/profile/impl/profiler_list_to_vector.h b/libstdc++-v3/include/profile/impl/profiler_list_to_vector.h
new file mode 100644 (file)
index 0000000..d3a3713
--- /dev/null
@@ -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 6c90e7a..e715e4c 100644 (file)
 
 namespace __gnu_profile
 {
 
 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_erase_cost(size_t __size)
-  { return __map_erase_cost_factor * 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_insert_cost(size_t __size)
+{
+  return (_GLIBCXX_PROFILE_DATA(__map_insert_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) { }
-
-    __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;
-
-    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();
-
-  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 __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 const char* 
-  __map2umap_info::__advice() const
-  { return "change std::map to std::unordered_map"; }
-
-  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 float __map_erase_cost(size_t __size)
+{
+  return (_GLIBCXX_PROFILE_DATA(__map_erase_cost_factor).__value
+          * static_cast<float>(__log2(__size)));
+}
 
 
-  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 float __map_find_cost(size_t __size)
+{
+  return (_GLIBCXX_PROFILE_DATA(__map_find_cost_factor).__value
+          * static_cast<float>(__log2(__size)));
+}
 
 
-  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;
-  }
+/** @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;
+
+  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();
+
+ 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 const char* __map2umap_info::__advice() const
+{
+  return strdup("change std::map to std::unordered_map");
+}
+
+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::__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_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 void 
-  __map2umap_info:: __record_find(size_t __size)
-  {
-    _M_find += 1;
-    _M_map_cost += __map_find_cost(__size);
-    _M_umap_cost += __umap_find_cost;
-  }
+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 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;
-  }
+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:: __record_invalidate()
-  {
-    _M_valid = false;
-  }
+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_invalidate()
+{
+  _M_valid = false;
+}
 
 
-  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::__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");
+}
 
 
-  /** @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 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();
-  };
+/** @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 __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_init()
+{
+  _GLIBCXX_PROFILE_DATA(_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 */
 
 } // namespace __gnu_profile
 #endif /* _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H */
index 66101a7..77654a8 100644 (file)
 #include <string.h>
 #endif
 #include <vector>
 #include <string.h>
 #endif
 #include <vector>
-#if defined HAVE_EXECINFO_H
+#if defined _GLIBCXX_HAVE_EXECINFO_H
 #include <execinfo.h>
 #endif
 
 namespace __gnu_profile
 {
 #include <execinfo.h>
 #endif
 
 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()
-  {
-#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;
-#else
+inline __stack_t __get_stack()
+{
+#if defined _GLIBCXX_HAVE_EXECINFO_H
+  size_t __max_depth = __stack_max_depth();
+  if (__max_depth == 0)
     return NULL;
     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;
 #endif
 #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;
+  }
+
+  __stack_npt::const_iterator __it;
+  for (__it = __stack->begin(); __it != __stack->end(); ++__it) {
+    fprintf(__f, "%p ", *__it);
   }
   }
+}
 
 
-  inline void __write(FILE* __f, const __stack_t __stack)
+/** @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;
     __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;
+
+ protected:
+  __stack_t _M_stack;
+  bool _M_valid;
+};
+
+inline __object_info_base::__object_info_base(__stack_t __stack)
+{
+  _M_stack = __stack;
+  _M_valid = true;
+}
 
 
-  /** @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;
-  };
-
-  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 */
 } // namespace __gnu_profile
 #endif /* _GLIBCXX_PROFILE_PROFILER_NODE_H */
index 347b5e2..540c3e4 100644 (file)
 #ifndef _GLIBCXX_PROFILE_PROFILER_STATE_H
 #define _GLIBCXX_PROFILE_PROFILER_STATE_H 1
 
 #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
 {
 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;
-
-    public:
-      static __state<_Unused>*         _S_diag_state;
-
-      __state() : _M_state(__INVALID) { }
-      ~__state() { }
-
-      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; }
-    };
-
-  template<int _Unused>
-    __state<_Unused>* __state<_Unused>::_S_diag_state = NULL;
-
-  inline bool 
-  __is_on()
-  {
-    return __state<0>::_S_diag_state && __state<0>::_S_diag_state->__is_on();
-  }
-
-  inline bool 
-  __is_off()
-  {
-    return __state<0>::_S_diag_state && __state<0>::_S_diag_state->__is_off();
-  }
-
-  inline bool 
-  __is_invalid()
-  {
-    return (!__state<0>::_S_diag_state || __state<0>::_S_diag_state->__is_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();
-  }
+
+enum __state_type { __ON, __OFF, __INVALID };
+
+_GLIBCXX_PROFILE_DEFINE_DATA(__state_type, __state, __INVALID);
+
+inline bool __turn(__state_type __s)
+{
+  return (_GLIBCXX_PROFILE_DATA(__state)
+          == __sync_val_compare_and_swap(&_GLIBCXX_PROFILE_DATA(__state),
+                                         __INVALID, __s));
+}
+
+inline bool __turn_on()
+{ return __turn(__ON); }
+
+inline bool __turn_off()
+{ return __turn(__OFF); }
+
+inline bool __is_on()
+{ return _GLIBCXX_PROFILE_DATA(__state) == __ON; }
+
+inline bool __is_off()
+{ return _GLIBCXX_PROFILE_DATA(__state) == __OFF; }
+
+inline bool __is_invalid()
+{ return _GLIBCXX_PROFILE_DATA(__state) == __INVALID; }
 
 } // end namespace __gnu_profile
 #endif /* _GLIBCXX_PROFILE_PROFILER_STATE_H */
 
 } // end namespace __gnu_profile
 #endif /* _GLIBCXX_PROFILE_PROFILER_STATE_H */
index 173b647..7512677 100644 (file)
 #endif
 
 #include <algorithm>
 #endif
 
 #include <algorithm>
+#include <fstream>
+#include <string>
 #include <utility>
 
 #include <utility>
 
-#if defined _GLIBCXX_PROFILE_THREADS && defined HAVE_TLS
+#if (defined _GLIBCXX_PROFILE_THREADS) && !(defined _GLIBCXX_HAVE_TLS)
+#error You do not seem to have TLS support, which is required by the profile \
+  mode.  If your program is not multithreaded, recompile with \
+  -D_GLIBCXX_PROFILE_NO_THREADS
+#endif
+
+#if defined _GLIBCXX_PROFILE_THREADS && defined _GLIBCXX_HAVE_TLS
 #include <pthread.h>
 #endif
 
 #include <pthread.h>
 #endif
 
 
 namespace __gnu_profile
 {
 
 namespace __gnu_profile
 {
-#if defined _GLIBCXX_PROFILE_THREADS && defined HAVE_TLS
+
+#if defined _GLIBCXX_PROFILE_THREADS && defined _GLIBCXX_HAVE_TLS
 #define _GLIBCXX_IMPL_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
 #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
 #else
+typedef int __mutex_t;
+/** @brief Mock mutex interface.  */
 #define _GLIBCXX_IMPL_MUTEX_INITIALIZER 0
 #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
 
 #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;
+};
+
+inline __warning_data::__warning_data()
+    : __magnitude(0.0), __context(NULL), __warning_id(NULL),
+      __warning_message(NULL)
+{
+}
 
 
-  /** @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(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; }
-
-  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;
-  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; }
-
-  inline size_t 
-  __min(size_t __a, size_t __b)  { return __a <= __b ? __a : __b; }
-
-  /** @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;
-    };
-
-  template<int _Unused>
-    __trace_hash_func* __tables<_Unused>::_S_hash_func = NULL;
-
-  template<int _Unused>
-    __trace_hashtable_size* __tables<_Unused>::_S_hashtable_size = NULL;
-
-  template<int _Unused>
-    __trace_map2umap* __tables<_Unused>::_S_map2umap = NULL;
-
-  template<int _Unused>
-    __trace_vector_size* __tables<_Unused>::_S_vector_size = NULL;
-
-  template<int _Unused>
-    __trace_vector_to_list* __tables<_Unused>::_S_vector_to_list = NULL;
-
-  /** @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;
-  };
-
-  template<int _Unused>
-    const char* __settings<_Unused>::_S_trace_file_name =
-    _GLIBCXX_PROFILE_TRACE_PATH_ROOT;
-
-  template<int _Unused>
-    size_t __settings<_Unused>::_S_max_warn_count =
-    _GLIBCXX_PROFILE_MAX_WARN_COUNT;
-
-  template<int _Unused>
-    size_t __settings<_Unused>::_S_max_stack_depth =
-    _GLIBCXX_PROFILE_MAX_STACK_DEPTH;
-
-  template<int _Unused>
-    size_t __settings<_Unused>::_S_max_mem =
-    _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC;
-
-  inline size_t 
-  __stack_max_depth() { return __settings<0>::_S_max_stack_depth; }
-
-  inline size_t 
-  __max_mem() { return __settings<0>::_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() { }
-      
-      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()));
-       }
-    }
+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)
+{
+}
 
 
-  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>::__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_object_table()
-    { __mutex<0>::__unlock(this->__object_table_lock); }
-
-  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;
-    }
+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;
+
+// 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&);
+
+// Utility functions.
+inline size_t __max(size_t __a, size_t __b)
+{
+  return __a >= __b ? __a : __b;
+}
 
 
-  template<typename __object_info, typename __stack_info>
-    void 
-    __trace_base<__object_info, __stack_info>::__add_object(__object_t __object, __object_info __info)
+inline size_t __min(size_t __a, size_t __b)
+{
+  return __a <= __b ? __a : __b;
+}
+
+struct __cost_factor
+{
+  const char* __env_var;
+  float __value;
+};
+
+typedef std::_GLIBCXX_STD_PR::vector<__cost_factor*> __cost_factor_vector;
+
+_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);
+
+_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);
+
+_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);
+
+inline size_t __stack_max_depth()
+{
+  return _GLIBCXX_PROFILE_DATA(_S_max_stack_depth);
+}
+
+inline size_t __max_mem()
+{
+  return _GLIBCXX_PROFILE_DATA(_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() {}
+
+  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 )
   {
   {
-    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();
-    }
+    __warnings.push_back(__warning_data((*__i).second.__magnitude(), 
+                                        (*__i).first, 
+                                        __id,
+                                        (*__i).second.__advice()));
   }
   }
+}
 
 
-  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);
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__lock_object_table()
+{
+  __lock(this->__object_table_lock);
+}
 
 
-    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>::__lock_stack_table()
+{
+  __lock(this->__stack_table_lock);
+}
 
 
-  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);
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__unlock_object_table()
+{
+  __unlock(this->__object_table_lock);
+}
 
 
-    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);
-      }
-    __unlock_stack_table();
+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>
+__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>::__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();
   }
     __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;
-
-    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);
-         }
-      }
+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;
   }
   }
+}
 
 
-  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;
+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);
   }
   }
+  __unlock_stack_table();
+  __unlock_object_table();
+}
 
 
-  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);
+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);
+    }
   }
   }
+}
 
 
-  inline void 
-  __set_max_mem()
-  {
-    __settings<0>::_S_max_mem = __env_to_size_t(_GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR, __settings<0>::_S_max_mem);
+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 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_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;
+}
 
 
-  struct __warn
+struct __warn
+{
+  FILE* __file;
+  __warn(FILE* __f) { __file = __f; }
+  void operator() (const __warning_data& __info)
   {
   {
-    FILE* __file;
-
-    __warn(FILE* __f) { __file = __f; }
-
-    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);
-    }
-  };
+    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 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();
-      }
+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();
   }
   }
+}
+
+/** @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));
 
 
-  /** @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);
+  __warning_vector_t __warnings;
 
 
-    __warning_vector_t __warnings;
+  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);
 
 
-    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);
+  // 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());
 
 
-    // Sort data by magnitude.
+  std::sort(__warnings.begin(), __warnings.end(),
+            std::greater<__warning_vector_t::value_type>());
+  __warnings.resize(__cutoff);
 
 
-    // XXX: instead of sorting, should collect only top N for better
-    // performance.
-    size_t __cutoff = __min(__settings<0>::_S_max_warn_count,
-                           __warnings.size());
+  FILE* __warn_file = __open_output_file("txt");
+  std::for_each(__warnings.begin(), __warnings.end(), __warn(__warn_file));
+  fclose(__warn_file);
 
 
-    std::sort(__warnings.begin(), __warnings.end(),
-             std::greater<__warning_vector_t::value_type>());
-    __warnings.resize(__cutoff);
+  __unlock(_GLIBCXX_PROFILE_DATA(__global_lock));
+}
 
 
-    FILE* __warn_file = __open_output_file("txt");
-    std::for_each(__warnings.begin(), __warnings.end(), __warn(__warn_file));
-    fclose(__warn_file);
+inline void __set_trace_path()
+{
+  char* __env_trace_file_name = getenv(_GLIBCXX_PROFILE_TRACE_ENV_VAR);
 
 
-    __mutex<0>::__unlock(__mutex<0>::__global_lock);
+  if (__env_trace_file_name) { 
+    _GLIBCXX_PROFILE_DATA(_S_trace_file_name) = __env_trace_file_name; 
   }
 
   }
 
-  inline void 
-  __set_trace_path()
-  {
-    char* __env_trace_file_name = getenv(_GLIBCXX_PROFILE_TRACE_ENV_VAR);
+  // Make sure early that we can create the trace file.
+  fclose(__open_output_file("txt"));
+}
 
 
-    if (__env_trace_file_name) 
-      __settings<0>::_S_trace_file_name = __env_trace_file_name;
+inline void __set_max_warn_count()
+{
+  char* __env_max_warn_count_str = getenv(
+      _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR);
 
 
-    // Make sure early that we can create the trace file.
-    fclose(__open_output_file("txt"));
+  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_max_warn_count()
-  {
-    char* __env_max_warn_count_str = getenv(_GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR);
+inline void __read_cost_factors()
+{
+  std::string __conf_file_name(_GLIBCXX_PROFILE_DATA(_S_trace_file_name));
+  __conf_file_name += ".conf";
+
+  std::ifstream __conf_file(__conf_file_name.c_str());
+
+  if (__conf_file.is_open()) {
+    std::string __line;
+
+    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();
 
 
     __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();
-
-       __trace_vector_size_init();
-       __trace_hashtable_size_init();
-       __trace_hash_func_init();
-       __trace_vector_to_list_init();
-       __trace_map_to_unordered_map_init();
-
-       atexit(__report);
-
-       __turn_on();
-       }
-      }
+    if (_GLIBCXX_PROFILE_DATA(_S_max_warn_count) == 0) {
+
+      __turn_off();
+
+    } else {
+
+      __set_max_stack_trace_depth();
+      __set_max_mem();
+      __set_trace_path();
+      __read_cost_factors(); 
+      __set_cost_factors();
+      __write_cost_factors();
+
+      __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();
 
 
-    __mutex<0>::__unlock(__mutex<0>::__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();
+  __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 */
 } // namespace __gnu_profile
 
 #endif /* _GLIBCXX_PROFILE_PROFILER_TRACE_H */
index 151e5d4..8d630e4 100644 (file)
 
 namespace __gnu_profile
 {
 
 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(); }
-
-  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);
-      }
-  }
 
 
-  // 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);
-  }
+/** @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_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_init()
+{
+  _GLIBCXX_PROFILE_DATA(_S_vector_size) = new __trace_vector_size();
+}
 
 
-  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);
+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_construct(const void* __obj, size_t __num)
+{
+  if (!__profcxx_init()) return;
+
+  _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 */
 } // namespace __gnu_profile
 
 #endif /* _GLIBCXX_PROFILE_PROFILER_VECTOR_SIZE_H */
index 45076f8..d4113da 100644 (file)
@@ -28,8 +28,8 @@
 // reasons why the executable file might be covered by the GNU General
 // Public License.
 
 // 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.
  */
 
 // Written by Lixia Liu and Silvius Rus.
 
 namespace __gnu_profile
 {
 
 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) { } 
-
-    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 "change std::vector to std::list"; }
-
-    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 __pos, size_t __num);
-    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;
-  };
-
-  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::__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;
-  }
+/** @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"); }
+
+  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 __pos, size_t __num);
+  void __opr_iterate(size_t __num);
+  void __resize(size_t __from, size_t __to);
+  void __opr_find(size_t __size);
+
+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 __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::__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::__opr_insert(size_t __pos, size_t __num)
+{
+  _M_shift_count += __num - __pos;
+}
 
 
-  inline void 
-  __vector2list_info::__opr_insert(size_t __pos, size_t __num)
-  { _M_shift_count += __num - __pos; }
-
-  inline void 
-  __vector2list_info::__resize(size_t __from, size_t __to)
-  { _M_resize += __from; }
-
-  /** @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() { }
-
-    // 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.
-    __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);
-  };
-
-  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 
-  __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::__resize(size_t __from, size_t __to)
+{
+  _M_resize += __from;
+}
 
 
-  // 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 * 0 + __iterate * 10 + __resize * 0; }
-
-  inline void 
-  __trace_vector_to_list::__destruct(const void* __obj)
-  {
-    if (!__is_on())
-      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);
-
-    __retire_object(__obj);
-  }
+inline void __vector2list_info::__opr_iterate(size_t __num)
+{ 
+  _M_iterate += __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 __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 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);
+  // 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);
+
+  // 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);
+};
+
+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::__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::__insert(__object_t __obj,
+                                             __stack_t __stack)
+{
+  __add_object(__obj, __vector2list_info(__stack));
+}
 
 
-  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 __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 
-  __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 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
+      );
+}
+
+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 void __trace_vector_to_list::__destruct(const void* __obj)
+{
+  if (!__is_on())
+    return;
 
 
-  // Initialization and report.
-  inline void 
-  __trace_vector_to_list_init()
-  { __tables<0>::_S_vector_to_list = new __trace_vector_to_list(); }
+ __vector2list_info* __res = __get_object_info(__obj);
+  if (!__res)
+    return;
 
 
-  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);
-      }
-  }
+  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);
 
 
-  // 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());
-  }
+  __retire_object(__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::__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_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);
-  }
+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_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)
+{
+  __vector2list_info* __res = __get_object_info(__obj);
+  if (__res)
+    __res->__set_invalid();
+}
 
 
-  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::__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_resize(const void* __obj, size_t __from, size_t __to)
-  {
-    if (!__profcxx_init()) return;
-    __tables<0>::_S_vector_to_list->__resize(__obj, __from, __to);
+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;
+
+  _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__insert(__obj, __get_stack());
+}
+
+inline void __trace_vector_to_list_destruct(const void* __obj)
+{
+  if (!__profcxx_init()) return;
+
+  _GLIBCXX_PROFILE_DATA(_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;
+
+  _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 = 1)
+{
+  if (!__profcxx_init()) return;
+
+  _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 */
 } // namespace __gnu_profile
 #endif /* _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H */
diff --git a/libstdc++-v3/include/profile/iterator_tracker.h b/libstdc++-v3/include/profile/iterator_tracker.h
new file mode 100644 (file)
index 0000000..8e07748
--- /dev/null
@@ -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 09510a0..01edd29 100644 (file)
 #define _GLIBCXX_PROFILE_LIST 1
 
 #include <list>
 #define _GLIBCXX_PROFILE_LIST 1
 
 #include <list>
+#include <profile/base.h> 
+#include <profile/iterator_tracker.h> 
 
 namespace std
 {
 namespace __profile
 {
 
 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>
     {
     class list
     : public _GLIBCXX_STD_D::list<_Tp, _Allocator>
     {
@@ -46,8 +48,10 @@ namespace __profile
       typedef typename _Base::reference             reference;
       typedef typename _Base::const_reference       const_reference;
 
       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;
 
       typedef typename _Base::size_type             size_type;
       typedef typename _Base::difference_type       difference_type;
@@ -61,35 +65,60 @@ namespace __profile
 
       // 23.2.2.1 construct/copy/destroy:
       explicit list(const _Allocator& __a = _Allocator())
 
       // 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())
 
       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)
 
       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)
 
       list(const list& __x)
-      : _Base(__x) { }
+      : _Base(__x) 
+      { 
+        __profcxx_list_construct(this); 
+        __profcxx_list_construct2(this); 
+      }
 
       list(const _Base& __x)
 
       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))
 
 #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(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)
 
       list&
       operator=(const list& __x)
@@ -118,7 +147,7 @@ namespace __profile
 
       void
       assign(initializer_list<value_type> __l)
 
       void
       assign(initializer_list<value_type> __l)
-      { _Base::assign(__l); }
+      {        _Base::assign(__l); }
 #endif
 
       template<class _InputIterator>
 #endif
 
       template<class _InputIterator>
@@ -128,34 +157,46 @@ namespace __profile
 
       void
       assign(size_type __n, const _Tp& __t)
 
       void
       assign(size_type __n, const _Tp& __t)
-      { _Base::assign(__n, __t); }
+      {        _Base::assign(__n, __t); }
 
       using _Base::get_allocator;
 
       // iterators:
       iterator
       begin()
 
       using _Base::get_allocator;
 
       // iterators:
       iterator
       begin()
-      { return iterator(_Base::begin()); }
+      { return iterator(_Base::begin(), this); }
 
       const_iterator
       begin() const
 
       const_iterator
       begin() const
-      { return const_iterator(_Base::begin()); }
+      { return const_iterator(_Base::begin(), this); }
 
       iterator
       end()
 
       iterator
       end()
-      { return iterator(_Base::end()); }
+      {
+        __profcxx_list_rewind(this);
+        return iterator(_Base::end(), this);
+      }
 
       const_iterator
       end() const
 
       const_iterator
       end() const
-      { return const_iterator(_Base::end()); }
+      {
+        __profcxx_list_rewind(this);
+        return const_iterator(_Base::end(), this);
+      }
 
       reverse_iterator
       rbegin()
 
       reverse_iterator
       rbegin()
-      { return reverse_iterator(end()); }
+      {
+        __profcxx_list_rewind(this);
+        return reverse_iterator(end());
+      }
 
       const_reverse_iterator
       rbegin() const
 
       const_reverse_iterator
       rbegin() const
-      { return const_reverse_iterator(end()); }
+      { 
+        __profcxx_list_rewind(this);
+        return const_reverse_iterator(end());
+      }
 
       reverse_iterator
       rend()
 
       reverse_iterator
       rend()
@@ -168,11 +209,11 @@ namespace __profile
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       const_iterator
       cbegin() const
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       const_iterator
       cbegin() const
-      { return const_iterator(_Base::begin()); }
+      { return const_iterator(_Base::begin(), this); }
 
       const_iterator
       cend() const
 
       const_iterator
       cend() const
-      { return const_iterator(_Base::end()); }
+      { return const_iterator(_Base::end(), this); }
 
       const_reverse_iterator
       crbegin() const
 
       const_reverse_iterator
       crbegin() const
@@ -203,14 +244,26 @@ namespace __profile
 
       reference
       back()
 
       reference
       back()
-      { return _Base::back(); }
+      {
+        __profcxx_list_rewind(this);
+       return _Base::back();
+      }
 
       const_reference
       back() const
 
       const_reference
       back() const
-      { return _Base::back(); }
+      {
+        __profcxx_list_rewind(this);
+       return _Base::back();
+      }
 
       // 23.2.2.3 modifiers:
 
       // 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;
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       using _Base::emplace_front;
@@ -219,7 +272,7 @@ namespace __profile
       void
       pop_front()
       {
       void
       pop_front()
       {
-       iterator __victim = begin();
+        __profcxx_list_operation(this);
        _Base::pop_front();
       }
 
        _Base::pop_front();
       }
 
@@ -235,6 +288,7 @@ namespace __profile
        iterator __victim = end();
        --__victim;
        _Base::pop_back();
        iterator __victim = end();
        --__victim;
        _Base::pop_back();
+        __profcxx_list_rewind(this);
       }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
@@ -242,54 +296,70 @@ namespace __profile
         iterator
         emplace(iterator __position, _Args&&... __args)
        {
         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)
        }
 #endif
 
       iterator
       insert(iterator __position, const _Tp& __x)
-      { return iterator(_Base::insert(__position, __x)); }
+      {
+        _M_profile_insert(this, __position, size());
+        return iterator(_Base::insert(__position.base(), __x), this);
+      }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       iterator
       insert(iterator __position, _Tp&& __x)
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       iterator
       insert(iterator __position, _Tp&& __x)
-      { return emplace(__position, std::move(__x)); }
+      { 
+        _M_profile_insert(this, __position, size());
+        return iterator(_Base::emplace(__position.base(), std::move(__x)),
+                        this); 
+      }
 
       void
 
       void
-      insert(iterator __p, initializer_list<value_type> __l)
-      { _Base::insert(__p, __l); }
+      insert(iterator __position, initializer_list<value_type> __l)
+      {
+        _M_profile_insert(this, __position, size());
+        _Base::insert(__position.base(), __l);
+      }
 #endif
 
       void
       insert(iterator __position, size_type __n, const _Tp& __x)
 #endif
 
       void
       insert(iterator __position, size_type __n, const _Tp& __x)
-      { _Base::insert(__position, __n, __x); }
+      {
+        _M_profile_insert(this, __position, size());
+       _Base::insert(__position.base(), __n, __x);
+      }
 
       template<class _InputIterator>
         void
         insert(iterator __position, _InputIterator __first,
               _InputIterator __last)
 
       template<class _InputIterator>
         void
         insert(iterator __position, _InputIterator __first,
               _InputIterator __last)
-        { _Base::insert(__position, __first, __last); }
+      {
+        _M_profile_insert(this, __position, size());
+        _Base::insert(__position.base(), __first, __last);
+      }
 
       iterator
       erase(iterator __position)
 
       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
 
       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)
       }
 
       void
       swap(list& __x)
-      { _Base::swap(__x); }
+      {        _Base::swap(__x); }
 
       void
       clear()
 
       void
       clear()
-      { _Base::clear(); }
+      {        _Base::clear(); }
 
       // 23.2.2.4 list operations:
       void
 
       // 23.2.2.4 list operations:
       void
@@ -306,6 +376,12 @@ namespace __profile
       { this->splice(__position, std::move(__x)); }
 #endif
 
       { 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)
       void
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       splice(iterator __position, list&& __x, iterator __i)
@@ -317,16 +393,10 @@ namespace __profile
        // after implementing the relevant bits of N1599.
 
        // _GLIBCXX_RESOLVE_LIB_DEFECTS
        // 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,
       void
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       splice(iterator __position, list&& __x, iterator __first,
@@ -339,8 +409,8 @@ namespace __profile
        // We used to perform the splice_alloc check:  not anymore, redundant
        // after implementing the relevant bits of N1599.
 
        // 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__
       }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
@@ -352,7 +422,7 @@ namespace __profile
       void
       remove(const _Tp& __value)
       {
       void
       remove(const _Tp& __value)
       {
-       for (iterator __x = begin(); __x != _Base::end(); )
+       for (iterator __x = begin(); __x != end(); )
          {
            if (*__x == __value)
              __x = erase(__x);
          {
            if (*__x == __value)
              __x = erase(__x);
@@ -365,8 +435,9 @@ namespace __profile
         void
         remove_if(_Predicate __pred)
         {
         void
         remove_if(_Predicate __pred)
         {
-         for (iterator __x = begin(); __x != _Base::end(); )
+         for (iterator __x = begin(); __x != end(); )
            {
            {
+              __profcxx_list_operation(this);
              if (__pred(*__x))
                __x = erase(__x);
              else
              if (__pred(*__x))
                __x = erase(__x);
              else
@@ -384,6 +455,7 @@ namespace __profile
        iterator __next = __first;
        while (++__next != __last)
          {
        iterator __next = __first;
        while (++__next != __last)
          {
+            __profcxx_list_operation(this);
            if (*__first == *__next)
              erase(__next);
            else
            if (*__first == *__next)
              erase(__next);
            else
@@ -403,6 +475,7 @@ namespace __profile
          iterator __next = __first;
          while (++__next != __last)
            {
          iterator __next = __first;
          while (++__next != __last)
            {
+              __profcxx_list_operation(this);
              if (__binary_pred(*__first, *__next))
                erase(__next);
              else
              if (__binary_pred(*__first, *__next))
                erase(__next);
              else
@@ -421,7 +494,7 @@ namespace __profile
        // _GLIBCXX_RESOLVE_LIB_DEFECTS
        // 300. list::merge() specification incomplete
        if (this != &__x)
        // _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__
       }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
@@ -429,7 +502,7 @@ namespace __profile
       merge(list& __x)
       { this->merge(std::move(__x)); }
 #endif
       merge(list& __x)
       { this->merge(std::move(__x)); }
 #endif
+
       template<class _Compare>
         void
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       template<class _Compare>
         void
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
@@ -441,7 +514,7 @@ namespace __profile
          // _GLIBCXX_RESOLVE_LIB_DEFECTS
          // 300. list::merge() specification incomplete
          if (this != &__x)
          // _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__
        }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
@@ -466,6 +539,28 @@ namespace __profile
       const _Base&
       _M_base() const { return *this; }
 
       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>
     };
 
   template<typename _Tp, typename _Alloc>
index e4e680f..ba4d5e7 100644 (file)
 #include <vector>
 #include <utility>
 #include <profile/base.h>
 #include <vector>
 #include <utility>
 #include <profile/base.h>
+#include <profile/iterator_tracker.h>
 
 namespace std
 {
 namespace __profile
 {
 
 namespace std
 {
 namespace __profile
 {
-  /// Class std::vector wrapper with performance instrumentation.
   template<typename _Tp,
           typename _Allocator = std::allocator<_Tp> >
     class vector
   template<typename _Tp,
           typename _Allocator = std::allocator<_Tp> >
     class vector
@@ -54,17 +54,21 @@ namespace __profile
       typedef typename _Base::reference             reference;
       typedef typename _Base::const_reference       const_reference;
 
       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 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 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; }
 
       _Base&
       _M_base()       { return *this; }
 
@@ -158,6 +162,58 @@ namespace __profile
       using _Base::assign;
       using _Base::get_allocator;
 
       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;
       // 23.2.4.2 capacity:
       using _Base::size;
       using _Base::max_size;
@@ -243,22 +299,24 @@ namespace __profile
       iterator
       insert(iterator __position, const _Tp& __x)
       {
       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();
         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());
         _M_profile_resize(this, __old_size, this->capacity());
-       return __res;
+       return iterator(__res, this);
       }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       iterator
       insert(iterator __position, _Tp&& __x)
       {
       }
 
 #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();
         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());
         _M_profile_resize(this, __old_size, this->capacity());
-       return __res;
+       return iterator(__res, this);
       }
 
       void
       }
 
       void
@@ -266,20 +324,27 @@ namespace __profile
       { this->insert(__position, __l.begin(), __l.end()); }
 #endif
 
       { this->insert(__position, __l.begin(), __l.end()); }
 #endif
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
       void
       void
+      swap(vector&& __x)
+      {
+        _Base::swap(__x);
+      }
+#endif
 
 
+      void
       swap(vector& __x)
       {
         _Base::swap(__x);
       }
 
       swap(vector& __x)
       {
         _Base::swap(__x);
       }
 
-
       void
       insert(iterator __position, size_type __n, const _Tp& __x)
       {
       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();
         size_type __old_size = this->capacity();
-           _Base::insert(__position, __n, __x);
+        _Base::insert(__position, __n, __x);
         _M_profile_resize(this, __old_size, this->capacity());
       }
 
         _M_profile_resize(this, __old_size, this->capacity());
       }
 
@@ -288,12 +353,31 @@ namespace __profile
       insert(iterator __position,
              _InputIterator __first, _InputIterator __last)
       {
       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());
       }
 
         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()
       {
       void
       clear()
       {
@@ -302,17 +386,14 @@ namespace __profile
         _Base::clear();
       }
 
         _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:
       }
 
     private:
@@ -367,6 +448,18 @@ namespace __profile
     swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
     { __lhs.swap(__rhs); }
 
     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
 } // namespace __profile
   using _GLIBCXX_STD_D::_S_word_bit;
 } // namespace std
index 65ef6db..5dc58a6 100644 (file)
@@ -28,7 +28,9 @@ typedef std::char_traits<char_t> traits_t;
 typedef __gnu_cxx::throw_allocator_random<char_t> allocator_t;
 typedef std::basic_string<char_t, traits_t, allocator_t> string_t;  
 
 typedef __gnu_cxx::throw_allocator_random<char_t> allocator_t;
 typedef std::basic_string<char_t, traits_t, allocator_t> string_t;  
 
+#ifndef _GLIBCXX_PROFILE
 string_t s("bayou bend");
 string_t s("bayou bend");
+#endif
 
 int main()
 {
 
 int main()
 {
index 4f00928..0b22a76 100644 (file)
@@ -29,12 +29,15 @@ typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
 
 int main()
 {
 
 int main()
 {
+#ifndef _GLIBCXX_PROFILE
   {
     string_t s;
     s += "bayou bend";
   }
   {
     string_t s;
     s += "bayou bend";
   }
+#endif
 
   if (__gnu_test::counter::count() != 0)
     throw std::runtime_error("count not zero");
 
   if (__gnu_test::counter::count() != 0)
     throw std::runtime_error("count not zero");
+
   return 0;
 }
   return 0;
 }