merge branch profile-stdlib

From-SVN: r152431
This commit is contained in:
Silvius Rus 2009-10-03 02:17:41 +00:00 committed by Silvius Rus
parent 3930dbe9d6
commit 1218d701f7
58 changed files with 10252 additions and 33 deletions

View file

@ -1,3 +1,64 @@
2009-10-02 Silvius Rus <silvius.rus@gmail.com>
* configure: Add check for execinfo.h.
* config.h.in: Add undef for HAVE_EXECINFO_H.
* include/Makefile.am: Add build support for profile mode.
* include/Makefile.in: Same.
* include/profile/base.h: New file.
* include/profile/bitset: Same.
* include/profile/deque: Same.
* include/profile/hashtable.h: Same.
* include/profile/list: Same.
* include/profile/map: Same.
* include/profile/map.h: Same.
* include/profile/multimap.h: Same.
* include/profile/multiset.h: Same.
* include/profile/set: Same.
* include/profile/set.h: Same.
* include/profile/unordered_map: Same.
* include/profile/unordered_set: Same.
* include/profile/vector: Same.
* include/profile/impl/profiler.h: Same.
* include/profile/impl/profiler_container_size.h: Same.
* include/profile/impl/profiler_hash_func.h: Same.
* include/profile/impl/profiler_hashtable_size.h: Same.
* include/profile/impl/profiler_map_to_unordered_map.h: Same.
* include/profile/impl/profiler_node.h: Same.
* include/profile/impl/profiler_state.h: Same.
* include/profile/impl/profiler_trace.h: Same.
* include/profile/impl/profiler_vector_size.h: Same.
* include/profile/impl/profiler_vector_to_list.h: Same.
* include/std/vector: Include corresponding profile header guarded by
_GLIBCXX_PROFILE.
* include/std/deque: Same.
* include/std/list: Same.
* include/std/map: Same.
* include/std/unordered_map: Same.
* include/std/bitset: Same.
* include/std/set: Same.
* include/std/unordered_set: Same.
* include/backward/hash_map: Same.
* include/backward/hash_set: Same.
* include/tr1_impl/hashtable (_Hashtable): Expose insert_return_type.
* include/bits/c++config: Define profile namespace.
* testsuite/Makefile.in: Add check-profile.
* testsuite/Makefile.am: Same.
* testsuite/ext/profile/all.cc: New file.
* testsuite/ext/profile/mh.cc: Same.
* testsuite/ext/profile/mutex_extensions.cc: Same.
* testsuite/23_containers/unordered_map/profile/hash_map.cc: Same.
* testsuite/23_containers/unordered_map/profile/unordered.cc: Same.
* testsuite/23_containers/vector/profile/vector.cc: Same.
* testsuite/23_containers/vector/resize/moveable.cc: Make it pass
in profile mode.
* testsuite/23_containers/deque/capacity/moveable.cc: Same.
* testsuite/23_containers/list/capacity/29134.cc: Same.
* doc/Makefile.in: Add reference to profile_mode.xml.
* doc/Makefile.am: Same.
* doc/xml/manual/profile_mode.xml: New file.
* doc/xml/manual/debug.xml: Add link to profile mode section.
* doc/xml/manual/extensions.xml: Add profile mode. Update numbering.
* doc/doxygen/user.cfg.in: Add profile mode files.
2009-10-02 Johannes Singler <singler@ira.uka.de>
* include/parallel/base.h: Take integer types from <tr1/cstdint>.

View file

@ -262,6 +262,9 @@
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <execinfo.h> header file. */
#undef HAVE_EXECINFO_H
/* Define to 1 if you have the `modf' function. */
#undef HAVE_MODF

View file

@ -7926,7 +7926,7 @@ fi
# On IRIX 5.3, sys/types and inttypes.h are conflicting.
for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
inttypes.h stdint.h unistd.h
inttypes.h stdint.h unistd.h execinfo.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default

View file

@ -100,6 +100,7 @@ xml_sources = \
${xml_srcdir}/manual/numerics.xml \
${xml_srcdir}/manual/parallel_mode.xml \
${xml_srcdir}/manual/prerequisites.xml \
${xml_srcdir}/manual/profile_mode.xml \
${xml_srcdir}/manual/internals.xml \
${xml_srcdir}/manual/shared_ptr.xml \
${xml_srcdir}/manual/spine.xml \

View file

@ -312,6 +312,7 @@ xml_sources = \
${xml_srcdir}/manual/numerics.xml \
${xml_srcdir}/manual/parallel_mode.xml \
${xml_srcdir}/manual/prerequisites.xml \
${xml_srcdir}/manual/profile_mode.xml \
${xml_srcdir}/manual/internals.xml \
${xml_srcdir}/manual/shared_ptr.xml \
${xml_srcdir}/manual/spine.xml \

View file

@ -661,6 +661,25 @@ INPUT = @srcdir@/doc/doxygen/doxygroups.cc \
include/debug/unordered_map \
include/debug/unordered_set \
include/debug/vector \
include/profile/bitset \
include/profile/deque \
include/profile/list \
include/profile/map \
include/profile/set \
include/profile/unordered_map \
include/profile/unordered_set \
include/profile/vector \
include/profile/base.h \
include/profile/impl/profiler.h \
include/profile/impl/profiler_container_size.h \
include/profile/impl/profiler_hash_func.h \
include/profile/impl/profiler_hashtable_size.h \
include/profile/impl/profiler_map_to_unordered_map.h \
include/profile/impl/profiler_node.h \
include/profile/impl/profiler_state.h \
include/profile/impl/profiler_trace.h \
include/profile/impl/profiler_vector_size.h \
include/profile/impl/profiler_vector_to_list.h \
include/ext/algorithm \
include/ext/functional \
include/ext/iterator \
@ -715,6 +734,7 @@ INPUT = @srcdir@/doc/doxygen/doxygroups.cc \
include/bits/shared_ptr.h \
include/debug \
include/parallel \
include/profile \
include/ext \
include/ext/pb_ds \
include/ext/pb_ds/detail

View file

@ -243,4 +243,12 @@
</para>
</sect2>
<sect2 id="debug.profile_mode" xreflabel="debug.profile_mode">
<title>Profile-based Performance Analysis</title>
<para> The <link linkend="manual.ext.profile_mode">Profile-based
Performance Analysis</link> Extension has performance checks for many
algorithms.
</para>
</sect2>
</sect1>

View file

@ -113,7 +113,13 @@ extensions, be aware of two things:
parse="xml" href="parallel_mode.xml">
</xi:include>
<!-- Chapter 04 : Allocators -->
<!-- Chapter 04 : Profile Mode -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="profile_mode.xml">
</xi:include>
<!-- Chapter 05 : Allocators -->
<chapter id="manual.ext.allocator" xreflabel="Allocators">
<?dbhtml filename="ext_allocators.html"?>
<title>Allocators</title>
@ -130,7 +136,7 @@ extensions, be aware of two things:
</chapter>
<!-- Chapter 05 : Containers -->
<!-- Chapter 06 : Containers -->
<chapter id="manual.ext.containers" xreflabel="Containers">
<?dbhtml filename="ext_containers.html"?>
<title>Containers</title>
@ -266,7 +272,7 @@ extensions, be aware of two things:
</sect1>
</chapter>
<!-- Chapter 06 : Utilities -->
<!-- Chapter 07 : Utilities -->
<chapter id="manual.ext.util" xreflabel="Utilities">
<?dbhtml filename="ext_utilities.html"?>
<title>Utilities</title>
@ -336,7 +342,7 @@ get_temporary_buffer(5, (int*)0);
</chapter>
<!-- Chapter 07 : Algorithms -->
<!-- Chapter 08 : Algorithms -->
<chapter id="manual.ext.algorithms" xreflabel="Algorithms">
<?dbhtml filename="ext_algorithms.html"?>
<title>Algorithms</title>
@ -374,7 +380,7 @@ get_temporary_buffer(5, (int*)0);
</chapter>
<!-- Chapter 08 : Numerics -->
<!-- Chapter 09 : Numerics -->
<chapter id="manual.ext.numerics" xreflabel="Numerics">
<?dbhtml filename="ext_numerics.html"?>
<title>Numerics</title>
@ -399,7 +405,7 @@ get_temporary_buffer(5, (int*)0);
void iota(_ForwardIter first, _ForwardIter last, _Tp value);</programlisting>
</chapter>
<!-- Chapter 09 : Iterators -->
<!-- Chapter 10 : Iterators -->
<chapter id="manual.ext.iterators" xreflabel="Iterators">
<?dbhtml filename="ext_iterators.html"?>
<title>Iterators</title>
@ -423,7 +429,7 @@ get_temporary_buffer(5, (int*)0);
</chapter>
<!-- Chapter 08 : IO -->
<!-- Chapter 11 : IO -->
<chapter id="manual.ext.io" xreflabel="IO">
<?dbhtml filename="ext_io.html"?>
<title>Input and Output</title>
@ -493,7 +499,7 @@ get_temporary_buffer(5, (int*)0);
</sect1>
</chapter>
<!-- Chapter 09 : Demangling -->
<!-- Chapter 12 : Demangling -->
<chapter id="manual.ext.demangle" xreflabel="Demangling">
<?dbhtml filename="ext_demangling.html"?>
<title>Demangling</title>
@ -579,7 +585,7 @@ int main()
</para>
</chapter>
<!-- Chapter 10 : Concurrency -->
<!-- Chapter 13 : Concurrency -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="concurrency.xml">
</xi:include>

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
## Makefile for the include subdirectory of the GNU C++ Standard library.
#o# Makefile for the include subdirectory of the GNU C++ Standard library.
##
## Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
## Free Software Foundation, Inc.
@ -771,6 +771,37 @@ else
parallel_headers =
endif
# Profile mode headers
profile_srcdir = ${glibcxx_srcdir}/include/profile
profile_builddir = ./profile
profile_headers = \
${profile_srcdir}/base.h \
${profile_srcdir}/unordered_map \
${profile_srcdir}/unordered_set \
${profile_srcdir}/vector \
${profile_srcdir}/bitset \
${profile_srcdir}/deque \
${profile_srcdir}/list \
${profile_srcdir}/map \
${profile_srcdir}/map.h \
${profile_srcdir}/multimap.h \
${profile_srcdir}/multiset.h \
${profile_srcdir}/set \
${profile_srcdir}/set.h \
${profile_srcdir}/hashtable.h
profile_impl_srcdir = ${glibcxx_srcdir}/include/profile/impl
profile_impl_builddir = ./profile/impl
profile_impl_headers = \
${profile_impl_srcdir}/profiler.h \
${profile_impl_srcdir}/profiler_container_size.h \
${profile_impl_srcdir}/profiler_hash_func.h \
${profile_impl_srcdir}/profiler_hashtable_size.h \
${profile_impl_srcdir}/profiler_map_to_unordered_map.h \
${profile_impl_srcdir}/profiler_node.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
# Some of the different "C" header models need extra files.
# Some "C" header schemes require the "C" compatibility headers.
@ -865,7 +896,8 @@ endif
allstamped = \
stamp-std stamp-bits stamp-c_base stamp-c_base_extra \
stamp-c_compatibility stamp-backward stamp-ext stamp-pb \
stamp-tr1 stamp-tr1-impl stamp-debug stamp-parallel stamp-host
stamp-tr1 stamp-tr1-impl stamp-debug stamp-parallel stamp-host \
stamp-profile stamp-profile-impl
# List of all files that are created by explicit building, editing, or
# catenation.
@ -989,6 +1021,16 @@ stamp-parallel: ${parallel_headers}
@-cd ${parallel_builddir} && $(LN_S) $? . 2>/dev/null
@$(STAMP) stamp-parallel
stamp-profile: ${profile_headers}
@-mkdir -p ${profile_builddir}
@-cd ${profile_builddir} && $(LN_S) $? . 2>/dev/null
@$(STAMP) stamp-profile
stamp-profile-impl: ${profile_impl_headers}
@-mkdir -p ${profile_impl_builddir}
@-cd ${profile_impl_builddir} && $(LN_S) $? . 2>/dev/null
@$(STAMP) stamp-profile-impl
stamp-${host_alias}:
@-mkdir -p ${host_builddir}
@$(STAMP) stamp-${host_alias}
@ -1217,6 +1259,12 @@ install-headers:
$(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${parallel_builddir};\
for file in $$parallel_headers_install; do \
$(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${parallel_builddir}; done
$(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${profile_builddir}
for file in ${profile_headers}; do \
$(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${profile_builddir}; done
$(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${profile_impl_builddir}
for file in ${profile_impl_headers}; do \
$(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${profile_impl_builddir}; done
$(mkinstalldirs) $(DESTDIR)${host_installdir}
for file in ${host_headers} ${host_headers_extra} \
${thread_host_headers}; do \

View file

@ -1001,6 +1001,39 @@ parallel_builddir = ./parallel
@ENABLE_PARALLEL_TRUE@ ${parallel_srcdir}/unique_copy.h \
@ENABLE_PARALLEL_TRUE@ ${parallel_srcdir}/workstealing.h
# Profile mode headers
profile_srcdir = ${glibcxx_srcdir}/include/profile
profile_builddir = ./profile
profile_headers = \
${profile_srcdir}/base.h \
${profile_srcdir}/unordered_map \
${profile_srcdir}/unordered_set \
${profile_srcdir}/vector \
${profile_srcdir}/bitset \
${profile_srcdir}/deque \
${profile_srcdir}/list \
${profile_srcdir}/map \
${profile_srcdir}/map.h \
${profile_srcdir}/multimap.h \
${profile_srcdir}/multiset.h \
${profile_srcdir}/set \
${profile_srcdir}/set.h \
${profile_srcdir}/hashtable.h
profile_impl_srcdir = ${glibcxx_srcdir}/include/profile/impl
profile_impl_builddir = ./profile/impl
profile_impl_headers = \
${profile_impl_srcdir}/profiler.h \
${profile_impl_srcdir}/profiler_container_size.h \
${profile_impl_srcdir}/profiler_hash_func.h \
${profile_impl_srcdir}/profiler_hashtable_size.h \
${profile_impl_srcdir}/profiler_map_to_unordered_map.h \
${profile_impl_srcdir}/profiler_node.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
@GLIBCXX_C_HEADERS_EXTRA_FALSE@c_base_headers_extra =
# Some of the different "C" header models need extra files.
@ -1083,7 +1116,8 @@ PCHFLAGS = -x c++-header $(CXXFLAGS)
allstamped = \
stamp-std stamp-bits stamp-c_base stamp-c_base_extra \
stamp-c_compatibility stamp-backward stamp-ext stamp-pb \
stamp-tr1 stamp-tr1-impl stamp-debug stamp-parallel stamp-host
stamp-tr1 stamp-tr1-impl stamp-debug stamp-parallel stamp-host \
stamp-profile stamp-profile-impl
# List of all files that are created by explicit building, editing, or
@ -1400,6 +1434,16 @@ stamp-parallel: ${parallel_headers}
@-cd ${parallel_builddir} && $(LN_S) $? . 2>/dev/null
@$(STAMP) stamp-parallel
stamp-profile: ${profile_headers}
@-mkdir -p ${profile_builddir}
@-cd ${profile_builddir} && $(LN_S) $? . 2>/dev/null
@$(STAMP) stamp-profile
stamp-profile-impl: ${profile_impl_headers}
@-mkdir -p ${profile_impl_builddir}
@-cd ${profile_impl_builddir} && $(LN_S) $? . 2>/dev/null
@$(STAMP) stamp-profile-impl
stamp-${host_alias}:
@-mkdir -p ${host_builddir}
@$(STAMP) stamp-${host_alias}
@ -1616,6 +1660,13 @@ install-headers:
$(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${parallel_builddir};\
for file in $$parallel_headers_install; do \
$(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${parallel_builddir}; done
$(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${profile_builddir} \
$(DESTDIR)${gxx_include_dir}/${profile_builddir}/impl
for file in ${profile_headers}; do \
$(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${profile_builddir}; done
$(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${profile_impl_builddir}
for file in ${profile_impl_headers}; do \
$(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${profile_impl_builddir}; done
$(mkinstalldirs) $(DESTDIR)${host_installdir}
for file in ${host_headers} ${host_headers_extra} \
${thread_host_headers}; do \

View file

@ -58,7 +58,11 @@
#include "backward_warning.h"
#include <bits/c++config.h>
#ifdef _GLIBCXX_PROFILE
#include <profile/hashtable.h>
#else
#include <backward/hashtable.h>
#endif
#include <bits/concept_check.h>
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)

View file

@ -58,7 +58,11 @@
#include "backward_warning.h"
#include <bits/c++config.h>
#ifdef _GLIBCXX_PROFILE
#include <profile/hashtable.h>
#else
#include <backward/hashtable.h>
#endif
#include <bits/concept_check.h>
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)

View file

@ -85,11 +85,17 @@
# define _GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL 1
#endif
// Namespace association for profile
#ifdef _GLIBCXX_PROFILE
# define _GLIBCXX_NAMESPACE_ASSOCIATION_PROFILE 1
#endif
#define _GLIBCXX_NAMESPACE_ASSOCIATION_VERSION
// Defined if any namespace association modes are active.
#if _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG \
|| _GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL \
|| _GLIBCXX_NAMESPACE_ASSOCIATION_PROFILE \
|| _GLIBCXX_NAMESPACE_ASSOCIATION_VERSION
# define _GLIBCXX_USE_NAMESPACE_ASSOCIATION 1
#endif
@ -108,6 +114,7 @@
#ifndef _GLIBCXX_USE_NAMESPACE_ASSOCIATION
# define _GLIBCXX_STD_D _GLIBCXX_STD
# define _GLIBCXX_STD_P _GLIBCXX_STD
# define _GLIBCXX_STD_PR _GLIBCXX_STD
# define _GLIBCXX_STD std
# define _GLIBCXX_BEGIN_NESTED_NAMESPACE(X, Y) _GLIBCXX_BEGIN_NAMESPACE(X)
# define _GLIBCXX_END_NESTED_NAMESPACE _GLIBCXX_END_NAMESPACE
@ -124,7 +131,7 @@
# endif
// debug
# if _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG && !_GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL
# if _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG && !_GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL && !_GLIBCXX_NAMESPACE_ASSOCIATION_PROFILE
# define _GLIBCXX_STD_D __norm
# define _GLIBCXX_STD_P _GLIBCXX_STD
# define _GLIBCXX_STD __cxx1998
@ -134,7 +141,7 @@
# endif
// parallel
# if _GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL && !_GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG
# if _GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL && !_GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG && !_GLIBCXX_NAMESPACE_ASSOCIATION_PROFILE
# define _GLIBCXX_STD_D _GLIBCXX_STD
# define _GLIBCXX_STD_P __norm
# define _GLIBCXX_STD __cxx1998
@ -144,7 +151,7 @@
# endif
// debug + parallel
# if _GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL && _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG
# if _GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL && _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG && !_GLIBCXX_NAMESPACE_ASSOCIATION_PROFILE
# define _GLIBCXX_STD_D __norm
# define _GLIBCXX_STD_P __norm
# define _GLIBCXX_STD __cxx1998
@ -153,6 +160,21 @@
# define _GLIBCXX_EXTERN_TEMPLATE -1
# endif
// profile
# if _GLIBCXX_NAMESPACE_ASSOCIATION_PROFILE
# if _GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL || _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG
# error Cannot use -D_GLIBCXX_PROFILE with -D_GLIBCXX_DEBUG or \
-D_GLIBCXX_PARALLEL
# endif
# define _GLIBCXX_STD_D __norm
# define _GLIBCXX_STD_P _GLIBCXX_STD
# define _GLIBCXX_STD_PR __norm
# define _GLIBCXX_STD __cxx1998
# define _GLIBCXX_BEGIN_NAMESPACE(X) namespace X _GLIBCXX_VISIBILITY_ATTR(default) {
# define _GLIBCXX_END_NAMESPACE }
# define _GLIBCXX_EXTERN_TEMPLATE -1
# endif
# if __NO_INLINE__ && !__GXX_WEAK__
# warning currently using namespace associated mode which may fail \
without inlining due to lack of weak symbols
@ -163,7 +185,7 @@
#endif
// Namespace associations for debug mode.
#if _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG
#if _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG && !_GLIBCXX_NAMESPACE_ASSOCIATION_PROFILE
namespace std
{
namespace __norm { }
@ -182,6 +204,16 @@ namespace std
}
#endif
// Namespace associations for profile mode
#if _GLIBCXX_NAMESPACE_ASSOCIATION_PROFILE
namespace std
{
namespace __norm { }
inline namespace __profile { }
inline namespace __cxx1998 { }
}
#endif
// Namespace associations for versioning mode.
#if _GLIBCXX_NAMESPACE_ASSOCIATION_VERSION
namespace std

View file

@ -0,0 +1,68 @@
// -*- 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/base.h
* @brief Sequential helper functions.
* This file is a GNU profile extension to the Standard C++ Library.
*/
// Written by Lixia Liu
#ifndef _GLIBCXX_PROFILE_BASE_H
#define _GLIBCXX_PROFILE_BASE_H 1
#include <cstdio>
#include <functional>
#include <bits/c++config.h>
#include <profile/impl/profiler.h>
// Profiling mode namespaces.
/**
* @namespace std::__profile
* @brief GNU profile code, replaces standard behavior with profile behavior.
*/
namespace std
{
namespace __profile { }
}
/**
* @namespace __gnu_profile
* @brief GNU profile code for public use.
*/
namespace __gnu_profile
{
// Import all the profile versions of components in namespace std.
using namespace std::__profile;
}
#endif /* _GLIBCXX_PROFILE_BASE_H */

View file

@ -0,0 +1,345 @@
// Profiling bitset implementation -*- 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 3, 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.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file profile/bitset
* This file is a GNU profile extension to the Standard C++ Library.
*/
#ifndef _GLIBCXX_PROFILE_BITSET
#define _GLIBCXX_PROFILE_BITSET
#include <bitset>
namespace std
{
namespace __profile
{
/** @brief Bitset wrapper with performance instrumentation. */
template<size_t _Nb>
class bitset
: public _GLIBCXX_STD_D::bitset<_Nb>
{
typedef _GLIBCXX_STD_D::bitset<_Nb> _Base;
public:
// bit reference:
class reference
: private _Base::reference
{
typedef typename _Base::reference _Base_ref;
friend class bitset;
reference();
reference(const _Base_ref& __base, bitset* __seq)
: _Base_ref(__base)
{ }
public:
reference(const reference& __x)
: _Base_ref(__x)
{ }
reference&
operator=(bool __x)
{
*static_cast<_Base_ref*>(this) = __x;
return *this;
}
reference&
operator=(const reference& __x)
{
*static_cast<_Base_ref*>(this) = __x;
return *this;
}
bool
operator~() const
{
return ~(*static_cast<const _Base_ref*>(this));
}
operator bool() const
{
return *static_cast<const _Base_ref*>(this);
}
reference&
flip()
{
_Base_ref::flip();
return *this;
}
};
// 23.3.5.1 constructors:
bitset() : _Base() { }
bitset(unsigned long __val) : _Base(__val) { }
template<typename _CharT, typename _Traits, typename _Alloc>
explicit
bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
__pos = 0,
typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
__n = (std::basic_string<_CharT, _Traits, _Alloc>::npos))
: _Base(__str, __pos, __n) { }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 396. what are characters zero and one.
template<class _CharT, class _Traits, class _Alloc>
bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
__pos,
typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
__n,
_CharT __zero, _CharT __one = _CharT('1'))
: _Base(__str, __pos, __n, __zero, __one) { }
bitset(const _Base& __x) : _Base(__x) { }
// 23.3.5.2 bitset operations:
bitset<_Nb>&
operator&=(const bitset<_Nb>& __rhs)
{
_M_base() &= __rhs;
return *this;
}
bitset<_Nb>&
operator|=(const bitset<_Nb>& __rhs)
{
_M_base() |= __rhs;
return *this;
}
bitset<_Nb>&
operator^=(const bitset<_Nb>& __rhs)
{
_M_base() ^= __rhs;
return *this;
}
bitset<_Nb>&
operator<<=(size_t __pos)
{
_M_base() <<= __pos;
return *this;
}
bitset<_Nb>&
operator>>=(size_t __pos)
{
_M_base() >>= __pos;
return *this;
}
bitset<_Nb>&
set()
{
_Base::set();
return *this;
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 186. bitset::set() second parameter should be bool
bitset<_Nb>&
set(size_t __pos, bool __val = true)
{
_Base::set(__pos, __val);
return *this;
}
bitset<_Nb>&
reset()
{
_Base::reset();
return *this;
}
bitset<_Nb>&
reset(size_t __pos)
{
_Base::reset(__pos);
return *this;
}
bitset<_Nb> operator~() const { return bitset(~_M_base()); }
bitset<_Nb>&
flip()
{
_Base::flip();
return *this;
}
bitset<_Nb>&
flip(size_t __pos)
{
_Base::flip(__pos);
return *this;
}
// element access:
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 11. Bitset minor problems
reference
operator[](size_t __pos)
{
return reference(_M_base()[__pos], this);
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 11. Bitset minor problems
bool
operator[](size_t __pos) const
{
return _M_base()[__pos];
}
using _Base::to_ulong;
template <typename _CharT, typename _Traits, typename _Alloc>
std::basic_string<_CharT, _Traits, _Alloc>
to_string() const
{ return _M_base().template to_string<_CharT, _Traits, _Alloc>(); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 396. what are characters zero and one.
template<class _CharT, class _Traits, class _Alloc>
std::basic_string<_CharT, _Traits, _Alloc>
to_string(_CharT __zero, _CharT __one = _CharT('1')) const
{
return _M_base().template
to_string<_CharT, _Traits, _Alloc>(__zero, __one);
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 434. bitset::to_string() hard to use.
template<typename _CharT, typename _Traits>
std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
to_string() const
{ return to_string<_CharT, _Traits, std::allocator<_CharT> >(); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 853. to_string needs updating with zero and one.
template<class _CharT, class _Traits>
std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
to_string(_CharT __zero, _CharT __one = _CharT('1')) const
{ return to_string<_CharT, _Traits,
std::allocator<_CharT> >(__zero, __one); }
template<typename _CharT>
std::basic_string<_CharT, std::char_traits<_CharT>,
std::allocator<_CharT> >
to_string() const
{
return to_string<_CharT, std::char_traits<_CharT>,
std::allocator<_CharT> >();
}
template<class _CharT>
std::basic_string<_CharT, std::char_traits<_CharT>,
std::allocator<_CharT> >
to_string(_CharT __zero, _CharT __one = _CharT('1')) const
{
return to_string<_CharT, std::char_traits<_CharT>,
std::allocator<_CharT> >(__zero, __one);
}
std::basic_string<char, std::char_traits<char>, std::allocator<char> >
to_string() const
{
return to_string<char,std::char_traits<char>,std::allocator<char> >();
}
std::basic_string<char, std::char_traits<char>, std::allocator<char> >
to_string(char __zero, char __one = '1') const
{
return to_string<char, std::char_traits<char>,
std::allocator<char> >(__zero, __one);
}
using _Base::count;
using _Base::size;
bool
operator==(const bitset<_Nb>& __rhs) const
{ return _M_base() == __rhs; }
bool
operator!=(const bitset<_Nb>& __rhs) const
{ return _M_base() != __rhs; }
using _Base::test;
using _Base::all;
using _Base::any;
using _Base::none;
bitset<_Nb>
operator<<(size_t __pos) const
{ return bitset<_Nb>(_M_base() << __pos); }
bitset<_Nb>
operator>>(size_t __pos) const
{ return bitset<_Nb>(_M_base() >> __pos); }
_Base&
_M_base() { return *this; }
const _Base&
_M_base() const { return *this; }
};
template<size_t _Nb>
bitset<_Nb>
operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
{ return bitset<_Nb>(__x) &= __y; }
template<size_t _Nb>
bitset<_Nb>
operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
{ return bitset<_Nb>(__x) |= __y; }
template<size_t _Nb>
bitset<_Nb>
operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
{ return bitset<_Nb>(__x) ^= __y; }
template<typename _CharT, typename _Traits, size_t _Nb>
std::basic_istream<_CharT, _Traits>&
operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x)
{ return __is >> __x._M_base(); }
template<typename _CharT, typename _Traits, size_t _Nb>
std::basic_ostream<_CharT, _Traits>&
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
const bitset<_Nb>& __x)
{ return __os << __x._M_base(); }
} // namespace __profile
} // namespace std
#endif

View file

@ -0,0 +1,420 @@
// Profiling deque implementation -*- 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 3, 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.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file profile/deque
* This file is a GNU profile extension to the Standard C++ Library.
*/
#ifndef _GLIBCXX_PROFILE_DEQUE
#define _GLIBCXX_PROFILE_DEQUE 1
#include <deque>
namespace std
{
namespace __profile
{
/** @brief Deque wrapper with performance instrumentation. */
template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
class deque
: public _GLIBCXX_STD_D::deque<_Tp, _Allocator>
{
typedef _GLIBCXX_STD_D::deque<_Tp, _Allocator> _Base;
public:
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 typename _Base::reverse_iterator reverse_iterator;
typedef typename _Base::const_reverse_iterator const_reverse_iterator;
typedef typename _Base::size_type size_type;
typedef typename _Base::difference_type difference_type;
typedef _Tp value_type;
typedef _Allocator allocator_type;
typedef typename _Base::pointer pointer;
typedef typename _Base::const_pointer const_pointer;
// 23.2.1.1 construct/copy/destroy:
explicit deque(const _Allocator& __a = _Allocator())
: _Base(__a) { }
explicit deque(size_type __n, const _Tp& __value = _Tp(),
const _Allocator& __a = _Allocator())
: _Base(__n, __value, __a) { }
template<class _InputIterator>
deque(_InputIterator __first, _InputIterator __last,
const _Allocator& __a = _Allocator())
: _Base(__first, __last, __a)
{ }
deque(const deque& __x)
: _Base(__x) { }
deque(const _Base& __x)
: _Base(__x) { }
#ifdef __GXX_EXPERIMENTAL_CXX0X__
deque(deque&& __x)
: _Base(std::forward<deque>(__x))
{ }
deque(initializer_list<value_type> __l,
const allocator_type& __a = allocator_type())
: _Base(__l, __a) { }
#endif
~deque() { }
deque&
operator=(const deque& __x)
{
*static_cast<_Base*>(this) = __x;
return *this;
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
deque&
operator=(deque&& __x)
{
// NB: DR 675.
this->clear();
this->swap(__x);
return *this;
}
deque&
operator=(initializer_list<value_type> __l)
{
*static_cast<_Base*>(this) = __l;
return *this;
}
#endif
template<class _InputIterator>
void
assign(_InputIterator __first, _InputIterator __last)
{
_Base::assign(__first, __last);
}
void
assign(size_type __n, const _Tp& __t)
{
_Base::assign(__n, __t);
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
void
assign(initializer_list<value_type> __l)
{
_Base::assign(__l);
}
#endif
using _Base::get_allocator;
// iterators:
iterator
begin()
{ return iterator(_Base::begin()); }
const_iterator
begin() const
{ return const_iterator(_Base::begin()); }
iterator
end()
{ return iterator(_Base::end()); }
const_iterator
end() const
{ return const_iterator(_Base::end()); }
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()); }
const_iterator
cend() const
{ return const_iterator(_Base::end()); }
const_reverse_iterator
crbegin() const
{ return const_reverse_iterator(end()); }
const_reverse_iterator
crend() const
{ return const_reverse_iterator(begin()); }
#endif
// 23.2.1.2 capacity:
using _Base::size;
using _Base::max_size;
void
resize(size_type __sz, _Tp __c = _Tp())
{
_Base::resize(__sz, __c);
}
using _Base::empty;
// element access:
reference
operator[](size_type __n)
{
return _M_base()[__n];
}
const_reference
operator[](size_type __n) const
{
return _M_base()[__n];
}
using _Base::at;
reference
front()
{
return _Base::front();
}
const_reference
front() const
{
return _Base::front();
}
reference
back()
{
return _Base::back();
}
const_reference
back() const
{
return _Base::back();
}
// 23.2.1.3 modifiers:
void
push_front(const _Tp& __x)
{
_Base::push_front(__x);
}
void
push_back(const _Tp& __x)
{
_Base::push_back(__x);
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
void
push_front(_Tp&& __x)
{ emplace_front(std::move(__x)); }
void
push_back(_Tp&& __x)
{ emplace_back(std::move(__x)); }
template<typename... _Args>
void
emplace_front(_Args&&... __args)
{
_Base::emplace_front(std::forward<_Args>(__args)...);
}
template<typename... _Args>
void
emplace_back(_Args&&... __args)
{
_Base::emplace_back(std::forward<_Args>(__args)...);
}
template<typename... _Args>
iterator
emplace(iterator __position, _Args&&... __args)
{
typename _Base::iterator __res = _Base::emplace(__position,
std::forward<_Args>(__args)...);
return iterator(__res);
}
#endif
iterator
insert(iterator __position, const _Tp& __x)
{
typename _Base::iterator __res = _Base::insert(__position, __x);
return iterator(__res);
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
iterator
insert(iterator __position, _Tp&& __x)
{ return emplace(__position, std::move(__x)); }
void
insert(iterator __p, initializer_list<value_type> __l)
{
_Base::insert(__p, __l);
}
#endif
void
insert(iterator __position, size_type __n, const _Tp& __x)
{
_Base::insert(__position, __n, __x);
}
template<class _InputIterator>
void
insert(iterator __position,
_InputIterator __first, _InputIterator __last)
{
_Base::insert(__position, __first, __last);
}
void
pop_front()
{
_Base::pop_front();
}
void
pop_back()
{
_Base::pop_back();
}
iterator
erase(iterator __position)
{
if (__position == begin() || __position == end()-1)
{
return iterator(_Base::erase(__position));
}
else
{
typename _Base::iterator __res = _Base::erase(__position);
return iterator(__res);
}
}
iterator
erase(iterator __first, iterator __last)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 151. can't currently clear() empty container
return iterator(_Base::erase(__first, __last));
}
void
swap(deque& __x)
{
_Base::swap(__x);
}
void
clear()
{
_Base::clear();
}
_Base&
_M_base() { return *this; }
const _Base&
_M_base() const { return *this; }
};
template<typename _Tp, typename _Alloc>
inline bool
operator==(const deque<_Tp, _Alloc>& __lhs,
const deque<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() == __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline bool
operator!=(const deque<_Tp, _Alloc>& __lhs,
const deque<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() != __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline bool
operator<(const deque<_Tp, _Alloc>& __lhs,
const deque<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() < __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline bool
operator<=(const deque<_Tp, _Alloc>& __lhs,
const deque<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() <= __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline bool
operator>=(const deque<_Tp, _Alloc>& __lhs,
const deque<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() >= __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline bool
operator>(const deque<_Tp, _Alloc>& __lhs,
const deque<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() > __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline void
swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs)
{ __lhs.swap(__rhs); }
} // namespace __profile
} // namespace std
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,326 @@
// -*- 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.h
* @brief Interface of the profiling runtime library.
*/
// Written by Lixia Liu and Silvius Rus.
#ifndef PROFCXX_PROFILER_H__
#define PROFCXX_PROFILER_H__ 1
#ifdef __GXX_EXPERIMENTAL_CXX0X__
#include <cstddef>
#else
#include <stddef.h>
#endif
/**
* @namespace std::__cxxprof_guard
* @brief Mechanism to protect all __cxxprof_impl operations against
* multithreaded and exception reentrance.
*/
namespace __cxxprof_guard
{
/** @brief Reentrance guard.
*
* Mechanism to protect all __cxxprof_impl operations against recursion,
* multithreaded and exception reentrance.
*/
template <int _Unused=0>
class __reentrance_guard
{
public:
static __thread bool __inside_cxxprof_impl;
static bool __get_in();
__reentrance_guard() {}
~__reentrance_guard() { __inside_cxxprof_impl = false; }
};
template <int _Unused>
__thread bool __reentrance_guard<_Unused>::__inside_cxxprof_impl = false;
template <int _Unused>
bool __reentrance_guard<_Unused>::__get_in()
{
if (__inside_cxxprof_impl) {
return false;
} else {
__inside_cxxprof_impl = true;
return true;
}
}
} // namespace __cxxprof_guard
#define _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD(__x...) \
{ \
if (__cxxprof_guard::__reentrance_guard<0>::__get_in()) \
{ \
__cxxprof_guard::__reentrance_guard<0> __auto_get_out; \
__x; \
} \
}
/**
* @namespace std::__cxxprof_impl
* @brief Implementation of profile extension.
*/
namespace __cxxprof_impl
{
// Forward declarations of implementation functions.
// Don't use any __cxxprof_impl:: 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*);
} // namespace __cxxprof_impl
// Master switch turns on all diagnostics.
#ifdef _GLIBCXX_PROFILE
#define _GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL
#define _GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE
#define _GLIBCXX_PROFILE_VECTOR_TOO_SMALL
#define _GLIBCXX_PROFILE_VECTOR_TOO_LARGE
#define _GLIBCXX_PROFILE_INEFFICIENT_HASH
#define _GLIBCXX_PROFILE_VECTOR_TO_LIST
#define _GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP
#endif
// Expose global management routines to user code.
#ifdef _GLIBCXX_PROFILE
#define __profcxx_report() \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD(__cxxprof_impl::__report())
#define __profcxx_turn_on() \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD(__cxxprof_impl::__turn_on())
#define __profcxx_turn_off() \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD(__cxxprof_impl::__turn_off())
#define __profcxx_is_invalid() \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD(__cxxprof_impl::__is_invalid())
#define __profcxx_is_on() \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD(__cxxprof_impl::__is_on())
#define __profcxx__is_off() \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD(__cxxprof_impl::__is_off())
#else
#define __profcxx_report()
#define __profcxx_turn_on()
#define __profcxx_turn_off()
#define __profcxx_is_invalid()
#define __profcxx_is_on()
#define __profcxx_is_off()
#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)))
#define __profcxx_hashtable_resize(__x...) \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
__cxxprof_impl::__trace_hashtable_size_resize(__x))
#define __profcxx_hashtable_destruct(__x...) \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
__cxxprof_impl::__trace_hashtable_size_destruct(__x))
#define __profcxx_hashtable_construct(__x...) \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
__cxxprof_impl::__trace_hashtable_size_construct(__x))
#else
#define __profcxx_hashtable_resize(__x...)
#define __profcxx_hashtable_destruct(__x...)
#define __profcxx_hashtable_construct(__x...)
#endif
// Turn on/off instrumentation for VECTOR_TOO_SMALL and VECTOR_TOO_LARGE.
#if ((defined(_GLIBCXX_PROFILE_VECTOR_TOO_SMALL) \
&& !defined(_NO_GLIBCXX_PROFILE_VECTOR_TOO_SMALL)) \
|| (defined(_GLIBCXX_PROFILE_VECTOR_TOO_LARGE) \
&& !defined(_NO_GLIBCXX_PROFILE_VECTOR_TOO_LARGE)))
#define __profcxx_vector_resize(__x...) \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
__cxxprof_impl::__trace_vector_size_resize(__x))
#define __profcxx_vector_destruct(__x...) \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
__cxxprof_impl::__trace_vector_size_destruct(__x))
#define __profcxx_vector_construct(__x...) \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
__cxxprof_impl::__trace_vector_size_construct(__x))
#else
#define __profcxx_vector_resize(__x...)
#define __profcxx_vector_destruct(__x...)
#define __profcxx_vector_construct(__x...)
#endif
// Turn on/off instrumentation for INEFFICIENT_HASH.
#if (defined(_GLIBCXX_PROFILE_INEFFICIENT_HASH) \
&& !defined(_NO_GLIBCXX_PROFILE_INEFFICIENT_HASH))
#define __profcxx_hashtable_construct2(__x...) \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
__cxxprof_impl::__trace_hash_func_construct(__x))
#define __profcxx_hashtable_destruct2(__x...) \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
__cxxprof_impl::__trace_hash_func_destruct(__x))
#else
#define __profcxx_hashtable_destruct2(__x...)
#define __profcxx_hashtable_construct2(__x...)
#endif
// Turn on/off instrumentation for VECTOR_TO_LIST.
#if (defined(_GLIBCXX_PROFILE_VECTOR_TO_LIST) \
&& !defined(_NO_GLIBCXX_PROFILE_VECTOR_TO_LIST))
#define __profcxx_vector_construct2(__x...) \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
__cxxprof_impl::__trace_vector_to_list_construct(__x))
#define __profcxx_vector_destruct2(__x...) \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
__cxxprof_impl::__trace_vector_to_list_destruct(__x))
#define __profcxx_vector_insert(__x...) \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
__cxxprof_impl::__trace_vector_to_list_insert(__x))
#define __profcxx_vector_iterate(__x...) \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
__cxxprof_impl::__trace_vector_to_list_iterate(__x))
#define __profcxx_vector_invalid_operator(__x...) \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
__cxxprof_impl::__trace_vector_to_list_invalid_operator(__x))
#define __profcxx_vector_resize2(__x...) \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
__cxxprof_impl::__trace_vector_to_list_resize(__x))
#else
#define __profcxx_vector_destruct2(__x...)
#define __profcxx_vector_construct2(__x...)
#define __profcxx_vector_insert(__x...)
#define __profcxx_vector_iterate(__x...)
#define __profcxx_vector_invalid_operator(__x...)
#define __profcxx_vector_resize2(__x...)
#endif
// Turn on/off instrumentation for MAP_TO_UNORDERED_MAP.
#if (defined(_GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP) \
&& !defined(_NO_GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP))
#define __profcxx_map_to_unordered_map_construct(__x...) \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
__cxxprof_impl::__trace_map_to_unordered_map_construct(__x))
#define __profcxx_map_to_unordered_map_destruct(__x...) \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
__cxxprof_impl::__trace_map_to_unordered_map_destruct(__x))
#define __profcxx_map_to_unordered_map_insert(__x...) \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
__cxxprof_impl::__trace_map_to_unordered_map_insert(__x))
#define __profcxx_map_to_unordered_map_erase(__x...) \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
__cxxprof_impl::__trace_map_to_unordered_map_erase(__x))
#define __profcxx_map_to_unordered_map_iterate(__x...) \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
__cxxprof_impl::__trace_map_to_unordered_map_iterate(__x))
#define __profcxx_map_to_unordered_map_invalidate(__x...) \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
__cxxprof_impl::__trace_map_to_unordered_map_invalidate(__x))
#define __profcxx_map_to_unordered_map_find(__x...) \
_GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
__cxxprof_impl::__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_iterate(__x...)
#define __profcxx_map_to_unordered_map_invalidate(__x...)
#define __profcxx_map_to_unordered_map_find(__x...)
#endif
// Run multithreaded unless instructed not to do so.
#ifndef _GLIBCXX_PROFILE_NOTHREADS
#define _GLIBCXX_PROFILE_THREADS
#endif
// Set default values for compile-time customizable variables.
#ifndef _GLIBCXX_PROFILE_TRACE_PATH_ROOT
#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"
#endif
#ifndef _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR
#define _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR \
"GLIBCXX_PROFILE_MAX_WARN_COUNT"
#endif
#ifndef _GLIBCXX_PROFILE_MAX_WARN_COUNT
#define _GLIBCXX_PROFILE_MAX_WARN_COUNT 10
#endif
#ifndef _GLIBCXX_PROFILE_MAX_STACK_DEPTH
#define _GLIBCXX_PROFILE_MAX_STACK_DEPTH 32
#endif
#ifndef _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR
#define _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR \
"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 \
"GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC"
#endif
// Instrumentation hook implementations.
#include "profile/impl/profiler_hash_func.h"
#include "profile/impl/profiler_hashtable_size.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"
#endif // PROFCXX_PROFILER_H__

