Commit b0af13ea by Paolo Carlini Committed by Paolo Carlini

profiler_list_to_slist.h: Fix formatting, other minor stylistic changes.

2010-06-22  Paolo Carlini  <paolo.carlini@oracle.com>

	* include/profile/impl/profiler_list_to_slist.h: Fix formatting,
	other minor stylistic changes.
	* include/profile/impl/profiler_container_size.h: Likewise.
	* include/profile/impl/profiler_vector_size.h: Likewise.
	* include/profile/impl/profiler_hash_func.h: Likewise.
	* include/profile/impl/profiler_trace.h: Likewise.
	* include/profile/impl/profiler_list_to_vector.h: Likewise.
	* include/profile/impl/profiler_vector_to_list.h: Likewise.
	* include/profile/impl/profiler_state.h: Likewise.
	* include/profile/impl/profiler_map_to_unordered_map.h: Likewise.
	* include/profile/impl/profiler_hashtable_size.h: Likewise.
	* include/profile/impl/profiler_node.h: Likewise.

From-SVN: r161236
parent b2e894b5
2010-06-22 Paolo Carlini <paolo.carlini@oracle.com>
* include/profile/impl/profiler_list_to_slist.h: Fix formatting,
other minor stylistic changes.
* include/profile/impl/profiler_container_size.h: Likewise.
* include/profile/impl/profiler_vector_size.h: Likewise.
* include/profile/impl/profiler_hash_func.h: Likewise.
* include/profile/impl/profiler_trace.h: Likewise.
* include/profile/impl/profiler_list_to_vector.h: Likewise.
* include/profile/impl/profiler_vector_to_list.h: Likewise.
* include/profile/impl/profiler_state.h: Likewise.
* include/profile/impl/profiler_map_to_unordered_map.h: Likewise.
* include/profile/impl/profiler_hashtable_size.h: Likewise.
* include/profile/impl/profiler_node.h: Likewise.
2010-06-22 Matthias Klose <doko@ubuntu.com> 2010-06-22 Matthias Klose <doko@ubuntu.com>
* python/libstdcxx/v6/printers.py: Don't use string exceptions. * python/libstdcxx/v6/printers.py: Don't use string exceptions.
......
...@@ -55,188 +55,178 @@ ...@@ -55,188 +55,178 @@
namespace __gnu_profile namespace __gnu_profile
{ {
/** @brief A container size instrumentation line in the object table. */
/** @brief A container size instrumentation line in the object table. */ class __container_size_info
class __container_size_info: public __object_info_base : public __object_info_base
{ {
public: public:
__container_size_info(); __container_size_info()
__container_size_info(const __container_size_info& __o); : _M_init(0), _M_max(0), _M_min(0), _M_total(0), _M_item_min(0),
__container_size_info(__stack_t __stack, size_t __num); _M_item_max(0), _M_item_total(0), _M_count(0), _M_resize(0), _M_cost(0)
virtual ~__container_size_info() {} { }
void __write(FILE* f) const; __container_size_info(const __container_size_info& __o)
float __magnitude() const { return static_cast<float>(_M_cost); } : __object_info_base(__o), _M_init(__o._M_init), _M_max(__o._M_max),
const char* __advice() const; _M_min(__o._M_min), _M_total(__o._M_total),
_M_item_min(__o._M_item_min), _M_item_max(__o._M_item_max),
void __merge(const __container_size_info& __o); _M_item_total(__o._M_item_total), _M_count(__o._M_count),
// Call if a container is destructed or cleaned. _M_resize(__o._M_resize), _M_cost(__o._M_cost)
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; } __container_size_info(__stack_t __stack, size_t __num)
// Call if container is resized. : __object_info_base(__stack), _M_init(__num), _M_max(__num),
void __resize(size_t __from, size_t __to); _M_min(0), _M_total(0), _M_item_min(0), _M_item_max(0),
_M_item_total(0), _M_count(0), _M_resize(0), _M_cost(0)
private: { }
size_t _M_init;
size_t _M_max; // range of # buckets virtual ~__container_size_info() { }
size_t _M_min;
size_t _M_total; void
size_t _M_item_min; // range of # items __write(FILE* __f) const
size_t _M_item_max; {
size_t _M_item_total; fprintf(__f, "%Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu\n",
size_t _M_count; _M_init, _M_count, _M_cost, _M_resize, _M_min, _M_max, _M_total,
size_t _M_resize; _M_item_min, _M_item_max, _M_item_total);
size_t _M_cost; }
};
float
inline const char* __container_size_info::__advice() const __magnitude() const
{ { return static_cast<float>(_M_cost); }
std::stringstream __message;
if (_M_init < _M_item_max) const char*
__message << "change initial container size from " << _M_init __advice() const
<< " to " << _M_item_max; {
std::stringstream __message;
return strdup(__message.str().c_str()); if (_M_init < _M_item_max)
} __message << "change initial container size from " << _M_init
<< " to " << _M_item_max;
inline void __container_size_info::__destruct(size_t __num, size_t __inum) return strdup(__message.str().c_str());
{ }
_M_max = std::max(_M_max, __num);
_M_item_max = std::max(_M_item_max, __inum); void
if (_M_min == 0) { __merge(const __container_size_info& __o)
_M_min = __num; {
_M_item_min = __inum; _M_init = std::max(_M_init, __o._M_init);
} else { _M_max = std::max(_M_max, __o._M_max);
_M_min = std::min(_M_min, __num); _M_item_max = std::max(_M_item_max, __o._M_item_max);
_M_item_min = std::min(_M_item_min, __inum); _M_min = std::min(_M_min, __o._M_min);
} _M_item_min = std::min(_M_item_min, __o._M_item_min);
_M_total += __num; _M_total += __o._M_total;
_M_item_total += __inum; _M_item_total += __o._M_item_total;
_M_count += 1; _M_count += __o._M_count;
} _M_cost += __o._M_cost;
_M_resize += __o._M_resize;
inline void __container_size_info::__resize(size_t __from, size_t __to) }
{
_M_cost += this->__resize_cost(__from, __to); // Call if a container is destructed or cleaned.
_M_resize += 1; void
_M_max = std::max(_M_max, __to); __destruct(size_t __num, size_t __inum)
} {
_M_max = std::max(_M_max, __num);
inline __container_size_info::__container_size_info(__stack_t __stack, _M_item_max = std::max(_M_item_max, __inum);
size_t __num) if (_M_min == 0)
: __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_min = __num;
_M_count(0), _M_resize(0) _M_item_min = __inum;
{ }
_M_init = _M_max = __num; else
_M_item_min = _M_item_max = _M_item_total = _M_total = 0; {
_M_min = 0; _M_min = std::min(_M_min, __num);
_M_count = 0; _M_item_min = std::min(_M_item_min, __inum);
_M_resize = 0; }
} _M_total += __num;
_M_item_total += __inum;
inline void __container_size_info::__merge(const __container_size_info& __o) _M_count += 1;
{ }
_M_init = std::max(_M_init, __o._M_init);
_M_max = std::max(_M_max, __o._M_max); // Estimate the cost of resize/rehash.
_M_item_max = std::max(_M_item_max, __o._M_item_max); float
_M_min = std::min(_M_min, __o._M_min); __resize_cost(size_t __from, size_t)
_M_item_min = std::min(_M_item_min, __o._M_item_min); { return __from; }
_M_total += __o._M_total;
_M_item_total += __o._M_item_total; // Call if container is resized.
_M_count += __o._M_count; void
_M_cost += __o._M_cost; __resize(size_t __from, size_t __to)
_M_resize += __o._M_resize; {
} _M_cost += this->__resize_cost(__from, __to);
_M_resize += 1;
inline __container_size_info::__container_size_info() _M_max = std::max(_M_max, __to);
: _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)
{ private:
} size_t _M_init;
size_t _M_max; // range of # buckets
inline __container_size_info::__container_size_info( size_t _M_min;
const __container_size_info& __o) size_t _M_total;
: __object_info_base(__o) size_t _M_item_min; // range of # items
{ size_t _M_item_max;
_M_init = __o._M_init; size_t _M_item_total;
_M_max = __o._M_max; size_t _M_count;
_M_item_max = __o._M_item_max; size_t _M_resize;
_M_min = __o._M_min; size_t _M_cost;
_M_item_min = __o._M_item_min; };
_M_total = __o._M_total;
_M_item_total = __o._M_item_total;
_M_cost = __o._M_cost; /** @brief A container size instrumentation line in the stack table. */
_M_count = __o._M_count; class __container_size_stack_info
_M_resize = __o._M_resize; : public __container_size_info
} {
public:
/** @brief A container size instrumentation line in the stack table. */ __container_size_stack_info(const __container_size_info& __o)
class __container_size_stack_info: public __container_size_info : __container_size_info(__o) { }
{ };
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>
/** @brief Container size instrumentation trace producer. */ {
class __trace_container_size public:
: public __trace_base<__container_size_info, __container_size_stack_info> ~__trace_container_size() { }
{
public: __trace_container_size()
~__trace_container_size() {} : __trace_base<__container_size_info, __container_size_stack_info>() { };
__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 a new node at construct with object, callstack and initial size. __insert(const __object_t __obj, __stack_t __stack, size_t __num)
void __insert(const __object_t __obj, __stack_t __stack, size_t __num); { __add_object(__obj, __container_size_info(__stack, __num)); }
// Call at destruction/clean to set container final size.
void __destruct(const void* __obj, size_t __num, size_t __inum); // XXX Undefined?
void __construct(const void* __obj, size_t __inum); void
// Call at resize to set resize/cost information. __construct(const void* __obj, size_t __inum);
void __resize(const void* __obj, int __from, int __to);
}; // Call at destruction/clean to set container final size.
void
inline void __trace_container_size::__insert(const __object_t __obj, __destruct(const void* __obj, size_t __num, size_t __inum)
__stack_t __stack, size_t __num) {
{ if (!__is_on())
__add_object(__obj, __container_size_info(__stack, __num)); return;
}
__object_t __obj_handle = static_cast<__object_t>(__obj);
inline void __container_size_info::__write(FILE* __f) const
{ __container_size_info* __object_info = __get_object_info(__obj_handle);
fprintf(__f, "%Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu\n", if (!__object_info)
_M_init, _M_count, _M_cost, _M_resize, _M_min, _M_max, _M_total, return;
_M_item_min, _M_item_max, _M_item_total);
} __object_info->__destruct(__num, __inum);
__retire_object(__obj_handle);
inline void __trace_container_size::__destruct(const void* __obj, }
size_t __num, size_t __inum)
{ // Call at resize to set resize/cost information.
if (!__is_on()) return; void
__resize(const void* __obj, int __from, int __to)
__object_t __obj_handle = static_cast<__object_t>(__obj); {
if (!__is_on())
__container_size_info* __object_info = __get_object_info(__obj_handle); return;
if (!__object_info)
return; __container_size_info* __object_info = __get_object_info(__obj);
if (!__object_info)
__object_info->__destruct(__num, __inum); return;
__retire_object(__obj_handle);
} __object_info->__resize(__from, __to);
}
inline void __trace_container_size::__resize(const void* __obj, int __from, };
int __to)
{
if (!__is_on()) return;
__container_size_info* __object_info = __get_object_info(__obj);
if (!__object_info)
return;
__object_info->__resize(__from, __to);
}
} // namespace __gnu_profile } // namespace __gnu_profile
#endif /* _GLIBCXX_PROFILE_PROFILER_CONTAINER_SIZE_H */ #endif /* _GLIBCXX_PROFILE_PROFILER_CONTAINER_SIZE_H */
...@@ -52,134 +52,137 @@ ...@@ -52,134 +52,137 @@
namespace __gnu_profile namespace __gnu_profile
{ {
/** @brief A hash performance instrumentation line in the object table. */
/** @brief A hash performance instrumentation line in the object table. */ class __hashfunc_info
class __hashfunc_info: public __object_info_base : public __object_info_base
{ {
public: public:
__hashfunc_info() __hashfunc_info()
:_M_longest_chain(0), _M_accesses(0), _M_hops(0) {} : _M_longest_chain(0), _M_accesses(0), _M_hops(0) { }
__hashfunc_info(const __hashfunc_info& o);
__hashfunc_info(__stack_t __stack) __hashfunc_info(const __hashfunc_info& __o)
: __object_info_base(__stack), : __object_info_base(__o), _M_longest_chain(__o._M_longest_chain),
_M_longest_chain(0), _M_accesses(0), _M_hops(0){} _M_accesses(__o._M_accesses), _M_hops(__o._M_hops) { }
virtual ~__hashfunc_info() {}
__hashfunc_info(__stack_t __stack)
void __merge(const __hashfunc_info& __o); : __object_info_base(__stack),
void __destruct(size_t __chain, size_t __accesses, size_t __hops); _M_longest_chain(0), _M_accesses(0), _M_hops(0){ }
void __write(FILE* __f) const;
float __magnitude() const { return static_cast<float>(_M_hops); } virtual ~__hashfunc_info() {}
const char* __advice() const { return strdup("change hash function"); }
void
private: __merge(const __hashfunc_info& __o)
size_t _M_longest_chain; {
size_t _M_accesses; _M_longest_chain = std::max(_M_longest_chain, __o._M_longest_chain);
size_t _M_hops; _M_accesses += __o._M_accesses;
}; _M_hops += __o._M_hops;
}
inline __hashfunc_info::__hashfunc_info(const __hashfunc_info& __o)
: __object_info_base(__o) void
{ __destruct(size_t __chain, size_t __accesses, size_t __hops)
_M_longest_chain = __o._M_longest_chain; {
_M_accesses = __o._M_accesses; _M_longest_chain = std::max(_M_longest_chain, __chain);
_M_hops = __o._M_hops; _M_accesses += __accesses;
} _M_hops += __hops;
}
inline void __hashfunc_info::__merge(const __hashfunc_info& __o)
{ void
_M_longest_chain = std::max(_M_longest_chain, __o._M_longest_chain); __write(FILE* __f) const
_M_accesses += __o._M_accesses; { fprintf(__f, "%Zu %Zu %Zu\n", _M_hops, _M_accesses, _M_longest_chain); }
_M_hops += __o._M_hops;
} float
__magnitude() const
inline void __hashfunc_info::__destruct(size_t __chain, size_t __accesses, { return static_cast<float>(_M_hops); }
size_t __hops)
{ const char*
_M_longest_chain = std::max(_M_longest_chain, __chain); __advice() const
_M_accesses += __accesses; { return strdup("change hash function"); }
_M_hops += __hops;
} private:
size_t _M_longest_chain;
/** @brief A hash performance instrumentation line in the stack table. */ size_t _M_accesses;
class __hashfunc_stack_info: public __hashfunc_info { size_t _M_hops;
public: };
__hashfunc_stack_info(const __hashfunc_info& __o) : __hashfunc_info(__o) {}
};
/** @brief A hash performance instrumentation line in the stack table. */
/** @brief Hash performance instrumentation producer. */ class __hashfunc_stack_info
class __trace_hash_func : public __hashfunc_info
: public __trace_base<__hashfunc_info, __hashfunc_stack_info> {
{ public:
public: __hashfunc_stack_info(const __hashfunc_info& __o)
__trace_hash_func(); : __hashfunc_info(__o) { }
~__trace_hash_func() {} };
// Insert a new node at construct with object, callstack and initial size.
void __insert(__object_t __obj, __stack_t __stack); /** @brief Hash performance instrumentation producer. */
// Call at destruction/clean to set container final size. class __trace_hash_func
void __destruct(const void* __obj, size_t __chain, : public __trace_base<__hashfunc_info, __hashfunc_stack_info>
size_t __accesses, size_t __hops); {
}; public:
__trace_hash_func()
inline __trace_hash_func::__trace_hash_func()
: __trace_base<__hashfunc_info, __hashfunc_stack_info>() : __trace_base<__hashfunc_info, __hashfunc_stack_info>()
{ { __id = "hash-distr"; }
__id = "hash-distr";
} ~__trace_hash_func() {}
inline void __trace_hash_func::__insert(__object_t __obj, __stack_t __stack) // Insert a new node at construct with object, callstack and initial size.
{ void
__add_object(__obj, __hashfunc_info(__stack)); __insert(__object_t __obj, __stack_t __stack)
} { __add_object(__obj, __hashfunc_info(__stack)); }
inline void __hashfunc_info::__write(FILE* __f) const // Call at destruction/clean to set container final size.
{ void
fprintf(__f, "%Zu %Zu %Zu\n", _M_hops, _M_accesses, _M_longest_chain); __destruct(const void* __obj, size_t __chain,
} size_t __accesses, size_t __hops)
{
inline void __trace_hash_func::__destruct(const void* __obj, size_t __chain, if (!__is_on())
size_t __accesses, size_t __hops) return;
{
if (!__is_on()) return; // First find the item from the live objects and update the informations.
__hashfunc_info* __objs = __get_object_info(__obj);
// First find the item from the live objects and update the informations. if (!__objs)
__hashfunc_info* __objs = __get_object_info(__obj); return;
if (!__objs)
return; __objs->__destruct(__chain, __accesses, __hops);
__retire_object(__obj);
__objs->__destruct(__chain, __accesses, __hops); }
__retire_object(__obj); };
}
inline void __trace_hash_func_init() inline void
{ __trace_hash_func_init()
_GLIBCXX_PROFILE_DATA(_S_hash_func) = new __trace_hash_func(); { _GLIBCXX_PROFILE_DATA(_S_hash_func) = new __trace_hash_func(); }
}
inline void
inline void __trace_hash_func_report(FILE* __f, __trace_hash_func_report(FILE* __f, __warning_vector_t& __warnings)
__warning_vector_t& __warnings) {
{ if (_GLIBCXX_PROFILE_DATA(_S_hash_func))
if (_GLIBCXX_PROFILE_DATA(_S_hash_func)) { {
_GLIBCXX_PROFILE_DATA(_S_hash_func)->__collect_warnings(__warnings); _GLIBCXX_PROFILE_DATA(_S_hash_func)->__collect_warnings(__warnings);
_GLIBCXX_PROFILE_DATA(_S_hash_func)->__write(__f); _GLIBCXX_PROFILE_DATA(_S_hash_func)->__write(__f);
}
} }
}
inline void __trace_hash_func_construct(const void* __obj) inline void
{ __trace_hash_func_construct(const void* __obj)
if (!__profcxx_init()) return; {
if (!__profcxx_init())
return;
_GLIBCXX_PROFILE_DATA(_S_hash_func)->__insert(__obj, __get_stack()); _GLIBCXX_PROFILE_DATA(_S_hash_func)->__insert(__obj, __get_stack());
} }
inline void __trace_hash_func_destruct(const void* __obj, size_t __chain, inline void
size_t __accesses, size_t __hops) __trace_hash_func_destruct(const void* __obj, size_t __chain,
{ size_t __accesses, size_t __hops)
if (!__profcxx_init()) return; {
if (!__profcxx_init())
return;
_GLIBCXX_PROFILE_DATA(_S_hash_func)->__destruct(__obj, __chain, __accesses, _GLIBCXX_PROFILE_DATA(_S_hash_func)->__destruct(__obj, __chain, __accesses,
__hops); __hops);
} }
} // namespace __gnu_profile } // namespace __gnu_profile
#endif /* _GLIBCXX_PROFILE_PROFILER_HASH_FUNC_H */ #endif /* _GLIBCXX_PROFILE_PROFILER_HASH_FUNC_H */
// -*- C++ -*- // -*- C++ -*-
// //
// Copyright (C) 2009 Free Software Foundation, Inc. // Copyright (C) 2009, 2010 Free Software Foundation, Inc.
// //
// This file is part of the GNU ISO C++ Library. This library is free // 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 // software; you can redistribute it and/or modify it under the terms
...@@ -54,54 +54,60 @@ ...@@ -54,54 +54,60 @@
namespace __gnu_profile namespace __gnu_profile
{ {
/** @brief Hashtable size instrumentation trace producer. */
/** @brief Hashtable size instrumentation trace producer. */ class __trace_hashtable_size
class __trace_hashtable_size : public __trace_container_size : public __trace_container_size
{
public:
__trace_hashtable_size() : __trace_container_size()
{ {
__id = "hashtable-size"; public:
} __trace_hashtable_size()
}; : __trace_container_size()
{ __id = "hashtable-size"; }
inline void __trace_hashtable_size_init() };
{
_GLIBCXX_PROFILE_DATA(_S_hashtable_size) = new __trace_hashtable_size(); inline void
} __trace_hashtable_size_init()
{ _GLIBCXX_PROFILE_DATA(_S_hashtable_size) = new __trace_hashtable_size(); }
inline void __trace_hashtable_size_report(FILE* __f,
__warning_vector_t& __warnings) inline void
{ __trace_hashtable_size_report(FILE* __f, __warning_vector_t& __warnings)
if (_GLIBCXX_PROFILE_DATA(_S_hashtable_size)) { {
_GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__collect_warnings(__warnings); if (_GLIBCXX_PROFILE_DATA(_S_hashtable_size))
_GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__write(__f); {
_GLIBCXX_PROFILE_DATA(_S_hashtable_size)->
__collect_warnings(__warnings);
_GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__write(__f);
}
} }
}
inline void __trace_hashtable_size_construct(const void* __obj, size_t __num) inline void
{ __trace_hashtable_size_construct(const void* __obj, size_t __num)
if (!__profcxx_init()) return; {
if (!__profcxx_init())
return;
_GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__insert(__obj, __get_stack(), _GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__insert(__obj, __get_stack(),
__num); __num);
} }
inline void __trace_hashtable_size_destruct(const void* __obj, size_t __num, inline void
size_t __inum) __trace_hashtable_size_destruct(const void* __obj, size_t __num,
{ size_t __inum)
if (!__profcxx_init()) return; {
if (!__profcxx_init())
return;
_GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__destruct(__obj, __num, __inum); _GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__destruct(__obj, __num, __inum);
} }
inline void __trace_hashtable_size_resize(const void* __obj, size_t __from, inline void
size_t __to) __trace_hashtable_size_resize(const void* __obj, size_t __from,
{ size_t __to)
if (!__profcxx_init()) return; {
if (!__profcxx_init())
return;
_GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__resize(__obj, __from, __to); _GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__resize(__obj, __from, __to);
} }
} // namespace __gnu_profile } // namespace __gnu_profile
......
// -*- C++ -*- // -*- C++ -*-
// //
// Copyright (C) 2009 Free Software Foundation, Inc. // Copyright (C) 2009, 2010 Free Software Foundation, Inc.
// //
// This file is part of the GNU ISO C++ Library. This library is free // 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 // software; you can redistribute it and/or modify it under the terms
...@@ -52,131 +52,173 @@ ...@@ -52,131 +52,173 @@
namespace __gnu_profile namespace __gnu_profile
{ {
class __list2slist_info
class __list2slist_info: public __object_info_base : public __object_info_base
{ {
public: public:
__list2slist_info() : _M_rewind(false), _M_operations(0) {} __list2slist_info()
__list2slist_info(__stack_t __stack) : _M_rewind(false), _M_operations(0) { }
: _M_rewind(false), _M_operations(0),__object_info_base(__stack) {}
virtual ~__list2slist_info() {} __list2slist_info(__stack_t __stack)
__list2slist_info(const __list2slist_info& __o) : __object_info_base(__o) : __object_info_base(__stack), _M_rewind(false), _M_operations(0) { }
{ _M_rewind = __o._M_rewind; _M_operations = __o._M_operations; }
// XXX: the magnitude should be multiplied with a constant factor F, virtual ~__list2slist_info() { }
// where F is 1 when the malloc size class of list nodes is different
// from the malloc size class of slist nodes. When they fall into the same __list2slist_info(const __list2slist_info& __o)
// class, the only slist benefit is from having to set fewer links, so : __object_info_base(__o), _M_rewind(__o._M_rewind),
// the factor F should be much smaller, closer to 0 than to 1. _M_operations(__o._M_operations) { }
// This could be implemented by passing the size classes in the config file.
// For now, we always assume F to be 1. // XXX: the magnitude should be multiplied with a constant factor F,
float __magnitude() const // where F is 1 when the malloc size class of list nodes is different
{ if (!_M_rewind) return _M_operations; else return 0; } // from the malloc size class of slist nodes. When they fall into the same
void __merge(const __list2slist_info& __o) {}; // class, the only slist benefit is from having to set fewer links, so
void __write(FILE* __f) const; // the factor F should be much smaller, closer to 0 than to 1.
const char* __advice() const // This could be implemented by passing the size classes in the config
{ return strdup("change std::list to std::forward_list"); } // file. For now, we always assume F to be 1.
void __opr_rewind() { _M_rewind = true; _M_valid = false;}
void __record_operation() { _M_operations++; } float
bool __has_rewind() { return _M_rewind; } __magnitude() const
{
private: if (!_M_rewind)
bool _M_rewind; return _M_operations;
size_t _M_operations; else
}; return 0;
}
class __list2slist_stack_info: public __list2slist_info {
public: void
__list2slist_stack_info(const __list2slist_info& __o) __merge(const __list2slist_info&) { };
: __list2slist_info(__o) {}
}; void
__write(FILE* __f) const
class __trace_list_to_slist { fprintf(__f, "%s\n", _M_rewind ? "invalid" : "valid"); }
: public __trace_base<__list2slist_info, __list2slist_stack_info>
{ const char*
public: __advice() const
~__trace_list_to_slist() {} { return strdup("change std::list to std::forward_list"); }
__trace_list_to_slist()
: __trace_base<__list2slist_info, __list2slist_stack_info>() void
{ __id = "list-to-slist"; } __opr_rewind()
void __opr_rewind(const void* __obj); {
void __record_operation(const void* __obj); _M_rewind = true;
void __insert(const __object_t __obj, __stack_t __stack) _M_valid = false;
{ __add_object(__obj, __list2slist_info(__stack)); } }
void __destruct(const void* __obj);
}; void
__record_operation()
inline void __list2slist_info::__write(FILE* __f) const { _M_operations++; }
{
fprintf(__f, "%s\n", _M_rewind ? "invalid" : "valid"); bool
} __has_rewind()
{ return _M_rewind; }
inline void __trace_list_to_slist::__destruct(const void* __obj)
{ private:
if (!__is_on()) bool _M_rewind;
return; size_t _M_operations;
};
__list2slist_info* __res = __get_object_info(__obj);
if (!__res) class __list2slist_stack_info
return; : public __list2slist_info
{
__retire_object(__obj); public:
} __list2slist_stack_info(const __list2slist_info& __o)
: __list2slist_info(__o) { }
inline void __trace_list_to_slist_init() };
{
_GLIBCXX_PROFILE_DATA(_S_list_to_slist) = new __trace_list_to_slist(); class __trace_list_to_slist
} : public __trace_base<__list2slist_info, __list2slist_stack_info>
{
inline void __trace_list_to_slist_report(FILE* __f, public:
__warning_vector_t& __warnings) ~__trace_list_to_slist() { }
{
if (_GLIBCXX_PROFILE_DATA(_S_list_to_slist)) { __trace_list_to_slist()
_GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__collect_warnings(__warnings); : __trace_base<__list2slist_info, __list2slist_stack_info>()
_GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__write(__f); { __id = "list-to-slist"; }
void
__opr_rewind(const void* __obj)
{
__list2slist_info* __res = __get_object_info(__obj);
if (__res)
__res->__opr_rewind();
}
void
__record_operation(const void* __obj)
{
__list2slist_info* __res = __get_object_info(__obj);
if (__res)
__res->__record_operation();
}
void
__insert(const __object_t __obj, __stack_t __stack)
{ __add_object(__obj, __list2slist_info(__stack)); }
void
__destruct(const void* __obj)
{
if (!__is_on())
return;
__list2slist_info* __res = __get_object_info(__obj);
if (!__res)
return;
__retire_object(__obj);
}
};
inline void
__trace_list_to_slist_init()
{ _GLIBCXX_PROFILE_DATA(_S_list_to_slist) = new __trace_list_to_slist(); }
inline void
__trace_list_to_slist_report(FILE* __f, __warning_vector_t& __warnings)
{
if (_GLIBCXX_PROFILE_DATA(_S_list_to_slist))
{
_GLIBCXX_PROFILE_DATA(_S_list_to_slist)->
__collect_warnings(__warnings);
_GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__write(__f);
}
} }
}
inline void __trace_list_to_slist::__opr_rewind(const void* __obj) inline void
{ __trace_list_to_slist_rewind(const void* __obj)
__list2slist_info* __res = __get_object_info(__obj); {
if (__res) if (!__profcxx_init())
__res->__opr_rewind(); return;
}
inline void __trace_list_to_slist::__record_operation(const void* __obj)
{
__list2slist_info* __res = __get_object_info(__obj);
if (__res)
__res->__record_operation();
}
inline void __trace_list_to_slist_rewind(const void* __obj) _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__opr_rewind(__obj);
{ }
if (!__profcxx_init()) return;
_GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__opr_rewind(__obj);
}
inline void __trace_list_to_slist_operation(const void* __obj) inline void
{ __trace_list_to_slist_operation(const void* __obj)
if (!__profcxx_init()) return; {
if (!__profcxx_init())
return;
_GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__record_operation(__obj); _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__record_operation(__obj);
} }
inline void __trace_list_to_slist_construct(const void* __obj) inline void
{ __trace_list_to_slist_construct(const void* __obj)
if (!__profcxx_init()) return; {
if (!__profcxx_init())
return;
_GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__insert(__obj, __get_stack()); _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__insert(__obj, __get_stack());
} }
inline void __trace_list_to_slist_destruct(const void* __obj) inline void
{ __trace_list_to_slist_destruct(const void* __obj)
if (!__profcxx_init()) return; {
if (!__profcxx_init())
return;
_GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__destruct(__obj); _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__destruct(__obj);
} }
} // namespace __gnu_profile } // namespace __gnu_profile
#endif /* _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H */ #endif /* _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H */
...@@ -54,260 +54,287 @@ ...@@ -54,260 +54,287 @@
namespace __gnu_profile namespace __gnu_profile
{ {
/** @brief A list-to-vector instrumentation line in the object table. */
/** @brief A list-to-vector instrumentation line in the object table. */ class __list2vector_info
class __list2vector_info: public __object_info_base : public __object_info_base
{ {
public: public:
__list2vector_info() __list2vector_info()
:_M_shift_count(0), _M_iterate(0), _M_resize(0), _M_list_cost(0), : _M_shift_count(0), _M_iterate(0), _M_resize(0), _M_list_cost(0),
_M_vector_cost(0), _M_valid(true), _M_max_size(0) {} _M_vector_cost(0), _M_valid(true), _M_max_size(0) { }
__list2vector_info(__stack_t __stack)
: __object_info_base(__stack), _M_shift_count(0), _M_iterate(0), __list2vector_info(__stack_t __stack)
_M_resize(0), _M_list_cost(0), _M_vector_cost(0), _M_valid(true), : __object_info_base(__stack), _M_shift_count(0), _M_iterate(0),
_M_max_size(0) {} _M_resize(0), _M_list_cost(0), _M_vector_cost(0), _M_valid(true),
virtual ~__list2vector_info() {} _M_max_size(0) { }
__list2vector_info(const __list2vector_info& __o);
void __merge(const __list2vector_info& __o); virtual ~__list2vector_info() { }
void __write(FILE* __f) const;
float __magnitude() const { return _M_list_cost - _M_vector_cost; } __list2vector_info(const __list2vector_info& __o)
const char* __advice() const; : __object_info_base(__o), _M_shift_count(__o._M_shift_count),
size_t __shift_count() { return _M_shift_count; } _M_iterate(__o._M_iterate), _M_resize(__o._M_resize),
size_t __iterate() { return _M_iterate; } _M_list_cost(__o._M_list_cost), _M_vector_cost(__o._M_vector_cost),
float __list_cost() { return _M_list_cost; } _M_valid(__o._M_valid), _M_max_size(__o._M_max_size) { }
size_t __resize() { return _M_resize; }
void __set_list_cost(float __lc) { _M_list_cost = __lc; } void
void __set_vector_cost(float __vc) { _M_vector_cost = __vc; } __merge(const __list2vector_info& __o)
bool __is_valid() { return _M_valid; } {
void __set_invalid() { _M_valid = false; } _M_shift_count += __o._M_shift_count;
_M_iterate += __o._M_iterate;
void __opr_insert(size_t __shift, size_t __size); _M_vector_cost += __o._M_vector_cost;
void __opr_iterate(size_t __num) { _M_iterate += __num;} _M_list_cost += __o._M_list_cost;
_M_valid &= __o._M_valid;
void __resize(size_t __from, size_t __to); _M_resize += __o._M_resize;
_M_max_size = std::max( _M_max_size, __o._M_max_size);
private: }
size_t _M_shift_count;
size_t _M_iterate; void
size_t _M_resize; __write(FILE* __f) const
float _M_list_cost; {
float _M_vector_cost; fprintf(__f, "%Zu %Zu %Zu %.0f %.0f\n", _M_shift_count, _M_resize,
bool _M_valid; _M_iterate, _M_vector_cost, _M_list_cost);
size_t _M_max_size; }
};
float
inline __list2vector_info::__list2vector_info(const __list2vector_info& __o) __magnitude() const
: __object_info_base(__o) { return _M_list_cost - _M_vector_cost; }
{
_M_shift_count = __o._M_shift_count; const char*
_M_iterate = __o._M_iterate; __advice() const
_M_vector_cost = __o._M_vector_cost; {
_M_list_cost = __o._M_list_cost; std::stringstream __sstream;
_M_valid = __o._M_valid; __sstream
_M_resize = __o._M_resize; << "change std::list to std::vector and its initial size from 0 to "
_M_max_size = __o._M_max_size; << _M_max_size;
} return strdup(__sstream.str().c_str());
}
inline const char* __list2vector_info::__advice() const {
std::stringstream __sstream; size_t
__sstream __shift_count()
<< "change std::list to std::vector and its initial size from 0 to " { return _M_shift_count; }
<< _M_max_size;
return strdup(__sstream.str().c_str()); size_t
} __iterate()
{ return _M_iterate; }
inline void __list2vector_info::__merge(const __list2vector_info& __o)
{ float
_M_shift_count += __o._M_shift_count; __list_cost()
_M_iterate += __o._M_iterate; { return _M_list_cost; }
_M_vector_cost += __o._M_vector_cost;
_M_list_cost += __o._M_list_cost; size_t
_M_valid &= __o._M_valid; __resize()
_M_resize += __o._M_resize; { return _M_resize; }
_M_max_size = std::max( _M_max_size, __o._M_max_size);
} void
__set_list_cost(float __lc)
inline void __list2vector_info::__opr_insert(size_t __shift, size_t __size) { _M_list_cost = __lc; }
{
_M_shift_count += __shift; void
_M_max_size = std::max(_M_max_size, __size); __set_vector_cost(float __vc)
} { _M_vector_cost = __vc; }
inline void __list2vector_info::__resize(size_t __from, size_t __to) bool
{ __is_valid()
_M_resize += __from; { return _M_valid; }
}
void
class __list2vector_stack_info: public __list2vector_info { __set_invalid()
public: { _M_valid = false; }
__list2vector_stack_info(const __list2vector_info& __o)
: __list2vector_info(__o) {} void
}; __opr_insert(size_t __shift, size_t __size)
{
class __trace_list_to_vector _M_shift_count += __shift;
: public __trace_base<__list2vector_info, __list2vector_stack_info> _M_max_size = std::max(_M_max_size, __size);
{ }
public:
__trace_list_to_vector(); void
~__trace_list_to_vector() {} __opr_iterate(size_t __num)
{ _M_iterate += __num;}
// Insert a new node at construct with object, callstack and initial size.
void __insert(__object_t __obj, __stack_t __stack); void
// Call at destruction/clean to set container final size. __resize(size_t __from, size_t)
void __destruct(const void* __obj); { _M_resize += __from; }
// Find the node in the live map. private:
__list2vector_info* __find(const void* __obj); size_t _M_shift_count;
size_t _M_iterate;
// Collect cost of operations. size_t _M_resize;
void __opr_insert(const void* __obj, size_t __shift, size_t __size); float _M_list_cost;
void __opr_iterate(const void* __obj, size_t __num); float _M_vector_cost;
void __invalid_operator(const void* __obj); bool _M_valid;
void __resize(const void* __obj, size_t __from, size_t __to); size_t _M_max_size;
float __vector_cost(size_t __shift, size_t __iterate); };
float __list_cost(size_t __shift, size_t __iterate);
}; class __list2vector_stack_info
: public __list2vector_info
inline __trace_list_to_vector::__trace_list_to_vector() {
public:
__list2vector_stack_info(const __list2vector_info& __o)
: __list2vector_info(__o) {}
};
class __trace_list_to_vector
: public __trace_base<__list2vector_info, __list2vector_stack_info>
{
public:
__trace_list_to_vector()
: __trace_base<__list2vector_info, __list2vector_stack_info>() : __trace_base<__list2vector_info, __list2vector_stack_info>()
{ { __id = "list-to-vector"; }
__id = "list-to-vector";
} ~__trace_list_to_vector() { }
inline void __trace_list_to_vector::__insert(__object_t __obj, // Insert a new node at construct with object, callstack and initial size.
__stack_t __stack) void
{ __insert(__object_t __obj, __stack_t __stack)
__add_object(__obj, __list2vector_info(__stack)); { __add_object(__obj, __list2vector_info(__stack)); }
}
// Call at destruction/clean to set container final size.
inline void __list2vector_info::__write(FILE* __f) const void
{ __destruct(const void* __obj)
fprintf(__f, "%Zu %Zu %Zu %.0f %.0f\n", {
_M_shift_count, _M_resize, _M_iterate, _M_vector_cost, _M_list_cost); if (!__is_on())
} return;
inline float __trace_list_to_vector::__vector_cost(size_t __shift, __list2vector_info* __res = __get_object_info(__obj);
size_t __iterate) if (!__res)
{ return;
// The resulting vector will use a 'reserve' method.
return __shift * _GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor).__value + float __vc = __vector_cost(__res->__shift_count(), __res->__iterate());
__iterate * _GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor).__value; float __lc = __list_cost(__res->__shift_count(), __res->__iterate());
} __res->__set_vector_cost(__vc);
__res->__set_list_cost(__lc);
inline float __trace_list_to_vector::__list_cost(size_t __shift, __retire_object(__obj);
size_t __iterate) }
{
return __shift * _GLIBCXX_PROFILE_DATA(__list_shift_cost_factor).__value + // Find the node in the live map.
__iterate * _GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor).__value; __list2vector_info* __find(const void* __obj);
}
// Collect cost of operations.
inline void __trace_list_to_vector::__destruct(const void* __obj) void
{ __opr_insert(const void* __obj, size_t __shift, size_t __size)
if (!__is_on()) {
return; __list2vector_info* __res = __get_object_info(__obj);
if (__res)
__list2vector_info* __res = __get_object_info(__obj); __res->__opr_insert(__shift, __size);
if (!__res) }
return;
void
float __vc = __vector_cost(__res->__shift_count(), __res->__iterate()); __opr_iterate(const void* __obj, size_t __num)
float __lc = __list_cost(__res->__shift_count(), __res->__iterate()); {
__res->__set_vector_cost(__vc); __list2vector_info* __res = __get_object_info(__obj);
__res->__set_list_cost(__lc); if (__res)
__retire_object(__obj); __res->__opr_iterate(__num);
} }
inline void __trace_list_to_vector::__opr_insert(const void* __obj, void
size_t __shift, size_t __size) __invalid_operator(const void* __obj)
{ {
__list2vector_info* __res = __get_object_info(__obj); __list2vector_info* __res = __get_object_info(__obj);
if (__res) if (__res)
__res->__opr_insert(__shift, __size); __res->__set_invalid();
} }
inline void __trace_list_to_vector::__opr_iterate(const void* __obj, void
size_t __num) __resize(const void* __obj, size_t __from, size_t __to)
{ {
__list2vector_info* __res = __get_object_info(__obj); __list2vector_info* __res = __get_object_info(__obj);
if (__res) { if (__res)
__res->__opr_iterate(__num); __res->__resize(__from, __to);
}
float
__vector_cost(size_t __shift, size_t __iterate)
{
// The resulting vector will use a 'reserve' method.
return (__shift
* _GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor).__value
+ __iterate
* _GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor).__value);
}
float
__list_cost(size_t __shift, size_t __iterate)
{
return (__shift
* _GLIBCXX_PROFILE_DATA(__list_shift_cost_factor).__value
+ __iterate
* _GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor).__value);
}
};
inline void
__trace_list_to_vector_init()
{ _GLIBCXX_PROFILE_DATA(_S_list_to_vector) = new __trace_list_to_vector(); }
inline void
__trace_list_to_vector_report(FILE* __f, __warning_vector_t& __warnings)
{
if (_GLIBCXX_PROFILE_DATA(_S_list_to_vector))
{
_GLIBCXX_PROFILE_DATA(_S_list_to_vector)->
__collect_warnings(__warnings);
_GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__write(__f);
}
} }
}
inline void __trace_list_to_vector::__invalid_operator(const void* __obj)
{
__list2vector_info* __res = __get_object_info(__obj);
if (__res)
__res->__set_invalid();
}
inline void __trace_list_to_vector::__resize(const void* __obj, size_t __from, inline void
size_t __to) __trace_list_to_vector_construct(const void* __obj)
{ {
__list2vector_info* __res = __get_object_info(__obj); if (!__profcxx_init())
if (__res) return;
__res->__resize(__from, __to);
}
inline void __trace_list_to_vector_init() _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__insert(__obj, __get_stack());
{
_GLIBCXX_PROFILE_DATA(_S_list_to_vector) = new __trace_list_to_vector();
}
inline void __trace_list_to_vector_report(FILE* __f,
__warning_vector_t& __warnings)
{
if (_GLIBCXX_PROFILE_DATA(_S_list_to_vector)) {
_GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__collect_warnings(__warnings);
_GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__write(__f);
} }
}
inline void __trace_list_to_vector_construct(const void* __obj)
{
if (!__profcxx_init()) return;
_GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__insert(__obj, __get_stack());
}
inline void __trace_list_to_vector_destruct(const void* __obj) inline void
{ __trace_list_to_vector_destruct(const void* __obj)
if (!__profcxx_init()) return; {
if (!__profcxx_init())
_GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__destruct(__obj); return;
}
inline void __trace_list_to_vector_insert(const void* __obj, _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__destruct(__obj);
size_t __shift, size_t __size) }
{
if (!__profcxx_init()) return;
_GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__opr_insert(__obj, __shift, inline void
__size); __trace_list_to_vector_insert(const void* __obj,
} size_t __shift, size_t __size)
{
if (!__profcxx_init())
return;
_GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__opr_insert(__obj, __shift,
__size);
}
inline void __trace_list_to_vector_iterate(const void* __obj, size_t __num = 1) inline void
{ __trace_list_to_vector_iterate(const void* __obj, size_t __num = 1)
if (!__profcxx_init()) return; {
if (!__profcxx_init())
return;
_GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__opr_iterate(__obj, __num); _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__opr_iterate(__obj, __num);
} }
inline void __trace_list_to_vector_invalid_operator(const void* __obj) inline void
{ __trace_list_to_vector_invalid_operator(const void* __obj)
if (!__profcxx_init()) return; {
if (!__profcxx_init())
return;
_GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__invalid_operator(__obj); _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__invalid_operator(__obj);
} }
inline void __trace_list_to_vector_resize(const void* __obj, inline void
size_t __from, size_t __to) __trace_list_to_vector_resize(const void* __obj,
{ size_t __from, size_t __to)
if (!__profcxx_init()) return; {
if (!__profcxx_init())
return;
_GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__resize(__obj, __from, __to); _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__resize(__obj, __from, __to);
} }
} // namespace __gnu_profile } // namespace __gnu_profile
#endif /* _GLIBCXX_PROFILE_PROFILER_LIST_TO_VECTOR_H__ */ #endif /* _GLIBCXX_PROFILE_PROFILER_LIST_TO_VECTOR_H__ */
// -*- C++ -*- // -*- C++ -*-
// //
// Copyright (C) 2009 Free Software Foundation, Inc. // Copyright (C) 2009, 2010 Free Software Foundation, Inc.
// //
// This file is part of the GNU ISO C++ Library. This library is free // 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 // software; you can redistribute it and/or modify it under the terms
...@@ -52,241 +52,255 @@ ...@@ -52,241 +52,255 @@
namespace __gnu_profile namespace __gnu_profile
{ {
inline int
inline int __log2(size_t __size) __log2(size_t __size)
{
for (int __bit_count = sizeof(size_t) - 1; __bit_count >= 0; -- __bit_count)
{ {
if ((2 << __bit_count) & __size) { for (int __bit_count = sizeof(size_t) - 1; __bit_count >= 0;
return __bit_count; -- __bit_count)
} if ((2 << __bit_count) & __size)
return __bit_count;
return 0;
} }
return 0;
}
inline float __map_insert_cost(size_t __size)
{
return (_GLIBCXX_PROFILE_DATA(__map_insert_cost_factor).__value
* static_cast<float>(__log2(__size)));
}
inline float __map_erase_cost(size_t __size)
{
return (_GLIBCXX_PROFILE_DATA(__map_erase_cost_factor).__value
* static_cast<float>(__log2(__size)));
}
inline float __map_find_cost(size_t __size) inline float
{ __map_insert_cost(size_t __size)
return (_GLIBCXX_PROFILE_DATA(__map_find_cost_factor).__value { return (_GLIBCXX_PROFILE_DATA(__map_insert_cost_factor).__value
* static_cast<float>(__log2(__size))); * static_cast<float>(__log2(__size))); }
}
inline float
/** @brief A map-to-unordered_map instrumentation line in the object table. */ __map_erase_cost(size_t __size)
class __map2umap_info: public __object_info_base { return (_GLIBCXX_PROFILE_DATA(__map_erase_cost_factor).__value
{ * static_cast<float>(__log2(__size))); }
public:
__map2umap_info() inline float
: _M_insert(0), _M_erase(0), _M_find(0), _M_iterate(0), __map_find_cost(size_t __size)
_M_map_cost(0.0), _M_umap_cost(0.0), _M_valid(true) {} { return (_GLIBCXX_PROFILE_DATA(__map_find_cost_factor).__value
__map2umap_info(__stack_t __stack) * static_cast<float>(__log2(__size))); }
: __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) {} /** @brief A map-to-unordered_map instrumentation line in the
virtual ~__map2umap_info() {} object table. */
__map2umap_info(const __map2umap_info& o); class __map2umap_info
void __merge(const __map2umap_info& o); : public __object_info_base
void __write(FILE* __f) const; {
float __magnitude() const { return _M_map_cost - _M_umap_cost; } public:
const char* __advice() const; __map2umap_info()
: _M_insert(0), _M_erase(0), _M_find(0), _M_iterate(0),
void __record_insert(size_t __size, size_t __count); _M_umap_cost(0.0), _M_map_cost(0.0), _M_valid(true) { }
void __record_erase(size_t __size, size_t __count);
void __record_find(size_t __size); __map2umap_info(__stack_t __stack)
void __record_iterate(size_t __count); : __object_info_base(__stack), _M_insert(0), _M_erase(0), _M_find(0),
void __record_invalidate(); _M_iterate(0), _M_umap_cost(0.0), _M_map_cost(0.0), _M_valid(true) { }
private: virtual ~__map2umap_info() { }
size_t _M_insert;
size_t _M_erase; __map2umap_info(const __map2umap_info& __o)
size_t _M_find; : __object_info_base(__o), _M_insert(__o._M_insert),
size_t _M_iterate; _M_erase(__o._M_erase), _M_find(__o._M_find),
float _M_umap_cost; _M_iterate(__o._M_iterate), _M_umap_cost(__o._M_umap_cost),
float _M_map_cost; _M_map_cost(__o._M_map_cost), _M_valid(__o._M_valid) { }
bool _M_valid;
}; void
__merge(const __map2umap_info& __o)
inline const char* __map2umap_info::__advice() const {
{ _M_insert += __o._M_insert;
return strdup("change std::map to std::unordered_map"); _M_erase += __o._M_erase;
} _M_find += __o._M_find;
_M_umap_cost += __o._M_umap_cost;
inline __map2umap_info::__map2umap_info(const __map2umap_info& __o) _M_map_cost += __o._M_map_cost;
: __object_info_base(__o), _M_valid &= __o._M_valid;
_M_insert(__o._M_insert), }
_M_erase(__o._M_erase),
_M_find(__o._M_find),
_M_iterate(__o._M_iterate),
_M_map_cost(__o._M_map_cost),
_M_umap_cost(__o._M_umap_cost),
_M_valid(__o._M_valid)
{}
inline void __map2umap_info::__merge(const __map2umap_info& __o)
{
_M_insert += __o._M_insert;
_M_erase += __o._M_erase;
_M_find += __o._M_find;
_M_map_cost += __o._M_map_cost;
_M_umap_cost += __o._M_umap_cost;
_M_valid &= __o._M_valid;
}
inline void __map2umap_info:: __record_insert(size_t __size, size_t __count)
{
_M_insert += __count;
_M_map_cost += __count * __map_insert_cost(__size);
_M_umap_cost += (__count
* _GLIBCXX_PROFILE_DATA(__umap_insert_cost_factor).__value);
}
inline void __map2umap_info:: __record_erase(size_t __size, size_t __count)
{
_M_erase += __count;
_M_map_cost += __count * __map_erase_cost(__size);
_M_umap_cost += (__count
* _GLIBCXX_PROFILE_DATA(__umap_erase_cost_factor).__value);
}
inline void __map2umap_info:: __record_find(size_t __size)
{
_M_find += 1;
_M_map_cost += __map_find_cost(__size);
_M_umap_cost += _GLIBCXX_PROFILE_DATA(__umap_find_cost_factor).__value;
}
inline void __map2umap_info:: __record_iterate(size_t __count) void
{ __write(FILE* __f) const
_M_iterate += __count; {
_M_map_cost += (__count fprintf(__f, "%Zu %Zu %Zu %Zu %.0f %.0f %s\n",
* _GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor).__value); _M_insert, _M_erase, _M_find, _M_iterate, _M_map_cost,
_M_umap_cost += ( _M_umap_cost, _M_valid ? "valid" : "invalid");
__count * _GLIBCXX_PROFILE_DATA(__umap_iterate_cost_factor).__value); }
}
float
inline void __map2umap_info:: __record_invalidate() __magnitude() const
{ { return _M_map_cost - _M_umap_cost; }
_M_valid = false;
} const char*
__advice() const
{ return strdup("change std::map to std::unordered_map"); }
void
__record_insert(size_t __size, size_t __count)
{
_M_insert += __count;
_M_map_cost += __count * __map_insert_cost(__size);
_M_umap_cost
+= (__count
* _GLIBCXX_PROFILE_DATA(__umap_insert_cost_factor).__value);
}
inline void __map2umap_info::__write(FILE* __f) const void
{ __record_erase(size_t __size, size_t __count)
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_erase += __count;
_M_valid ? "valid" : "invalid"); _M_map_cost += __count * __map_erase_cost(__size);
} _M_umap_cost
+= (__count
* _GLIBCXX_PROFILE_DATA(__umap_erase_cost_factor).__value);
}
/** @brief A map-to-unordered_map instrumentation line in the stack table. */ void
class __map2umap_stack_info: public __map2umap_info __record_find(size_t __size)
{ {
public: _M_find += 1;
__map2umap_stack_info(const __map2umap_info& o) : __map2umap_info(o) {} _M_map_cost += __map_find_cost(__size);
}; _M_umap_cost += _GLIBCXX_PROFILE_DATA(__umap_find_cost_factor).__value;
}
/** @brief Map-to-unordered_map instrumentation producer. */ void
class __trace_map2umap __record_iterate(size_t __count)
: public __trace_base<__map2umap_info, __map2umap_stack_info> {
{ _M_iterate += __count;
public: _M_map_cost
__trace_map2umap(); += (__count
}; * _GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor).__value);
_M_umap_cost
+= (__count
* _GLIBCXX_PROFILE_DATA(__umap_iterate_cost_factor).__value);
}
inline __trace_map2umap::__trace_map2umap() void
__record_invalidate()
{ _M_valid = false; }
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;
};
/** @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()
: __trace_base<__map2umap_info, __map2umap_stack_info>() : __trace_base<__map2umap_info, __map2umap_stack_info>()
{ { __id = "map-to-unordered-map"; }
__id = "map-to-unordered-map"; };
}
inline void __trace_map_to_unordered_map_init() inline void
{ __trace_map_to_unordered_map_init()
_GLIBCXX_PROFILE_DATA(_S_map2umap) = new __trace_map2umap(); { _GLIBCXX_PROFILE_DATA(_S_map2umap) = new __trace_map2umap(); }
}
inline void __trace_map_to_unordered_map_report( inline void
FILE* __f, __warning_vector_t& __warnings) __trace_map_to_unordered_map_report(FILE* __f,
{ __warning_vector_t& __warnings)
if (_GLIBCXX_PROFILE_DATA(_S_map2umap)) { {
_GLIBCXX_PROFILE_DATA(_S_map2umap)->__collect_warnings(__warnings); if (_GLIBCXX_PROFILE_DATA(_S_map2umap))
_GLIBCXX_PROFILE_DATA(_S_map2umap)->__write(__f); {
_GLIBCXX_PROFILE_DATA(_S_map2umap)->__collect_warnings(__warnings);
_GLIBCXX_PROFILE_DATA(_S_map2umap)->__write(__f);
}
} }
}
inline void __trace_map_to_unordered_map_construct(const void* __obj)
{
if (!__profcxx_init()) return;
_GLIBCXX_PROFILE_DATA(_S_map2umap)->__add_object( inline void
__obj, __map2umap_info(__get_stack())); __trace_map_to_unordered_map_construct(const void* __obj)
} {
if (!__profcxx_init())
inline void __trace_map_to_unordered_map_destruct(const void* __obj) return;
{
if (!__profcxx_init()) return;
_GLIBCXX_PROFILE_DATA(_S_map2umap)->__retire_object(__obj); _GLIBCXX_PROFILE_DATA(_S_map2umap)->
} __add_object(__obj, __map2umap_info(__get_stack()));
}
inline void __trace_map_to_unordered_map_insert(const void* __obj, inline void
size_t __size, size_t __count) __trace_map_to_unordered_map_destruct(const void* __obj)
{ {
if (!__profcxx_init()) return; if (!__profcxx_init())
return;
__map2umap_info* __info = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__retire_object(__obj);
_GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj); }
if (__info) __info->__record_insert(__size, __count); inline void
} __trace_map_to_unordered_map_insert(const void* __obj,
size_t __size, size_t __count)
{
if (!__profcxx_init())
return;
inline void __trace_map_to_unordered_map_erase(const void* __obj, __map2umap_info* __info
size_t __size, size_t __count) = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
{
if (!__profcxx_init()) return;
__map2umap_info* __info = if (__info)
_GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj); __info->__record_insert(__size, __count);
}
if (__info) __info->__record_erase(__size, __count); inline void
} __trace_map_to_unordered_map_erase(const void* __obj,
size_t __size, size_t __count)
{
if (!__profcxx_init())
return;
inline void __trace_map_to_unordered_map_find(const void* __obj, size_t __size) __map2umap_info* __info
{ = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
if (!__profcxx_init()) return;
__map2umap_info* __info = if (__info)
_GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj); __info->__record_erase(__size, __count);
}
if (__info) __info->__record_find(__size); inline void
} __trace_map_to_unordered_map_find(const void* __obj, size_t __size)
{
if (!__profcxx_init())
return;
inline void __trace_map_to_unordered_map_iterate(const void* __obj, __map2umap_info* __info
size_t __count) = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
{
if (!__profcxx_init()) return;
__map2umap_info* __info = if (__info)
_GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj); __info->__record_find(__size);
}
if (__info) __info->__record_iterate(__count); inline void
} __trace_map_to_unordered_map_iterate(const void* __obj, size_t __count)
{
if (!__profcxx_init())
return;
__map2umap_info* __info
= _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
if (__info)
__info->__record_iterate(__count);
}
inline void __trace_map_to_unordered_map_invalidate(const void* __obj) inline void
{ __trace_map_to_unordered_map_invalidate(const void* __obj)
if (!__profcxx_init()) return; {
if (!__profcxx_init())
return;
__map2umap_info* __info = __map2umap_info* __info
_GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj); = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
if (__info) __info->__record_invalidate(); if (__info)
} __info->__record_invalidate();
}
} // namespace __gnu_profile } // namespace __gnu_profile
#endif /* _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H */ #endif /* _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H */
...@@ -53,120 +53,125 @@ ...@@ -53,120 +53,125 @@
namespace __gnu_profile namespace __gnu_profile
{ {
typedef const void* __object_t; typedef const void* __object_t;
typedef void* __instruction_address_t; typedef void* __instruction_address_t;
typedef std::_GLIBCXX_STD_PR::vector<__instruction_address_t> __stack_npt; typedef std::_GLIBCXX_STD_PR::vector<__instruction_address_t> __stack_npt;
typedef __stack_npt* __stack_t; typedef __stack_npt* __stack_t;
size_t __stack_max_depth(); size_t __stack_max_depth();
inline __stack_t __get_stack() inline __stack_t
{ __get_stack()
{
#if defined _GLIBCXX_HAVE_EXECINFO_H #if defined _GLIBCXX_HAVE_EXECINFO_H
size_t __max_depth = __stack_max_depth(); size_t __max_depth = __stack_max_depth();
if (__max_depth == 0) if (__max_depth == 0)
return 0; return 0;
__stack_npt __buffer(__max_depth); __stack_npt __buffer(__max_depth);
int __depth = backtrace(&__buffer[0], __max_depth); int __depth = backtrace(&__buffer[0], __max_depth);
__stack_t __stack = new __stack_npt(__depth); __stack_t __stack = new __stack_npt(__depth);
memcpy(&(*__stack)[0], &__buffer[0], __depth * sizeof(__object_t)); memcpy(&(*__stack)[0], &__buffer[0], __depth * sizeof(__object_t));
return __stack; return __stack;
#else #else
return 0;
#endif
}
inline __size(const __stack_t& __stack)
{
if (!__stack) {
return 0; return 0;
} else { #endif
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. */ inline size_t
class __stack_hash __size(__stack_t __stack)
{
public:
size_t operator()(const __stack_t __s) const
{ {
if (!__s) { if (!__stack)
return 0; return 0;
} else
return __stack->size();
}
uintptr_t __index = 0; // XXX
inline void
__write(FILE* __f, __stack_t __stack)
{
if (!__stack)
return;
__stack_npt::const_iterator __it; __stack_npt::const_iterator __it;
for (__it = __s->begin(); __it != __s->end(); ++__it) { for (__it = __stack->begin(); __it != __stack->end(); ++__it)
__index += reinterpret_cast<uintptr_t>(*__it); fprintf(__f, "%p ", *__it);
}
return __index;
} }
bool operator() (const __stack_t __stack1, const __stack_t __stack2) const /** @brief Hash function for summary trace using call stack as index. */
class __stack_hash
{ {
if (!__stack1 && !__stack2) return true; public:
if (!__stack1 || !__stack2) return false; size_t
if (__stack1->size() != __stack2->size()) return false; operator()(__stack_t __s) const
{
size_t __byte_size = __stack1->size() * sizeof(__stack_npt::value_type); if (!__s)
return memcmp(&(*__stack1)[0], &(*__stack2)[0], __byte_size) == 0; 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;
}
/** @brief Base class for a line in the object table. */ bool operator() (__stack_t __stack1, __stack_t __stack2) const
class __object_info_base {
{ if (!__stack1 && !__stack2)
public: return true;
__object_info_base() {} if (!__stack1 || !__stack2)
__object_info_base(__stack_t __stack); return false;
__object_info_base(const __object_info_base& o); if (__stack1->size() != __stack2->size())
virtual ~__object_info_base() {} return false;
bool __is_valid() const { return _M_valid; }
__stack_t __stack() const { return _M_stack; } size_t __byte_size = __stack1->size() * sizeof(__stack_npt::value_type);
virtual void __write(FILE* f) const = 0; return memcmp(&(*__stack1)[0], &(*__stack2)[0], __byte_size) == 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. */ /** @brief Base class for a line in the object table. */
template<typename __object_info> class __object_info_base
class __stack_info_base {
{ public:
public: __object_info_base() { }
__stack_info_base() {}
__stack_info_base(const __object_info& __info) = 0; __object_info_base(__stack_t __stack)
virtual ~__stack_info_base() {} : _M_stack(__stack), _M_valid(true) { }
void __merge(const __object_info& __info) = 0;
virtual float __magnitude() const = 0; __object_info_base(const __object_info_base& __o)
virtual const char* __get_id() const = 0; : _M_stack(__o._M_stack), _M_valid(__o._M_valid) { }
};
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;
};
/** @brief Base class for a line in the stack table. */
template<typename __object_info>
class __stack_info_base
{
public:
__stack_info_base() { }
__stack_info_base(const __object_info& __info) = 0;
virtual ~__stack_info_base() {}
void __merge(const __object_info& __info) = 0;
virtual float __magnitude() const = 0;
virtual const char* __get_id() const = 0;
};
} // namespace __gnu_profile } // namespace __gnu_profile
#endif /* _GLIBCXX_PROFILE_PROFILER_NODE_H */ #endif /* _GLIBCXX_PROFILE_PROFILER_NODE_H */
// -*- C++ -*- // -*- C++ -*-
// //
// Copyright (C) 2009 Free Software Foundation, Inc. // Copyright (C) 2009, 2010 Free Software Foundation, Inc.
// //
// This file is part of the GNU ISO C++ Library. This library is free // 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 // software; you can redistribute it and/or modify it under the terms
...@@ -39,32 +39,35 @@ ...@@ -39,32 +39,35 @@
namespace __gnu_profile namespace __gnu_profile
{ {
enum __state_type { __ON, __OFF, __INVALID };
enum __state_type { __ON, __OFF, __INVALID }; _GLIBCXX_PROFILE_DEFINE_DATA(__state_type, __state, __INVALID);
_GLIBCXX_PROFILE_DEFINE_DATA(__state_type, __state, __INVALID); inline bool
__turn(__state_type __s)
{ return (_GLIBCXX_PROFILE_DATA(__state)
== __sync_val_compare_and_swap(&_GLIBCXX_PROFILE_DATA(__state),
__INVALID, __s)); }
inline bool __turn(__state_type __s) inline bool
{ __turn_on()
return (_GLIBCXX_PROFILE_DATA(__state) { return __turn(__ON); }
== __sync_val_compare_and_swap(&_GLIBCXX_PROFILE_DATA(__state),
__INVALID, __s));
}
inline bool __turn_on()
{ return __turn(__ON); }
inline bool __turn_off() inline bool
{ return __turn(__OFF); } __turn_off()
{ return __turn(__OFF); }
inline bool __is_on() inline bool
{ return _GLIBCXX_PROFILE_DATA(__state) == __ON; } __is_on()
{ return _GLIBCXX_PROFILE_DATA(__state) == __ON; }
inline bool __is_off() inline bool
{ return _GLIBCXX_PROFILE_DATA(__state) == __OFF; } __is_off()
{ return _GLIBCXX_PROFILE_DATA(__state) == __OFF; }
inline bool __is_invalid() inline bool
{ return _GLIBCXX_PROFILE_DATA(__state) == __INVALID; } __is_invalid()
{ return _GLIBCXX_PROFILE_DATA(__state) == __INVALID; }
} // end namespace __gnu_profile } // end namespace __gnu_profile
#endif /* _GLIBCXX_PROFILE_PROFILER_STATE_H */ #endif /* _GLIBCXX_PROFILE_PROFILER_STATE_H */
...@@ -65,333 +65,371 @@ ...@@ -65,333 +65,371 @@
namespace __gnu_profile namespace __gnu_profile
{ {
/** @brief Internal environment. Values can be set one of two ways: /** @brief Internal environment. Values can be set one of two ways:
1. In config file "var = value". The default config file path is 1. In config file "var = value". The default config file path is
libstdcxx-profile.conf. libstdcxx-profile.conf.
2. By setting process environment variables. For instance, in a Bash 2. By setting process environment variables. For instance, in a Bash
shell you can set the unit cost of iterating through a map like this: shell you can set the unit cost of iterating through a map like this:
export __map_iterate_cost_factor=5.0. export __map_iterate_cost_factor=5.0.
If a value is set both in the input file and through an environment If a value is set both in the input file and through an environment
variable, the environment value takes precedence. */ variable, the environment value takes precedence. */
typedef _GLIBCXX_IMPL_UNORDERED_MAP<std::string, std::string> __env_t; typedef _GLIBCXX_IMPL_UNORDERED_MAP<std::string, std::string> __env_t;
_GLIBCXX_PROFILE_DEFINE_UNINIT_DATA(__env_t, __env);
_GLIBCXX_PROFILE_DEFINE_UNINIT_DATA(__env_t, __env);
/** @brief Master lock. */
_GLIBCXX_PROFILE_DEFINE_UNINIT_DATA(__gnu_cxx::__mutex, __global_lock); /** @brief Master lock. */
_GLIBCXX_PROFILE_DEFINE_UNINIT_DATA(__gnu_cxx::__mutex, __global_lock);
/** @brief Representation of a warning. */
struct __warning_data /** @brief Representation of a warning. */
{ struct __warning_data
float __magnitude; {
__stack_t __context; float __magnitude;
const char* __warning_id; __stack_t __context;
const char* __warning_message; const char* __warning_id;
__warning_data() const char* __warning_message;
: __magnitude(0.0), __context(0), __warning_id(0), __warning_data()
: __magnitude(0.0), __context(0), __warning_id(0),
__warning_message(0) { } __warning_message(0) { }
__warning_data(float __m, __stack_t __c, const char* __id, __warning_data(float __m, __stack_t __c, const char* __id,
const char* __msg) const char* __msg)
: __magnitude(__m), __context(__c), __warning_id(__id), : __magnitude(__m), __context(__c), __warning_id(__id),
__warning_message(__msg) { } __warning_message(__msg) { }
bool operator<(const struct __warning_data& __other) const
{ return __magnitude < __other.__magnitude; } bool
}; 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. typedef std::_GLIBCXX_STD_PR::vector<__warning_data> __warning_vector_t;
class __trace_hash_func;
class __trace_hashtable_size; // Defined in profiler_<diagnostic name>.h.
class __trace_map2umap; class __trace_hash_func;
class __trace_vector_size; class __trace_hashtable_size;
class __trace_vector_to_list; class __trace_map2umap;
class __trace_list_to_slist; class __trace_vector_size;
class __trace_list_to_vector; class __trace_vector_to_list;
void __trace_vector_size_init(); class __trace_list_to_slist;
void __trace_hashtable_size_init(); class __trace_list_to_vector;
void __trace_hash_func_init(); void __trace_vector_size_init();
void __trace_vector_to_list_init(); void __trace_hashtable_size_init();
void __trace_list_to_slist_init(); void __trace_hash_func_init();
void __trace_list_to_vector_init(); void __trace_vector_to_list_init();
void __trace_map_to_unordered_map_init(); void __trace_list_to_slist_init();
void __trace_vector_size_report(FILE*, __warning_vector_t&); void __trace_list_to_vector_init();
void __trace_hashtable_size_report(FILE*, __warning_vector_t&); void __trace_map_to_unordered_map_init();
void __trace_hash_func_report(FILE*, __warning_vector_t&); void __trace_vector_size_report(FILE*, __warning_vector_t&);
void __trace_vector_to_list_report(FILE*, __warning_vector_t&); void __trace_hashtable_size_report(FILE*, __warning_vector_t&);
void __trace_list_to_slist_report(FILE*, __warning_vector_t&); void __trace_hash_func_report(FILE*, __warning_vector_t&);
void __trace_list_to_vector_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&); void __trace_list_to_slist_report(FILE*, __warning_vector_t&);
void __trace_list_to_vector_report(FILE*, __warning_vector_t&);
struct __cost_factor void __trace_map_to_unordered_map_report(FILE*, __warning_vector_t&);
{
const char* __env_var; struct __cost_factor
float __value;
};
typedef std::_GLIBCXX_STD_PR::vector<__cost_factor*> __cost_factor_vector;
_GLIBCXX_PROFILE_DEFINE_DATA(__trace_hash_func*, _S_hash_func, 0);
_GLIBCXX_PROFILE_DEFINE_DATA(__trace_hashtable_size*, _S_hashtable_size, 0);
_GLIBCXX_PROFILE_DEFINE_DATA(__trace_map2umap*, _S_map2umap, 0);
_GLIBCXX_PROFILE_DEFINE_DATA(__trace_vector_size*, _S_vector_size, 0);
_GLIBCXX_PROFILE_DEFINE_DATA(__trace_vector_to_list*, _S_vector_to_list, 0);
_GLIBCXX_PROFILE_DEFINE_DATA(__trace_list_to_slist*, _S_list_to_slist, 0);
_GLIBCXX_PROFILE_DEFINE_DATA(__trace_list_to_vector*, _S_list_to_vector, 0);
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_shift_cost_factor,
{"__vector_shift_cost_factor", 1.0});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_iterate_cost_factor,
{"__vector_iterate_cost_factor", 1.0});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_resize_cost_factor,
{"__vector_resize_cost_factor", 1.0});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_shift_cost_factor,
{"__list_shift_cost_factor", 0.0});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_iterate_cost_factor,
{"__list_iterate_cost_factor", 10.0});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_resize_cost_factor,
{"__list_resize_cost_factor", 0.0});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_insert_cost_factor,
{"__map_insert_cost_factor", 1.5});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_erase_cost_factor,
{"__map_erase_cost_factor", 1.5});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_find_cost_factor,
{"__map_find_cost_factor", 1});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_iterate_cost_factor,
{"__map_iterate_cost_factor", 2.3});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_insert_cost_factor,
{"__umap_insert_cost_factor", 12.0});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_erase_cost_factor,
{"__umap_erase_cost_factor", 12.0});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_find_cost_factor,
{"__umap_find_cost_factor", 10.0});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_iterate_cost_factor,
{"__umap_iterate_cost_factor", 1.7});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor_vector*, __cost_factors, 0);
_GLIBCXX_PROFILE_DEFINE_DATA(const char*, _S_trace_file_name,
_GLIBCXX_PROFILE_TRACE_PATH_ROOT);
_GLIBCXX_PROFILE_DEFINE_DATA(size_t, _S_max_warn_count,
_GLIBCXX_PROFILE_MAX_WARN_COUNT);
_GLIBCXX_PROFILE_DEFINE_DATA(size_t, _S_max_stack_depth,
_GLIBCXX_PROFILE_MAX_STACK_DEPTH);
_GLIBCXX_PROFILE_DEFINE_DATA(size_t, _S_max_mem,
_GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC);
inline size_t __stack_max_depth()
{
return _GLIBCXX_PROFILE_DATA(_S_max_stack_depth);
}
inline size_t __max_mem()
{
return _GLIBCXX_PROFILE_DATA(_S_max_mem);
}
/** @brief Base class for all trace producers. */
template <typename __object_info, typename __stack_info>
class __trace_base
{
public:
__trace_base();
virtual ~__trace_base() {}
void __add_object(__object_t object, __object_info __info);
__object_info* __get_object_info(__object_t __object);
void __retire_object(__object_t __object);
void __write(FILE* f);
void __collect_warnings(__warning_vector_t& __warnings);
private:
__gnu_cxx::__mutex __object_table_lock;
__gnu_cxx::__mutex __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(), const char* __env_var;
(*__i).first, float __value;
__id, };
(*__i).second.__advice()));
} typedef std::_GLIBCXX_STD_PR::vector<__cost_factor*> __cost_factor_vector;
}
_GLIBCXX_PROFILE_DEFINE_DATA(__trace_hash_func*, _S_hash_func, 0);
_GLIBCXX_PROFILE_DEFINE_DATA(__trace_hashtable_size*, _S_hashtable_size, 0);
_GLIBCXX_PROFILE_DEFINE_DATA(__trace_map2umap*, _S_map2umap, 0);
_GLIBCXX_PROFILE_DEFINE_DATA(__trace_vector_size*, _S_vector_size, 0);
_GLIBCXX_PROFILE_DEFINE_DATA(__trace_vector_to_list*, _S_vector_to_list, 0);
_GLIBCXX_PROFILE_DEFINE_DATA(__trace_list_to_slist*, _S_list_to_slist, 0);
_GLIBCXX_PROFILE_DEFINE_DATA(__trace_list_to_vector*, _S_list_to_vector, 0);
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_shift_cost_factor,
{"__vector_shift_cost_factor", 1.0});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_iterate_cost_factor,
{"__vector_iterate_cost_factor", 1.0});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_resize_cost_factor,
{"__vector_resize_cost_factor", 1.0});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_shift_cost_factor,
{"__list_shift_cost_factor", 0.0});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_iterate_cost_factor,
{"__list_iterate_cost_factor", 10.0});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_resize_cost_factor,
{"__list_resize_cost_factor", 0.0});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_insert_cost_factor,
{"__map_insert_cost_factor", 1.5});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_erase_cost_factor,
{"__map_erase_cost_factor", 1.5});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_find_cost_factor,
{"__map_find_cost_factor", 1});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_iterate_cost_factor,
{"__map_iterate_cost_factor", 2.3});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_insert_cost_factor,
{"__umap_insert_cost_factor", 12.0});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_erase_cost_factor,
{"__umap_erase_cost_factor", 12.0});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_find_cost_factor,
{"__umap_find_cost_factor", 10.0});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_iterate_cost_factor,
{"__umap_iterate_cost_factor", 1.7});
_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor_vector*, __cost_factors, 0);
_GLIBCXX_PROFILE_DEFINE_DATA(const char*, _S_trace_file_name,
_GLIBCXX_PROFILE_TRACE_PATH_ROOT);
_GLIBCXX_PROFILE_DEFINE_DATA(size_t, _S_max_warn_count,
_GLIBCXX_PROFILE_MAX_WARN_COUNT);
_GLIBCXX_PROFILE_DEFINE_DATA(size_t, _S_max_stack_depth,
_GLIBCXX_PROFILE_MAX_STACK_DEPTH);
_GLIBCXX_PROFILE_DEFINE_DATA(size_t, _S_max_mem,
_GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC);
inline size_t
__stack_max_depth()
{ return _GLIBCXX_PROFILE_DATA(_S_max_stack_depth); }
inline size_t
__max_mem()
{ return _GLIBCXX_PROFILE_DATA(_S_max_mem); }
/** @brief Base class for all trace producers. */
template<typename __object_info, typename __stack_info>
class __trace_base
{
public:
__trace_base();
virtual ~__trace_base() {}
void __add_object(__object_t object, __object_info __info);
__object_info* __get_object_info(__object_t __object);
void __retire_object(__object_t __object);
void __write(FILE* f);
void __collect_warnings(__warning_vector_t& __warnings);
private:
__gnu_cxx::__mutex __object_table_lock;
__gnu_cxx::__mutex __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> template<typename __object_info, typename __stack_info>
__trace_base<__object_info, __stack_info>::__trace_base() __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. // Do not pick the initial size too large, as we don't know which
__object_table.rehash(10000); // diagnostics are more active.
__stack_table.rehash(10000); __object_table.rehash(10000);
__stack_table_byte_size = 0; __stack_table.rehash(10000);
__id = 0; __stack_table_byte_size = 0;
} __id = 0;
}
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()) {
this->__object_table_lock.lock();
__object_table.insert(
typename __object_table_t::value_type(__object, __info));
this->__object_table_lock.unlock();
}
}
template <typename __object_info, typename __stack_info> template<typename __object_info, typename __stack_info>
__object_info* __trace_base<__object_info, __stack_info>::__get_object_info( void
__object_t __object) __trace_base<__object_info, __stack_info>::
{ __add_object(__object_t __object, __object_info __info)
// XXX: Revisit this to see if we can decrease mutex spans. {
// Without this mutex, the object table could be rehashed during an if (__max_mem() == 0
// insertion on another thread, which could result in a segfault. || __object_table.size() * sizeof(__object_info) <= __max_mem())
this->__object_table_lock.lock(); {
typename __object_table_t::iterator __object_it = this->__object_table_lock.lock();
__object_table.find(__object); __object_table.insert(typename __object_table_t::
if (__object_it == __object_table.end()){ value_type(__object, __info));
this->__object_table_lock.unlock(); this->__object_table_lock.unlock();
return 0; }
} else { }
this->__object_table_lock.unlock();
return &__object_it->second;
}
}
template <typename __object_info, typename __stack_info> template<typename __object_info, typename __stack_info>
void __trace_base<__object_info, __stack_info>::__retire_object( __object_info*
__object_t __object) __trace_base<__object_info, __stack_info>::
{ __get_object_info(__object_t __object)
this->__object_table_lock.lock(); {
this->__stack_table_lock.lock(); // XXX: Revisit this to see if we can decrease mutex spans.
typename __object_table_t::iterator __object_it = // Without this mutex, the object table could be rehashed during an
__object_table.find(__object); // insertion on another thread, which could result in a segfault.
if (__object_it != __object_table.end()){ this->__object_table_lock.lock();
const __object_info& __info = __object_it->second; typename __object_table_t::iterator __object_it
const __stack_t& __stack = __info.__stack(); = __object_table.find(__object);
typename __stack_table_t::iterator __stack_it =
__stack_table.find(__stack); if (__object_it == __object_table.end())
if (__stack_it == __stack_table.end()) { {
// First occurence of this call context. this->__object_table_lock.unlock();
if (__max_mem() == 0 || __stack_table_byte_size < __max_mem()) { return 0;
__stack_table_byte_size += }
(sizeof(__instruction_address_t) * __size(__stack) else
+ sizeof(__stack) + sizeof(__stack_info)); {
__stack_table.insert(make_pair(__stack, __stack_info(__info))); this->__object_table_lock.unlock();
} return &__object_it->second;
} else { }
// Merge object info into info summary for this call context.
__stack_it->second.__merge(__info);
delete __stack;
} }
__object_table.erase(__object);
}
this->__object_table_lock.unlock();
this->__stack_table_lock.unlock();
}
template <typename __object_info, typename __stack_info> template<typename __object_info, typename __stack_info>
void __trace_base<__object_info, __stack_info>::__write(FILE* __f) void
{ __trace_base<__object_info, __stack_info>::
typename __stack_table_t::iterator __it; __retire_object(__object_t __object)
{
for (__it = __stack_table.begin(); __it != __stack_table.end(); __it++) { this->__object_table_lock.lock();
if (__it->second.__is_valid()) { this->__stack_table_lock.lock();
fprintf(__f, __id); typename __object_table_t::iterator __object_it
fprintf(__f, "|"); = __object_table.find(__object);
__gnu_profile::__write(__f, __it->first);
fprintf(__f, "|"); if (__object_it != __object_table.end())
__it->second.__write(__f); {
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);
}
this->__object_table_lock.unlock();
this->__stack_table_lock.unlock();
} }
}
}
inline size_t __env_to_size_t(const char* __env_var, size_t __default_value) template<typename __object_info, typename __stack_info>
{ void
char* __env_value = getenv(__env_var); __trace_base<__object_info, __stack_info>::
if (__env_value) { __write(FILE* __f)
long int __converted_value = strtol(__env_value, 0, 10); {
if (errno || __converted_value < 0) { typename __stack_table_t::iterator __it;
fprintf(stderr, "Bad value for environment variable '%s'.\n", __env_var);
abort(); for (__it = __stack_table.begin(); __it != __stack_table.end(); ++__it)
} else { {
return static_cast<size_t>(__converted_value); if (__it->second.__is_valid())
{
fprintf(__f, __id);
fprintf(__f, "|");
__gnu_profile::__write(__f, __it->first);
fprintf(__f, "|");
__it->second.__write(__f);
}
}
} }
} else {
return __default_value;
}
}
inline void __set_max_stack_trace_depth() inline size_t
{ __env_to_size_t(const char* __env_var, size_t __default_value)
_GLIBCXX_PROFILE_DATA(_S_max_stack_depth) = __env_to_size_t( {
_GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR, char* __env_value = getenv(__env_var);
_GLIBCXX_PROFILE_DATA(_S_max_stack_depth)); if (__env_value)
} {
long __converted_value = strtol(__env_value, 0, 10);
if (errno || __converted_value < 0)
{
fprintf(stderr, "Bad value for environment variable '%s'.\n",
__env_var);
abort();
}
else
return static_cast<size_t>(__converted_value);
}
else
return __default_value;
}
inline void __set_max_mem() inline void
{ __set_max_stack_trace_depth()
_GLIBCXX_PROFILE_DATA(_S_max_mem) = __env_to_size_t( {
_GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR, _GLIBCXX_PROFILE_DATA(_S_max_stack_depth)
_GLIBCXX_PROFILE_DATA(_S_max_mem)); = __env_to_size_t(_GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR,
} _GLIBCXX_PROFILE_DATA(_S_max_stack_depth));
}
inline int __log_magnitude(float __f) inline void
{ __set_max_mem()
const float __log_base = 10.0; {
int __result = 0; _GLIBCXX_PROFILE_DATA(_S_max_mem)
int __sign = 1; = __env_to_size_t(_GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR,
if (__f < 0) { _GLIBCXX_PROFILE_DATA(_S_max_mem));
__f = -__f;
__sign = -1;
} }
while (__f > __log_base) {
++__result; inline int
__f /= 10.0; __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;
} }
return __sign * __result;
}
inline FILE* __open_output_file(const char* __extension) inline FILE*
{ __open_output_file(const char* __extension)
// The path is made of _S_trace_file_name + "." + extension. {
size_t __root_len = strlen(_GLIBCXX_PROFILE_DATA(_S_trace_file_name)); // The path is made of _S_trace_file_name + "." + extension.
size_t __ext_len = strlen(__extension); size_t __root_len = strlen(_GLIBCXX_PROFILE_DATA(_S_trace_file_name));
char* __file_name = new char[__root_len + 1 + __ext_len + 1]; size_t __ext_len = strlen(__extension);
memcpy(__file_name, _GLIBCXX_PROFILE_DATA(_S_trace_file_name), char* __file_name = new char[__root_len + 1 + __ext_len + 1];
__root_len); memcpy(__file_name, _GLIBCXX_PROFILE_DATA(_S_trace_file_name),
*(__file_name + __root_len) = '.'; __root_len);
memcpy(__file_name + __root_len + 1, __extension, __ext_len + 1); *(__file_name + __root_len) = '.';
FILE* __out_file = fopen(__file_name, "w"); memcpy(__file_name + __root_len + 1, __extension, __ext_len + 1);
if (__out_file) { FILE* __out_file = fopen(__file_name, "w");
return __out_file; if (__out_file)
} else { return __out_file;
fprintf(stderr, "Could not open trace file '%s'.\n", __file_name); else
abort(); {
fprintf(stderr, "Could not open trace file '%s'.\n", __file_name);
abort();
}
} }
}
struct __warn struct __warn
{ {
FILE* __file; FILE* __file;
__warn(FILE* __f) { __file = __f; } __warn(FILE* __f) { __file = __f; }
void operator() (const __warning_data& __info) void
operator() (const __warning_data& __info)
{ {
fprintf(__file, __info.__warning_id); fprintf(__file, __info.__warning_id);
fprintf(__file, ": improvement = %d", fprintf(__file, ": improvement = %d",
...@@ -402,121 +440,125 @@ struct __warn ...@@ -402,121 +440,125 @@ struct __warn
free(const_cast<void*> free(const_cast<void*>
(reinterpret_cast<const void*>(__info.__warning_message))); (reinterpret_cast<const void*>(__info.__warning_message)));
} }
}; };
/** @brief Final report method, registered with @b atexit. /** @brief Final report method, registered with @b atexit.
* *
* This can also be called directly by user code, including signal handlers. * This can also be called directly by user code, including signal handlers.
* It is protected against deadlocks by the reentrance guard in profiler.h. * It is protected against deadlocks by the reentrance guard in profiler.h.
* However, when called from a signal handler that triggers while within * However, when called from a signal handler that triggers while within
* __gnu_profile (under the guarded zone), no output will be produced. * __gnu_profile (under the guarded zone), no output will be produced.
*/ */
inline void __report(void) inline void
{ __report(void)
_GLIBCXX_PROFILE_DATA(__global_lock).lock(); {
_GLIBCXX_PROFILE_DATA(__global_lock).lock();
__warning_vector_t __warnings, __top_warnings;
__warning_vector_t __warnings, __top_warnings;
FILE* __raw_file = __open_output_file("raw");
__trace_vector_size_report(__raw_file, __warnings); FILE* __raw_file = __open_output_file("raw");
__trace_hashtable_size_report(__raw_file, __warnings); __trace_vector_size_report(__raw_file, __warnings);
__trace_hash_func_report(__raw_file, __warnings); __trace_hashtable_size_report(__raw_file, __warnings);
__trace_vector_to_list_report(__raw_file, __warnings); __trace_hash_func_report(__raw_file, __warnings);
__trace_list_to_slist_report(__raw_file, __warnings); __trace_vector_to_list_report(__raw_file, __warnings);
__trace_list_to_vector_report(__raw_file, __warnings); __trace_list_to_slist_report(__raw_file, __warnings);
__trace_map_to_unordered_map_report(__raw_file, __warnings); __trace_list_to_vector_report(__raw_file, __warnings);
fclose(__raw_file); __trace_map_to_unordered_map_report(__raw_file, __warnings);
fclose(__raw_file);
// Sort data by magnitude, keeping just top N.
size_t __cutoff = std::min(_GLIBCXX_PROFILE_DATA(_S_max_warn_count), // Sort data by magnitude, keeping just top N.
__warnings.size()); size_t __cutoff = std::min(_GLIBCXX_PROFILE_DATA(_S_max_warn_count),
__top_n(__warnings, __top_warnings, __cutoff); __warnings.size());
__top_n(__warnings, __top_warnings, __cutoff);
FILE* __warn_file = __open_output_file("txt");
__for_each(__top_warnings.begin(), __top_warnings.end(), FILE* __warn_file = __open_output_file("txt");
__warn(__warn_file)); __for_each(__top_warnings.begin(), __top_warnings.end(),
fclose(__warn_file); __warn(__warn_file));
fclose(__warn_file);
_GLIBCXX_PROFILE_DATA(__global_lock).unlock();
} _GLIBCXX_PROFILE_DATA(__global_lock).unlock();
inline void __set_trace_path()
{
char* __env_trace_file_name = getenv(_GLIBCXX_PROFILE_TRACE_ENV_VAR);
if (__env_trace_file_name) {
_GLIBCXX_PROFILE_DATA(_S_trace_file_name) = __env_trace_file_name;
} }
// Make sure early that we can create the trace file. inline void
fclose(__open_output_file("txt")); __set_trace_path()
} {
char* __env_trace_file_name = getenv(_GLIBCXX_PROFILE_TRACE_ENV_VAR);
inline void __set_max_warn_count() if (__env_trace_file_name)
{ _GLIBCXX_PROFILE_DATA(_S_trace_file_name) = __env_trace_file_name;
char* __env_max_warn_count_str = getenv(
_GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR);
if (__env_max_warn_count_str) { // Make sure early that we can create the trace file.
_GLIBCXX_PROFILE_DATA(_S_max_warn_count) = static_cast<size_t>( fclose(__open_output_file("txt"));
atoi(__env_max_warn_count_str));
} }
}
inline void inline void
__read_cost_factors() __set_max_warn_count()
{ {
std::string __conf_file_name(_GLIBCXX_PROFILE_DATA(_S_trace_file_name)); char* __env_max_warn_count_str
__conf_file_name += ".conf"; = getenv(_GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR);
std::ifstream __conf_file(__conf_file_name.c_str()); if (__env_max_warn_count_str)
_GLIBCXX_PROFILE_DATA(_S_max_warn_count)
= static_cast<size_t>(atoi(__env_max_warn_count_str));
}
if (__conf_file.is_open()) inline void
{ __read_cost_factors()
std::string __line; {
std::string __conf_file_name(_GLIBCXX_PROFILE_DATA(_S_trace_file_name));
__conf_file_name += ".conf";
while (std::getline(__conf_file, __line)) std::ifstream __conf_file(__conf_file_name.c_str());
{
std::string::size_type __i = __line.find_first_not_of(" \t\n\v");
if (__line.length() <= 0 || __line[__i] == '#') if (__conf_file.is_open())
// Skip empty lines or comments. {
continue; std::string __line;
}
// Trim. while (std::getline(__conf_file, __line))
__line.erase(__remove(__line.begin(), __line.end(), ' '), __line.end()); {
std::string::size_type __pos = __line.find("="); std::string::size_type __i = __line.find_first_not_of(" \t\n\v");
std::string __factor_name = __line.substr(0, __pos);
std::string::size_type __end = __line.find_first_of(";\n");
std::string __factor_value = __line.substr(__pos + 1, __end - __pos);
_GLIBCXX_PROFILE_DATA(__env)[__factor_name] = __factor_value; if (__line.length() <= 0 || __line[__i] == '#')
} // Skip empty lines or comments.
} continue;
}
struct __cost_factor_writer // Trim.
{ __line.erase(__remove(__line.begin(), __line.end(), ' '),
FILE* __file; __line.end());
__cost_factor_writer(FILE* __f) : __file(__f) {} std::string::size_type __pos = __line.find("=");
void std::string __factor_name = __line.substr(0, __pos);
operator() (const __cost_factor* __factor) std::string::size_type __end = __line.find_first_of(";\n");
{ fprintf(__file, "%s = %f\n", __factor->__env_var, __factor->__value); } std::string __factor_value = __line.substr(__pos + 1, __end - __pos);
};
inline void
__write_cost_factors()
{
FILE* __file = __open_output_file("conf.out");
__for_each(_GLIBCXX_PROFILE_DATA(__cost_factors)->begin(),
_GLIBCXX_PROFILE_DATA(__cost_factors)->end(),
__cost_factor_writer(__file));
fclose(__file);
}
struct __cost_factor_setter _GLIBCXX_PROFILE_DATA(__env)[__factor_name] = __factor_value;
{ }
void operator() (__cost_factor* __factor) }
struct __cost_factor_writer
{
FILE* __file;
__cost_factor_writer(FILE* __f) : __file(__f) { }
void
operator() (const __cost_factor* __factor)
{ fprintf(__file, "%s = %f\n", __factor->__env_var, __factor->__value); }
};
inline void
__write_cost_factors()
{
FILE* __file = __open_output_file("conf.out");
__for_each(_GLIBCXX_PROFILE_DATA(__cost_factors)->begin(),
_GLIBCXX_PROFILE_DATA(__cost_factors)->end(),
__cost_factor_writer(__file));
fclose(__file);
}
struct __cost_factor_setter
{
void
operator() (__cost_factor* __factor)
{ {
// Look it up in the process environment first. // Look it up in the process environment first.
const char* __env_value = getenv(__factor->__env_var); const char* __env_value = getenv(__factor->__env_var);
...@@ -524,8 +566,8 @@ struct __cost_factor_setter ...@@ -524,8 +566,8 @@ struct __cost_factor_setter
if (!__env_value) if (!__env_value)
{ {
// Look it up in the config file. // Look it up in the config file.
__env_t::iterator it = _GLIBCXX_PROFILE_DATA(__env).find( __env_t::iterator it
__factor->__env_var); = _GLIBCXX_PROFILE_DATA(__env).find(__factor->__env_var);
if (it != _GLIBCXX_PROFILE_DATA(__env).end()) if (it != _GLIBCXX_PROFILE_DATA(__env).end())
__env_value = (*it).second.c_str(); __env_value = (*it).second.c_str();
} }
...@@ -533,96 +575,95 @@ struct __cost_factor_setter ...@@ -533,96 +575,95 @@ struct __cost_factor_setter
if (__env_value) if (__env_value)
__factor->__value = atof(__env_value); __factor->__value = atof(__env_value);
} }
}; };
inline void __set_cost_factors() inline void
{ __set_cost_factors()
_GLIBCXX_PROFILE_DATA(__cost_factors) = new __cost_factor_vector; {
_GLIBCXX_PROFILE_DATA(__cost_factors)->push_back( _GLIBCXX_PROFILE_DATA(__cost_factors) = new __cost_factor_vector;
&_GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor)); _GLIBCXX_PROFILE_DATA(__cost_factors)->
_GLIBCXX_PROFILE_DATA(__cost_factors)->push_back( push_back(&_GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor));
&_GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor)); _GLIBCXX_PROFILE_DATA(__cost_factors)->
_GLIBCXX_PROFILE_DATA(__cost_factors)->push_back( push_back(&_GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor));
&_GLIBCXX_PROFILE_DATA(__vector_resize_cost_factor)); _GLIBCXX_PROFILE_DATA(__cost_factors)->
_GLIBCXX_PROFILE_DATA(__cost_factors)->push_back( push_back(&_GLIBCXX_PROFILE_DATA(__vector_resize_cost_factor));
&_GLIBCXX_PROFILE_DATA(__list_shift_cost_factor)); _GLIBCXX_PROFILE_DATA(__cost_factors)->
_GLIBCXX_PROFILE_DATA(__cost_factors)->push_back( push_back(&_GLIBCXX_PROFILE_DATA(__list_shift_cost_factor));
&_GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor)); _GLIBCXX_PROFILE_DATA(__cost_factors)->
_GLIBCXX_PROFILE_DATA(__cost_factors)->push_back( push_back(&_GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor));
&_GLIBCXX_PROFILE_DATA(__list_resize_cost_factor)); _GLIBCXX_PROFILE_DATA(__cost_factors)->
_GLIBCXX_PROFILE_DATA(__cost_factors)->push_back( push_back(&_GLIBCXX_PROFILE_DATA(__list_resize_cost_factor));
&_GLIBCXX_PROFILE_DATA(__map_insert_cost_factor)); _GLIBCXX_PROFILE_DATA(__cost_factors)->
_GLIBCXX_PROFILE_DATA(__cost_factors)->push_back( push_back(&_GLIBCXX_PROFILE_DATA(__map_insert_cost_factor));
&_GLIBCXX_PROFILE_DATA(__map_erase_cost_factor)); _GLIBCXX_PROFILE_DATA(__cost_factors)->
_GLIBCXX_PROFILE_DATA(__cost_factors)->push_back( push_back(&_GLIBCXX_PROFILE_DATA(__map_erase_cost_factor));
&_GLIBCXX_PROFILE_DATA(__map_find_cost_factor)); _GLIBCXX_PROFILE_DATA(__cost_factors)->
_GLIBCXX_PROFILE_DATA(__cost_factors)->push_back( push_back(&_GLIBCXX_PROFILE_DATA(__map_find_cost_factor));
&_GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor)); _GLIBCXX_PROFILE_DATA(__cost_factors)->
_GLIBCXX_PROFILE_DATA(__cost_factors)->push_back( push_back(&_GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor));
&_GLIBCXX_PROFILE_DATA(__umap_insert_cost_factor)); _GLIBCXX_PROFILE_DATA(__cost_factors)->
_GLIBCXX_PROFILE_DATA(__cost_factors)->push_back( push_back(&_GLIBCXX_PROFILE_DATA(__umap_insert_cost_factor));
&_GLIBCXX_PROFILE_DATA(__umap_erase_cost_factor)); _GLIBCXX_PROFILE_DATA(__cost_factors)->
_GLIBCXX_PROFILE_DATA(__cost_factors)->push_back( push_back(&_GLIBCXX_PROFILE_DATA(__umap_erase_cost_factor));
&_GLIBCXX_PROFILE_DATA(__umap_find_cost_factor)); _GLIBCXX_PROFILE_DATA(__cost_factors)->
_GLIBCXX_PROFILE_DATA(__cost_factors)->push_back( push_back(&_GLIBCXX_PROFILE_DATA(__umap_find_cost_factor));
&_GLIBCXX_PROFILE_DATA(__umap_iterate_cost_factor)); _GLIBCXX_PROFILE_DATA(__cost_factors)->
push_back(&_GLIBCXX_PROFILE_DATA(__umap_iterate_cost_factor));
__for_each(_GLIBCXX_PROFILE_DATA(__cost_factors)->begin(), __for_each(_GLIBCXX_PROFILE_DATA(__cost_factors)->begin(),
_GLIBCXX_PROFILE_DATA(__cost_factors)->end(), _GLIBCXX_PROFILE_DATA(__cost_factors)->end(),
__cost_factor_setter()); __cost_factor_setter());
} }
inline void __profcxx_init_unconditional()
{
_GLIBCXX_PROFILE_DATA(__global_lock).lock();
if (__is_invalid()) {
__set_max_warn_count();
if (_GLIBCXX_PROFILE_DATA(_S_max_warn_count) == 0) {
__turn_off();
} else {
__set_max_stack_trace_depth();
__set_max_mem();
__set_trace_path();
__read_cost_factors();
__set_cost_factors();
__write_cost_factors();
__trace_vector_size_init();
__trace_hashtable_size_init();
__trace_hash_func_init();
__trace_vector_to_list_init();
__trace_list_to_slist_init();
__trace_list_to_vector_init();
__trace_map_to_unordered_map_init();
atexit(__report);
__turn_on(); inline void
__profcxx_init_unconditional()
{
_GLIBCXX_PROFILE_DATA(__global_lock).lock();
if (__is_invalid())
{
__set_max_warn_count();
if (_GLIBCXX_PROFILE_DATA(_S_max_warn_count) == 0)
__turn_off();
else
{
__set_max_stack_trace_depth();
__set_max_mem();
__set_trace_path();
__read_cost_factors();
__set_cost_factors();
__write_cost_factors();
__trace_vector_size_init();
__trace_hashtable_size_init();
__trace_hash_func_init();
__trace_vector_to_list_init();
__trace_list_to_slist_init();
__trace_list_to_vector_init();
__trace_map_to_unordered_map_init();
atexit(__report);
__turn_on();
}
}
} _GLIBCXX_PROFILE_DATA(__global_lock).unlock();
} }
_GLIBCXX_PROFILE_DATA(__global_lock).unlock(); /** @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();
/** @brief This function must be called by each instrumentation point. return __is_on();
*
* The common path is inlined fully.
*/
inline bool __profcxx_init(void)
{
if (__is_invalid()) {
__profcxx_init_unconditional();
} }
return __is_on();
}
} // namespace __gnu_profile } // namespace __gnu_profile
#endif /* _GLIBCXX_PROFILE_PROFILER_TRACE_H */ #endif /* _GLIBCXX_PROFILE_PROFILER_TRACE_H */
// -*- C++ -*- // -*- C++ -*-
// //
// Copyright (C) 2009 Free Software Foundation, Inc. // Copyright (C) 2009, 2010 Free Software Foundation, Inc.
// //
// This file is part of the GNU ISO C++ Library. This library is free // 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 // software; you can redistribute it and/or modify it under the terms
...@@ -54,50 +54,57 @@ ...@@ -54,50 +54,57 @@
namespace __gnu_profile namespace __gnu_profile
{ {
/** @brief Hashtable size instrumentation trace producer. */
/** @brief Hashtable size instrumentation trace producer. */ class __trace_vector_size
class __trace_vector_size : public __trace_container_size : public __trace_container_size
{ {
public: public:
__trace_vector_size() : __trace_container_size() { __id = "vector-size"; } __trace_vector_size()
}; : __trace_container_size()
{ __id = "vector-size"; }
inline void __trace_vector_size_init() };
{
_GLIBCXX_PROFILE_DATA(_S_vector_size) = new __trace_vector_size(); inline void
} __trace_vector_size_init()
{ _GLIBCXX_PROFILE_DATA(_S_vector_size) = new __trace_vector_size(); }
inline void __trace_vector_size_report(FILE* __f,
__warning_vector_t& __warnings) inline void
{ __trace_vector_size_report(FILE* __f, __warning_vector_t& __warnings)
if (_GLIBCXX_PROFILE_DATA(_S_vector_size)) { {
_GLIBCXX_PROFILE_DATA(_S_vector_size)->__collect_warnings(__warnings); if (_GLIBCXX_PROFILE_DATA(_S_vector_size))
_GLIBCXX_PROFILE_DATA(_S_vector_size)->__write(__f); {
_GLIBCXX_PROFILE_DATA(_S_vector_size)->__collect_warnings(__warnings);
_GLIBCXX_PROFILE_DATA(_S_vector_size)->__write(__f);
}
} }
}
inline void __trace_vector_size_construct(const void* __obj, size_t __num) inline void
{ __trace_vector_size_construct(const void* __obj, size_t __num)
if (!__profcxx_init()) return; {
if (!__profcxx_init())
return;
_GLIBCXX_PROFILE_DATA(_S_vector_size)->__insert(__obj, __get_stack(), __num); _GLIBCXX_PROFILE_DATA(_S_vector_size)->__insert(__obj, __get_stack(),
} __num);
}
inline void __trace_vector_size_destruct(const void* __obj, size_t __num, inline void
size_t __inum) __trace_vector_size_destruct(const void* __obj, size_t __num, size_t __inum)
{ {
if (!__profcxx_init()) return; if (!__profcxx_init())
return;
_GLIBCXX_PROFILE_DATA(_S_vector_size)->__destruct(__obj, __num, __inum); _GLIBCXX_PROFILE_DATA(_S_vector_size)->__destruct(__obj, __num, __inum);
} }
inline void __trace_vector_size_resize(const void* __obj, size_t __from, inline void
size_t __to) __trace_vector_size_resize(const void* __obj, size_t __from, size_t __to)
{ {
if (!__profcxx_init()) return; if (!__profcxx_init())
return;
_GLIBCXX_PROFILE_DATA(_S_vector_size)->__resize(__obj, __from, __to); _GLIBCXX_PROFILE_DATA(_S_vector_size)->__resize(__obj, __from, __to);
} }
} // namespace __gnu_profile } // namespace __gnu_profile
......
// -*- C++ -*- // -*- C++ -*-
// //
// Copyright (C) 2009 Free Software Foundation, Inc. // Copyright (C) 2009, 2010 Free Software Foundation, Inc.
// //
// This file is part of the GNU ISO C++ Library. This library is free // 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 // software; you can redistribute it and/or modify it under the terms
...@@ -52,285 +52,305 @@ ...@@ -52,285 +52,305 @@
namespace __gnu_profile namespace __gnu_profile
{ {
/** @brief A vector-to-list instrumentation line in the object table. */
/** @brief A vector-to-list instrumentation line in the object table. */ class __vector2list_info
class __vector2list_info: public __object_info_base : public __object_info_base
{ {
public: public:
__vector2list_info() __vector2list_info()
:_M_shift_count(0), _M_iterate(0), _M_resize(0), _M_list_cost(0), : _M_shift_count(0), _M_iterate(0), _M_resize(0), _M_list_cost(0),
_M_vector_cost(0), _M_valid(true) {} _M_vector_cost(0), _M_valid(true) { }
__vector2list_info(__stack_t __stack)
: __object_info_base(__stack), _M_shift_count(0), _M_iterate(0), __vector2list_info(__stack_t __stack)
_M_resize(0), _M_list_cost(0), _M_vector_cost(0), _M_valid(true) {} : __object_info_base(__stack), _M_shift_count(0), _M_iterate(0),
virtual ~__vector2list_info() {} _M_resize(0), _M_list_cost(0), _M_vector_cost(0), _M_valid(true) { }
__vector2list_info(const __vector2list_info& __o);
void __merge(const __vector2list_info& __o); virtual ~__vector2list_info() { }
void __write(FILE* __f) const;
float __magnitude() const { return _M_vector_cost - _M_list_cost; } __vector2list_info(const __vector2list_info& __o)
const char* __advice() const : __object_info_base(__o), _M_shift_count(__o._M_shift_count),
{ return strdup("change std::vector to std::list"); } _M_iterate(__o._M_iterate), _M_resize(__o._M_resize),
_M_list_cost(__o._M_list_cost), _M_vector_cost(__o._M_vector_cost),
size_t __shift_count() { return _M_shift_count; } _M_valid(__o._M_valid) { }
size_t __iterate() { return _M_iterate; }
float __list_cost() { return _M_list_cost; } void
size_t __resize() { return _M_resize; } __merge(const __vector2list_info& __o)
void __set_list_cost(float __lc) { _M_list_cost = __lc; } {
void __set_vector_cost(float __vc) { _M_vector_cost = __vc; } _M_shift_count += __o._M_shift_count;
bool __is_valid() { return _M_valid; } _M_iterate += __o._M_iterate;
void __set_invalid() { _M_valid = false; } _M_vector_cost += __o._M_vector_cost;
_M_list_cost += __o._M_list_cost;
void __opr_insert(size_t __pos, size_t __num); _M_valid &= __o._M_valid;
void __opr_iterate(size_t __num); _M_resize += __o._M_resize;
void __resize(size_t __from, size_t __to); }
void __opr_find(size_t __size);
void
private: __write(FILE* __f) const
size_t _M_shift_count; {
size_t _M_iterate; fprintf(__f, "%Zu %Zu %Zu %.0f %.0f\n", _M_shift_count, _M_resize,
size_t _M_resize; _M_iterate, _M_vector_cost, _M_list_cost);
float _M_list_cost; }
float _M_vector_cost;
bool _M_valid; float
}; __magnitude() const
{ return _M_vector_cost - _M_list_cost; }
inline __vector2list_info::__vector2list_info(const __vector2list_info& __o)
: __object_info_base(__o) const char* __advice() const
{ { return strdup("change std::vector to std::list"); }
_M_shift_count = __o._M_shift_count;
_M_iterate = __o._M_iterate; size_t
_M_vector_cost = __o._M_vector_cost; __shift_count()
_M_list_cost = __o._M_list_cost; { return _M_shift_count; }
_M_valid = __o._M_valid;
_M_resize = __o._M_resize; size_t
} __iterate()
{ return _M_iterate; }
inline void __vector2list_info::__merge(const __vector2list_info& __o)
{ float __list_cost()
_M_shift_count += __o._M_shift_count; { return _M_list_cost; }
_M_iterate += __o._M_iterate;
_M_vector_cost += __o._M_vector_cost; size_t
_M_list_cost += __o._M_list_cost; __resize()
_M_valid &= __o._M_valid; { return _M_resize; }
_M_resize += __o._M_resize;
} void
__set_list_cost(float __lc)
inline void __vector2list_info::__opr_insert(size_t __pos, size_t __num) { _M_list_cost = __lc; }
{
_M_shift_count += __num - __pos; void
} __set_vector_cost(float __vc)
{ _M_vector_cost = __vc; }
inline void __vector2list_info::__resize(size_t __from, size_t __to)
{ bool
_M_resize += __from; __is_valid()
} { return _M_valid; }
inline void __vector2list_info::__opr_iterate(size_t __num) void
{ __set_invalid()
_M_iterate += __num; { _M_valid = false; }
}
void
inline void __vector2list_info::__opr_find(size_t __size) __opr_insert(size_t __pos, size_t __num)
{ { _M_shift_count += __num - __pos; }
// Use average case complexity.
_M_iterate += 3.0 / 4.0 * __size; void
} __opr_iterate(size_t __num)
{ _M_iterate += __num; }
/** @brief A vector-to-list instrumentation line in the stack table. */
class __vector2list_stack_info: public __vector2list_info { void
public: __resize(size_t __from, size_t)
__vector2list_stack_info(const __vector2list_info& __o) { _M_resize += __from; }
: __vector2list_info(__o) {}
}; void __opr_find(size_t __size)
{
/** @brief Vector-to-list instrumentation producer. */ // Use average case complexity.
class __trace_vector_to_list _M_iterate += 3.0 / 4.0 * __size;
: public __trace_base<__vector2list_info, __vector2list_stack_info> }
{
public: private:
__trace_vector_to_list(); size_t _M_shift_count;
~__trace_vector_to_list() {} size_t _M_iterate;
size_t _M_resize;
// Insert a new node at construct with object, callstack and initial size. float _M_list_cost;
void __insert(__object_t __obj, __stack_t __stack); float _M_vector_cost;
// Call at destruction/clean to set container final size. bool _M_valid;
void __destruct(const void* __obj); };
// Find the node in the live map.
__vector2list_info* __find(const void* __obj); /** @brief A vector-to-list instrumentation line in the stack table. */
class __vector2list_stack_info
// Collect cost of operations. : public __vector2list_info
void __opr_insert(const void* __obj, size_t __pos, size_t __num); {
void __opr_iterate(const void* __obj, size_t __num); public:
void __invalid_operator(const void* __obj); __vector2list_stack_info(const __vector2list_info& __o)
void __resize(const void* __obj, size_t __from, size_t __to); : __vector2list_info(__o) { }
float __vector_cost(size_t __shift, size_t __iterate, size_t __resize); };
float __list_cost(size_t __shift, size_t __iterate, size_t __resize);
void __opr_find(const void* __obj, size_t __size);
}; /** @brief Vector-to-list instrumentation producer. */
class __trace_vector_to_list
inline __trace_vector_to_list::__trace_vector_to_list() : public __trace_base<__vector2list_info, __vector2list_stack_info>
{
public:
__trace_vector_to_list()
: __trace_base<__vector2list_info, __vector2list_stack_info>() : __trace_base<__vector2list_info, __vector2list_stack_info>()
{ { __id = "vector-to-list"; }
__id = "vector-to-list";
} ~__trace_vector_to_list() { }
inline void __trace_vector_to_list::__insert(__object_t __obj, // Insert a new node at construct with object, callstack and initial size.
__stack_t __stack) void
{ __insert(__object_t __obj, __stack_t __stack)
__add_object(__obj, __vector2list_info(__stack)); { __add_object(__obj, __vector2list_info(__stack)); }
}
// Call at destruction/clean to set container final size.
inline void __vector2list_info::__write(FILE* __f) const void
{ __destruct(const void* __obj)
fprintf(__f, "%Zu %Zu %Zu %.0f %.0f\n", {
_M_shift_count, _M_resize, _M_iterate, _M_vector_cost, _M_list_cost); if (!__is_on())
} return;
inline float __trace_vector_to_list::__vector_cost(size_t __shift, __vector2list_info* __res = __get_object_info(__obj);
size_t __iterate, if (!__res)
size_t __resize) return;
{
return ( float __vc = __vector_cost(__res->__shift_count(), __res->__iterate(),
__shift * _GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor).__value __res->__resize());
+ __iterate * _GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor).__value float __lc = __list_cost(__res->__shift_count(), __res->__iterate(),
+ __resize * _GLIBCXX_PROFILE_DATA(__vector_resize_cost_factor).__value __res->__resize());
); __res->__set_vector_cost(__vc);
} __res->__set_list_cost(__lc);
inline float __trace_vector_to_list::__list_cost(size_t __shift, __retire_object(__obj);
size_t __iterate, }
size_t __resize)
{ // Find the node in the live map.
return ( // XXX Undefined?!?
__shift * _GLIBCXX_PROFILE_DATA(__list_shift_cost_factor).__value __vector2list_info* __find(const void* __obj);
+ __iterate * _GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor).__value
+ __resize * _GLIBCXX_PROFILE_DATA(__list_resize_cost_factor).__value); // Collect cost of operations.
} void
__opr_insert(const void* __obj, size_t __pos, size_t __num)
inline void __trace_vector_to_list::__destruct(const void* __obj) {
{ __vector2list_info* __res = __get_object_info(__obj);
if (!__is_on()) if (__res)
return; __res->__opr_insert(__pos, __num);
}
__vector2list_info* __res = __get_object_info(__obj);
if (!__res) void
return; __opr_iterate(const void* __obj, size_t __num)
{
float __vc = __vector_cost(__res->__shift_count(), __res->__iterate(), __vector2list_info* __res = __get_object_info(__obj);
__res->__resize()); if (__res)
float __lc = __list_cost(__res->__shift_count(), __res->__iterate(), __res->__opr_iterate(__num);
__res->__resize()); }
__res->__set_vector_cost(__vc);
__res->__set_list_cost(__lc); void
__invalid_operator(const void* __obj)
__retire_object(__obj); {
} __vector2list_info* __res = __get_object_info(__obj);
if (__res)
inline void __trace_vector_to_list::__opr_insert(const void* __obj, __res->__set_invalid();
size_t __pos, size_t __num) }
{
__vector2list_info* __res = __get_object_info(__obj); void
if (__res) __resize(const void* __obj, size_t __from, size_t __to)
__res->__opr_insert(__pos, __num); {
} __vector2list_info* __res = __get_object_info(__obj);
if (__res)
inline void __trace_vector_to_list::__opr_iterate(const void* __obj, __res->__resize(__from, __to);
size_t __num) }
{
__vector2list_info* __res = __get_object_info(__obj); float
if (__res) __vector_cost(size_t __shift, size_t __iterate, size_t __resize)
__res->__opr_iterate(__num); {
} return (__shift
* _GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor).__value
inline void __trace_vector_to_list::__invalid_operator(const void* __obj) + __iterate
{ * _GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor).__value
__vector2list_info* __res = __get_object_info(__obj); + __resize
if (__res) * _GLIBCXX_PROFILE_DATA(__vector_resize_cost_factor).__value);
__res->__set_invalid(); }
}
float
inline void __trace_vector_to_list::__resize(const void* __obj, size_t __from, __list_cost(size_t __shift, size_t __iterate, size_t __resize)
size_t __to) {
{ return (__shift
__vector2list_info* __res = __get_object_info(__obj); * _GLIBCXX_PROFILE_DATA(__list_shift_cost_factor).__value
if (__res) + __iterate
__res->__resize(__from, __to); * _GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor).__value
} + __resize
* _GLIBCXX_PROFILE_DATA(__list_resize_cost_factor).__value);
inline void __trace_vector_to_list::__opr_find(const void* __obj, }
size_t __size)
{ void
__vector2list_info* __res = __get_object_info(__obj); __opr_find(const void* __obj, size_t __size)
if (__res) {
__res->__opr_find(__size); __vector2list_info* __res = __get_object_info(__obj);
} if (__res)
__res->__opr_find(__size);
inline void __trace_vector_to_list_init() }
{ };
_GLIBCXX_PROFILE_DATA(_S_vector_to_list) = new __trace_vector_to_list();
}
inline void
inline void __trace_vector_to_list_report(FILE* __f, __trace_vector_to_list_init()
__warning_vector_t& __warnings) { _GLIBCXX_PROFILE_DATA(_S_vector_to_list) = new __trace_vector_to_list(); }
{
if (_GLIBCXX_PROFILE_DATA(_S_vector_to_list)) { inline void
_GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__collect_warnings(__warnings); __trace_vector_to_list_report(FILE* __f, __warning_vector_t& __warnings)
_GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__write(__f); {
if (_GLIBCXX_PROFILE_DATA(_S_vector_to_list))
{
_GLIBCXX_PROFILE_DATA(_S_vector_to_list)->
__collect_warnings(__warnings);
_GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__write(__f);
}
} }
}
inline void __trace_vector_to_list_construct(const void* __obj)
{
if (!__profcxx_init()) return;
_GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__insert(__obj, __get_stack()); inline void
} __trace_vector_to_list_construct(const void* __obj)
{
if (!__profcxx_init())
return;
inline void __trace_vector_to_list_destruct(const void* __obj) _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__insert(__obj, __get_stack());
{ }
if (!__profcxx_init()) return;
_GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__destruct(__obj); inline void
} __trace_vector_to_list_destruct(const void* __obj)
{
if (!__profcxx_init())
return;
inline void __trace_vector_to_list_insert(const void* __obj, _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__destruct(__obj);
size_t __pos, size_t __num) }
{
if (!__profcxx_init()) return;
_GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_insert(__obj, __pos, __num); inline void
} __trace_vector_to_list_insert(const void* __obj, size_t __pos, size_t __num)
{
if (!__profcxx_init())
return;
_GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_insert(__obj, __pos,
__num);
}
inline void __trace_vector_to_list_iterate(const void* __obj, size_t __num = 1) inline void
{ __trace_vector_to_list_iterate(const void* __obj, size_t __num = 1)
if (!__profcxx_init()) return; {
if (!__profcxx_init())
return;
_GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_iterate(__obj, __num); _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_iterate(__obj, __num);
} }
inline void __trace_vector_to_list_invalid_operator(const void* __obj) inline void
{ __trace_vector_to_list_invalid_operator(const void* __obj)
if (!__profcxx_init()) return; {
if (!__profcxx_init())
return;
_GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__invalid_operator(__obj); _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__invalid_operator(__obj);
} }
inline void __trace_vector_to_list_resize(const void* __obj, inline void
size_t __from, size_t __to) __trace_vector_to_list_resize(const void* __obj, size_t __from, size_t __to)
{ {
if (!__profcxx_init()) return; if (!__profcxx_init())
return;
_GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__resize(__obj, __from, __to); _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__resize(__obj, __from, __to);
} }
inline void __trace_vector_to_list_find(const void* __obj, size_t __size) inline void
{ __trace_vector_to_list_find(const void* __obj, size_t __size)
if (!__profcxx_init()) return; {
if (!__profcxx_init())
return;
_GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_find(__obj, __size); _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_find(__obj, __size);
} }
} // namespace __gnu_profile } // namespace __gnu_profile
#endif /* _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H */ #endif /* _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment