Commit b12db708 by François Dumont

Major maintenance patch of the profile mode.

2014-11-10  François Dumont  <fdumont@gcc.gnu.org>

	Major maintenance patch of the profile mode.
	* include/profile/impl/profiler_container_size.h
	(__container_size_info()): Delete.
	(__container_size_info(const __container_size_info&)): Delete.
	(virtual ~__container_size_info()): Delete.
	(__container_size_info(__stack_t, size_t)): Delete.
	(__container_size_info(__stack_t)): New.
	(__container_size_info::__init(size_t)): New.
	(__container_size_info::__merge): Call __object_info_base::__merge.
	(__trace_container_size::__construct): Delete declaration.
	(__trace_container_size::__insert): Return __container_size_info*,
	call __init.
	* include/profile/impl/profiler_hash_func.h
	(__hashfunc_into()): Delete.
	(__hashfunc_info(const __hashfunc_info&)): Delete.
	(virtual ~__hashfunc_info()): Delete.
	(__hashfunc_info::__merge): Call __object_info_base::__merge.
	(__trace_hash_func::__insert): Delete.
	(__trace_hash_func_free): New.
	(__trace_hash_func_report): Call __trace_report.
	(__trace_hash_func_construct): Return __hashfunc_info*. Add check for
	reentrancy.
	* include/profile/impl/profiler_hashtable_size.h
	(__trace_hashtable_size_free): New.
	(__trace_hashtable_size_report): Call __trace_report.
	(__trace_hashtable_size_construct): Return __container_size_info*. Add
	check for reentrancy.
	* include/profile/impl/profiler_list_to_slist.h
	(__list2slist_info()): Delete.
	(__list2slist_info(const __list2slist_info&)): Delete.
	(virtual ~__list2slist_info()): Delete.
	(__trace_list_to_slist::__merge(const __list2slist_info&)): Delete.
	(__trace_list_to_slist::__opr_rewind(const void*)): Delete.
	(__trace_list_to_slist::__record_operation(const void*)): Delete.
	(__trace_list_to_slist::__insert(const __object_t, __stack_t)): Delete.
	(__trace_list_to_slist::__destruct): Only call __retire_object.
	(__trace_list_to_slist_free()): New.
	(__trace_list_to_slist_report): Call __trace_report.
	(__trace_list_to_slist_construct): Return __list2slist_info*. Add check
	for reentrancy.
	* include/profile/impl/profiler_list_to_vector.h
	(__list2vector_info()): Delete.
	(__list2vector_info(const __list2vector_info&)): Delete.
	(virtual ~__list2vector_info()): Delete.
	(_list2vector_info::__is_valid): Delete.
	(_list2vector_info::__set_invalid): Delete.
	(_list2vector_info::__opr_iterate): Use atomic operation.
	(_list2vector_info::_M_valid): Delete.
	(__trace_list_to_vector::__insert): Delete.
	(__trace_list_to_vector::__find): Delete.
	(__trace_list_to_vector::__opr_insert): Delete.
	(__trace_list_to_vector::__opr_iterate): Delete.
	(__trace_list_to_vector::__invalid_operator): Delete.
	(__trace_list_to_vector::__resize): Delete.
	(__trace_list_to_vector_free): New.
	(__trace_list_to_vector_report): Call __trace_report.
	(__trace_list_to_vector_construct): Return __list2vector_info*. Add
	check for reentrancy.
	* include/profile/impl/profiler_map_to_unordered_map.h
	(__map2umap_info()): Delete.
	(__map2umap_info(const __map2umap_info&)): Delete.
	(virtual ~__map2umap_info()): Delete.
	(__map2umap_info::__record_iterate): Use atomic operation.
	(__map2umap_info::__set_iterate_costs): New.
	(__map2umap_info::__record_invalidate): Delete.
	(__map2umap_info::_M_valid): Delete.
	(__trace_map2umap::__destruct): New.
	(__trace_map_to_unordered_map_free): New.
	(__trace_map_to_unordered_map_report): Call __trace_report.
	(__trace_map_to_unordered_map_construct): Return __map2umap_info*. Add
	check for reentrancy.
	* include/profile/impl/profiler_node.h (__object_t): Delete typedef.
	(__get_stack): Return null stack trace in case of (bad_alloc) exception.
	(__object_info_base()): Delete.
	(__object_info_base(const __object_info_base&)): Delete.
	(virtual ~__object_info_base()): Delete.
	(__object_info_base::__set_invalid): New.
	(__object_info_base::__merge): New.
	(virtual void __write(FILE*)): Delete.
	(class __stack_info_base): Delete.
	* include/profile/impl/profiler_trace.h (__global_lock): Rename into
	__global_mutex.
	(__trace_vector_size_free): New declaration.
	(__trace_hashtable_size_free): Likewise.
	(__trace_hash_func_free): Likewise.
	(__trace_vector_to_list_free): Likewise.
	(__trace_list_to_slist_free): Likewise.
	(__trace_list_to_vector_free): Likewise.
	(__trace_map_to_unordered_map_free): Likewise.
	(__trace_base::~__trace_base()): Not virtual anymore. Delete stored
	backtrace information.
	(__trace_base::__add_object): Return __object_info*, take only a stack
	trace.
	(__trace_base::__get_object_info): Delete.
	(__trace_base::__retire_object): Take __object_info* instead of
	__object_t.
	(__trace_base::__object_table_lock): Delete.
	(__trace_base::__stack_table_lock): Delete.
	(__trace_base::__object_table_t): Delete typedef.
	(__trace_base::__object_table): Delete.
	(__trace_base::__trace_mutex): New.
	(__trace_base::__object_byte_size): New.
	(__trace_report): New.
	(__report): Use __gnu_cxx::__scoped_lock to lock/unlock __global_mutex
	rather than explicitely calling lock() method, exception safe.
	(__report_and_free): New. Call __report and free all profile mode
	resources.
	(__profcxx_init_unconditional): Use __scoped_lock. Register
	__report_and_free with atexit.
	* include/profile/impl/profiler_vector_size.h
	(__trace_vector_size_free): New.
	(__trace_vector_size_report): Call __trace_report.
	(__trace_vector_size_construct): Return __container_size_info*. Add
	check for reentrancy.
	* include/profile/impl/profiler_vector_to_list.h
	(__vector2list_info()): Delete.
	(virtual ~__vector2list_info()): Delete.
	(__vector2list_info(const __vector2list_info&)): Delete.
	(__vector2list_info::__merge): Call __object_info_base::__merge.
	(__vector2list_info::__is_valid): Delete.
	(__vector2list_info::__set_valid): Delete.
	(__vector2list_info::__opr_find): Delete.
	(__vector2list_info::_M_valid): Delete.
	(__trace_vector_to_list::__insert): Delete.
	(__trace_vector_to_list::__find): Delete.
	(__trace_vector_to_list::__opr_insert): Delete.
	(__trace_vector_to_list::__opr_iterate): Delete.
	(__trace_vector_to_list::__invalid_operator): Delete.
	(__trace_vector_to_list::__resize): Delete.
	(__trace_vector_to_list::__opr_find): Delete.
	(__trace_vector_to_list_free): New.
	(__trace_vector_to_list_report): Call __trace_report.
	(__trace_vector_to_list_construct): Return __vector2list_info*. Add
	check for reentrancy.
	* include/profile/iterator_tracker.h
	(__iterator_tracker<>::operator=): Add missing _M_ds assignment.
	(__iterator_tracker<>::_M_find): Delete.
	* include/profile/impl/profiler.h
	([_GLIBCXX_PROFILE_REENTRANCE_GUARD]): Delete.
	(__container_size_info): Add class declaration.
	(__hashfunc_info): Likewise.
	(__map2umap_info): Likewise.
	(__vector2list_info): Likewise.
	(__list2slist_info): Likewise.
	(__list2vector_info): Likewise.
	(__trace_list_to_set_destruct): Delete declaration.
	(__trace_list_to_set_construct): Likewise.
	(__trace_list_to_set_insert): Likewise.
	(__trace_list_to_set_iterate): Likewise.
	(__trace_list_to_set_invalid_operator): Likewise.
	(__trace_list_to_set_find): Likewise.
	([__profcxx_report]): Remove usage of _GLIBCXX_PROFILE_REENTRANCE_GUARD.
	([__profcxx_turn_on]): Likewise.
	([__profcxx_turn_off]): Likewise.
	([__profcxx_is_invalid]): Likewise.
	([__profcxx_is_on]): Likewise.
	([__profcxx_is_off]): Likewise.
	([__profcxx_hashtable_resize]): Likewise.
	([__profcxx_hashtable_destruct]): Likewise.
	([__profcxx_hashtable_construct]): Likewise.
	([__profcxx_vector_size_construct]): Likewise.
	([__profcxx_vector_size_resize]): Likewise.
	([__profcxx_vector_size_destruct]): Likewise.
	([__profcxx_inefficient_hash_is_on]): Delete.
	([__profcxx_hash_func_construct]): Remove usage of
	_GLIBCXX_PROFILE_REENTRANCE_GUARD.
	([__profcxx_hash_func_destruct]): Likewise.
	([__profcxx_vector_construct2]): Rename into...
	([__profcxx_vector2list_construct]): ... this. Remove usage of
	_GLIBCXX_PROFILE_REENTRANCE_GUARD.
	([__profcxx_vector_insert]): Rename into...
	([__profcxx_vector2list_insert]): ... this. Remove usage of
	_GLIBCXX_PROFILE_REENTRANCE_GUARD.
	([__profcxx_vector_iterate]): Rename into...
	([__profcxx_vector2list_iterate]): ... this. Remove usage of
	_GLIBCXX_PROFILE_REENTRANCE_GUARD.
	([__profcxx_vector_invalid_operator]): Rename into...
	([__profcxx_vector2list_invalid_operator]): ... this. Remove usage of
	_GLIBCXX_PROFILE_REENTRANCE_GUARD.
	([__profcxx_vector_resize2]): Rename into...
	([__profcxx_vector2list_resize]): ... this. Remove usage of
	_GLIBCXX_PROFILE_REENTRANCE_GUARD.
	([__profcxx_vector_destruct2]): Rename into...
	([__profcxx_vector2list_destruct]): ... this. Remove usage of
	_GLIBCXX_PROFILE_REENTRANCE_GUARD.
	([__profcxx_vector_find]): Delete.
	([__profcxx_list_construct2]): Rename into...
	([__profcxx_list2vector_construct]): ... this. Remove usage of
	_GLIBCXX_PROFILE_REENTRANCE_GUARD.
	([__profcxx_list_insert]): Rename into...
	([__profcxx_list2vector_insert]): ... this. Remove usage of
	_GLIBCXX_PROFILE_REENTRANCE_GUARD.
	([__profcxx_list_iterate]): Rename into...
	([__profcxx_list2vector_iterate]): ... this. Remove usage of
	_GLIBCXX_PROFILE_REENTRANCE_GUARD.
	([_profcxx_list_invalid_operator]): Rename into...
	([__profcxx_list2vector_invalid_operator]): ... this. Remove usage of
	_GLIBCXX_PROFILE_REENTRANCE_GUARD.
	([__profcxx_list_destruct2]): Rename into...
	([__profcxx_list2vector_destruct]): ... this. Remove usage of
	_GLIBCXX_PROFILE_REENTRANCE_GUARD.
	([__profcxx_list_construct]): Rename into...
	([__profcxx_list2slist_construct]): ... this. Remove usage of
	_GLIBCXX_PROFILE_REENTRANCE_GUARD.
	([__profcxx_list_rewind]): Rename into...
	([__profcxx_list2slist_rewind]): ... this. Remove usage of
	_GLIBCXX_PROFILE_REENTRANCE_GUARD.
	([__profcxx_list_operation]): Rename into...
	([__profcxx_list2slist_operation]): ... this. Remove usage of
	_GLIBCXX_PROFILE_REENTRANCE_GUARD.
	([__profcxx_list_destruct]): Rename into...
	([__profcxx_list2slist_destruct]): ... this. Remove usage of
	_GLIBCXX_PROFILE_REENTRANCE_GUARD.
	([__profcxx_map_to_unordered_map_construct]): Rename into...
	([__profcxx_map2umap_construct]): ... this. Remove usage of
	_GLIBCXX_PROFILE_REENTRANCE_GUARD.
	([__profcxx_map_to_unordered_map_insert]): Rename into...
	([__profcxx_map2umap_insert]): ... this. Remove usage of
	_GLIBCXX_PROFILE_REENTRANCE_GUARD.
	([__profcxx_map_to_unordered_map_erase]): Rename into...
	([__profcxx_map2umap_erase]): ... this. Remove usage of
	_GLIBCXX_PROFILE_REENTRANCE_GUARD.
	([__profcxx_map_to_unordered_map_iterate]): Rename into...
	([__profcxx_map2umap_iterate]): ... this. Remove usage of
	_GLIBCXX_PROFILE_REENTRANCE_GUARD.
	([__profcxx_map_to_unordered_map_invalidate]): Rename into...
	([__profcxx_map2umap_invalidate]): ... this. Remove usage of
	_GLIBCXX_PROFILE_REENTRANCE_GUARD.
	([__profcxx_map_to_unordered_map_find]): Rename into...
	([__profcxx_map2umap_find]): ... this. Remove usage of
	_GLIBCXX_PROFILE_REENTRANCE_GUARD.
	([__profcxx_map_to_unordered_map_destruct]): Rename into...
	([__profcxx_map2umap_destruct]): ... this. Remove usage of
	_GLIBCXX_PROFILE_REENTRANCE_GUARD.
	* include/profile/list
	(_List_profile): Adapt.
	(_List_profile::_M_profile_construct): New.
	(_List_profile()): Call latter.
	(_List_profile::_M_profile_destruct): New.
	(~_List_profile()): Call latter.
	(_List_profile::_M_swap): New.
	(_List_profile(_List_profile&&)): Call latter.
	(_List_profile::operator=(const _List_profile&)): Reinit profile
	structures.
	(_List_profile::operator=(_List_profile&&)): Move profile struct and
	re-init profile structures on moved instance.
	(std::__profile::list<>): Adapt.
	* include/profile/ordered_base.h
	(_Ordered_profile::_M_profile_iterate): New.
	(_Ordered_profile::_M_profile_construct): New.
	(_Ordered_profile()): Call latter.
	(_Ordered_profile::_M_swap): New.
	(_Ordered_profile(_Ordered_profile&&)): Call latter.
	(_Ordered_profile::operator=(const _Ordered_profile&)): Reinit
	profiling.
	(_Ordered_profile::operator=(_Ordered_profile&&)): Swap and reinit
	profiling on the moved instance.
	(_Ordered_profile::_M_profile_destruct): New.
	(~_Ordered_profile()): Call latter.
	* include/profile/map.h (std::__profile::map<>): Add profiling on
	iterators. Adapt.
	* include/profile/multimap.h (std::__profile::multimap<>): Likewise.
	* include/profile/set.h (std::__profile::set<>): Likewise.
	* include/profile/multiset.h (std::__profile::multiset<>): Likewise.
	* include/profile/unordered_base.h
	(_Unordered_profile::_M_profile_construct): New.
	(_Unordered_profile()): Call latter.
	(_Unordered_profile::_M_swap): New.
	(_Unordered_profile(_Unordered_profile&&)): Call latter.
	(_Unordered_profile::operator=(const _Unordered_profile&)): Reinit
	profiling.
	(_Unordered_profile::operator=(_Unordered_profile&&)): Swap and reinit
	profiling on the moved instance.
	(_Unordered_profile::_M_profile_destruct): New.
	(~_Ordered_profile()): Call latter.
	* include/profile/unordered_map
	(std::__profile::unordered_map<>): Adapt.
	(std::__profile::unordered_multimap<>): Adapt.
	* include/profile/unordered_set
	(std::__profile::unordered_set<>): Adapt.
	(std::__profile::unordered_multiset<>): Adapt.
	* include/profile/vector
	(_Vector_profile_pre::_M_profile_destruct): Move...
	(_Vector_profile_post::_M_profile_destruct): ...here.
	(_Vector_profile_post::_M_profile_construct): New.
	(_Vector_profile_post()): Call latter.
	(std::__profile::vector<>): Adapt.
	* testsuite/ext/profile/mh.cc: Rename into...
	* testsuite/ext/profile/replace_new.cc: ... this and fix test.