View file

@ -0,0 +1,250 @@
// -*- 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_trace.h
* @brief Diagnostics for container sizes.
*/
// Written by Lixia Liu and Silvius Rus.
#ifndef PROFCXX_PROFILER_CONTAINER_SIZE_H__
#define PROFCXX_PROFILER_CONTAINER_SIZE_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 __cxxprof_impl
{
/** @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;
}
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)
: __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;
}
/** @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));
}
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;
__object_t __obj_handle = static_cast<__object_t>(__obj);
__container_size_info* __object_info = __get_object_info(__obj_handle);
if (!__object_info)
return;
__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;
__container_size_info* __object_info = __get_object_info(__obj);
if (!__object_info)
return;
__object_info->__resize(__from, __to);
}
} // namespace __cxxprof_impl
#endif /* PROFCXX_PROFILER_CONTAINER_SIZE_H__ */

View file

@ -0,0 +1,192 @@
// -*- 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_trace.h
* @brief Data structures to represent profiling traces.
*/
// Written by Lixia Liu and Silvius Rus.
#ifndef PROFCXX_PROFILER_HASH_FUNC_H__
#define PROFCXX_PROFILER_HASH_FUNC_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 __cxxprof_impl
{
/** @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;
}
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";
}
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);
}
//////////////////////////////////////////////////////////////////////////////
// Initialization and report.
//////////////////////////////////////////////////////////////////////////////
inline void __trace_hash_func_init()
{
__tables<0>::_S_hash_func = new __trace_hash_func();
}
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);
}
}
//////////////////////////////////////////////////////////////////////////////
// Implementations of instrumentation hooks.
//////////////////////////////////////////////////////////////////////////////
inline void __trace_hash_func_construct(const void* __obj)
{
if (!__profcxx_init()) return;
__tables<0>::_S_hash_func->__insert(__obj, __get_stack());
}
inline void __trace_hash_func_destruct(const void* __obj, size_t __chain,
size_t __accesses, size_t __hops)
{
if (!__profcxx_init()) return;
__tables<0>::_S_hash_func->__destruct(__obj, __chain, __accesses, __hops);
}
} // namespace __cxxprof_impl
#endif /* PROFCXX_PROFILER_HASH_FUNC_H__ */

View file

@ -0,0 +1,115 @@
// -*- 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_hashtable_size.cc
* @brief Collection of hashtable size traces.
*/
// Written by Lixia Liu and Silvius Rus.
#ifndef PROFCXX_PROFILER_HASHTABLE_SIZE_H__
#define PROFCXX_PROFILER_HASHTABLE_SIZE_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"
#include "profile/impl/profiler_state.h"
#include "profile/impl/profiler_container_size.h"
namespace __cxxprof_impl
{
/** @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)
{
if (__tables<0>::_S_hashtable_size) {
__tables<0>::_S_hashtable_size->__collect_warnings(__warnings);
__tables<0>::_S_hashtable_size->__write(__f);
}
}
//////////////////////////////////////////////////////////////////////////////
// Implementations of instrumentation hooks.
//////////////////////////////////////////////////////////////////////////////
inline void __trace_hashtable_size_construct(const void* __obj, size_t __num)
{
if (!__profcxx_init()) return;
__tables<0>::_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);
}
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);
}
} // namespace __cxxprof_impl
#endif /* PROFCXX_PROFILER_HASHTABLE_SIZE_H__ */

View file

@ -0,0 +1,305 @@
// -*- 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_map_to_unordered_map.h
* @brief Diagnostics for map to unordered_map.
*/
// Written by Silvius Rus.
#ifndef PROFCXX_PROFILER_MAP_TO_UNORDERED_MAP_H__
#define PROFCXX_PROFILER_MAP_TO_UNORDERED_MAP_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 __cxxprof_impl
{
// Cost model. XXX: this must be taken from the machine model instead.
// 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
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)
{
for (int __bit_count = sizeof(size_t) - 1; __bit_count >= 0; --__bit_count) {
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));
}
/** @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 "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 * __umap_insert_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 * __umap_erase_cost;
}
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_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_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");
}
/** @brief A map-to-unordered_map instrumentation line in the stack table. */
class __map2umap_stack_info: public __map2umap_info
{
public:
__map2umap_stack_info(const __map2umap_info& o) : __map2umap_info(o) {}
};
/** @brief Map-to-unordered_map instrumentation producer. */
class __trace_map2umap
: public __trace_base<__map2umap_info, __map2umap_stack_info>
{
public:
__trace_map2umap();
};
inline __trace_map2umap::__trace_map2umap()
: __trace_base<__map2umap_info, __map2umap_stack_info>()
{
__id = "map-to-unordered-map";
}
inline void __trace_map_to_unordered_map_init()
{
__tables<0>::_S_map2umap = new __trace_map2umap();
}
inline void __trace_map_to_unordered_map_report(
FILE* __f, __warning_vector_t& __warnings)
{
if (__tables<0>::_S_map2umap) {
__tables<0>::_S_map2umap->__collect_warnings(__warnings);
__tables<0>::_S_map2umap->__write(__f);
}
}
//////////////////////////////////////////////////////////////////////////////
// Implementations of instrumentation hooks.
//////////////////////////////////////////////////////////////////////////////
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()));
}
inline void __trace_map_to_unordered_map_destruct(const void* __obj)
{
if (!__profcxx_init()) return;
__tables<0>::_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;
__map2umap_info* __info = __tables<0>::_S_map2umap->__get_object_info(__obj);
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;
__map2umap_info* __info = __tables<0>::_S_map2umap->__get_object_info(__obj);
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;
__map2umap_info* __info = __tables<0>::_S_map2umap->__get_object_info(__obj);
if (__info) __info->__record_find(__size);
}
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);
if (__info) __info->__record_iterate(__count);
}
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);
if (__info) __info->__record_invalidate();
}
} // namespace __cxxprof_impl
#endif /* PROFCXX_PROFILER_MAP_TO_UNORDERED_MAP_H__ */

View file

@ -0,0 +1,172 @@
// -*- 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_node.h
* @brief Data structures to represent a single profiling event.
*/
// Written by Lixia Liu and Silvius Rus.
#ifndef PROFCXX_PROFILER_NODE_H__
#define PROFCXX_PROFILER_NODE_H__ 1
#ifdef __GXX_EXPERIMENTAL_CXX0X__
#include <cstdio>
#include <cstdint>
#include <cstring>
#else
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#endif
#include <vector>
#if defined HAVE_EXECINFO_H
#include <execinfo.h>
#endif
namespace __cxxprof_impl
{
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();
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
return NULL;
#endif
}
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);
}
}
/** @brief Hash function for summary trace using call stack as index. */
class __stack_hash
{
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;
}
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;
}
};
/** @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;
}
/** @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 __cxxprof_impl
#endif /* PROFCXX_PROFILER_NODE_H__ */

View file

@ -0,0 +1,107 @@
// -*- 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_state.cc
* @brief Global profiler state.
*/
// Written by Lixia Liu and Silvius Rus.
#ifndef PROFCXX_PROFILER_STATE_H__
#define PROFCXX_PROFILER_STATE_H__ 1
#ifdef __GXX_EXPERIMENTAL_CXX0X__
#include <cstdio>
#else
#include <stdio.h>
#endif
namespace __cxxprof_impl
{
/** @brief Profiling mode on/off state. */
template <int _Unused=0>
class __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; }
private:
enum __state_type { __ON, __OFF, __INVALID };
__state_type _M_state;
};
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();
}
} // end namespace __cxxprof_impl
#endif /* PROFCXX_PROFILER_STATE_H__ */

View file

@ -0,0 +1,564 @@
// -*- 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_trace.h
* @brief Data structures to represent profiling traces.
*/
// Written by Lixia Liu and Silvius Rus.
#ifndef PROFCXX_PROFILER_TRACE_H__
#define PROFCXX_PROFILER_TRACE_H__ 1
#ifdef __GXX_EXPERIMENTAL_CXX0X__
#include <cerrno>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#define _GLIBCXX_IMPL_UNORDERED_MAP std::_GLIBCXX_STD_PR::unordered_map
#include <unordered_map>
#else
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <tr1/unordered_map>
#define _GLIBCXX_IMPL_UNORDERED_MAP std::tr1::unordered_map
#endif
#include <algorithm>
#include <utility>
#if defined _GLIBCXX_PROFILE_THREADS && defined HAVE_TLS
#include <pthread.h>
#endif
#include "profile/impl/profiler_state.h"
#include "profile/impl/profiler_node.h"
namespace __cxxprof_impl
{
#if defined _GLIBCXX_PROFILE_THREADS && defined HAVE_TLS
#define _GLIBCXX_IMPL_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
typedef pthread_mutex_t __mutex_t;
/** @brief Pthread mutex wrapper. */
template <int _Unused=0>
class __mutex {
public:
static __mutex_t __global_lock;
static void __lock(__mutex_t& __m) { pthread_mutex_lock(&__m); }
static void __unlock(__mutex_t& __m) { pthread_mutex_unlock(&__m); }
};
#else
#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) {}
};
#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)
{
}
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()));
}
}
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;
__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();
}
}
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;
}
}
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();
}
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, "|");
__cxxprof_impl::__write(__f, __it->first);
fprintf(__f, "|");
__it->second.__write(__f);
}
}
}
inline size_t __env_to_size_t(const char* __env_var, size_t __default_value)
{
char* __env_value = getenv(__env_var);
if (__env_value) {
long int __converted_value = strtol(__env_value, NULL, 10);
if (errno || __converted_value < 0) {
fprintf(stderr, "Bad value for environment variable '%s'.", __env_var);
abort();
} else {
return static_cast<size_t>(__converted_value);
}
} else {
return __default_value;
}
}
inline void __set_max_stack_trace_depth()
{
__settings<0>::_S_max_stack_depth = __env_to_size_t(
_GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR,
__settings<0>::_S_max_stack_depth);
}
inline void __set_max_mem()
{
__settings<0>::_S_max_mem = __env_to_size_t(
_GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR, __settings<0>::_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
{
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 = ");
__cxxprof_impl::__write(__file, __info.__context);
fprintf(__file, ": advice = %s\n", __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();
}
}
/** @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
* __cxxprof_impl (under the guarded zone), no output will be produced.
*/
inline void __report(void)
{
__mutex<0>::__lock(__mutex<0>::__global_lock);
__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_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(__settings<0>::_S_max_warn_count,
__warnings.size());
std::sort(__warnings.begin(), __warnings.end(),
std::greater<__warning_vector_t::value_type>());
__warnings.resize(__cutoff);
FILE* __warn_file = __open_output_file("txt");
std::for_each(__warnings.begin(), __warnings.end(), __warn(__warn_file));
fclose(__warn_file);
__mutex<0>::__unlock(__mutex<0>::__global_lock);
}
inline void __set_trace_path()
{
char* __env_trace_file_name = getenv(_GLIBCXX_PROFILE_TRACE_ENV_VAR);
if (__env_trace_file_name) {
__settings<0>::_S_trace_file_name = __env_trace_file_name;
}
// Make sure early that we can create the trace file.
fclose(__open_output_file("txt"));
}
inline void __set_max_warn_count()
{
char* __env_max_warn_count_str = getenv(
_GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR);
if (__env_max_warn_count_str) {
__settings<0>::_S_max_warn_count = static_cast<size_t>(
atoi(__env_max_warn_count_str));
}
}
inline void __profcxx_init_unconditional()
{
__mutex<0>::__lock(__mutex<0>::__global_lock);
__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();
}
}
__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();
}
} // namespace __cxxprof_impl
#endif /* PROFCXX_PROFILER_TRACE_H__ */

