profiler_list_to_slist.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Copyright (C) 2009 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the terms
00007 // of the GNU General Public License as published by the Free Software
00008 // Foundation; either version 2, or (at your option) any later
00009 // version.
00010 
00011 // This library is distributed in the hope that it will be useful, but
00012 // WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // General Public License for more details.
00015 
00016 // You should have received a copy of the GNU General Public License
00017 // along with this library; see the file COPYING.  If not, write to
00018 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
00019 // MA 02111-1307, USA.
00020 
00021 // As a special exception, you may use this file as part of a free
00022 // software library without restriction.  Specifically, if other files
00023 // instantiate templates or use macros or inline functions from this
00024 // file, or you compile this file and link it with other files to
00025 // produce an executable, this file does not by itself cause the
00026 // resulting executable to be covered by the GNU General Public
00027 // License.  This exception does not however invalidate any other
00028 // reasons why the executable file might be covered by the GNU General
00029 // Public License.
00030 
00031 /** @file profile/impl/profiler_list_to_slist.h
00032  *  @brief Diagnostics for list to slist.
00033  */
00034 
00035 // Written by Changhee Jung.
00036 
00037 #ifndef _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H
00038 #define _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H 1
00039 
00040 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00041 #include <cstdlib>
00042 #include <cstdio>
00043 #include <cstring>
00044 #else
00045 #include <stdlib.h>
00046 #include <stdio.h>
00047 #include <string.h>
00048 #endif
00049 #include "profile/impl/profiler.h"
00050 #include "profile/impl/profiler_node.h"
00051 #include "profile/impl/profiler_trace.h"
00052 
00053 namespace __gnu_profile
00054 {
00055 
00056 class __list2slist_info: public __object_info_base
00057 {
00058  public:
00059   __list2slist_info() : _M_rewind(false), _M_operations(0) {}
00060   __list2slist_info(__stack_t __stack) 
00061       : _M_rewind(false), _M_operations(0),__object_info_base(__stack) {}
00062   virtual ~__list2slist_info() {}
00063   __list2slist_info(const __list2slist_info& __o) : __object_info_base(__o)
00064   { _M_rewind = __o._M_rewind; _M_operations = __o._M_operations; }
00065   // XXX: the magnitude should be multiplied with a constant factor F,
00066   // where F is 1 when the malloc size class of list nodes is different
00067   // from the malloc size class of slist nodes.  When they fall into the same
00068   // class, the only slist benefit is from having to set fewer links, so
00069   // the factor F should be much smaller, closer to 0 than to 1.
00070   // This could be implemented by passing the size classes in the config file.
00071   // For now, we always assume F to be 1.
00072   float __magnitude() const
00073   { if (!_M_rewind) return _M_operations; else return 0; }
00074   void __merge(const __list2slist_info& __o) {};
00075   void __write(FILE* __f) const;
00076   const char* __advice() const
00077   { return strdup("change std::list to std::forward_list"); }
00078   void __opr_rewind() { _M_rewind = true; _M_valid = false;}
00079   void __record_operation() { _M_operations++; }
00080   bool __has_rewind() { return _M_rewind; }
00081 
00082 private:
00083   bool _M_rewind;
00084   size_t _M_operations;
00085 };
00086 
00087 class __list2slist_stack_info: public __list2slist_info {
00088  public:
00089   __list2slist_stack_info(const __list2slist_info& __o) 
00090       : __list2slist_info(__o) {}
00091 };
00092 
00093 class __trace_list_to_slist
00094     : public __trace_base<__list2slist_info, __list2slist_stack_info> 
00095 {
00096  public:
00097   ~__trace_list_to_slist() {}
00098   __trace_list_to_slist() 
00099       : __trace_base<__list2slist_info, __list2slist_stack_info>()
00100   { __id = "list-to-slist"; }
00101   void __opr_rewind(const void* __obj);
00102   void __record_operation(const void* __obj);
00103   void __insert(const __object_t __obj, __stack_t __stack)
00104   { __add_object(__obj, __list2slist_info(__stack)); }
00105   void __destruct(const void* __obj);
00106 };
00107 
00108 inline void __list2slist_info::__write(FILE* __f) const
00109 {
00110   fprintf(__f, "%s\n", _M_rewind ? "invalid" : "valid");
00111 }
00112 
00113 inline void __trace_list_to_slist::__destruct(const void* __obj)
00114 {
00115   if (!__is_on())
00116     return;
00117 
00118   __list2slist_info* __res = __get_object_info(__obj);
00119   if (!__res)
00120     return;
00121 
00122   __retire_object(__obj);
00123 }
00124 
00125 inline void __trace_list_to_slist_init()
00126 {
00127   _GLIBCXX_PROFILE_DATA(_S_list_to_slist) = new __trace_list_to_slist();
00128 }
00129 
00130 inline void __trace_list_to_slist_report(FILE* __f, 
00131                                        __warning_vector_t& __warnings)
00132 {
00133   if (_GLIBCXX_PROFILE_DATA(_S_list_to_slist)) {
00134     _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__collect_warnings(__warnings);
00135     _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__write(__f);
00136   }
00137 }
00138 
00139 inline void __trace_list_to_slist::__opr_rewind(const void* __obj)
00140 {
00141   __list2slist_info* __res = __get_object_info(__obj);
00142   if (__res)
00143     __res->__opr_rewind();
00144 }
00145 
00146 inline void __trace_list_to_slist::__record_operation(const void* __obj)
00147 {
00148   __list2slist_info* __res = __get_object_info(__obj);
00149   if (__res)
00150     __res->__record_operation();
00151 }
00152 
00153 inline void __trace_list_to_slist_rewind(const void* __obj) 
00154 {
00155   if (!__profcxx_init()) return;
00156 
00157   _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__opr_rewind(__obj);
00158 }
00159 
00160 inline void __trace_list_to_slist_operation(const void* __obj) 
00161 {
00162   if (!__profcxx_init()) return;
00163 
00164   _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__record_operation(__obj);
00165 }
00166 
00167 inline void __trace_list_to_slist_construct(const void* __obj)
00168 {
00169   if (!__profcxx_init()) return;
00170 
00171   _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__insert(__obj, __get_stack());
00172 }
00173 
00174 inline void __trace_list_to_slist_destruct(const void* __obj)
00175 {
00176   if (!__profcxx_init()) return;
00177 
00178   _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__destruct(__obj);
00179 }
00180 
00181 } // namespace __gnu_profile
00182 #endif /* _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H */