From-SVN: r217321
parent 6750565c
......@@ -43,27 +43,12 @@ namespace __gnu_profile
: public __object_info_base
{
public:
__container_size_info()
: _M_init(0), _M_max(0), _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)
{ }
__container_size_info(const __container_size_info& __o)
: __object_info_base(__o), _M_init(__o._M_init), _M_max(__o._M_max),
_M_min(__o._M_min), _M_total(__o._M_total),
_M_item_min(__o._M_item_min), _M_item_max(__o._M_item_max),
_M_item_total(__o._M_item_total), _M_count(__o._M_count),
_M_resize(__o._M_resize), _M_cost(__o._M_cost)
{ }
__container_size_info(__stack_t __stack, std::size_t __num)
: __object_info_base(__stack), _M_init(__num), _M_max(__num),
__container_size_info(__stack_t __stack)
: __object_info_base(__stack), _M_init(0), _M_max(0),
_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)
{ }
virtual ~__container_size_info() { }
void
__write(FILE* __f) const
{
......@@ -87,8 +72,16 @@ namespace __gnu_profile
}
void
__init(std::size_t __num)
{
_M_init = __num;
_M_max = __num;
}
void
__merge(const __container_size_info& __o)
{
__object_info_base::__merge(__o);
_M_init = std::max(_M_init, __o._M_init);
_M_max = std::max(_M_max, __o._M_max);
_M_item_max = std::max(_M_item_max, __o._M_item_max);
......@@ -117,6 +110,7 @@ namespace __gnu_profile
_M_min = std::min(_M_min, __num);
_M_item_min = std::min(_M_item_min, __inum);
}
_M_total += __num;
_M_item_total += __inum;
_M_count += 1;
......@@ -149,7 +143,6 @@ namespace __gnu_profile
std::size_t _M_cost;
};
/** @brief A container size instrumentation line in the stack table. */
class __container_size_stack_info
: public __container_size_info
......@@ -158,7 +151,6 @@ namespace __gnu_profile
__container_size_stack_info(const __container_size_info& __o)
: __container_size_info(__o) { }
};
/** @brief Container size instrumentation trace producer. */
class __trace_container_size
......@@ -171,43 +163,22 @@ namespace __gnu_profile
: __trace_base<__container_size_info, __container_size_stack_info>() { };
// Insert a new node at construct with object, callstack and initial size.
void
__insert(const __object_t __obj, __stack_t __stack, std::size_t __num)
{ __add_object(__obj, __container_size_info(__stack, __num)); }
// XXX Undefined?
void
__construct(const void* __obj, std::size_t __inum);
// Call at destruction/clean to set container final size.
void
__destruct(const void* __obj, std::size_t __num, std::size_t __inum)
__container_size_info*
__insert(__stack_t __stack, std::size_t __num)
{
if (!__is_on())
return;
__object_t __obj_handle = static_cast<__object_t>(__obj);
__container_size_info* __object_info = __get_object_info(__obj_handle);
if (!__object_info)
return;
__object_info->__destruct(__num, __inum);
__retire_object(__obj_handle);
__container_size_info* __ret = __add_object(__stack);
if (__ret)
__ret->__init(__num);
return __ret;
}
// Call at resize to set resize/cost information.
// Call at destruction/clean to set container final size.
void
__resize(const void* __obj, int __from, int __to)
__destruct(__container_size_info* __obj_info,
std::size_t __num, std::size_t __inum)
{
if (!__is_on())
return;
__container_size_info* __object_info = __get_object_info(__obj);
if (!__object_info)
return;
__object_info->__resize(__from, __to);
__obj_info->__destruct(__num, __inum);
__retire_object(__obj_info);
}
};
......
......@@ -41,22 +41,14 @@ namespace __gnu_profile
: public __object_info_base
{
public:
__hashfunc_info()
: _M_longest_chain(0), _M_accesses(0), _M_hops(0) { }
__hashfunc_info(const __hashfunc_info& __o)
: __object_info_base(__o), _M_longest_chain(__o._M_longest_chain),
_M_accesses(__o._M_accesses), _M_hops(__o._M_hops) { }
__hashfunc_info(__stack_t __stack)
: __object_info_base(__stack), _M_longest_chain(0),
_M_accesses(0), _M_hops(0) { }
virtual ~__hashfunc_info() { }
void
__merge(const __hashfunc_info& __o)
{
__object_info_base::__merge(__o);
_M_longest_chain = std::max(_M_longest_chain, __o._M_longest_chain);
_M_accesses += __o._M_accesses;
_M_hops += __o._M_hops;
......@@ -90,7 +82,6 @@ namespace __gnu_profile
std::size_t _M_hops;
};
/** @brief A hash performance instrumentation line in the stack table. */
class __hashfunc_stack_info
: public __hashfunc_info
......@@ -100,7 +91,6 @@ namespace __gnu_profile
: __hashfunc_info(__o) { }
};
/** @brief Hash performance instrumentation producer. */
class __trace_hash_func
: public __trace_base<__hashfunc_info, __hashfunc_stack_info>
......@@ -112,61 +102,50 @@ namespace __gnu_profile
~__trace_hash_func() {}
// Insert a new node at construct with object, callstack and initial size.
void
__insert(__object_t __obj, __stack_t __stack)
{ __add_object(__obj, __hashfunc_info(__stack)); }
// Call at destruction/clean to set container final size.
void
__destruct(const void* __obj, std::size_t __chain,
std::size_t __accesses, std::size_t __hops)
__destruct(__hashfunc_info* __obj_info,
std::size_t __chain, std::size_t __accesses, std::size_t __hops)
{
if (!__is_on())
return;
// First find the item from the live objects and update the information.
__hashfunc_info* __objs = __get_object_info(__obj);
if (!__objs)
if (!__obj_info)
return;
__objs->__destruct(__chain, __accesses, __hops);
__retire_object(__obj);
__obj_info->__destruct(__chain, __accesses, __hops);
__retire_object(__obj_info);
}
};
inline void
__trace_hash_func_init()
{ _GLIBCXX_PROFILE_DATA(_S_hash_func) = new __trace_hash_func(); }
inline void
__trace_hash_func_report(FILE* __f, __warning_vector_t& __warnings)
{
if (_GLIBCXX_PROFILE_DATA(_S_hash_func))
{
_GLIBCXX_PROFILE_DATA(_S_hash_func)->__collect_warnings(__warnings);
_GLIBCXX_PROFILE_DATA(_S_hash_func)->__write(__f);
}
}
__trace_hash_func_free()
{ delete _GLIBCXX_PROFILE_DATA(_S_hash_func); }
inline void
__trace_hash_func_construct(const void* __obj)
__trace_hash_func_report(FILE* __f, __warning_vector_t& __warnings)
{ __trace_report(_GLIBCXX_PROFILE_DATA(_S_hash_func), __f, __warnings); }
inline __hashfunc_info*
__trace_hash_func_construct()
{
if (!__profcxx_init())
return;
return 0;
if (!__reentrance_guard::__get_in())
return 0;
_GLIBCXX_PROFILE_DATA(_S_hash_func)->__insert(__obj, __get_stack());
__reentrance_guard __get_out;
return _GLIBCXX_PROFILE_DATA(_S_hash_func)->__add_object(__get_stack());
}
inline void
__trace_hash_func_destruct(const void* __obj, std::size_t __chain,
std::size_t __accesses, std::size_t __hops)
__trace_hash_func_destruct(__hashfunc_info* __obj_info,
std::size_t __chain, std::size_t __accesses,
std::size_t __hops)
{
if (!__profcxx_init())
return;
_GLIBCXX_PROFILE_DATA(_S_hash_func)->__destruct(__obj, __chain,
_GLIBCXX_PROFILE_DATA(_S_hash_func)->__destruct(__obj_info, __chain,
__accesses, __hops);
}
......
......@@ -53,44 +53,46 @@ namespace __gnu_profile
{ _GLIBCXX_PROFILE_DATA(_S_hashtable_size) = new __trace_hashtable_size(); }
inline void
__trace_hashtable_size_report(FILE* __f, __warning_vector_t& __warnings)
{
if (_GLIBCXX_PROFILE_DATA(_S_hashtable_size))
{
_GLIBCXX_PROFILE_DATA(_S_hashtable_size)->
__collect_warnings(__warnings);
_GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__write(__f);
}
}
__trace_hashtable_size_free()
{ delete _GLIBCXX_PROFILE_DATA(_S_hashtable_size); }
inline void
__trace_hashtable_size_construct(const void* __obj, std::size_t __num)
__trace_hashtable_size_report(FILE* __f, __warning_vector_t& __warnings)
{ __trace_report(_GLIBCXX_PROFILE_DATA(_S_hashtable_size), __f, __warnings); }
inline __container_size_info*
__trace_hashtable_size_construct(std::size_t __num)
{
if (!__profcxx_init())
return;
return 0;
_GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__insert(__obj, __get_stack(),
__num);
if (!__reentrance_guard::__get_in())
return 0;
__reentrance_guard __get_out;
return _GLIBCXX_PROFILE_DATA(_S_hashtable_size)->
__insert(__get_stack(), __num);
}
inline void
__trace_hashtable_size_destruct(const void* __obj, std::size_t __num,
std::size_t __inum)
__trace_hashtable_size_resize(__container_size_info* __obj_info,
std::size_t __from, std::size_t __to)
{
if (!__profcxx_init())
if (!__obj_info)
return;
_GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__destruct(__obj, __num, __inum);
__obj_info->__resize(__from, __to);
}
inline void
__trace_hashtable_size_resize(const void* __obj, std::size_t __from,
std::size_t __to)
__trace_hashtable_size_destruct(__container_size_info* __obj_info,
std::size_t __num, std::size_t __inum)
{
if (!__profcxx_init())
if (!__obj_info)
return;
_GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__resize(__obj, __from, __to);
_GLIBCXX_PROFILE_DATA(_S_hashtable_size)->
__destruct(__obj_info, __num, __inum);
}
} // namespace __gnu_profile
......
......@@ -40,18 +40,9 @@ namespace __gnu_profile
: public __object_info_base
{
public:
__list2slist_info()
: _M_rewind(false), _M_operations(0) { }
__list2slist_info(__stack_t __stack)
: __object_info_base(__stack), _M_rewind(false), _M_operations(0) { }
virtual ~__list2slist_info() { }
__list2slist_info(const __list2slist_info& __o)
: __object_info_base(__o), _M_rewind(__o._M_rewind),
_M_operations(__o._M_operations) { }
// XXX: the magnitude should be multiplied with a constant factor F,
// where F is 1 when the malloc size class of list nodes is different
// from the malloc size class of slist nodes. When they fall into the same
......@@ -70,9 +61,6 @@ namespace __gnu_profile
}
void
__merge(const __list2slist_info&) { }
void
__write(FILE* __f) const
{ std::fprintf(__f, "%s\n", _M_rewind ? "invalid" : "valid"); }
......@@ -84,7 +72,7 @@ namespace __gnu_profile
__opr_rewind()
{
_M_rewind = true;
_M_valid = false;
__set_invalid();
}
void
......@@ -119,37 +107,8 @@ namespace __gnu_profile
{ __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);
}
__destruct(__list2slist_info* __obj_info)
{ __retire_object(__obj_info); }
};
......@@ -158,50 +117,51 @@ namespace __gnu_profile
{ _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);
}
}
__trace_list_to_slist_free()
{ delete _GLIBCXX_PROFILE_DATA(_S_list_to_slist); }
inline void
__trace_list_to_slist_rewind(const void* __obj)
__trace_list_to_slist_report(FILE* __f, __warning_vector_t& __warnings)
{ __trace_report(_GLIBCXX_PROFILE_DATA(_S_list_to_slist), __f, __warnings); }
inline __list2slist_info*
__trace_list_to_slist_construct()
{
if (!__profcxx_init())
return;
return 0;
if (!__reentrance_guard::__get_in())
return 0;
_GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__opr_rewind(__obj);
__reentrance_guard __get_out;
return _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__add_object(__get_stack());
}
inline void
__trace_list_to_slist_operation(const void* __obj)
__trace_list_to_slist_rewind(__list2slist_info* __obj_info)
{
if (!__profcxx_init())
if (!__obj_info)
return;
_GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__record_operation(__obj);
__obj_info->__opr_rewind();
}
inline void
__trace_list_to_slist_construct(const void* __obj)
__trace_list_to_slist_operation(__list2slist_info* __obj_info)
{
if (!__profcxx_init())
if (!__obj_info)
return;
_GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__insert(__obj, __get_stack());
__obj_info->__record_operation();
}
inline void
__trace_list_to_slist_destruct(const void* __obj)
__trace_list_to_slist_destruct(__list2slist_info* __obj_info)
{
if (!__profcxx_init())
if (!__obj_info)
return;
_GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__destruct(__obj);
_GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__destruct(__obj_info);
}
} // namespace __gnu_profile
......
......@@ -43,31 +43,19 @@ namespace __gnu_profile
: public __object_info_base
{
public:
__list2vector_info()
: _M_shift_count(0), _M_iterate(0), _M_resize(0), _M_list_cost(0),
_M_vector_cost(0), _M_valid(true), _M_max_size(0) { }
__list2vector_info(__stack_t __stack)
: __object_info_base(__stack), _M_shift_count(0), _M_iterate(0),
_M_resize(0), _M_list_cost(0), _M_vector_cost(0), _M_valid(true),
_M_resize(0), _M_list_cost(0), _M_vector_cost(0),
_M_max_size(0) { }
virtual ~__list2vector_info() { }
__list2vector_info(const __list2vector_info& __o)
: __object_info_base(__o), _M_shift_count(__o._M_shift_count),
_M_iterate(__o._M_iterate), _M_resize(__o._M_resize),
_M_list_cost(__o._M_list_cost), _M_vector_cost(__o._M_vector_cost),
_M_valid(__o._M_valid), _M_max_size(__o._M_max_size) { }
void
__merge(const __list2vector_info& __o)
{
__object_info_base::__merge(__o);
_M_shift_count += __o._M_shift_count;
_M_iterate += __o._M_iterate;
_M_vector_cost += __o._M_vector_cost;
_M_list_cost += __o._M_list_cost;
_M_valid &= __o._M_valid;
_M_resize += __o._M_resize;
_M_max_size = std::max( _M_max_size, __o._M_max_size);
}
......@@ -117,14 +105,6 @@ namespace __gnu_profile
__set_vector_cost(float __vc)
{ _M_vector_cost = __vc; }
bool
__is_valid()
{ return _M_valid; }
void
__set_invalid()
{ _M_valid = false; }
void
__opr_insert(std::size_t __shift, std::size_t __size)
{
......@@ -133,8 +113,8 @@ namespace __gnu_profile
}
void
__opr_iterate(std::size_t __num)
{ _M_iterate += __num;}
__opr_iterate(int __num)
{ __gnu_cxx::__atomic_add(&_M_iterate, __num); }
void
__resize(std::size_t __from, std::size_t)
......@@ -142,11 +122,10 @@ namespace __gnu_profile
private:
std::size_t _M_shift_count;
std::size_t _M_iterate;
mutable _Atomic_word _M_iterate;
std::size_t _M_resize;
float _M_list_cost;
float _M_vector_cost;
bool _M_valid;
std::size_t _M_max_size;
};
......@@ -168,65 +147,20 @@ namespace __gnu_profile
~__trace_list_to_vector() { }
// Insert a new node at construct with object, callstack and initial size.
void
__insert(__object_t __obj, __stack_t __stack)
{ __add_object(__obj, __list2vector_info(__stack)); }
// Call at destruction/clean to set container final size.
void
__destruct(const void* __obj)
__destruct(__list2vector_info* __obj_info)
{
if (!__is_on())
return;
__list2vector_info* __res = __get_object_info(__obj);
if (!__res)
return;
float __vc = __vector_cost(__res->__shift_count(), __res->__iterate());
float __lc = __list_cost(__res->__shift_count(), __res->__iterate());
__res->__set_vector_cost(__vc);
__res->__set_list_cost(__lc);
__retire_object(__obj);
float __vc = __vector_cost(__obj_info->__shift_count(),
__obj_info->__iterate());
float __lc = __list_cost(__obj_info->__shift_count(),
__obj_info->__iterate());
__obj_info->__set_vector_cost(__vc);
__obj_info->__set_list_cost(__lc);
__retire_object(__obj_info);
}
// Find the node in the live map.
__list2vector_info* __find(const void* __obj);
// Collect cost of operations.
void
__opr_insert(const void* __obj, std::size_t __shift, std::size_t __size)
{
__list2vector_info* __res = __get_object_info(__obj);
if (__res)
__res->__opr_insert(__shift, __size);
}
void
__opr_iterate(const void* __obj, std::size_t __num)
{
__list2vector_info* __res = __get_object_info(__obj);
if (__res)
__res->__opr_iterate(__num);
}
void
__invalid_operator(const void* __obj)
{
__list2vector_info* __res = __get_object_info(__obj);
if (__res)
__res->__set_invalid();
}
void
__resize(const void* __obj, std::size_t __from, std::size_t __to)
{
__list2vector_info* __res = __get_object_info(__obj);
if (__res)
__res->__resize(__from, __to);
}
float
__vector_cost(std::size_t __shift, std::size_t __iterate)
{
......@@ -253,71 +187,74 @@ namespace __gnu_profile
{ _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);
}
}
__trace_list_to_vector_free()
{ delete _GLIBCXX_PROFILE_DATA(_S_list_to_vector); }
inline void
__trace_list_to_vector_construct(const void* __obj)
__trace_list_to_vector_report(FILE* __f, __warning_vector_t& __warnings)
{ __trace_report(_GLIBCXX_PROFILE_DATA(_S_list_to_vector), __f, __warnings); }
inline __list2vector_info*
__trace_list_to_vector_construct()
{
if (!__profcxx_init())
return;
return 0;
_GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__insert(__obj, __get_stack());
if (!__reentrance_guard::__get_in())
return 0;
__reentrance_guard __get_out;
return _GLIBCXX_PROFILE_DATA(_S_list_to_vector)
->__add_object(__get_stack());
}
inline void
__trace_list_to_vector_destruct(const void* __obj)
__trace_list_to_vector_insert(__list2vector_info* __obj_info,
std::size_t __shift, std::size_t __size)
{
if (!__profcxx_init())
if (!__obj_info)
return;
_GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__destruct(__obj);
__obj_info->__opr_insert(__shift, __size);
}
inline void
__trace_list_to_vector_insert(const void* __obj,
std::size_t __shift, std::size_t __size)
__trace_list_to_vector_iterate(__list2vector_info* __obj_info,
int)
{
if (!__profcxx_init())
if (!__obj_info)
return;
_GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__opr_insert(__obj, __shift,
__size);
// We only collect if an iteration took place no matter in what side.
__obj_info->__opr_iterate(1);
}
inline void
__trace_list_to_vector_iterate(const void* __obj, std::size_t __num = 1)
__trace_list_to_vector_invalid_operator(__list2vector_info* __obj_info)
{
if (!__profcxx_init())
if (!__obj_info)
return;
_GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__opr_iterate(__obj, __num);
__obj_info->__set_invalid();
}
inline void
__trace_list_to_vector_invalid_operator(const void* __obj)
__trace_list_to_vector_resize(__list2vector_info* __obj_info,
std::size_t __from, std::size_t __to)
{
if (!__profcxx_init())
if (!__obj_info)
return;
_GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__invalid_operator(__obj);
__obj_info->__resize(__from, __to);
}
inline void
__trace_list_to_vector_resize(const void* __obj,
std::size_t __from, std::size_t __to)
__trace_list_to_vector_destruct(__list2vector_info* __obj_info)
{
if (!__profcxx_init())
if (!__obj_info)
return;
_GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__resize(__obj, __from, __to);
_GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__destruct(__obj_info);
}
} // namespace __gnu_profile
......
......@@ -67,39 +67,29 @@ namespace __gnu_profile
: public __object_info_base
{
public:
__map2umap_info()
: _M_insert(0), _M_erase(0), _M_find(0), _M_iterate(0),
_M_umap_cost(0.0), _M_map_cost(0.0), _M_valid(true) { }
__map2umap_info(__stack_t __stack)
: __object_info_base(__stack), _M_insert(0), _M_erase(0), _M_find(0),
_M_iterate(0), _M_umap_cost(0.0), _M_map_cost(0.0), _M_valid(true) { }
virtual ~__map2umap_info() { }
__map2umap_info(const __map2umap_info& __o)
: __object_info_base(__o), _M_insert(__o._M_insert),
_M_erase(__o._M_erase), _M_find(__o._M_find),
_M_iterate(__o._M_iterate), _M_umap_cost(__o._M_umap_cost),
_M_map_cost(__o._M_map_cost), _M_valid(__o._M_valid) { }
_M_iterate(0), _M_umap_cost(0.0), _M_map_cost(0.0)
{ }
void
__merge(const __map2umap_info& __o)
{
_M_insert += __o._M_insert;
_M_erase += __o._M_erase;
_M_find += __o._M_find;
_M_umap_cost += __o._M_umap_cost;
_M_map_cost += __o._M_map_cost;
_M_valid &= __o._M_valid;
__object_info_base::__merge(__o);
_M_insert += __o._M_insert;
_M_erase += __o._M_erase;
_M_find += __o._M_find;
_M_iterate += __o._M_iterate;
_M_umap_cost += __o._M_umap_cost;
_M_map_cost += __o._M_map_cost;
}
void
__write(FILE* __f) const
{
std::fprintf(__f, "%Zu %Zu %Zu %Zu %.0f %.0f %s\n",
std::fprintf(__f, "%Zu %Zu %Zu %Zu %.0f %.0f\n",
_M_insert, _M_erase, _M_find, _M_iterate, _M_map_cost,
_M_umap_cost, _M_valid ? "valid" : "invalid");
_M_umap_cost);
}
float
......@@ -145,29 +135,27 @@ namespace __gnu_profile
}
void
__record_iterate(std::size_t __count)
__record_iterate(int __count)
{ __gnu_cxx::__atomic_add(&_M_iterate, __count); }
void
__set_iterate_costs()
{
_M_iterate += __count;
_M_map_cost
+= (__count
* _GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor).__value);
_M_umap_cost
+= (__count
+= (_M_iterate
* _GLIBCXX_PROFILE_DATA(__umap_iterate_cost_factor).__value);
_M_map_cost
+= (_M_iterate
* _GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor).__value);
}
void
__record_invalidate()
{ _M_valid = false; }
private:
std::size_t _M_insert;
std::size_t _M_erase;
std::size_t _M_find;
std::size_t _M_iterate;
mutable _Atomic_word _M_iterate;
float _M_umap_cost;
float _M_map_cost;
bool _M_valid;
};
......@@ -189,6 +177,14 @@ namespace __gnu_profile
__trace_map2umap()
: __trace_base<__map2umap_info, __map2umap_stack_info>()
{ __id = "ordered-to-unordered"; }
// Call at destruction/clean to set container final size.
void
__destruct(__map2umap_info* __obj_info)
{
__obj_info->__set_iterate_costs();
__retire_object(__obj_info);
}
};
inline void
......@@ -196,101 +192,84 @@ namespace __gnu_profile
{ _GLIBCXX_PROFILE_DATA(_S_map2umap) = new __trace_map2umap(); }
inline void
__trace_map_to_unordered_map_free()
{ delete _GLIBCXX_PROFILE_DATA(_S_map2umap); }
inline void
__trace_map_to_unordered_map_report(FILE* __f,
__warning_vector_t& __warnings)
{
if (_GLIBCXX_PROFILE_DATA(_S_map2umap))
{
_GLIBCXX_PROFILE_DATA(_S_map2umap)->__collect_warnings(__warnings);
_GLIBCXX_PROFILE_DATA(_S_map2umap)->__write(__f);
}
}
{ __trace_report(_GLIBCXX_PROFILE_DATA(_S_map2umap), __f, __warnings); }
inline void
__trace_map_to_unordered_map_construct(const void* __obj)
inline __map2umap_info*
__trace_map_to_unordered_map_construct()
{
if (!__profcxx_init())
return;
return 0;
if (!__reentrance_guard::__get_in())
return 0;
_GLIBCXX_PROFILE_DATA(_S_map2umap)->
__add_object(__obj, __map2umap_info(__get_stack()));
__reentrance_guard __get_out;
return _GLIBCXX_PROFILE_DATA(_S_map2umap)->__add_object(__get_stack());
}
inline void
__trace_map_to_unordered_map_destruct(const void* __obj)
__trace_map_to_unordered_map_insert(__map2umap_info* __info,
std::size_t __size, std::size_t __count)
{
if (!__profcxx_init())
if (!__info)
return;
_GLIBCXX_PROFILE_DATA(_S_map2umap)->__retire_object(__obj);
__info->__record_insert(__size, __count);
}
inline void
__trace_map_to_unordered_map_insert(const void* __obj,
std::size_t __size, std::size_t __count)
__trace_map_to_unordered_map_erase(__map2umap_info* __info,
std::size_t __size, std::size_t __count)
{
if (!__profcxx_init())
if (!__info)
return;
__map2umap_info* __info
= _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
if (__info)
__info->__record_insert(__size, __count);
__info->__record_erase(__size, __count);
}
inline void
__trace_map_to_unordered_map_erase(const void* __obj,
std::size_t __size, std::size_t __count)
__trace_map_to_unordered_map_find(__map2umap_info* __info,
std::size_t __size)
{
if (!__profcxx_init())
if (!__info)
return;
__map2umap_info* __info
= _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
if (__info)
__info->__record_erase(__size, __count);
__info->__record_find(__size);
}
inline void
__trace_map_to_unordered_map_find(const void* __obj, std::size_t __size)
__trace_map_to_unordered_map_iterate(__map2umap_info* __info,
int)
{
if (!__profcxx_init())
if (!__info)
return;
__map2umap_info* __info
= _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
if (__info)
__info->__record_find(__size);
// We only collect if an iteration took place no matter in what side.
__info->__record_iterate(1);
}
inline void
__trace_map_to_unordered_map_iterate(const void* __obj, std::size_t __count)
__trace_map_to_unordered_map_invalidate(__map2umap_info* __info)
{
if (!__profcxx_init())
if (!__info)
return;
__map2umap_info* __info
= _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
if (__info)
__info->__record_iterate(__count);
__info->__set_invalid();
}
inline void
__trace_map_to_unordered_map_invalidate(const void* __obj)
__trace_map_to_unordered_map_destruct(__map2umap_info* __info)
{
if (!__profcxx_init())
if (!__info)
return;
__map2umap_info* __info
= _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
if (__info)
__info->__record_invalidate();
_GLIBCXX_PROFILE_DATA(_S_map2umap)->__destruct(__info);
}
} // namespace __gnu_profile
#endif /* _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H */
......@@ -39,7 +39,6 @@
namespace __gnu_profile
{
typedef const void* __object_t;
typedef void* __instruction_address_t;
typedef std::_GLIBCXX_STD_C::vector<__instruction_address_t> __stack_npt;
typedef __stack_npt* __stack_t;
......@@ -50,15 +49,20 @@ namespace __gnu_profile
__get_stack()
{
#if defined _GLIBCXX_HAVE_EXECINFO_H
std::size_t __max_depth = __stack_max_depth();
if (__max_depth == 0)
return 0;
__stack_npt __buffer(__max_depth);
int __depth = backtrace(&__buffer[0], __max_depth);
__stack_t __stack = new __stack_npt(__depth);
__builtin_memcpy(&(*__stack)[0], &__buffer[0],
__depth * sizeof(__object_t));
return __stack;
__try
{
std::size_t __max_depth = __stack_max_depth();
if (__max_depth == 0)
return 0;
__stack_npt __buffer(__max_depth);
int __depth = backtrace(&__buffer[0], __max_depth);
return new(std::nothrow) __stack_npt(__buffer.begin(),
__buffer.begin() + __depth);
}
__catch(...)
{
return 0;
}
#else
return 0;
#endif
......@@ -123,44 +127,29 @@ namespace __gnu_profile
class __object_info_base
{
public:
__object_info_base() { }
__object_info_base(__stack_t __stack)
: _M_stack(__stack), _M_valid(true) { }
__object_info_base(const __object_info_base& __o)
: _M_stack(__o._M_stack), _M_valid(__o._M_valid) { }
virtual ~__object_info_base() { }
bool
__is_valid() const
{ return _M_valid; }
void
__set_invalid()
{ _M_valid = false; }
void
__merge(const __object_info_base& __o)
{ _M_valid &= __o._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
#endif /* _GLIBCXX_PROFILE_PROFILER_NODE_H */
......@@ -53,43 +53,46 @@ namespace __gnu_profile
{ _GLIBCXX_PROFILE_DATA(_S_vector_size) = new __trace_vector_size(); }
inline void
__trace_vector_size_report(FILE* __f, __warning_vector_t& __warnings)
{
if (_GLIBCXX_PROFILE_DATA(_S_vector_size))
{
_GLIBCXX_PROFILE_DATA(_S_vector_size)->__collect_warnings(__warnings);
_GLIBCXX_PROFILE_DATA(_S_vector_size)->__write(__f);
}
}
__trace_vector_size_free()
{ delete _GLIBCXX_PROFILE_DATA(_S_vector_size); }
inline void
__trace_vector_size_construct(const void* __obj, std::size_t __num)
__trace_vector_size_report(FILE* __f, __warning_vector_t& __warnings)
{ __trace_report(_GLIBCXX_PROFILE_DATA(_S_vector_size), __f, __warnings); }
inline __container_size_info*
__trace_vector_size_construct(std::size_t __num)
{
if (!__profcxx_init())
return;
return 0;
if (!__reentrance_guard::__get_in())
return 0;
_GLIBCXX_PROFILE_DATA(_S_vector_size)->__insert(__obj, __get_stack(),
__num);
__reentrance_guard __get_out;
return _GLIBCXX_PROFILE_DATA(_S_vector_size)->
__insert(__get_stack(), __num);
}
inline void
__trace_vector_size_destruct(const void* __obj, std::size_t __num,
std::size_t __inum)
__trace_vector_size_resize(__container_size_info* __obj_info,
std::size_t __from, std::size_t __to)
{
if (!__profcxx_init())
if (!__obj_info)
return;
_GLIBCXX_PROFILE_DATA(_S_vector_size)->__destruct(__obj, __num, __inum);
__obj_info->__resize(__from, __to);
}
inline void
__trace_vector_size_resize(const void* __obj, std::size_t __from,
std::size_t __to)
__trace_vector_size_destruct(__container_size_info* __obj_info,
std::size_t __num, std::size_t __inum)
{
if (!__profcxx_init())
if (!__obj_info)
return;
_GLIBCXX_PROFILE_DATA(_S_vector_size)->__resize(__obj, __from, __to);
_GLIBCXX_PROFILE_DATA(_S_vector_size)->
__destruct(__obj_info, __num, __inum);
}
} // namespace __gnu_profile
......
......@@ -41,30 +41,19 @@ namespace __gnu_profile
: public __object_info_base
{
public:
__vector2list_info()
: _M_shift_count(0), _M_iterate(0), _M_resize(0), _M_list_cost(0),
_M_vector_cost(0), _M_valid(true) { }
__vector2list_info(__stack_t __stack)
: __object_info_base(__stack), _M_shift_count(0), _M_iterate(0),
_M_resize(0), _M_list_cost(0), _M_vector_cost(0), _M_valid(true) { }
virtual ~__vector2list_info() { }
__vector2list_info(const __vector2list_info& __o)
: __object_info_base(__o), _M_shift_count(__o._M_shift_count),
_M_iterate(__o._M_iterate), _M_resize(__o._M_resize),
_M_list_cost(__o._M_list_cost), _M_vector_cost(__o._M_vector_cost),
_M_valid(__o._M_valid) { }
_M_resize(0), _M_list_cost(0), _M_vector_cost(0)
{ }
void
__merge(const __vector2list_info& __o)
{
__object_info_base::__merge(__o);
_M_shift_count += __o._M_shift_count;
_M_iterate += __o._M_iterate;
_M_vector_cost += __o._M_vector_cost;
_M_list_cost += __o._M_list_cost;
_M_valid &= __o._M_valid;
_M_resize += __o._M_resize;
}
......@@ -107,40 +96,24 @@ namespace __gnu_profile
__set_vector_cost(float __vc)
{ _M_vector_cost = __vc; }
bool
__is_valid()
{ return _M_valid; }
void
__set_invalid()
{ _M_valid = false; }
void
__opr_insert(std::size_t __pos, std::size_t __num)
{ _M_shift_count += __num - __pos; }
void
__opr_iterate(std::size_t __num)
{ _M_iterate += __num; }
__opr_iterate(int __num)
{ __gnu_cxx::__atomic_add(&_M_iterate, __num); }
void
__resize(std::size_t __from, std::size_t)
{ _M_resize += __from; }
void
__opr_find(std::size_t __size)
{
// Use average case complexity.
_M_iterate += 3.0 / 4.0 * __size;
}
private:
std::size_t _M_shift_count;
std::size_t _M_iterate;
mutable _Atomic_word _M_iterate;
std::size_t _M_resize;
float _M_list_cost;
float _M_vector_cost;
bool _M_valid;
};
......@@ -165,69 +138,23 @@ namespace __gnu_profile
~__trace_vector_to_list() { }
// Insert a new node at construct with object, callstack and initial size.
void
__insert(__object_t __obj, __stack_t __stack)
{ __add_object(__obj, __vector2list_info(__stack)); }
// Call at destruction/clean to set container final size.
void
__destruct(const void* __obj)
__destruct(__vector2list_info* __obj_info)
{
if (!__is_on())
return;
__vector2list_info* __res = __get_object_info(__obj);
if (!__res)
return;
float __vc = __vector_cost(__res->__shift_count(), __res->__iterate(),
__res->__resize());
float __lc = __list_cost(__res->__shift_count(), __res->__iterate(),
__res->__resize());
__res->__set_vector_cost(__vc);
__res->__set_list_cost(__lc);
__retire_object(__obj);
float __vc = __vector_cost(__obj_info->__shift_count(),
__obj_info->__iterate(),
__obj_info->__resize());
float __lc = __list_cost(__obj_info->__shift_count(),
__obj_info->__iterate(),
__obj_info->__resize());
__obj_info->__set_vector_cost(__vc);
__obj_info->__set_list_cost(__lc);
__retire_object(__obj_info);
}
// Find the node in the live map.
// XXX Undefined?!?
__vector2list_info* __find(const void* __obj);
// Collect cost of operations.
void
__opr_insert(const void* __obj, std::size_t __pos, std::size_t __num)
{
__vector2list_info* __res = __get_object_info(__obj);
if (__res)
__res->__opr_insert(__pos, __num);
}
void
__opr_iterate(const void* __obj, std::size_t __num)
{
__vector2list_info* __res = __get_object_info(__obj);
if (__res)
__res->__opr_iterate(__num);
}
void
__invalid_operator(const void* __obj)
{
__vector2list_info* __res = __get_object_info(__obj);
if (__res)
__res->__set_invalid();
}
void
__resize(const void* __obj, std::size_t __from, std::size_t __to)
{
__vector2list_info* __res = __get_object_info(__obj);
if (__res)
__res->__resize(__from, __to);
}
float
__vector_cost(std::size_t __shift, std::size_t __iterate,
std::size_t __resize)
......@@ -251,14 +178,6 @@ namespace __gnu_profile
+ __resize
* _GLIBCXX_PROFILE_DATA(__list_resize_cost_factor).__value);
}
void
__opr_find(const void* __obj, std::size_t __size)
{
__vector2list_info* __res = __get_object_info(__obj);
if (__res)
__res->__opr_find(__size);
}
};
......@@ -267,80 +186,75 @@ namespace __gnu_profile
{ _GLIBCXX_PROFILE_DATA(_S_vector_to_list) = new __trace_vector_to_list(); }
inline void
__trace_vector_to_list_report(FILE* __f, __warning_vector_t& __warnings)
{
if (_GLIBCXX_PROFILE_DATA(_S_vector_to_list))
{
_GLIBCXX_PROFILE_DATA(_S_vector_to_list)->
__collect_warnings(__warnings);
_GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__write(__f);
}
}
__trace_vector_to_list_free()
{ delete _GLIBCXX_PROFILE_DATA(_S_vector_to_list); }
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());
}
__trace_vector_to_list_report(FILE* __f, __warning_vector_t& __warnings)
{ __trace_report(_GLIBCXX_PROFILE_DATA(_S_vector_to_list), __f, __warnings); }
inline void
__trace_vector_to_list_destruct(const void* __obj)
inline __vector2list_info*
__trace_vector_to_list_construct()
{
if (!__profcxx_init())
return;
return 0;
_GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__destruct(__obj);
if (!__reentrance_guard::__get_in())
return 0;
__reentrance_guard __get_out;
return _GLIBCXX_PROFILE_DATA(_S_vector_to_list)
->__add_object(__get_stack());
}
inline void
__trace_vector_to_list_insert(const void* __obj, std::size_t __pos,
__trace_vector_to_list_insert(__vector2list_info* __obj_info,
std::size_t __pos,
std::size_t __num)
{
if (!__profcxx_init())
if (!__obj_info)
return;
_GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_insert(__obj, __pos,
__num);
__obj_info->__opr_insert(__pos, __num);
}
inline void
__trace_vector_to_list_iterate(const void* __obj, std::size_t __num = 1)
__trace_vector_to_list_iterate(__vector2list_info* __obj_info, int)
{
if (!__profcxx_init())
if (!__obj_info)
return;
_GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_iterate(__obj, __num);
// We only collect if an iteration took place no matter in what side.
__obj_info->__opr_iterate(1);
}
inline void
__trace_vector_to_list_invalid_operator(const void* __obj)
__trace_vector_to_list_invalid_operator(__vector2list_info* __obj_info)
{
if (!__profcxx_init())
if (!__obj_info)
return;
_GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__invalid_operator(__obj);
__obj_info->__set_invalid();
}
inline void
__trace_vector_to_list_resize(const void* __obj, std::size_t __from,
__trace_vector_to_list_resize(__vector2list_info* __obj_info,
std::size_t __from,
std::size_t __to)
{
if (!__profcxx_init())
if (!__obj_info)
return;
_GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__resize(__obj, __from, __to);
__obj_info->__resize(__from, __to);
}
inline void
__trace_vector_to_list_find(const void* __obj, std::size_t __size)
__trace_vector_to_list_destruct(__vector2list_info* __obj_info)
{
if (!__profcxx_init())
if (!__obj_info)
return;
_GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_find(__obj, __size);
_GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__destruct(__obj_info);
}
} // namespace __gnu_profile
......
......@@ -123,6 +123,7 @@ namespace __profile
operator=(const __iterator_tracker& __x) _GLIBCXX_NOEXCEPT
{
_M_current = __x._M_current;
_M_ds = __x._M_ds;
return *this;
}
......@@ -165,10 +166,6 @@ namespace __profile
return __tmp;
}
void
_M_find()
{ _M_ds->_M_profile_find(); }
const _Sequence*
_M_get_sequence() const
{ return static_cast<const _Sequence*>(_M_ds); }
......
......@@ -35,28 +35,63 @@ namespace __profile
template<typename _Cont>
class _Ordered_profile
{
_Cont&
_M_conjure()
{ return *static_cast<_Cont*>(this); }
public:
void
_M_profile_iterate(int __rewind = 0) const
{ __profcxx_map2umap_iterate(this->_M_map2umap_info, __rewind); }
protected:
_Ordered_profile() _GLIBCXX_NOEXCEPT
{ __profcxx_map_to_unordered_map_construct(&_M_conjure()); }
{ _M_profile_construct(); }
#if __cplusplus >= 201103L
_Ordered_profile(const _Ordered_profile&) noexcept
: _Ordered_profile() { }
_Ordered_profile(_Ordered_profile&&) noexcept
: _Ordered_profile() { }
_Ordered_profile(_Ordered_profile&& __other) noexcept
: _Ordered_profile()
{ _M_swap(__other); }
_Ordered_profile&
operator=(const _Ordered_profile&) = default;
operator=(const _Ordered_profile&) noexcept
{
_M_profile_destruct();
_M_profile_construct();
}
_Ordered_profile&
operator=(_Ordered_profile&&) = default;
operator=(_Ordered_profile&& __other) noexcept
{
_M_swap(__other);
__other._M_profile_destruct();
__other._M_profile_construct();
}
#endif
~_Ordered_profile()
{ __profcxx_map_to_unordered_map_destruct(&_M_conjure()); }
{ _M_profile_destruct(); }
void
_M_profile_construct() _GLIBCXX_NOEXCEPT
{ _M_map2umap_info = __profcxx_map2umap_construct(); }
void
_M_profile_destruct() _GLIBCXX_NOEXCEPT
{
__profcxx_map2umap_destruct(_M_map2umap_info);
_M_map2umap_info = 0;
}
void
_M_swap(_Ordered_profile& __other)
{ std::swap(_M_map2umap_info, __other._M_map2umap_info); }
__gnu_profile::__map2umap_info* _M_map2umap_info;
private:
_Cont&
_M_conjure()
{ return *static_cast<_Cont*>(this); }
};
} // namespace __profile
......
......@@ -154,39 +154,79 @@ namespace __profile
using __unique_keys = std::integral_constant<bool, _Unique_keys>;
protected:
_Unordered_profile()
{
auto& __uc = _M_conjure();
__profcxx_hashtable_construct(&__uc, __uc.bucket_count());
__profcxx_hashtable_construct2(&__uc);
}
_Unordered_profile(const _Unordered_profile&)
: _Unordered_profile() { }
_Unordered_profile(_Unordered_profile&&)
_Unordered_profile() noexcept
{ _M_profile_construct(); }
_Unordered_profile(const _Unordered_profile&) noexcept
: _Unordered_profile() { }
~_Unordered_profile() noexcept
_Unordered_profile(_Unordered_profile&& __other) noexcept
: _Unordered_profile()
{ _M_swap(__other); }
~_Unordered_profile()
{ _M_profile_destruct(); }
_Unordered_profile&
operator=(const _Unordered_profile&) noexcept
{
auto& __uc = _M_conjure();
__profcxx_hashtable_destruct(&__uc, __uc.bucket_count(), __uc.size());
// Assignment just reset profiling.
_M_profile_destruct();
_M_profile_construct();
}
_Unordered_profile&
operator=(const _Unordered_profile&) = default;
operator=(_Unordered_profile&& __other) noexcept
{
// Take profiling of the moved instance...
_M_swap(__other);
_Unordered_profile&
operator=(_Unordered_profile&&) = default;
// ...and then reset other instance profiling.
__other._M_profile_destruct();
__other._M_profile_construct();
}
void
_M_profile_construct() noexcept
{
auto& __uc = _M_conjure();
_M_size_info = __profcxx_hashtable_size_construct(__uc.bucket_count());
_M_hashfunc_info = __profcxx_hash_func_construct();
}
void
_M_profile_destruct()
_M_profile_destruct() noexcept
{
if (!__profcxx_inefficient_hash_is_on())
auto& __uc = _M_conjure();
__profcxx_hashtable_size_destruct(_M_size_info,
__uc.bucket_count(), __uc.size());
_M_size_info = 0;
if (!_M_hashfunc_info)
return;
_M_profile_destruct(__unique_keys());
_M_hashfunc_info = 0;
}
void
_M_swap(_Unordered_profile& __other) noexcept
{
std::swap(_M_size_info, __other._M_size_info);
std::swap(_M_hashfunc_info, __other._M_hashfunc_info);
}
void
_M_profile_resize(std::size_t __old_size)
{
auto __new_size = _M_conjure().bucket_count();
if (__old_size != __new_size)
__profcxx_hashtable_size_resize(_M_size_info, __old_size, __new_size);
}
__gnu_profile::__container_size_info* _M_size_info;
__gnu_profile::__hashfunc_info* _M_hashfunc_info;
private:
void
_M_profile_destruct(std::true_type);
......@@ -219,7 +259,9 @@ namespace __profile
__chain = 0;
}
}
__profcxx_hashtable_destruct2(&__uc, __lc, __uc.size(), __hops);
__profcxx_hash_func_destruct(_M_hashfunc_info,
__lc, __uc.size(), __hops);
}
template<typename _UnorderedCont, bool _Unique_keys>
......@@ -255,7 +297,9 @@ namespace __profile
__chain = 0;
}
}
__profcxx_hashtable_destruct2(&__uc, __lc, __unique_size, __hops);
__profcxx_hash_func_destruct(_M_hashfunc_info,
__lc, __unique_size, __hops);
}
} // namespace __profile
......
......@@ -76,8 +76,10 @@ namespace __profile
typedef typename _Base::iterator iterator;
typedef typename _Base::const_iterator const_iterator;
unordered_map() = default;
explicit
unordered_map(size_type __n = 10,
unordered_map(size_type __n,
const hasher& __hf = hasher(),
const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
......@@ -126,17 +128,18 @@ namespace __profile
unordered_map&
operator=(initializer_list<value_type> __l)
{
this->_M_profile_destruct();
_M_base() = __l;
this->_M_profile_construct();
return *this;
}
void
clear() noexcept
{
__profcxx_hashtable_destruct(this, _Base::bucket_count(),
_Base::size());
this->_M_profile_destruct();
_Base::clear();
this->_M_profile_construct();
}
template<typename... _Args>
......@@ -146,7 +149,7 @@ namespace __profile
size_type __old_size = _Base::bucket_count();
std::pair<iterator, bool> __res
= _Base::emplace(std::forward<_Args>(__args)...);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -157,7 +160,7 @@ namespace __profile
size_type __old_size = _Base::bucket_count();
iterator __res
= _Base::emplace_hint(__it, std::forward<_Args>(__args)...);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -166,7 +169,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
_Base::insert(__l);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
}
std::pair<iterator, bool>
......@@ -174,7 +177,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
std::pair<iterator, bool> __res = _Base::insert(__obj);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -183,7 +186,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
iterator __res = _Base::insert(__iter, __v);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -196,7 +199,7 @@ namespace __profile
size_type __old_size = _Base::bucket_count();
std::pair<iterator, bool> __res
= _Base::insert(std::forward<_Pair>(__obj));
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -208,7 +211,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v));
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -218,7 +221,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
_Base::insert(__first, __last);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
}
// operator[]
......@@ -227,7 +230,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
mapped_type& __res = _M_base()[__k];
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -236,29 +239,23 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
mapped_type& __res = _M_base()[std::move(__k)];
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
void
swap(unordered_map& __x)
noexcept( noexcept(__x._M_base().swap(__x)) )
{ _Base::swap(__x._M_base()); }
{
_Base::swap(__x._M_base());
this->_M_swap(__x);
}
void rehash(size_type __n)
{
size_type __old_size = _Base::bucket_count();
_Base::rehash(__n);
_M_profile_resize(__old_size);
}
private:
void
_M_profile_resize(size_type __old_size)
{
size_type __new_size = _Base::bucket_count();
if (__old_size != __new_size)
__profcxx_hashtable_resize(this, __old_size, __new_size);
this->_M_profile_resize(__old_size);
}
};
......@@ -321,8 +318,10 @@ namespace __profile
typedef typename _Base::iterator iterator;
typedef typename _Base::const_iterator const_iterator;
unordered_multimap() = default;
explicit
unordered_multimap(size_type __n = 10,
unordered_multimap(size_type __n,
const hasher& __hf = hasher(),
const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
......@@ -371,17 +370,18 @@ namespace __profile
unordered_multimap&
operator=(initializer_list<value_type> __l)
{
this->_M_profile_destruct();
_M_base() = __l;
this->_M_profile_construct();
return *this;
}
void
clear() noexcept
{
__profcxx_hashtable_destruct(this, _Base::bucket_count(),
_Base::size());
this->_M_profile_destruct();
_Base::clear();
this->_M_profile_construct();
}
template<typename... _Args>
......@@ -391,7 +391,7 @@ namespace __profile
size_type __old_size = _Base::bucket_count();
iterator __res
= _Base::emplace(std::forward<_Args>(__args)...);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -402,7 +402,7 @@ namespace __profile
size_type __old_size = _Base::bucket_count();
iterator __res
= _Base::emplace_hint(__it, std::forward<_Args>(__args)...);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -411,7 +411,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
_Base::insert(__l);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
}
iterator
......@@ -419,7 +419,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
iterator __res = _Base::insert(__obj);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -428,7 +428,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
iterator __res = _Base::insert(__iter, __v);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -440,7 +440,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
iterator __res = _Base::insert(std::forward<_Pair>(__obj));
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -452,7 +452,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v));
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -462,29 +462,23 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
_Base::insert(__first, __last);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
}
void
swap(unordered_multimap& __x)
noexcept( noexcept(__x._M_base().swap(__x)) )
{ _Base::swap(__x._M_base()); }
{
_Base::swap(__x._M_base());
this->_M_swap(__x);
}
void
rehash(size_type __n)
{
size_type __old_size = _Base::bucket_count();
_Base::rehash(__n);
_M_profile_resize(__old_size);
}
private:
void
_M_profile_resize(size_type __old_size)
{
size_type __new_size = _Base::bucket_count();
if (__old_size != __new_size)
__profcxx_hashtable_resize(this, __old_size, __new_size);
this->_M_profile_resize(__old_size);
}
};
......
......@@ -75,8 +75,10 @@ namespace __profile
typedef typename _Base::iterator iterator;
typedef typename _Base::const_iterator const_iterator;
unordered_set() = default;
explicit
unordered_set(size_type __n = 10,
unordered_set(size_type __n,
const hasher& __hf = hasher(),
const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
......@@ -132,22 +134,26 @@ namespace __profile
unordered_set&
operator=(initializer_list<value_type> __l)
{
this->_M_profile_destruct();
_M_base() = __l;
this->_M_profile_construct();
return *this;
}
void
swap(unordered_set& __x)
noexcept( noexcept(__x._M_base().swap(__x)) )
{ _Base::swap(__x); }
{
_Base::swap(__x);
this->_M_swap(__x);
}
void
clear() noexcept
{
__profcxx_hashtable_destruct(this, _Base::bucket_count(),
_Base::size());
this->_M_profile_destruct();
_Base::clear();
this->_M_profile_construct();
}
template<typename... _Args>
......@@ -157,7 +163,7 @@ namespace __profile
size_type __old_size = _Base::bucket_count();
std::pair<iterator, bool> __res
= _Base::emplace(std::forward<_Args>(__args)...);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -168,7 +174,7 @@ namespace __profile
size_type __old_size = _Base::bucket_count();
iterator __res
= _Base::emplace_hint(__it, std::forward<_Args>(__args)...);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -177,7 +183,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
_Base::insert(__l);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
}
std::pair<iterator, bool>
......@@ -185,7 +191,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
std::pair<iterator, bool> __res = _Base::insert(__obj);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -194,7 +200,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
iterator __res = _Base::insert(__iter, __v);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -203,7 +209,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
std::pair<iterator, bool> __res = _Base::insert(std::move(__obj));
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -212,7 +218,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
iterator __res = _Base::insert(__iter, std::move(__v));
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -222,7 +228,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
_Base::insert(__first, __last);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
}
void
......@@ -230,16 +236,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
_Base::rehash(__n);
_M_profile_resize(__old_size);
}
private:
void
_M_profile_resize(size_type __old_size)
{
size_type __new_size = _Base::bucket_count();
if (__old_size != __new_size)
__profcxx_hashtable_resize(this, __old_size, __new_size);
this->_M_profile_resize(__old_size);
}
};
......@@ -299,8 +296,10 @@ namespace __profile
typedef typename _Base::iterator iterator;
typedef typename _Base::const_iterator const_iterator;
unordered_multiset() = default;
explicit
unordered_multiset(size_type __n = 10,
unordered_multiset(size_type __n,
const hasher& __hf = hasher(),
const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
......@@ -356,22 +355,26 @@ namespace __profile
unordered_multiset&
operator=(initializer_list<value_type> __l)
{
this->_M_profile_destruct();
_M_base() = __l;
this->_M_profile_construct();
return *this;
}
void
swap(unordered_multiset& __x)
noexcept( noexcept(__x._M_base().swap(__x)) )
{ _Base::swap(__x); }
{
_Base::swap(__x);
this->_M_swap(__x);
}
void
clear() noexcept
{
__profcxx_hashtable_destruct(this, _Base::bucket_count(),
_Base::size());
this->_M_profile_destruct();
_Base::clear();
this->_M_profile_construct();
}
template<typename... _Args>
......@@ -380,7 +383,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
iterator __res = _Base::emplace(std::forward<_Args>(__args)...);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -391,7 +394,7 @@ namespace __profile
size_type __old_size = _Base::bucket_count();
iterator __res
= _Base::emplace_hint(__it, std::forward<_Args>(__args)...);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -400,7 +403,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
_Base::insert(__l);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
}
iterator
......@@ -408,7 +411,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
iterator __res = _Base::insert(__obj);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -417,7 +420,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
iterator __res = _Base::insert(__iter, __v);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -426,7 +429,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
iterator __res = _Base::insert(std::move(__obj));
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -435,7 +438,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
iterator __res = _Base::insert(__iter, std::move(__v));
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
return __res;
}
......@@ -445,7 +448,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
_Base::insert(__first, __last);
_M_profile_resize(__old_size);
this->_M_profile_resize(__old_size);
}
void
......@@ -453,16 +456,7 @@ namespace __profile
{
size_type __old_size = _Base::bucket_count();
_Base::rehash(__n);
_M_profile_resize(__old_size);
}
private:
void
_M_profile_resize(size_type __old_size)
{
size_type __new_size = _Base::bucket_count();
if (__old_size != __new_size)
__profcxx_hashtable_resize(this, __old_size, __new_size);
this->_M_profile_resize(__old_size);
}
};
......
......@@ -51,20 +51,13 @@ namespace __profile
_Vector_profile_pre(_Vector_profile_pre&&) = default;
_Vector_profile_pre&
operator=(const _Vector_profile_pre&) = default;
operator=(const _Vector_profile_pre&)
{ _M_conjure()._M_profile_destruct(); }
_Vector_profile_pre&
operator=(_Vector_profile_pre&&) noexcept
{ _M_profile_destruct(); }
{ _M_conjure()._M_profile_destruct(); }
#endif
void
_M_profile_destruct()
{
__profcxx_vector_destruct2(&_M_conjure());
__profcxx_vector_destruct(&_M_conjure(),
_M_conjure().capacity(), _M_conjure().size());
}
};
template<typename _Vector>
......@@ -75,26 +68,60 @@ namespace __profile
{ return *static_cast<_Vector*>(this); }
protected:
__gnu_profile::__container_size_info* _M_size_info;
__gnu_profile::__vector2list_info* _M_vect2list_info;
_Vector_profile_post() _GLIBCXX_NOEXCEPT
{
__profcxx_vector_construct(&_M_conjure(), _M_conjure().capacity());
__profcxx_vector_construct2(&_M_conjure());
}
{ _M_profile_construct(); }
#if __cplusplus >= 201103L
_Vector_profile_post(const _Vector_profile_post&) noexcept
: _Vector_profile_post() { }
_Vector_profile_post(_Vector_profile_post&&) noexcept
: _Vector_profile_post() { }
_Vector_profile_post(_Vector_profile_post&& __other) noexcept
: _Vector_profile_post()
{ _M_swap(__other); }
_Vector_profile_post&
operator=(const _Vector_profile_post&) = default;
operator=(const _Vector_profile_post&) noexcept
{ _M_profile_construct(); }
_Vector_profile_post&
operator=(_Vector_profile_post&&) = default;
operator=(_Vector_profile_post&& __other) noexcept
{
_M_swap(__other);
__other._M_profile_construct();
}
#endif
~_Vector_profile_post()
{ _M_conjure()._M_profile_destruct(); }
public:
void
_M_profile_construct() _GLIBCXX_NOEXCEPT
{
_M_size_info =
__profcxx_vector_size_construct(_M_conjure().capacity());
_M_vect2list_info = __profcxx_vector2list_construct();
}
void
_M_profile_destruct() _GLIBCXX_NOEXCEPT
{
__profcxx_vector2list_destruct(_M_vect2list_info);
_M_vect2list_info = 0;
__profcxx_vector_size_destruct(_M_size_info,
_M_conjure().capacity(),
_M_conjure().size());
_M_size_info = 0;
}
void
_M_swap(_Vector_profile_post& __other) _GLIBCXX_NOEXCEPT
{
std::swap(_M_size_info, __other._M_size_info);
std::swap(_M_vect2list_info, __other._M_vect2list_info);
}
};
template<typename _Tp,
......@@ -197,7 +224,9 @@ namespace __profile
vector&
operator=(const vector& __x)
{
this->_M_profile_destruct();
_M_base() = __x;
this->_M_profile_construct();
return *this;
}
#else
......@@ -210,7 +239,9 @@ namespace __profile
vector&
operator=(initializer_list<value_type> __l)
{
this->_M_profile_destruct();
_M_base() = __l;
this->_M_profile_construct();
return *this;
}
#endif
......@@ -272,7 +303,7 @@ namespace __profile
void
resize(size_type __sz)
{
__profcxx_vector_invalid_operator(this);
__profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
_M_profile_resize(this->capacity(), __sz);
_Base::resize(__sz);
}
......@@ -280,7 +311,7 @@ namespace __profile
void
resize(size_type __sz, const _Tp& __c)
{
__profcxx_vector_invalid_operator(this);
__profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
_M_profile_resize(this->capacity(), __sz);
_Base::resize(__sz, __c);
}
......@@ -288,7 +319,7 @@ namespace __profile
void
resize(size_type __sz, _Tp __c = _Tp())
{
__profcxx_vector_invalid_operator(this);
__profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
_M_profile_resize(this->capacity(), __sz);
_Base::resize(__sz, __c);
}
......@@ -298,13 +329,13 @@ namespace __profile
reference
operator[](size_type __n) _GLIBCXX_NOEXCEPT
{
__profcxx_vector_invalid_operator(this);
__profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
return _M_base()[__n];
}
const_reference
operator[](size_type __n) const _GLIBCXX_NOEXCEPT
{
__profcxx_vector_invalid_operator(this);
__profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
return _M_base()[__n];
}
......@@ -335,8 +366,9 @@ namespace __profile
insert(iterator __pos, const _Tp& __x)
#endif
{
__profcxx_vector_insert(this, __pos.base() - _Base::begin(),
this->size());
__profcxx_vector2list_insert(this->_M_vect2list_info,
__pos.base() - _Base::begin(),
this->size());
size_type __old_size = this->capacity();
_Base_iterator __res = _Base::insert(__pos.base(), __x);
_M_profile_resize(__old_size, this->capacity());
......@@ -347,8 +379,9 @@ namespace __profile
iterator
insert(const_iterator __pos, _Tp&& __x)
{
__profcxx_vector_insert(this, __pos.base() - _Base::cbegin(),
this->size());
__profcxx_vector2list_insert(this->_M_vect2list_info,
__pos.base() - _Base::cbegin(),
this->size());
size_type __old_size = this->capacity();
_Base_iterator __res = _Base::insert(__pos.base(), __x);
_M_profile_resize(__old_size, this->capacity());
......@@ -374,14 +407,18 @@ namespace __profile
#if __cplusplus >= 201103L
noexcept( noexcept(declval<_Base>().swap(__x)) )
#endif
{ _Base::swap(__x); }
{
_Base::swap(__x);
this->_M_swap(__x);
}
#if __cplusplus >= 201103L
iterator
insert(const_iterator __pos, size_type __n, const _Tp& __x)
{
__profcxx_vector_insert(this, __pos.base() - _Base::cbegin(),
this->size());
__profcxx_vector2list_insert(this->_M_vect2list_info,
__pos.base() - _Base::cbegin(),
this->size());
size_type __old_size = this->capacity();
_Base_iterator __res = _Base::insert(__pos, __n, __x);
_M_profile_resize(__old_size, this->capacity());
......@@ -391,8 +428,9 @@ namespace __profile
void
insert(iterator __pos, size_type __n, const _Tp& __x)
{
__profcxx_vector_insert(this, __pos.base() - _Base::begin(),
this->size());
__profcxx_vector2list_insert(this->_M_vect2list_info,
__pos.base() - _Base::begin(),
this->size());
size_type __old_size = this->capacity();
_Base::insert(__pos, __n, __x);
_M_profile_resize(__old_size, this->capacity());
......@@ -406,8 +444,9 @@ namespace __profile
insert(const_iterator __pos,
_InputIterator __first, _InputIterator __last)
{
__profcxx_vector_insert(this, __pos.base() - _Base::cbegin(),
this->size());
__profcxx_vector2list_insert(this->_M_vect2list_info,
__pos.base() - _Base::cbegin(),
this->size());
size_type __old_size = this->capacity();
_Base_iterator __res = _Base::insert(__pos, __first, __last);
_M_profile_resize(__old_size, this->capacity());
......@@ -419,8 +458,9 @@ namespace __profile
insert(iterator __pos,
_InputIterator __first, _InputIterator __last)
{
__profcxx_vector_insert(this, __pos.base() - _Base::begin(),
this->size());
__profcxx_vector2list_insert(this->_M_vect2list_info,
__pos.base() - _Base::begin(),
this->size());
size_type __old_size = this->capacity();
_Base::insert(__pos, __first, __last);
_M_profile_resize(__old_size, this->capacity());
......@@ -448,21 +488,22 @@ namespace __profile
{
this->_M_profile_destruct();
_Base::clear();
this->_M_profile_construct();
}
inline void _M_profile_find() const
{ __profcxx_vector_find(this, this->size()); }
inline void _M_profile_iterate(int __rewind = 0) const
{ __profcxx_vector_iterate(this); }
inline void
_M_profile_iterate(int __rewind = 0) const
{ __profcxx_vector2list_iterate(this->_M_vect2list_info, __rewind); }
private:
void _M_profile_resize(size_type __old_size, size_type __new_size)
{
if (__old_size < __new_size)
{
__profcxx_vector_resize(this, this->size(), __new_size);
__profcxx_vector_resize2(this, this->size(), __new_size);
__profcxx_vector_size_resize(this->_M_size_info,
this->size(), __new_size);
__profcxx_vector2list_resize(this->_M_vect2list_info,
this->size(), __new_size);
}
}
};
......@@ -531,8 +572,9 @@ namespace __profile
{
size_t
operator()(const __profile::vector<bool, _Alloc>& __b) const noexcept
{ return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>()
(__b._M_base()); }
{
return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>()(__b._M_base());
}
};
#endif
......
// { dg-do compile { target *-*-linux* *-*-gnu* } }
// { dg-xfail-if "" { uclibc } { "*" } { "" } }
// { dg-require-profile-mode "" }
// -*- C++ -*-
// Copyright (C) 2006-2014 Free Software Foundation, Inc.
......@@ -21,47 +17,37 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
#include <stdio.h>
#include <malloc.h>
// { dg-require-profile-mode "" }
#include <vector>
using std::vector;
static void my_init_hook (void);
static void *my_malloc_hook (size_t, const void *);
typedef void* (*malloc_hook) (size_t, const void *);
malloc_hook old_malloc_hook;
void (*__malloc_initialize_hook) (void) = my_init_hook;
static void
my_init_hook (void)
void* operator new(std::size_t size) throw(std::bad_alloc)
{
old_malloc_hook = __malloc_hook;
__malloc_hook = my_malloc_hook;
void* p = std::malloc(size);
if (!p)
throw std::bad_alloc();
return p;
}
static void *
my_malloc_hook (size_t size, const void *caller)
void* operator new (std::size_t size, const std::nothrow_t&) throw()
{
void *result;
__malloc_hook = old_malloc_hook;
result = malloc (size);
old_malloc_hook = __malloc_hook;
// With _GLIBCXX_PROFILE, the instrumentation of the vector constructor
// will call back into malloc.
// will call back into this new operator.
vector<int> v;
return std::malloc(size);
}
__malloc_hook = my_malloc_hook;
return result;
void operator delete(void* p) throw()
{
if (p)
std::free(p);
}
int main()
int
main()
{
int* test = (int*) malloc(sizeof(int));
*test = 1;
return *test;
vector<int> v;
return 0;
}
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