View file

@ -0,0 +1,112 @@
// -*- 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_vector_size.h
* @brief Collection of vector size traces.
*/
// Written by Lixia Liu and Silvius Rus.
#ifndef PROFCXX_PROFILER_VECTOR_SIZE_H__
#define PROFCXX_PROFILER_VECTOR_SIZE_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"
#include "profile/impl/profiler_state.h"
#include "profile/impl/profiler_container_size.h"
namespace __cxxprof_impl
{
/** @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);
}
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_resize(const void* __obj, size_t __from,
size_t __to)
{
if (!__profcxx_init()) return;
__tables<0>::_S_vector_size->__resize(__obj, __from, __to);
}
} // namespace __cxxprof_impl
#endif /* PROFCXX_PROFILER_VECTOR_SIZE_H__ */

View file

@ -0,0 +1,318 @@
// -*- 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_trace.h
* @brief Data structures to represent profiling traces.
*/
// Written by Lixia Liu and Silvius Rus.
#ifndef PROFCXX_PROFILER_VECTOR_TO_LIST_H__
#define PROFCXX_PROFILER_VECTOR_TO_LIST_H__ 1
#ifdef __GXX_EXPERIMENTAL_CXX0X__
#include <cstdio>
#include <cstdlib>
#include <cstring>
#else
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#endif
#include "profile/impl/profiler.h"
#include "profile/impl/profiler_node.h"
#include "profile/impl/profiler_trace.h"
namespace __cxxprof_impl
{
/** @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;
}
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);
}
// Cost model. XXX: get this from the cost model database instead.
// 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
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 __trace_vector_to_list::__opr_insert(const void* __obj,
size_t __pos, size_t __num)
{
__vector2list_info* __res = __get_object_info(__obj);
if (__res)
__res->__opr_insert(__pos, __num);
}
inline void __trace_vector_to_list::__opr_iterate(const void* __obj,
size_t __num)
{
__vector2list_info* __res = __get_object_info(__obj);
if (__res)
__res->__opr_iterate(__num);
}
inline void __trace_vector_to_list::__invalid_operator(const void* __obj)
{
__vector2list_info* __res = __get_object_info(__obj);
if (__res)
__res->__set_invalid();
}
inline void __trace_vector_to_list::__resize(const void* __obj, size_t __from,
size_t __to)
{
__vector2list_info* __res = __get_object_info(__obj);
if (__res)
__res->__resize(__from, __to);
}
//////////////////////////////////////////////////////////////////////////////
// Initialization and report.
//////////////////////////////////////////////////////////////////////////////
inline void __trace_vector_to_list_init()
{
__tables<0>::_S_vector_to_list = new __trace_vector_to_list();
}
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);
}
}
//////////////////////////////////////////////////////////////////////////////
// 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());
}
inline void __trace_vector_to_list_destruct(const void* __obj)
{
if (!__profcxx_init()) return;
__tables<0>::_S_vector_to_list->__destruct(__obj);
}
inline void __trace_vector_to_list_insert(const void* __obj,
size_t __pos, size_t __num)
{
if (!__profcxx_init()) return;
__tables<0>::_S_vector_to_list->__opr_insert(__obj, __pos, __num);
}
inline void __trace_vector_to_list_iterate(const void* __obj, size_t __num)
{
if (!__profcxx_init()) return;
__tables<0>::_S_vector_to_list->__opr_iterate(__obj, __num);
}
inline void __trace_vector_to_list_invalid_operator(const void* __obj)
{
if (!__profcxx_init()) return;
__tables<0>::_S_vector_to_list->__invalid_operator(__obj);
}
inline void __trace_vector_to_list_resize(const void* __obj,
size_t __from, size_t __to)
{
if (!__profcxx_init()) return;
__tables<0>::_S_vector_to_list->__resize(__obj, __from, __to);
}
} // namespace __cxxprof_impl
#endif /* PROFCXX_PROFILER_VECTOR_TO_LIST_H__ */

View file

@ -0,0 +1,520 @@
// Profiling list implementation -*- 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 3, 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.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file profile/list
* This file is a GNU profile extension to the Standard C++ Library.
*/
#ifndef _GLIBCXX_PROFILE_LIST
#define _GLIBCXX_PROFILE_LIST 1
#include <list>
namespace std
{
namespace __profile
{
/** @brief List wrapper with performance instrumentation. */
template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
class list
: public _GLIBCXX_STD_D::list<_Tp, _Allocator>
{
typedef _GLIBCXX_STD_D::list<_Tp, _Allocator> _Base;
public:
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 typename _Base::size_type size_type;
typedef typename _Base::difference_type difference_type;
typedef _Tp value_type;
typedef _Allocator allocator_type;
typedef typename _Base::pointer pointer;
typedef typename _Base::const_pointer const_pointer;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
// 23.2.2.1 construct/copy/destroy:
explicit list(const _Allocator& __a = _Allocator())
: _Base(__a) { }
explicit list(size_type __n, const _Tp& __value = _Tp(),
const _Allocator& __a = _Allocator())
: _Base(__n, __value, __a) { }
template<class _InputIterator>
list(_InputIterator __first, _InputIterator __last,
const _Allocator& __a = _Allocator())
: _Base(__first, __last, __a)
{ }
list(const list& __x)
: _Base(__x) { }
list(const _Base& __x)
: _Base(__x) { }
#ifdef __GXX_EXPERIMENTAL_CXX0X__
list(list&& __x)
: _Base(std::forward<list>(__x))
{ }
list(initializer_list<value_type> __l,
const allocator_type& __a = allocator_type())
: _Base(__l, __a) { }
#endif
~list() { }
list&
operator=(const list& __x)
{
static_cast<_Base&>(*this) = __x;
return *this;
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
list&
operator=(list&& __x)
{
// NB: DR 675.
this->clear();
this->swap(__x);
return *this;
}
list&
operator=(initializer_list<value_type> __l)
{
static_cast<_Base&>(*this) = __l;
return *this;
}
void
assign(initializer_list<value_type> __l)
{
_Base::assign(__l);
}
#endif
template<class _InputIterator>
void
assign(_InputIterator __first, _InputIterator __last)
{
_Base::assign(__first, __last);
}
void
assign(size_type __n, const _Tp& __t)
{
_Base::assign(__n, __t);
}
using _Base::get_allocator;
// iterators:
iterator
begin()
{ return iterator(_Base::begin()); }
const_iterator
begin() const
{ return const_iterator(_Base::begin()); }
iterator
end()
{ return iterator(_Base::end()); }
const_iterator
end() const
{ return const_iterator(_Base::end()); }
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()); }
const_iterator
cend() const
{ return const_iterator(_Base::end()); }
const_reverse_iterator
crbegin() const
{ return const_reverse_iterator(end()); }
const_reverse_iterator
crend() const
{ return const_reverse_iterator(begin()); }
#endif
// 23.2.2.2 capacity:
using _Base::empty;
using _Base::size;
using _Base::max_size;
void
resize(size_type __sz, _Tp __c = _Tp())
{
_Base::resize(__sz, __c);
}
// element access:
reference
front()
{
return _Base::front();
}
const_reference
front() const
{
return _Base::front();
}
reference
back()
{
return _Base::back();
}
const_reference
back() const
{
return _Base::back();
}
// 23.2.2.3 modifiers:
using _Base::push_front;
#ifdef __GXX_EXPERIMENTAL_CXX0X__
using _Base::emplace_front;
#endif
void
pop_front()
{
iterator __victim = begin();
_Base::pop_front();
}
using _Base::push_back;
#ifdef __GXX_EXPERIMENTAL_CXX0X__
using _Base::emplace_back;
#endif
void
pop_back()
{
iterator __victim = end();
--__victim;
_Base::pop_back();
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
template<typename... _Args>
iterator
emplace(iterator __position, _Args&&... __args)
{
return iterator(_Base::emplace(__position,
std::forward<_Args>(__args)...));
}
#endif
iterator
insert(iterator __position, const _Tp& __x)
{
return iterator(_Base::insert(__position, __x));
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
iterator
insert(iterator __position, _Tp&& __x)
{ return emplace(__position, std::move(__x)); }
void
insert(iterator __p, initializer_list<value_type> __l)
{
_Base::insert(__p, __l);
}
#endif
void
insert(iterator __position, size_type __n, const _Tp& __x)
{
_Base::insert(__position, __n, __x);
}
template<class _InputIterator>
void
insert(iterator __position, _InputIterator __first,
_InputIterator __last)
{
_Base::insert(__position, __first, __last);
}
iterator
erase(iterator __position)
{
return iterator(_Base::erase(__position));
}
iterator
erase(iterator __position, iterator __last)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 151. can't currently clear() empty container
return iterator(_Base::erase(__position, __last));
}
void
swap(list& __x)
{
_Base::swap(__x);
}
void
clear()
{
_Base::clear();
}
// 23.2.2.4 list operations:
void
#ifdef __GXX_EXPERIMENTAL_CXX0X__
splice(iterator __position, list&& __x)
#else
splice(iterator __position, list& __x)
#endif
{
this->splice(__position, _GLIBCXX_MOVE(__x), __x.begin(), __x.end());
}
void
#ifdef __GXX_EXPERIMENTAL_CXX0X__
splice(iterator __position, list&& __x, iterator __i)
#else
splice(iterator __position, list& __x, iterator __i)
#endif
{
// We used to perform the splice_alloc check: not anymore, redundant
// after implementing the relevant bits of N1599.
// _GLIBCXX_RESOLVE_LIB_DEFECTS
_Base::splice(__position, _GLIBCXX_MOVE(__x._M_base()),
__i);
}
void
#ifdef __GXX_EXPERIMENTAL_CXX0X__
splice(iterator __position, list&& __x, iterator __first,
iterator __last)
#else
splice(iterator __position, list& __x, iterator __first,
iterator __last)
#endif
{
// 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);
}
void
remove(const _Tp& __value)
{
for (iterator __x = begin(); __x != _Base::end(); )
{
if (*__x == __value)
__x = erase(__x);
else
++__x;
}
}
template<class _Predicate>
void
remove_if(_Predicate __pred)
{
for (iterator __x = begin(); __x != _Base::end(); )
{
if (__pred(*__x))
__x = erase(__x);
else
++__x;
}
}
void
unique()
{
iterator __first = begin();
iterator __last = end();
if (__first == __last)
return;
iterator __next = __first;
while (++__next != __last)
{
if (*__first == *__next)
erase(__next);
else
__first = __next;
__next = __first;
}
}
template<class _BinaryPredicate>
void
unique(_BinaryPredicate __binary_pred)
{
iterator __first = begin();
iterator __last = end();
if (__first == __last)
return;
iterator __next = __first;
while (++__next != __last)
{
if (__binary_pred(*__first, *__next))
erase(__next);
else
__first = __next;
__next = __first;
}
}
void
#ifdef __GXX_EXPERIMENTAL_CXX0X__
merge(list&& __x)
#else
merge(list& __x)
#endif
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 300. list::merge() specification incomplete
if (this != &__x)
{
_Base::merge(_GLIBCXX_MOVE(__x._M_base()));
}
}
template<class _Compare>
void
#ifdef __GXX_EXPERIMENTAL_CXX0X__
merge(list&& __x, _Compare __comp)
#else
merge(list& __x, _Compare __comp)
#endif
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 300. list::merge() specification incomplete
if (this != &__x)
{
_Base::merge(_GLIBCXX_MOVE(__x._M_base()), __comp);
}
}
void
sort() { _Base::sort(); }
template<typename _StrictWeakOrdering>
void
sort(_StrictWeakOrdering __pred) { _Base::sort(__pred); }
using _Base::reverse;
_Base&
_M_base() { return *this; }
const _Base&
_M_base() const { return *this; }
};
template<typename _Tp, typename _Alloc>
inline bool
operator==(const list<_Tp, _Alloc>& __lhs,
const list<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() == __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline bool
operator!=(const list<_Tp, _Alloc>& __lhs,
const list<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() != __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline bool
operator<(const list<_Tp, _Alloc>& __lhs,
const list<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() < __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline bool
operator<=(const list<_Tp, _Alloc>& __lhs,
const list<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() <= __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline bool
operator>=(const list<_Tp, _Alloc>& __lhs,
const list<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() >= __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline bool
operator>(const list<_Tp, _Alloc>& __lhs,
const list<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() > __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline void
swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs)
{ __lhs.swap(__rhs); }
} // namespace __profile
} // namespace std
#endif

View file

@ -0,0 +1,41 @@
// Profiling map/multimap implementation -*- 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, 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.
/** @file profile/map
* This file is a GNU profile extension to the Standard C++ Library.
*/
#ifndef _GLIBCXX_PROFILE_MAP
#define _GLIBCXX_PROFILE_MAP 1
#include <map>
#include <profile/map.h>
#include <profile/multimap.h>
#endif

View file

@ -0,0 +1,489 @@
// Profiling map implementation -*- 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, 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.
/** @file profile/map.h
* This file is a GNU profile extension to the Standard C++ Library.
*/
#ifndef _GLIBCXX_PROFILE_MAP_H
#define _GLIBCXX_PROFILE_MAP_H 1
#include <utility>
#include <profile/base.h>
namespace std
{
namespace __profile
{
/** @brief Map wrapper with performance instrumentation. */
template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
class map
: public _GLIBCXX_STD_D::map<_Key, _Tp, _Compare, _Allocator>
{
typedef _GLIBCXX_STD_D::map<_Key, _Tp, _Compare, _Allocator> _Base;
public:
// types:
typedef _Key key_type;
typedef _Tp mapped_type;
typedef std::pair<const _Key, _Tp> value_type;
typedef _Compare key_compare;
typedef _Allocator allocator_type;
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 typename _Base::size_type size_type;
typedef typename _Base::difference_type difference_type;
typedef typename _Base::pointer pointer;
typedef typename _Base::const_pointer const_pointer;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
using _Base::value_compare;
// 23.3.1.1 construct/copy/destroy:
explicit map(const _Compare& __comp = _Compare(),
const _Allocator& __a = _Allocator())
: _Base(__comp, __a) {
__profcxx_map_to_unordered_map_construct(this);
}
template<typename _InputIterator>
map(_InputIterator __first, _InputIterator __last,
const _Compare& __comp = _Compare(),
const _Allocator& __a = _Allocator())
: _Base(__first, __last, __comp, __a) {
__profcxx_map_to_unordered_map_construct(this);
}
map(const map& __x)
: _Base(__x) {
__profcxx_map_to_unordered_map_construct(this);
}
map(const _Base& __x)
: _Base(__x) {
__profcxx_map_to_unordered_map_construct(this);
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
map(map&& __x)
: _Base(std::forward<map>(__x))
{ }
map(initializer_list<value_type> __l,
const _Compare& __c = _Compare(),
const allocator_type& __a = allocator_type())
: _Base(__l, __c, __a) { }
#endif
~map() {
__profcxx_map_to_unordered_map_destruct(this);
}
map&
operator=(const map& __x)
{
*static_cast<_Base*>(this) = __x;
return *this;
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
map&
operator=(map&& __x)
{
// NB: DR 675.
this->clear();
this->swap(__x);
return *this;
}
map&
operator=(initializer_list<value_type> __l)
{
this->clear();
this->insert(__l);
return *this;
}
#endif
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 133. map missing get_allocator()
using _Base::get_allocator;
// iterators:
iterator
begin()
{ return _Base::begin(); }
const_iterator
begin() const
{ return _Base::begin(); }
iterator
end()
{ return _Base::end(); }
const_iterator
end() const
{ return _Base::end(); }
reverse_iterator
rbegin()
{
__profcxx_map_to_unordered_map_invalidate(this);
return reverse_iterator(end());
}
const_reverse_iterator
rbegin() const
{
__profcxx_map_to_unordered_map_invalidate(this);
return const_reverse_iterator(end());
}
reverse_iterator
rend()
{
__profcxx_map_to_unordered_map_invalidate(this);
return reverse_iterator(begin());
}
const_reverse_iterator
rend() const
{
__profcxx_map_to_unordered_map_invalidate(this);
return const_reverse_iterator(begin());
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
const_iterator
cbegin() const
{ return const_iterator(_Base::begin()); }
const_iterator
cend() const
{ return const_iterator(_Base::end()); }
const_reverse_iterator
crbegin() const
{
__profcxx_map_to_unordered_map_invalidate(this);
return const_reverse_iterator(end());
}
const_reverse_iterator
crend() const
{
__profcxx_map_to_unordered_map_invalidate(this);
return const_reverse_iterator(begin());
}
#endif
// capacity:
using _Base::empty;
using _Base::size;
using _Base::max_size;
// 23.3.1.2 element access:
mapped_type&
operator[](const key_type& __k)
{
__profcxx_map_to_unordered_map_find(this, size());
return _Base::operator[](__k);
}
mapped_type&
at(const key_type& __k)
{
__profcxx_map_to_unordered_map_find(this, size());
return _Base::at(__k);
}
const mapped_type&
at(const key_type& __k) const
{
__profcxx_map_to_unordered_map_find(this, size());
return _Base::at(__k);
}
// modifiers:
std::pair<iterator, bool>
insert(const value_type& __x)
{
__profcxx_map_to_unordered_map_insert(this, size(), 1);
typedef typename _Base::iterator _Base_iterator;
std::pair<_Base_iterator, bool> __res = _Base::insert(__x);
return std::pair<iterator, bool>(iterator(__res.first),
__res.second);
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
void
insert(std::initializer_list<value_type> __list)
{
size_type size_before = size();
_Base::insert(__list);
__profcxx_map_to_unordered_map_insert(this, size_before,
size() - size_before);
}
#endif
iterator
insert(iterator __position, const value_type& __x)
{
size_type size_before = size();
return iterator(_Base::insert(__position, __x));
__profcxx_map_to_unordered_map_insert(this, size_before,
size() - size_before);
}
template<typename _InputIterator>
void
insert(_InputIterator __first, _InputIterator __last)
{
size_type size_before = size();
_Base::insert(__first, __last);
__profcxx_map_to_unordered_map_insert(this, size_before,
size() - size_before);
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
iterator
erase(iterator __position)
{
iterator __i = _Base::erase(__position);
__profcxx_map_to_unordered_map_erase(this, size(), 1);
return __i;
}
#else
void
erase(iterator __position)
{
_Base::erase(__position);
__profcxx_map_to_unordered_map_erase(this, size(), 1);
}
#endif
size_type
erase(const key_type& __x)
{
iterator __victim = find(__x);
if (__victim == end())
return 0;
else
{
_Base::erase(__victim);
return 1;
}
}
void
erase(iterator __first, iterator __last)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 151. can't currently clear() empty container
while (__first != __last)
this->erase(__first++);
}
void
swap(map& __x)
{
_Base::swap(__x);
}
void
clear()
{ this->erase(begin(), end()); }
// observers:
using _Base::key_comp;
using _Base::value_comp;
// 23.3.1.3 map operations:
iterator
find(const key_type& __x)
{
__profcxx_map_to_unordered_map_find(this, size());
return iterator(_Base::find(__x));
}
const_iterator
find(const key_type& __x) const
{
__profcxx_map_to_unordered_map_find(this, size());
return const_iterator(_Base::find(__x));
}
size_type
count(const key_type& __x) const
{
__profcxx_map_to_unordered_map_find(this, size());
return _Base::count(__x);
}
iterator
lower_bound(const key_type& __x)
{
__profcxx_map_to_unordered_map_invalidate(this);
return iterator(_Base::lower_bound(__x));
}
const_iterator
lower_bound(const key_type& __x) const
{
__profcxx_map_to_unordered_map_invalidate(this);
return const_iterator(_Base::lower_bound(__x));
}
iterator
upper_bound(const key_type& __x)
{
__profcxx_map_to_unordered_map_invalidate(this);
return iterator(_Base::upper_bound(__x));
}
const_iterator
upper_bound(const key_type& __x) const
{
__profcxx_map_to_unordered_map_invalidate(this);
return const_iterator(_Base::upper_bound(__x));
}
std::pair<iterator,iterator>
equal_range(const key_type& __x)
{
typedef typename _Base::iterator _Base_iterator;
std::pair<_Base_iterator, _Base_iterator> __res =
_Base::equal_range(__x);
return std::make_pair(iterator(__res.first),
iterator(__res.second));
}
std::pair<const_iterator,const_iterator>
equal_range(const key_type& __x) const
{
__profcxx_map_to_unordered_map_find(this, size());
typedef typename _Base::const_iterator _Base_const_iterator;
std::pair<_Base_const_iterator, _Base_const_iterator> __res =
_Base::equal_range(__x);
return std::make_pair(const_iterator(__res.first),
const_iterator(__res.second));
}
_Base&
_M_base() { return *this; }
const _Base&
_M_base() const { return *this; }
};
template<typename _Key, typename _Tp,
typename _Compare, typename _Allocator>
inline bool
operator==(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
{
__profcxx_map_to_unordered_map_invalidate(&__lhs);
__profcxx_map_to_unordered_map_invalidate(&__rhs);
return __lhs._M_base() == __rhs._M_base();
}
template<typename _Key, typename _Tp,
typename _Compare, typename _Allocator>
inline bool
operator!=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
{
__profcxx_map_to_unordered_map_invalidate(&__lhs);
__profcxx_map_to_unordered_map_invalidate(&__rhs);
return __lhs._M_base() != __rhs._M_base();
}
template<typename _Key, typename _Tp,
typename _Compare, typename _Allocator>
inline bool
operator<(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
{
__profcxx_map_to_unordered_map_invalidate(&__lhs);
__profcxx_map_to_unordered_map_invalidate(&__rhs);
return __lhs._M_base() < __rhs._M_base();
}
template<typename _Key, typename _Tp,
typename _Compare, typename _Allocator>
inline bool
operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
{
__profcxx_map_to_unordered_map_invalidate(&__lhs);
__profcxx_map_to_unordered_map_invalidate(&__rhs);
return __lhs._M_base() <= __rhs._M_base();
}
template<typename _Key, typename _Tp,
typename _Compare, typename _Allocator>
inline bool
operator>=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
{
__profcxx_map_to_unordered_map_invalidate(&__lhs);
__profcxx_map_to_unordered_map_invalidate(&__rhs);
return __lhs._M_base() >= __rhs._M_base();
}
template<typename _Key, typename _Tp,
typename _Compare, typename _Allocator>
inline bool
operator>(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
{
__profcxx_map_to_unordered_map_invalidate(&__lhs);
__profcxx_map_to_unordered_map_invalidate(&__rhs);
return __lhs._M_base() > __rhs._M_base();
}
template<typename _Key, typename _Tp,
typename _Compare, typename _Allocator>
inline void
swap(map<_Key, _Tp, _Compare, _Allocator>& __lhs,
map<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ __lhs.swap(__rhs); }
} // namespace __profile
} // namespace std
#endif

View file

@ -0,0 +1,363 @@
// Profiling multimap implementation -*- 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 3, 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.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file profile/multimap.h
* This file is a GNU profile extension to the Standard C++ Library.
*/
#ifndef _GLIBCXX_PROFILE_MULTIMAP_H
#define _GLIBCXX_PROFILE_MULTIMAP_H 1
#include <utility>
namespace std
{
namespace __profile
{
/** @brief Multimap wrapper with performance instrumentation. */
template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
class multimap
: public _GLIBCXX_STD_D::multimap<_Key, _Tp, _Compare, _Allocator>
{
typedef _GLIBCXX_STD_D::multimap<_Key, _Tp, _Compare, _Allocator> _Base;
public:
// types:
typedef _Key key_type;
typedef _Tp mapped_type;
typedef std::pair<const _Key, _Tp> value_type;
typedef _Compare key_compare;
typedef _Allocator allocator_type;
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 typename _Base::reverse_iterator reverse_iterator;
typedef typename _Base::const_reverse_iterator const_reverse_iterator;
typedef typename _Base::size_type size_type;
typedef typename _Base::difference_type difference_type;
typedef typename _Base::pointer pointer;
typedef typename _Base::const_pointer const_pointer;
using _Base::value_compare;
// 23.3.1.1 construct/copy/destroy:
explicit multimap(const _Compare& __comp = _Compare(),
const _Allocator& __a = _Allocator())
: _Base(__comp, __a) { }
template<typename _InputIterator>
multimap(_InputIterator __first, _InputIterator __last,
const _Compare& __comp = _Compare(),
const _Allocator& __a = _Allocator())
: _Base(__first, __last, __comp, __a) { }
multimap(const multimap& __x)
: _Base(__x) { }
multimap(const _Base& __x)
: _Base(__x) { }
#ifdef __GXX_EXPERIMENTAL_CXX0X__
multimap(multimap&& __x)
: _Base(std::forward<multimap>(__x))
{ }
multimap(initializer_list<value_type> __l,
const _Compare& __c = _Compare(),
const allocator_type& __a = allocator_type())
: _Base(__l, __c, __a) { }
#endif
~multimap() { }
multimap&
operator=(const multimap& __x)
{
*static_cast<_Base*>(this) = __x;
return *this;
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
multimap&
operator=(multimap&& __x)
{
// NB: DR 675.
this->clear();
this->swap(__x);
return *this;
}
multimap&
operator=(initializer_list<value_type> __l)
{
this->clear();
this->insert(__l);
return *this;
}
#endif
using _Base::get_allocator;
// iterators:
iterator
begin()
{ return iterator(_Base::begin()); }
const_iterator
begin() const
{ return const_iterator(_Base::begin()); }
iterator
end()
{ return iterator(_Base::end()); }
const_iterator
end() const
{ return const_iterator(_Base::end()); }
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()); }
const_iterator
cend() const
{ return const_iterator(_Base::end()); }
const_reverse_iterator
crbegin() const
{ return const_reverse_iterator(end()); }
const_reverse_iterator
crend() const
{ return const_reverse_iterator(begin()); }
#endif
// capacity:
using _Base::empty;
using _Base::size;
using _Base::max_size;
// modifiers:
iterator
insert(const value_type& __x)
{ return iterator(_Base::insert(__x)); }
#ifdef __GXX_EXPERIMENTAL_CXX0X__
void
insert(std::initializer_list<value_type> __list)
{ _Base::insert(__list); }
#endif
iterator
insert(iterator __position, const value_type& __x)
{
return iterator(_Base::insert(__position, __x));
}
template<typename _InputIterator>
void
insert(_InputIterator __first, _InputIterator __last)
{
_Base::insert(__first, __last);
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
iterator
erase(iterator __position)
{
return _Base::erase(__position);
}
#else
void
erase(iterator __position)
{
_Base::erase(__position);
}
#endif
size_type
erase(const key_type& __x)
{
std::pair<iterator, iterator> __victims = this->equal_range(__x);
size_type __count = 0;
while (__victims.first != __victims.second)
{
iterator __victim = __victims.first++;
_Base::erase(__victim);
++__count;
}
return __count;
}
void
erase(iterator __first, iterator __last)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 151. can't currently clear() empty container
while (__first != __last)
this->erase(__first++);
}
void
swap(multimap& __x)
{
_Base::swap(__x);
}
void
clear()
{ this->erase(begin(), end()); }
// observers:
using _Base::key_comp;
using _Base::value_comp;
// 23.3.1.3 multimap operations:
iterator
find(const key_type& __x)
{ return iterator(_Base::find(__x)); }
const_iterator
find(const key_type& __x) const
{ return const_iterator(_Base::find(__x)); }
using _Base::count;
iterator
lower_bound(const key_type& __x)
{ return iterator(_Base::lower_bound(__x)); }
const_iterator
lower_bound(const key_type& __x) const
{ return const_iterator(_Base::lower_bound(__x)); }
iterator
upper_bound(const key_type& __x)
{ return iterator(_Base::upper_bound(__x)); }
const_iterator
upper_bound(const key_type& __x) const
{ return const_iterator(_Base::upper_bound(__x)); }
std::pair<iterator,iterator>
equal_range(const key_type& __x)
{
typedef typename _Base::iterator _Base_iterator;
std::pair<_Base_iterator, _Base_iterator> __res =
_Base::equal_range(__x);
return std::make_pair(iterator(__res.first),
iterator(__res.second));
}
std::pair<const_iterator,const_iterator>
equal_range(const key_type& __x) const
{
typedef typename _Base::const_iterator _Base_const_iterator;
std::pair<_Base_const_iterator, _Base_const_iterator> __res =
_Base::equal_range(__x);
return std::make_pair(const_iterator(__res.first),
const_iterator(__res.second));
}
_Base&
_M_base() { return *this; }
const _Base&
_M_base() const { return *this; }
};
template<typename _Key, typename _Tp,
typename _Compare, typename _Allocator>
inline bool
operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() == __rhs._M_base(); }
template<typename _Key, typename _Tp,
typename _Compare, typename _Allocator>
inline bool
operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() != __rhs._M_base(); }
template<typename _Key, typename _Tp,
typename _Compare, typename _Allocator>
inline bool
operator<(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() < __rhs._M_base(); }
template<typename _Key, typename _Tp,
typename _Compare, typename _Allocator>
inline bool
operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() <= __rhs._M_base(); }
template<typename _Key, typename _Tp,
typename _Compare, typename _Allocator>
inline bool
operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() >= __rhs._M_base(); }
template<typename _Key, typename _Tp,
typename _Compare, typename _Allocator>
inline bool
operator>(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() > __rhs._M_base(); }
template<typename _Key, typename _Tp,
typename _Compare, typename _Allocator>
inline void
swap(multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ __lhs.swap(__rhs); }
} // namespace __profile
} // namespace std
#endif

View file

@ -0,0 +1,363 @@
// Profiling multiset implementation -*- 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 3, 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.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file profile/multiset.h
* This file is a GNU profile extension to the Standard C++ Library.
*/
#ifndef _GLIBCXX_PROFILE_MULTISET_H
#define _GLIBCXX_PROFILE_MULTISET_H 1
#include <utility>
namespace std
{
namespace __profile
{
/** @brief Multiset wrapper with performance instrumentation. */
template<typename _Key, typename _Compare = std::less<_Key>,
typename _Allocator = std::allocator<_Key> >
class multiset
: public _GLIBCXX_STD_D::multiset<_Key, _Compare, _Allocator>
{
typedef _GLIBCXX_STD_D::multiset<_Key, _Compare, _Allocator> _Base;
public:
// types:
typedef _Key key_type;
typedef _Key value_type;
typedef _Compare key_compare;
typedef _Compare value_compare;
typedef _Allocator allocator_type;
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 typename _Base::reverse_iterator reverse_iterator;
typedef typename _Base::const_reverse_iterator const_reverse_iterator;
typedef typename _Base::size_type size_type;
typedef typename _Base::difference_type difference_type;
typedef typename _Base::pointer pointer;
typedef typename _Base::const_pointer const_pointer;
// 23.3.3.1 construct/copy/destroy:
explicit multiset(const _Compare& __comp = _Compare(),
const _Allocator& __a = _Allocator())
: _Base(__comp, __a) { }
template<typename _InputIterator>
multiset(_InputIterator __first, _InputIterator __last,
const _Compare& __comp = _Compare(),
const _Allocator& __a = _Allocator())
: _Base(__first, __last, __comp, __a) { }
multiset(const multiset& __x)
: _Base(__x) { }
multiset(const _Base& __x)
: _Base(__x) { }
#ifdef __GXX_EXPERIMENTAL_CXX0X__
multiset(multiset&& __x)
: _Base(std::forward<multiset>(__x))
{ }
multiset(initializer_list<value_type> __l,
const _Compare& __comp = _Compare(),
const allocator_type& __a = allocator_type())
: _Base(__l, __comp, __a) { }
#endif
~multiset() { }
multiset&
operator=(const multiset& __x)
{
*static_cast<_Base*>(this) = __x;
return *this;
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
multiset&
operator=(multiset&& __x)
{
// NB: DR 675.
this->clear();
this->swap(__x);
return *this;
}
multiset&
operator=(initializer_list<value_type> __l)
{
this->clear();
this->insert(__l);
return *this;
}
#endif
using _Base::get_allocator;
// iterators:
iterator
begin()
{ return iterator(_Base::begin()); }
const_iterator
begin() const
{ return const_iterator(_Base::begin()); }
iterator
end()
{ return iterator(_Base::end()); }
const_iterator
end() const
{ return const_iterator(_Base::end()); }
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()); }
const_iterator
cend() const
{ return const_iterator(_Base::end()); }
const_reverse_iterator
crbegin() const
{ return const_reverse_iterator(end()); }
const_reverse_iterator
crend() const
{ return const_reverse_iterator(begin()); }
#endif
// capacity:
using _Base::empty;
using _Base::size;
using _Base::max_size;
// modifiers:
iterator
insert(const value_type& __x)
{ return iterator(_Base::insert(__x)); }
iterator
insert(iterator __position, const value_type& __x)
{
return iterator(_Base::insert(__position, __x));
}
template<typename _InputIterator>
void
insert(_InputIterator __first, _InputIterator __last)
{
_Base::insert(__first, __last);
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
void
insert(initializer_list<value_type> __l)
{ _Base::insert(__l); }
#endif
#ifdef __GXX_EXPERIMENTAL_CXX0X__
iterator
erase(iterator __position)
{
return _Base::erase(__position);
}
#else
void
erase(iterator __position)
{
_Base::erase(__position);
}
#endif
size_type
erase(const key_type& __x)
{
std::pair<iterator, iterator> __victims = this->equal_range(__x);
size_type __count = 0;
while (__victims.first != __victims.second)
{
iterator __victim = __victims.first++;
_Base::erase(__victim);
++__count;
}
return __count;
}
void
erase(iterator __first, iterator __last)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 151. can't currently clear() empty container
while (__first != __last)
this->erase(__first++);
}
void
swap(multiset& __x)
{
_Base::swap(__x);
}
void
clear()
{ this->erase(begin(), end()); }
// observers:
using _Base::key_comp;
using _Base::value_comp;
// multiset operations:
iterator
find(const key_type& __x)
{ return iterator(_Base::find(__x)); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 214. set::find() missing const overload
const_iterator
find(const key_type& __x) const
{ return const_iterator(_Base::find(__x)); }
using _Base::count;
iterator
lower_bound(const key_type& __x)
{ return iterator(_Base::lower_bound(__x)); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 214. set::find() missing const overload
const_iterator
lower_bound(const key_type& __x) const
{ return const_iterator(_Base::lower_bound(__x)); }
iterator
upper_bound(const key_type& __x)
{ return iterator(_Base::upper_bound(__x)); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 214. set::find() missing const overload
const_iterator
upper_bound(const key_type& __x) const
{ return const_iterator(_Base::upper_bound(__x)); }
std::pair<iterator,iterator>
equal_range(const key_type& __x)
{
typedef typename _Base::iterator _Base_iterator;
std::pair<_Base_iterator, _Base_iterator> __res =
_Base::equal_range(__x);
return std::make_pair(iterator(__res.first),
iterator(__res.second));
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 214. set::find() missing const overload
std::pair<const_iterator,const_iterator>
equal_range(const key_type& __x) const
{
typedef typename _Base::const_iterator _Base_iterator;
std::pair<_Base_iterator, _Base_iterator> __res =
_Base::equal_range(__x);
return std::make_pair(const_iterator(__res.first),
const_iterator(__res.second));
}
_Base&
_M_base() { return *this; }
const _Base&
_M_base() const { return *this; }
};
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
operator==(const multiset<_Key, _Compare, _Allocator>& __lhs,
const multiset<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() == __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
operator!=(const multiset<_Key, _Compare, _Allocator>& __lhs,
const multiset<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() != __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
operator<(const multiset<_Key, _Compare, _Allocator>& __lhs,
const multiset<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() < __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
operator<=(const multiset<_Key, _Compare, _Allocator>& __lhs,
const multiset<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() <= __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
operator>=(const multiset<_Key, _Compare, _Allocator>& __lhs,
const multiset<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() >= __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
operator>(const multiset<_Key, _Compare, _Allocator>& __lhs,
const multiset<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() > __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
void
swap(multiset<_Key, _Compare, _Allocator>& __x,
multiset<_Key, _Compare, _Allocator>& __y)
{ return __x.swap(__y); }
} // namespace __profile
} // namespace std
#endif

View file

@ -0,0 +1,41 @@
// Profiling set/multiset implementation -*- 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, 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.
/** @file profile/set
* This file is a GNU profile extension to the Standard C++ Library.
*/
#ifndef _GLIBCXX_PROFILE_SET
#define _GLIBCXX_PROFILE_SET 1
#include <set>
#include <profile/set.h>
#include <profile/multiset.h>
#endif

View file

@ -0,0 +1,367 @@
// Profiling set implementation -*- 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 3, 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.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file profile/set.h
* This file is a GNU profile extension to the Standard C++ Library.
*/
#ifndef _GLIBCXX_PROFILE_SET_H
#define _GLIBCXX_PROFILE_SET_H 1
#include <utility>
namespace std
{
namespace __profile
{
/** @brief Set wrapper with performance instrumentation. */
template<typename _Key, typename _Compare = std::less<_Key>,
typename _Allocator = std::allocator<_Key> >
class set
: public _GLIBCXX_STD_D::set<_Key,_Compare,_Allocator>
{
typedef _GLIBCXX_STD_D::set<_Key, _Compare, _Allocator> _Base;
public:
// types:
typedef _Key key_type;
typedef _Key value_type;
typedef _Compare key_compare;
typedef _Compare value_compare;
typedef _Allocator allocator_type;
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 typename _Base::reverse_iterator reverse_iterator;
typedef typename _Base::const_reverse_iterator const_reverse_iterator;
typedef typename _Base::size_type size_type;
typedef typename _Base::difference_type difference_type;
typedef typename _Base::pointer pointer;
typedef typename _Base::const_pointer const_pointer;
// 23.3.3.1 construct/copy/destroy:
explicit set(const _Compare& __comp = _Compare(),
const _Allocator& __a = _Allocator())
: _Base(__comp, __a) { }
template<typename _InputIterator>
set(_InputIterator __first, _InputIterator __last,
const _Compare& __comp = _Compare(),
const _Allocator& __a = _Allocator())
: _Base(__first, __last, __comp, __a) { }
set(const set& __x)
: _Base(__x) { }
set(const _Base& __x)
: _Base(__x) { }
#ifdef __GXX_EXPERIMENTAL_CXX0X__
set(set&& __x)
: _Base(std::forward<set>(__x))
{ }
set(initializer_list<value_type> __l,
const _Compare& __comp = _Compare(),
const allocator_type& __a = allocator_type())
: _Base(__l, __comp, __a) { }
#endif
~set() { }
set&
operator=(const set& __x)
{
*static_cast<_Base*>(this) = __x;
return *this;
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
set&
operator=(set&& __x)
{
// NB: DR 675.
this->clear();
this->swap(__x);
return *this;
}
set&
operator=(initializer_list<value_type> __l)
{
this->clear();
this->insert(__l);
return *this;
}
#endif
using _Base::get_allocator;
// iterators:
iterator
begin()
{ return iterator(_Base::begin()); }
const_iterator
begin() const
{ return const_iterator(_Base::begin()); }
iterator
end()
{ return iterator(_Base::end()); }
const_iterator
end() const
{ return const_iterator(_Base::end()); }
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()); }
const_iterator
cend() const
{ return const_iterator(_Base::end()); }
const_reverse_iterator
crbegin() const
{ return const_reverse_iterator(end()); }
const_reverse_iterator
crend() const
{ return const_reverse_iterator(begin()); }
#endif
// capacity:
using _Base::empty;
using _Base::size;
using _Base::max_size;
// modifiers:
std::pair<iterator, bool>
insert(const value_type& __x)
{
typedef typename _Base::iterator _Base_iterator;
std::pair<_Base_iterator, bool> __res = _Base::insert(__x);
return std::pair<iterator, bool>(iterator(__res.first),
__res.second);
}
iterator
insert(iterator __position, const value_type& __x)
{
return iterator(_Base::insert(__position, __x));
}
template <typename _InputIterator>
void
insert(_InputIterator __first, _InputIterator __last)
{
_Base::insert(__first, __last);
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
void
insert(initializer_list<value_type> __l)
{ _Base::insert(__l); }
#endif
#ifdef __GXX_EXPERIMENTAL_CXX0X__
iterator
erase(iterator __position)
{
return _Base::erase(__position);
}
#else
void
erase(iterator __position)
{
_Base::erase(__position);
}
#endif
size_type
erase(const key_type& __x)
{
iterator __victim = find(__x);
if (__victim == end())
return 0;
else
{
_Base::erase(__victim);
return 1;
}
}
void
erase(iterator __first, iterator __last)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 151. can't currently clear() empty container
while (__first != __last)
this->erase(__first++);
}
void
swap(set& __x)
{
_Base::swap(__x);
}
void
clear()
{ this->erase(begin(), end()); }
// observers:
using _Base::key_comp;
using _Base::value_comp;
// set operations:
iterator
find(const key_type& __x)
{ return iterator(_Base::find(__x)); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 214. set::find() missing const overload
const_iterator
find(const key_type& __x) const
{ return const_iterator(_Base::find(__x)); }
using _Base::count;
iterator
lower_bound(const key_type& __x)
{ return iterator(_Base::lower_bound(__x)); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 214. set::find() missing const overload
const_iterator
lower_bound(const key_type& __x) const
{ return const_iterator(_Base::lower_bound(__x)); }
iterator
upper_bound(const key_type& __x)
{ return iterator(_Base::upper_bound(__x)); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 214. set::find() missing const overload
const_iterator
upper_bound(const key_type& __x) const
{ return const_iterator(_Base::upper_bound(__x)); }
std::pair<iterator,iterator>
equal_range(const key_type& __x)
{
typedef typename _Base::iterator _Base_iterator;
std::pair<_Base_iterator, _Base_iterator> __res =
_Base::equal_range(__x);
return std::make_pair(iterator(__res.first),
iterator(__res.second));
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 214. set::find() missing const overload
std::pair<const_iterator,const_iterator>
equal_range(const key_type& __x) const
{
typedef typename _Base::const_iterator _Base_iterator;
std::pair<_Base_iterator, _Base_iterator> __res =
_Base::equal_range(__x);
return std::make_pair(const_iterator(__res.first),
const_iterator(__res.second));
}
_Base&
_M_base() { return *this; }
const _Base&
_M_base() const { return *this; }
};
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
operator==(const set<_Key, _Compare, _Allocator>& __lhs,
const set<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() == __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
operator!=(const set<_Key, _Compare, _Allocator>& __lhs,
const set<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() != __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
operator<(const set<_Key, _Compare, _Allocator>& __lhs,
const set<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() < __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
operator<=(const set<_Key, _Compare, _Allocator>& __lhs,
const set<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() <= __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
operator>=(const set<_Key, _Compare, _Allocator>& __lhs,
const set<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() >= __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
operator>(const set<_Key, _Compare, _Allocator>& __lhs,
const set<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() > __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
void
swap(set<_Key, _Compare, _Allocator>& __x,
set<_Key, _Compare, _Allocator>& __y)
{ return __x.swap(__y); }
} // namespace __profile
} // namespace std
#endif

View file

@ -0,0 +1,498 @@
// Profiling unordered_map/unordered_multimap implementation -*- 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, 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.
/** @file profile/unordered_map
* This file is a GNU profile extension to the Standard C++ Library.
*/
#ifndef _GLIBCXX_PROFILE_UNORDERED_MAP
#define _GLIBCXX_PROFILE_UNORDERED_MAP 1
#include <profile/base.h>
#ifdef __GXX_EXPERIMENTAL_CXX0X__
# include <unordered_map>
#else
# include <c++0x_warning.h>
#endif
#include <initializer_list>
#define _GLIBCXX_BASE unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>
#define _GLIBCXX_STD_BASE _GLIBCXX_STD_PR::_GLIBCXX_BASE
namespace std
{
namespace __profile
{
/** @brief Unordered_map wrapper with performance instrumentation. */
template<typename _Key, typename _Tp,
typename _Hash = std::hash<_Key>,
typename _Pred = std::equal_to<_Key>,
typename _Alloc = std::allocator<_Key> >
class unordered_map
: public _GLIBCXX_STD_BASE
{
typedef typename _GLIBCXX_STD_BASE _Base;
public:
typedef typename _Base::size_type size_type;
typedef typename _Base::hasher hasher;
typedef typename _Base::key_equal key_equal;
typedef typename _Base::allocator_type allocator_type;
typedef typename _Base::key_type key_type;
typedef typename _Base::value_type value_type;
typedef typename _Base::difference_type difference_type;
typedef typename _Base::reference reference;
typedef typename _Base::const_reference const_reference;
typedef typename _Base::mapped_type mapped_type;
typedef std::pair<typename _Base::iterator, bool> pair_type;
typedef typename _Base::insert_return_type insert_return_type;
typedef typename _Base::iterator iterator;
typedef typename _Base::const_iterator const_iterator;
explicit
unordered_map(size_type __n = 10,
const hasher& __hf = hasher(),
const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
: _Base(__n, __hf, __eql, __a)
{
__profcxx_hashtable_construct(this, _Base::bucket_count());
__profcxx_hashtable_construct2(this);
}
template<typename _InputIterator>
unordered_map(_InputIterator __f, _InputIterator __l,
size_type __n = 10,
const hasher& __hf = hasher(),
const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
: _Base(__f, __l, __n, __hf, __eql, __a)
{
__profcxx_hashtable_construct(this, _Base::bucket_count());
__profcxx_hashtable_construct2(this);
}
unordered_map(const _Base& __x)
: _Base(__x)
{
__profcxx_hashtable_construct(this, _Base::bucket_count());
__profcxx_hashtable_construct2(this);
}
unordered_map(unordered_map&& __x)
: _Base(std::forward<_Base>(__x))
{
__profcxx_hashtable_construct(this, _Base::bucket_count());
__profcxx_hashtable_construct2(this);
}
unordered_map(initializer_list<value_type> __l,
size_type __n = 10,
const hasher& __hf = hasher(),
const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
: _Base(__l, __n, __hf, __eql, __a) { }
unordered_map&
operator=(const unordered_map& __x)
{
*static_cast<_Base*>(this) = __x;
return *this;
}
unordered_map&
operator=(unordered_map&& __x)
{
// NB: DR 675.
this->clear();
this->swap(__x);
return *this;
}
unordered_map&
operator=(initializer_list<value_type> __l)
{
this->clear();
this->insert(__l);
return *this;
}
~unordered_map()
{
__profcxx_hashtable_destruct(this, _Base::bucket_count(), _Base::size());
_M_profile_destruct();
}
_Base&
_M_base() { return *this; }
const _Base&
_M_base() const { return *this; }
void
clear()
{
__profcxx_hashtable_destruct(this, _Base::bucket_count(), _Base::size());
_M_profile_destruct();
_Base::clear();
}
void
insert(std::initializer_list<value_type> __l)
{
size_type __old_size = _Base::bucket_count();
_Base::insert(__l);
_M_profile_resize(__old_size, _Base::bucket_count());
}
insert_return_type
insert(const value_type& __obj)
{
size_type __old_size = _Base::bucket_count();
insert_return_type __res = _Base::insert(__obj);
_M_profile_resize(__old_size, _Base::bucket_count());
return __res;
}
iterator
insert(iterator __iter, const value_type& __v)
{
size_type __old_size = _Base::bucket_count();
iterator res = _Base::insert(__iter, __v);
_M_profile_resize(__old_size, _Base::bucket_count());
return res;
}
const_iterator
insert(const_iterator __iter, const value_type& __v)
{
size_type __old_size = _Base::bucket_count();
const_iterator res =_Base::insert(__iter, __v);
_M_profile_resize(__old_size, _Base::bucket_count());
return res;
}
template<typename _InputIter>
void
insert(_InputIter __first, _InputIter __last)
{
size_type __old_size = _Base::bucket_count();
_Base::insert(__first.base(), __last.base());
_M_profile_resize(__old_size, _Base::bucket_count());
}
void
insert(const value_type* __first, const value_type* __last)
{
size_type __old_size = _Base::bucket_count();
_Base::insert(__first, __last);
_M_profile_resize(__old_size, _Base::bucket_count());
}
// operator []
mapped_type&
operator[](const _Key& _k)
{
size_type __old_size = _Base::bucket_count();
mapped_type& __res = _M_base()[_k];
size_type __new_size = _Base::bucket_count();
_M_profile_resize(__old_size, _Base::bucket_count());
return __res;
}
void
swap(unordered_map& __x)
{
_Base::swap(__x);
}
void rehash(size_type __n)
{
size_type __old_size = _Base::bucket_count();
_Base::rehash(__n);
_M_profile_resize(__old_size, _Base::bucket_count());
}
private:
void _M_profile_resize(size_type __old_size, size_type __new_size)
{
if (__old_size != __new_size)
{
__profcxx_hashtable_resize(this, __old_size, __new_size);
}
}
void _M_profile_destruct()
{
size_type __hops = 0, __lc = 0, __chain = 0;
for (iterator it = _M_base().begin(); it != _M_base().end(); it++)
{
while (it._M_cur_node->_M_next) {
__chain++;
it++;
}
if (__chain) {
__chain++;
__lc = __lc > __chain ? __lc : __chain;
__hops += __chain * (__chain - 1) / 2;
__chain = 0;
}
}
__profcxx_hashtable_destruct2(this, __lc, _Base::size(), __hops);
}
};
template<typename _Key, typename _Tp, typename _Hash,
typename _Pred, typename _Alloc>
inline void
swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
{ __x.swap(__y); }
#undef _GLIBCXX_BASE
#undef _GLIBCXX_STD_BASE
#define _GLIBCXX_BASE unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>
#define _GLIBCXX_STD_BASE _GLIBCXX_STD_PR::_GLIBCXX_BASE
/** @brief Unordered_multimap wrapper with performance instrumentation. */
template<typename _Key, typename _Tp,
typename _Hash = std::hash<_Key>,
typename _Pred = std::equal_to<_Key>,
typename _Alloc = std::allocator<_Key> >
class unordered_multimap
: public _GLIBCXX_STD_BASE
{
typedef typename _GLIBCXX_STD_BASE _Base;
public:
typedef typename _Base::size_type size_type;
typedef typename _Base::hasher hasher;
typedef typename _Base::key_equal key_equal;
typedef typename _Base::allocator_type allocator_type;
typedef typename _Base::key_type key_type;
typedef typename _Base::value_type value_type;
typedef typename _Base::difference_type difference_type;
typedef typename _Base::reference reference;
typedef typename _Base::const_reference const_reference;
typedef std::pair<typename _Base::iterator, bool> pair_type;
typedef typename _Base::insert_return_type insert_return_type;
typedef typename _Base::iterator iterator;
typedef typename _Base::const_iterator const_iterator;
explicit
unordered_multimap(size_type __n = 10,
const hasher& __hf = hasher(),
const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
: _Base(__n, __hf, __eql, __a)
{
__profcxx_hashtable_construct(this, _Base::bucket_count());
}
template<typename _InputIterator>
unordered_multimap(_InputIterator __f, _InputIterator __l,
size_type __n = 10,
const hasher& __hf = hasher(),
const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
: _Base(__f, __l, __n, __hf, __eql, __a)
{
__profcxx_hashtable_construct(this, _Base::bucket_count());
}
unordered_multimap(const _Base& __x)
: _Base(__x)
{
__profcxx_hashtable_construct(this, _Base::bucket_count());
}
unordered_multimap(unordered_multimap&& __x)
: _Base(std::forward<_Base>(__x))
{
__profcxx_hashtable_construct(this, _Base::bucket_count());
}
unordered_multimap(initializer_list<value_type> __l,
size_type __n = 10,
const hasher& __hf = hasher(),
const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
: _Base(__l, __n, __hf, __eql, __a) { }
unordered_multimap&
operator=(const unordered_multimap& __x)
{
*static_cast<_Base*>(this) = __x;
return *this;
}
unordered_multimap&
operator=(unordered_multimap&& __x)
{
// NB: DR 675.
this->clear();
this->swap(__x);
return *this;
}
unordered_multimap&
operator=(initializer_list<value_type> __l)
{
this->clear();
this->insert(__l);
return *this;
}
~unordered_multimap()
{
__profcxx_hashtable_destruct(this, _Base::bucket_count(), _Base::size());
_M_profile_destruct();
}
_Base&
_M_base() { return *this; }
const _Base&
_M_base() const { return *this; }
void
clear()
{
__profcxx_hashtable_destruct(this, _Base::bucket_count(), _Base::size());
_M_profile_destruct();
_Base::clear();
}
void
insert(std::initializer_list<value_type> __l)
{
size_type __old_size = _Base::bucket_count();
_Base::insert(__l);
_M_profile_resize(__old_size, _Base::bucket_count());
}
insert_return_type
insert(const value_type& __obj)
{
size_type __old_size = _Base::bucket_count();
insert_return_type __res = _Base::insert(__obj);
_M_profile_resize(__old_size, _Base::bucket_count());
return __res;
}
iterator
insert(iterator __iter, const value_type& __v)
{
size_type __old_size = _Base::bucket_count();
iterator res = _Base::insert(__iter, __v);
_M_profile_resize(__old_size, _Base::bucket_count());
return res;
}
const_iterator
insert(const_iterator __iter, const value_type& __v)
{
size_type __old_size = _Base::bucket_count();
const_iterator res =_Base::insert(__iter, __v);
_M_profile_resize(__old_size, _Base::bucket_count());
return res;
}
template<typename _InputIter>
void
insert(_InputIter __first, _InputIter __last)
{
size_type __old_size = _Base::bucket_count();
_Base::insert(__first.base(), __last.base());
_M_profile_resize(__old_size, _Base::bucket_count());
}
void
insert(const value_type* __first, const value_type* __last)
{
size_type __old_size = _Base::bucket_count();
_Base::insert(__first, __last);
_M_profile_resize(__old_size, _Base::bucket_count());
}
void
swap(unordered_multimap& __x)
{
_Base::swap(__x);
}
void rehash(size_type __n)
{
size_type __old_size = _Base::bucket_count();
_Base::rehash(__n);
_M_profile_resize(__old_size, _Base::bucket_count());
}
private:
void _M_profile_resize(size_type __old_size, size_type __new_size)
{
if (__old_size != __new_size)
{
__profcxx_hashtable_resize(this, __old_size, __new_size);
}
}
void _M_profile_destruct()
{
size_type __hops = 0, __lc = 0, __chain = 0;
for (iterator it = _M_base().begin(); it != _M_base().end(); it++)
{
while (it._M_cur_node->_M_next) {
__chain++;
it++;
}
if (__chain) {
__chain++;
__lc = __lc > __chain ? __lc : __chain;
__hops += __chain * (__chain - 1) / 2;
__chain = 0;
}
}
__profcxx_hashtable_destruct2(this, __lc, _Base::size(), __hops);
}
};
template<typename _Key, typename _Tp, typename _Hash,
typename _Pred, typename _Alloc>
inline void
swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
{ __x.swap(__y); }
} // namespace __profile
} // namespace std
#undef _GLIBCXX_BASE
#undef _GLIBCXX_STD_BASE
#endif

View file

@ -0,0 +1,480 @@
// Profiling unordered_set/unordered_multiset implementation -*- 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, 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.
/** @file profile/unordered_set
* This file is a GNU profile extension to the Standard C++ Library.
*/
#ifndef _GLIBCXX_PROFILE_UNORDERED_SET
#define _GLIBCXX_PROFILE_UNORDERED_SET 1
#include <profile/base.h>
#ifdef __GXX_EXPERIMENTAL_CXX0X__
# include <unordered_set>
#else
# include <c++0x_warning.h>
#endif
#include <initializer_list>
#define _GLIBCXX_BASE unordered_set<_Key, _Hash, _Pred, _Alloc>
#define _GLIBCXX_STD_BASE _GLIBCXX_STD_PR::_GLIBCXX_BASE
namespace std
{
namespace __profile
{
/** @brief Unordered_set wrapper with performance instrumentation. */
template<typename _Key,
typename _Hash = std::hash<_Key>,
typename _Pred = std::equal_to<_Key>,
typename _Alloc = std::allocator<_Key> >
class unordered_set
: public _GLIBCXX_STD_BASE
{
typedef typename _GLIBCXX_STD_BASE _Base;
public:
typedef typename _Base::size_type size_type;
typedef typename _Base::hasher hasher;
typedef typename _Base::key_equal key_equal;
typedef typename _Base::allocator_type allocator_type;
typedef typename _Base::key_type key_type;
typedef typename _Base::value_type value_type;
typedef typename _Base::difference_type difference_type;
typedef typename _Base::reference reference;
typedef typename _Base::const_reference const_reference;
typedef typename _Base::insert_return_type insert_return_type;
typedef typename _Base::iterator iterator;
typedef typename _Base::const_iterator const_iterator;
explicit
unordered_set(size_type __n = 10,
const hasher& __hf = hasher(),
const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
: _Base(__n, __hf, __eql, __a)
{
__profcxx_hashtable_construct(this, _Base::bucket_count());
__profcxx_hashtable_construct2(this);
}
template<typename _InputIterator>
unordered_set(_InputIterator __f, _InputIterator __l,
size_type __n = 10,
const hasher& __hf = hasher(),
const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
: _Base(__f, __l, __n, __hf, __eql, __a)
{
__profcxx_hashtable_construct(this, _Base::bucket_count());
__profcxx_hashtable_construct2(this);
}
unordered_set(const _Base& __x)
: _Base(__x)
{
__profcxx_hashtable_construct(this, _Base::bucket_count());
__profcxx_hashtable_construct2(this);
}
unordered_set(unordered_set&& __x)
: _Base(std::forward<_Base>(__x))
{
__profcxx_hashtable_construct(this, _Base::bucket_count());
__profcxx_hashtable_construct2(this);
}
unordered_set(initializer_list<value_type> __l,
size_type __n = 10,
const hasher& __hf = hasher(),
const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
: _Base(__l, __n, __hf, __eql, __a) { }
unordered_set&
operator=(const unordered_set& __x)
{
*static_cast<_Base*>(this) = __x;
return *this;
}
unordered_set&
operator=(unordered_set&& __x)
{
// NB: DR 675.
this->clear();
this->swap(__x);
return *this;
}
unordered_set&
operator=(initializer_list<value_type> __l)
{
this->clear();
this->insert(__l);
return *this;
}
~unordered_set()
{
__profcxx_hashtable_destruct(this, _Base::bucket_count(),
_Base::size());
_M_profile_destruct();
}
void
swap(unordered_set& __x)
{
_Base::swap(__x);
}
void
clear()
{
__profcxx_hashtable_destruct(this, _Base::bucket_count(),
_Base::size());
_M_profile_destruct();
_Base::clear();
}
void
insert(std::initializer_list<value_type> __l)
{
size_type __old_size = _Base::bucket_count();
_Base::insert(__l);
_M_profile_resize(__old_size, _Base::bucket_count());
}
insert_return_type insert(const value_type& __obj)
{
size_type __old_size = _Base::bucket_count();
insert_return_type __res = _Base::insert(__obj);
_M_profile_resize(__old_size, _Base::bucket_count());
return __res;
}
iterator
insert(iterator __iter, const value_type& __v)
{
size_type __old_size = _Base::bucket_count();
iterator res = _Base::insert(__iter, __v);
_M_profile_resize(__old_size, _Base::bucket_count());
return res;
}
const_iterator
insert(const_iterator __iter, const value_type& __v)
{
size_type __old_size = _Base::bucket_count();
const_iterator res =_Base::insert(__iter, __v);
_M_profile_resize(__old_size, _Base::bucket_count());
return res;
}
template<typename _InputIter>
void
insert(_InputIter __first, _InputIter __last)
{
size_type __old_size = _Base::bucket_count();
_Base::insert(__first, __last);
_M_profile_resize(__old_size, _Base::bucket_count());
}
void
insert(const value_type* __first, const value_type* __last)
{
size_type __old_size = _Base::bucket_count();
_Base::insert(__first, __last);
_M_profile_resize(__old_size, _Base::bucket_count());
}
void rehash(size_type __n)
{
size_type __old_size = _Base::bucket_count();
_Base::rehash(__n);
_M_profile_resize(__old_size, _Base::bucket_count());
}
private:
_Base&
_M_base() { return *this; }
const _Base&
_M_base() const { return *this; }
void _M_profile_resize(size_type __old_size, size_type __new_size)
{
if (__old_size != __new_size)
{
__profcxx_hashtable_resize(this, __old_size, __new_size);
}
}
void _M_profile_destruct()
{
size_type __hops = 0, __lc = 0, __chain = 0;
for (iterator it = _M_base().begin(); it != _M_base().end(); it++)
{
while (it._M_cur_node->_M_next) {
__chain++;
it++;
}
if (__chain) {
__chain++;
__lc = __lc > __chain ? __lc : __chain;
__hops += __chain * (__chain - 1) / 2;
__chain = 0;
}
}
__profcxx_hashtable_destruct2(this, __lc, _Base::size(), __hops);
}
};
template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
inline void
swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
{ __x.swap(__y); }
#undef _GLIBCXX_BASE
#undef _GLIBCXX_STD_BASE
#define _GLIBCXX_STD_BASE _GLIBCXX_STD_PR::_GLIBCXX_BASE
#define _GLIBCXX_BASE unordered_multiset<_Value, _Hash, _Pred, _Alloc>
/** @brief Unordered_multiset wrapper with performance instrumentation. */
template<typename _Value,
typename _Hash = std::hash<_Value>,
typename _Pred = std::equal_to<_Value>,
typename _Alloc = std::allocator<_Value> >
class unordered_multiset
: public _GLIBCXX_STD_BASE
{
typedef typename _GLIBCXX_STD_BASE _Base;
public:
typedef typename _Base::size_type size_type;
typedef typename _Base::hasher hasher;
typedef typename _Base::key_equal key_equal;
typedef typename _Base::allocator_type allocator_type;
typedef typename _Base::key_type key_type;
typedef typename _Base::value_type value_type;
typedef typename _Base::difference_type difference_type;
typedef typename _Base::reference reference;
typedef typename _Base::const_reference const_reference;
typedef typename _Base::insert_return_type insert_return_type;
typedef typename _Base::iterator iterator;
typedef typename _Base::const_iterator const_iterator;
explicit
unordered_multiset(size_type __n = 10,
const hasher& __hf = hasher(),
const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
: _Base(__n, __hf, __eql, __a)
{
__profcxx_hashtable_construct(this, _Base::bucket_count());
}
template<typename _InputIterator>
unordered_multiset(_InputIterator __f, _InputIterator __l,
size_type __n = 10,
const hasher& __hf = hasher(),
const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
: _Base(__f, __l, __n, __hf, __eql, __a)
{
__profcxx_hashtable_construct(this, _Base::bucket_count());
}
unordered_multiset(const _Base& __x)
: _Base(__x)
{
__profcxx_hashtable_construct(this, _Base::bucket_count());
}
unordered_multiset(unordered_multiset&& __x)
: _Base(std::forward<_Base>(__x))
{
__profcxx_hashtable_construct(this, _Base::bucket_count());
}
unordered_multiset(initializer_list<value_type> __l,
size_type __n = 10,
const hasher& __hf = hasher(),
const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
: _Base(__l, __n, __hf, __eql, __a) { }
unordered_multiset&
operator=(const unordered_multiset& __x)
{
*static_cast<_Base*>(this) = __x;
return *this;
}
unordered_multiset&
operator=(unordered_multiset&& __x)
{
// NB: DR 675.
this->clear();
this->swap(__x);
return *this;
}
unordered_multiset&
operator=(initializer_list<value_type> __l)
{
this->clear();
this->insert(__l);
return *this;
}
~unordered_multiset()
{
__profcxx_hashtable_destruct(this, _Base::bucket_count(),
_Base::size());
_M_profile_destruct();
}
void
swap(unordered_multiset& __x)
{
_Base::swap(__x);
}
void
clear()
{
__profcxx_hashtable_destruct(this, _Base::bucket_count(),
_Base::size());
_M_profile_destruct();
_Base::clear();
}
void
insert(std::initializer_list<value_type> __l)
{
size_type __old_size = _Base::bucket_count();
_Base::insert(__l);
_M_profile_resize(__old_size, _Base::bucket_count());
}
insert_return_type insert(const value_type& __obj)
{
size_type __old_size = _Base::bucket_count();
insert_return_type __res = _Base::insert(__obj);
_M_profile_resize(__old_size, _Base::bucket_count());
return __res;
}
iterator
insert(iterator __iter, const value_type& __v)
{
size_type __old_size = _Base::bucket_count();
iterator res = _Base::insert(__iter, __v);
_M_profile_resize(__old_size, _Base::bucket_count());
return res;
}
const_iterator
insert(const_iterator __iter, const value_type& __v)
{
size_type __old_size = _Base::bucket_count();
const_iterator res =_Base::insert(__iter, __v);
_M_profile_resize(__old_size, _Base::bucket_count());
return res;
}
template<typename _InputIter>
void
insert(_InputIter __first, _InputIter __last)
{
size_type __old_size = _Base::bucket_count();
_Base::insert(__first, __last);
_M_profile_resize(__old_size, _Base::bucket_count());
}
void
insert(const value_type* __first, const value_type* __last)
{
size_type __old_size = _Base::bucket_count();
_Base::insert(__first, __last);
_M_profile_resize(__old_size, _Base::bucket_count());
}
void rehash(size_type __n)
{
size_type __old_size = _Base::bucket_count();
_Base::rehash(__n);
_M_profile_resize(__old_size, _Base::bucket_count());
}
private:
_Base&
_M_base() { return *this; }
const _Base&
_M_base() const { return *this; }
void _M_profile_resize(size_type __old_size, size_type __new_size)
{
if (__old_size != __new_size)
{
__profcxx_hashtable_resize(this, __old_size, __new_size);
}
}
void _M_profile_destruct()
{
size_type __hops = 0, __lc = 0, __chain = 0;
for (iterator it = _M_base().begin(); it != _M_base().end(); it++)
{
while (it._M_cur_node->_M_next) {
__chain++;
it++;
}
if (__chain) {
__chain++;
__lc = __lc > __chain ? __lc : __chain;
__hops += __chain * (__chain - 1) / 2;
__chain = 0;
}
}
__profcxx_hashtable_destruct2(this, __lc, _Base::size(), __hops);
}
};
template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
inline void
swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
{ __x.swap(__y); }
} // namespace __profile
} // namespace std
#undef _GLIBCXX_BASE
#undef _GLIBCXX_STD_BASE
#endif

View file

@ -0,0 +1,369 @@
// Profiling vector implementation -*- 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, 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.
/** @file profile/vector
* This file is a GNU profile extension to the Standard C++ Library.
*/
#ifndef _GLIBCXX_PROFILE_VECTOR
#define _GLIBCXX_PROFILE_VECTOR 1
#include <vector>
#include <utility>
#include <profile/base.h>
namespace std
{
namespace __profile
{
/** @brief Vector wrapper with performance instrumentation. */
template<typename _Tp,
typename _Allocator = std::allocator<_Tp> >
class vector
: public _GLIBCXX_STD_PR::vector<_Tp, _Allocator>
{
typedef _GLIBCXX_STD_PR::vector<_Tp, _Allocator> _Base;
public:
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 typename _Base::size_type size_type;
typedef typename _Base::difference_type difference_type;
typedef _Tp value_type;
typedef _Allocator allocator_type;
typedef typename _Base::pointer pointer;
typedef typename _Base::const_pointer const_pointer;
_Base&
_M_base() { return *this; }
const _Base&
_M_base() const { return *this; }
// 23.2.4.1 construct/copy/destroy:
explicit vector(const _Allocator& __a = _Allocator())
: _Base(__a)
{
__profcxx_vector_construct(this, this->capacity());
__profcxx_vector_construct2(this);
}
explicit vector(size_type __n, const _Tp& __value = _Tp(),
const _Allocator& __a = _Allocator())
: _Base(__n, __value, __a)
{
__profcxx_vector_construct(this, this->capacity());
__profcxx_vector_construct2(this);
}
template<class _InputIterator>
vector(_InputIterator __first, _InputIterator __last,
const _Allocator& __a = _Allocator())
: _Base(__first, __last, __a)
{
__profcxx_vector_construct(this, this->capacity());
__profcxx_vector_construct2(this);
}
vector(const vector& __x)
: _Base(__x)
{
__profcxx_vector_construct(this, this->capacity());
__profcxx_vector_construct2(this);
}
/// Construction from a release-mode vector
vector(const _Base& __x)
: _Base(__x)
{
__profcxx_vector_construct(this, this->capacity());
__profcxx_vector_construct2(this);
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
vector(vector&& __x)
: _Base(std::forward<vector>(__x))
{
__profcxx_vector_construct(this, this->capacity());
__profcxx_vector_construct2(this);
}
vector(initializer_list<value_type> __l,
const allocator_type& __a = allocator_type())
: _Base(__l, __a) { }
#endif
~vector() {
__profcxx_vector_destruct(this, this->capacity(), this->size());
__profcxx_vector_destruct2(this);
}
vector&
operator=(const vector& __x)
{
static_cast<_Base&>(*this) = __x;
return *this;
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
vector&
operator=(vector&& __x)
{
// NB: DR 675.
this->clear();
this->swap(__x);
return *this;
}
vector&
operator=(initializer_list<value_type> __l)
{
static_cast<_Base&>(*this) = __l;
return *this;
}
#endif
using _Base::assign;
using _Base::get_allocator;
// 23.2.4.2 capacity:
using _Base::size;
using _Base::max_size;
void
resize(size_type __sz, _Tp __c = _Tp())
{
__profcxx_vector_invalid_operator(this);
_M_profile_resize(this, this->capacity(), __sz);
_Base::resize(__sz, __c);
}
using _Base::empty;
// element access:
reference
operator[](size_type __n)
{
__profcxx_vector_invalid_operator(this);
return _M_base()[__n];
}
const_reference
operator[](size_type __n) const
{
__profcxx_vector_invalid_operator(this);
return _M_base()[__n];
}
using _Base::at;
reference
front()
{
return _Base::front();
}
const_reference
front() const
{
return _Base::front();
}
reference
back()
{
return _Base::back();
}
const_reference
back() const
{
return _Base::back();
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 464. Suggestion for new member functions in standard containers.
using _Base::data;
// 23.2.4.3 modifiers:
void
push_back(const _Tp& __x)
{
size_type __old_size = this->capacity();
_Base::push_back(__x);
_M_profile_resize(this, __old_size, this->capacity());
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
void
push_back(_Tp&& __x)
{
size_type __old_size = this->capacity();
_Base::push_back(__x);
_M_profile_resize(this, __old_size, this->capacity());
}
#endif
iterator
insert(iterator __position, const _Tp& __x)
{
__profcxx_vector_insert(this, __position-_Base::begin(), this->size());
size_type __old_size = this->capacity();
typename _Base::iterator __res = _Base::insert(__position,__x);
_M_profile_resize(this, __old_size, this->capacity());
return __res;
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
iterator
insert(iterator __position, _Tp&& __x)
{
__profcxx_vector_insert(this, __position-_Base::begin(), this->size());
size_type __old_size = this->capacity();
typename _Base::iterator __res = _Base::insert(__position,__x);
_M_profile_resize(this, __old_size, this->capacity());
return __res;
}
void
insert(iterator __position, initializer_list<value_type> __l)
{ this->insert(__position, __l.begin(), __l.end()); }
#endif
void
swap(vector& __x)
{
_Base::swap(__x);
}
void
insert(iterator __position, size_type __n, const _Tp& __x)
{
__profcxx_vector_insert(this, __position-_Base::begin(), this->size());
size_type __old_size = this->capacity();
_Base::insert(__position, __n, __x);
_M_profile_resize(this, __old_size, this->capacity());
}
template<class _InputIterator>
void
insert(iterator __position,
_InputIterator __first, _InputIterator __last)
{
__profcxx_vector_insert(this, __position-_Base::begin(), this->size());
size_type __old_size = this->capacity();
_Base::insert(__position, __first, __last);
_M_profile_resize(this, __old_size, this->capacity());
}
void
clear()
{
__profcxx_vector_destruct(this, this->capacity(), this->size());
__profcxx_vector_destruct2(this);
_Base::clear();
}
// iterators:
iterator
begin()
{
return _Base::begin();
}
const_iterator
begin() const
{
return _Base::begin();
}
private:
void _M_profile_resize(void* obj, size_type __old_size,
size_type __new_size)
{
if (__old_size < __new_size) {
__profcxx_vector_resize(this, this->size(), __new_size);
__profcxx_vector_resize2(this, this->size(), __new_size);
}
}
};
template<typename _Tp, typename _Alloc>
inline bool
operator==(const vector<_Tp, _Alloc>& __lhs,
const vector<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() == __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline bool
operator!=(const vector<_Tp, _Alloc>& __lhs,
const vector<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() != __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline bool
operator<(const vector<_Tp, _Alloc>& __lhs,
const vector<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() < __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline bool
operator<=(const vector<_Tp, _Alloc>& __lhs,
const vector<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() <= __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline bool
operator>=(const vector<_Tp, _Alloc>& __lhs,
const vector<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() >= __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline bool
operator>(const vector<_Tp, _Alloc>& __lhs,
const vector<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() > __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline void
swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
{ __lhs.swap(__rhs); }
} // namespace __profile
using _GLIBCXX_STD_D::_S_word_bit;
} // namespace std
#endif

View file

@ -1393,4 +1393,8 @@ _GLIBCXX_END_NESTED_NAMESPACE
# include <debug/bitset>
#endif
#ifdef _GLIBCXX_PROFILE
# include <profile/bitset>
#endif
#endif /* _GLIBCXX_BITSET */

View file

@ -72,4 +72,8 @@
# include <debug/deque>
#endif
#ifdef _GLIBCXX_PROFILE
# include <profile/deque>
#endif
#endif /* _GLIBCXX_DEQUE */

View file

@ -70,5 +70,9 @@
# include <debug/list>
#endif
#ifdef _GLIBCXX_PROFILE
# include <profile/list>
#endif
#endif /* _GLIBCXX_LIST */

View file

@ -65,4 +65,8 @@
# include <debug/map>
#endif
#ifdef _GLIBCXX_PROFILE
# include <profile/map>
#endif
#endif /* _GLIBCXX_MAP */

View file

@ -65,4 +65,8 @@
# include <debug/set>
#endif
#ifdef _GLIBCXX_PROFILE
# include <profile/set>
#endif
#endif /* _GLIBCXX_SET */

View file

@ -53,7 +53,7 @@
# include <tr1_impl/unordered_map>
#else
# define _GLIBCXX_INCLUDE_AS_CXX0X
#if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PARALLEL)
#if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PARALLEL) || defined(_GLIBCXX_PROFILE)
# define _GLIBCXX_BEGIN_NAMESPACE_TR1 namespace _GLIBCXX_STD_D {
# define _GLIBCXX_END_NAMESPACE_TR1 }
# define _GLIBCXX_TR1 _GLIBCXX_STD_D
@ -73,6 +73,10 @@
# include <debug/unordered_map>
#endif
#ifdef _GLIBCXX_PROFILE
# include <profile/unordered_map>
#endif
#endif // __GXX_EXPERIMENTAL_CXX0X__
#endif // _GLIBCXX_UNORDERED_MAP

View file

@ -53,7 +53,7 @@
# include <tr1_impl/unordered_set>
#else
# define _GLIBCXX_INCLUDE_AS_CXX0X
#if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PARALLEL)
#if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PARALLEL) || defined(_GLIBCXX_PROFILE)
# define _GLIBCXX_BEGIN_NAMESPACE_TR1 namespace _GLIBCXX_STD_D {
# define _GLIBCXX_END_NAMESPACE_TR1 }
# define _GLIBCXX_TR1 _GLIBCXX_STD_D
@ -73,6 +73,9 @@
# include <debug/unordered_set>
#endif
#ifdef _GLIBCXX_PROFILE
# include <profile/unordered_set>
#endif
#endif // __GXX_EXPERIMENTAL_CXX0X__
#endif // _GLIBCXX_UNORDERED_SET

View file

@ -34,7 +34,7 @@
* 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.
ded "as is" without express or implied warranty.
*
*
* Copyright (c) 1996
@ -73,5 +73,9 @@
# include <debug/vector>
#endif
#ifdef _GLIBCXX_PROFILE
# include <profile/vector>
#endif
#endif /* _GLIBCXX_VECTOR */

View file

@ -409,6 +409,9 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
_M_erase_node(_Node*, _Node**);
public:
// Expose insert_return_type for profiling mode.
typedef _Insert_Return_Type insert_return_type;
// Insert and erase
_Insert_Return_Type
insert(const value_type& __v)

View file

@ -38,26 +38,26 @@ test01()
a.resize(98);
a.resize(99);
a.resize(100);
#ifndef _GLIBCXX_DEBUG
#if ! defined _GLIBCXX_DEBUG && ! defined _GLIBCXX_PROFILE
VERIFY( copycounter::copycount == 100 );
#else
VERIFY( copycounter::copycount == 100 + 4 );
#endif
a.resize(99);
a.resize(0);
#ifndef _GLIBCXX_DEBUG
#if ! defined _GLIBCXX_DEBUG && ! defined _GLIBCXX_PROFILE
VERIFY( copycounter::copycount == 100 );
#else
VERIFY( copycounter::copycount == 100 + 6 );
#endif
a.resize(100);
#ifndef _GLIBCXX_DEBUG
#if ! defined _GLIBCXX_DEBUG && ! defined _GLIBCXX_PROFILE
VERIFY( copycounter::copycount == 200 );
#else
VERIFY( copycounter::copycount == 200 + 7 );
#endif
a.clear();
#ifndef _GLIBCXX_DEBUG
#if ! defined _GLIBCXX_DEBUG && ! defined _GLIBCXX_PROFILE
VERIFY( copycounter::copycount == 200 );
#else
VERIFY( copycounter::copycount == 200 + 7 );

View file

@ -28,7 +28,7 @@ void test01()
typedef std::list<int> list_type;
list_type l;
#ifndef _GLIBCXX_DEBUG
#if ! defined _GLIBCXX_DEBUG && ! defined _GLIBCXX_PROFILE
using std::_List_node;
#else
using std::_GLIBCXX_STD_D::_List_node;

View file

@ -0,0 +1,22 @@
// { dg-options "-Wno-deprecated" }
/* testing the gcc instrumented */
#include <ext/hash_map>
using namespace std;
using __gnu_cxx::hash_map;
int main()
{
hash_map <int, int> *tmp;
for (int j=1; j<=10; j++)
{
tmp = new hash_map<int, int>;
// Insert more than default item
for (int i=0; i<10000*j; i++) {
(*tmp)[i]= i;
}
delete tmp;
}
}

View file

@ -0,0 +1,47 @@
// { dg-options "-std=gnu++0x" }
/* testing the gcc instrumented */
#include <unordered_map>
#include <unordered_set>
using std::unordered_map;
using std::unordered_set;
void test_unordered_set()
{
// Test for unordered set
unordered_set <int> *tmp2;
tmp2 = new unordered_set<int>;
tmp2->insert(1);
delete tmp2;
}
void test_unordered_map()
{
unordered_map <int, int> *tmp;
for (int i=0; i<20; i++)
{
tmp = new unordered_map<int, int>(i+2);
// Insert more than default item
for (int j=0; j<10000; j++) {
(*tmp)[j]= j;
}
delete tmp;
}
tmp = new unordered_map<int, int>;
// Insert more than default item
for (int i=0; i<150000; i++) {
// (*tmp)[i] = i;
(*tmp).insert(unordered_map<int, int>::value_type(i, i));
}
(*tmp).erase(1);
delete tmp;
}
int main()
{
test_unordered_set();
test_unordered_map();
}

View file

@ -0,0 +1,18 @@
// Test vector: performance difference 25% (0.444s vs 0.539s)
// Advice: set tmp as 10000
#include <vector>
using std::vector;
int main()
{
vector <int> tmp;
for (int j=0; j<2000; j++)
// Insert more than default item
for (int i=0; i<10000; i++) {
tmp.push_back(i);
}
}

View file

@ -41,26 +41,26 @@ test01()
a.resize(98);
a.resize(99);
a.resize(100);
#ifndef _GLIBCXX_DEBUG
#if !defined(_GLIBCXX_DEBUG) && !defined(_GLIBCXX_PROFILE)
VERIFY( copycounter::copycount == 100 + 1 );
#else
VERIFY( copycounter::copycount == 100 + 1 + 4 );
#endif
a.resize(99);
a.resize(0);
#ifndef _GLIBCXX_DEBUG
#if !defined(_GLIBCXX_DEBUG) && !defined(_GLIBCXX_PROFILE)
VERIFY( copycounter::copycount == 100 + 1 );
#else
VERIFY( copycounter::copycount == 100 + 1 + 6 );
#endif
a.resize(100);
#ifndef _GLIBCXX_DEBUG
#if !defined(_GLIBCXX_DEBUG) && !defined(_GLIBCXX_PROFILE)
VERIFY( copycounter::copycount == 200 + 2 );
#else
VERIFY( copycounter::copycount == 200 + 2 + 7 );
#endif
a.clear();
#ifndef _GLIBCXX_DEBUG
#if !defined(_GLIBCXX_DEBUG) && !defined(_GLIBCXX_PROFILE)
VERIFY( copycounter::copycount == 200 + 2 );
#else
VERIFY( copycounter::copycount == 200 + 2 + 7 );

View file

@ -196,6 +196,9 @@ libgomp_flags=-B${glibcxx_builddir}/../libgomp \
atomic_flags=$(ATOMIC_FLAGS)
parallel_flags="unix/-D_GLIBCXX_PARALLEL/-fopenmp"
# Runs the testsuite in profile mode.
profile_flags = "unix/-D_GLIBCXX_PROFILE"
check-parallel: site.exp
-@(if test ! -d $${libgomp_dir}; then \
echo "Testing parallel mode failed as libgomp not present."; \
@ -214,8 +217,17 @@ check-performance-parallel: testsuite_files_performance ${performance_script}
CXXFLAGS="-D_GLIBCXX_PARALLEL -fopenmp $(atomic_flags) $(libgomp_flags)"; export CXXFLAGS; \
${check_performance_script} ${glibcxx_srcdir} ${glibcxx_builddir})
check-profile: site.exp
-@(outputdir=profile; export outputdir; \
if test ! -d $${outputdir}; then \
mkdir $${outputdir}; \
fi; \
srcdir=`$(am__cd) $(srcdir) && pwd`; export srcdir; \
EXPECT=$(EXPECT); export EXPECT; \
$(MAKE) CXXFLAGS="$(atomic_flags) " RUNTESTFLAGS="$(RUNTESTFLAGS) conformance.exp --outdir $${outputdir} --objdir $${outputdir} --target_board=$(profile_flags)" check-DEJAGNU; )
.PHONY: baseline_symbols new-abi-baseline \
check-abi check-compile check-performance check-parallel
check-abi check-compile check-performance check-parallel check-profile
# By adding these files here, automake will remove them for 'make clean'
CLEANFILES = *.txt *.tst *.exe core* filebuf_* tmp* ostream_* *.log *.sum \
@ -224,4 +236,4 @@ CLEANFILES = *.txt *.tst *.exe core* filebuf_* tmp* ostream_* *.log *.sum \
# To remove directories.
clean-local:
rm -rf parallel
rm -rf parallel profile

View file

@ -299,6 +299,9 @@ libgomp_flags = -B${glibcxx_builddir}/../libgomp \
atomic_flags = $(ATOMIC_FLAGS)
parallel_flags = "unix/-D_GLIBCXX_PARALLEL/-fopenmp"
# Runs the testsuite in profile
profile_flags = "unix/-D_GLIBCXX_PROFILE"
# By adding these files here, automake will remove them for 'make clean'
CLEANFILES = *.txt *.tst *.exe core* filebuf_* tmp* ostream_* *.log *.sum \
testsuite_* site.exp abi_check baseline_symbols *TEST* *.dat \
@ -642,12 +645,21 @@ check-performance-parallel: testsuite_files_performance ${performance_script}
CXXFLAGS="-D_GLIBCXX_PARALLEL -fopenmp $(atomic_flags) $(libgomp_flags)"; export CXXFLAGS; \
${check_performance_script} ${glibcxx_srcdir} ${glibcxx_builddir})
check-profile: site.exp
-@(outputdir=profile; export outputdir; \
if test ! -d $${outputdir}; then \
mkdir $${outputdir}; \
fi; \
srcdir=`$(am__cd) $(srcdir) && pwd`; export srcdir; \
EXPECT=$(EXPECT); export EXPECT; \
$(MAKE) CXXFLAGS="$(atomic_flags)" RUNTESTFLAGS="$(RUNTESTFLAGS) conformance.exp --outdir $${outputdir} --objdir $${outputdir} --target_board=$(profile_flags)" check-DEJAGNU; )
.PHONY: baseline_symbols new-abi-baseline \
check-abi check-compile check-performance check-parallel
check-abi check-compile check-performance check-parallel check-profile
# To remove directories.
clean-local:
rm -rf parallel
rm -rf parallel profile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.

View file

@ -0,0 +1,50 @@
// { dg-options "-std=gnu++0x -O0 -D_GLIBCXX_PROFILE" }
// { dg-do compile }
// -*- C++ -*-
// Copyright (C) 2006, 2007, 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 3, 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 COPYING3. If not see
// <http://www.gnu.org/licenses/>.
#include <map>
#include <vector>
#include <unordered_map>
using std::map;
using std::vector;
using std::unordered_map;
struct dumb_hash {
size_t operator()(int x) const {return 0;}
size_t operator()(int x, int y) const {return x == y;}
};
int main() {
map<int, int> m_to_umap;
vector<int> v_to_list;
unordered_map<int, int> um_too_small;
unordered_map<int, int> um_too_large(1000000);
unordered_map<int, int, dumb_hash, dumb_hash> um_dumb_hash;
for (int i = 0; i < 10000; ++i) {
m_to_umap[i] = i;
v_to_list.insert(v_to_list.begin(), i);
um_too_small[i] = i;
um_too_small[i] = i;
um_dumb_hash[i] = i;
}
}

View file

@ -0,0 +1,65 @@
// -*- C++ -*-
// Copyright (C) 2006, 2007, 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 3, 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 COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-options "-D_GLIBCXX_PROFILE" }
// { dg-do compile }
#include <stdio.h>
#include <malloc.h>
#include <vector>
using std::vector;
static void my_init_hook (void);
static void *my_malloc_hook (size_t, const void *);
typedef void* (*malloc_hook) (size_t, const void *);
malloc_hook old_malloc_hook;
void (*__malloc_initialize_hook) (void) = my_init_hook;
static void
my_init_hook (void)
{
old_malloc_hook = __malloc_hook;
__malloc_hook = my_malloc_hook;
}
static void *
my_malloc_hook (size_t size, const void *caller)
{
void *result;
__malloc_hook = old_malloc_hook;
result = malloc (size);
old_malloc_hook = __malloc_hook;
// With _GLIBCXX_PROFILE, the instrumentation of the vector constructor
// will call back into malloc.
vector<int> v;
__malloc_hook = my_malloc_hook;
return result;
}
int main() {
int* test = (int*) malloc(sizeof(int));
*test = 1;
return *test;
}

View file

@ -0,0 +1,26 @@
// { dg-options "-D_GLIBCXX_DEBUG -D_GLIBCXX_PROFILE" }
// { dg-do compile }
// -*- C++ -*-
// Copyright (C) 2006, 2007, 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 3, 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 COPYING3. If not see
// <http://www.gnu.org/licenses/>.
#include <vector>
// { dg-error "Cannot use -D_GLIBCXX_PROFILE with " "" { target *-*-* } 166 }
// { dg-excess-errors "In file included from" }