diff --git a/src/ant/ant/antObject.h b/src/ant/ant/antObject.h index ce7a62490..4c09a27ad 100644 --- a/src/ant/ant/antObject.h +++ b/src/ant/ant/antObject.h @@ -688,22 +688,6 @@ public: */ virtual std::string to_string () const; - /** - * @brief Returns the memory used in bytes - */ - virtual size_t mem_used () const - { - return sizeof (*this); - } - - /** - * @brief Returns the memory required in bytes - */ - virtual size_t mem_reqd () const - { - return sizeof (*this); - } - protected: /** * @brief A notification method that is called when a property of the annotation has changed diff --git a/src/db/db/dbArray.cc b/src/db/db/dbArray.cc index 9325f9226..41558709d 100644 --- a/src/db/db/dbArray.cc +++ b/src/db/db/dbArray.cc @@ -66,30 +66,15 @@ ArrayRepository::operator= (const ArrayRepository &d) return *this; } -size_t -ArrayRepository::mem_used () const +void +ArrayRepository::mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const { - size_t mem = 0; + db::mem_stat (stat, purpose, cat, m_reps, no_self, parent); for (repositories::const_iterator r = m_reps.begin (); r != m_reps.end (); ++r) { - mem += db::mem_used (*r); for (basic_repository::const_iterator rr = r->begin (); rr != r->end (); ++rr) { - mem += (*rr)->mem_used (); + db::mem_stat (stat, purpose, cat, *rr, false, (void *) this); } } - return mem + sizeof (*this); -} - -size_t -ArrayRepository::mem_reqd () const -{ - size_t mem = 0; - for (repositories::const_iterator r = m_reps.begin (); r != m_reps.end (); ++r) { - mem += db::mem_reqd (*r); - for (basic_repository::const_iterator rr = r->begin (); rr != r->end (); ++rr) { - mem += (*rr)->mem_reqd (); - } - } - return mem + sizeof (*this); } } diff --git a/src/db/db/dbArray.h b/src/db/db/dbArray.h index f4bd7ff27..1474e92f3 100644 --- a/src/db/db/dbArray.h +++ b/src/db/db/dbArray.h @@ -102,13 +102,19 @@ struct ArrayBase virtual bool less (const ArrayBase *) const = 0; - virtual size_t mem_used () const = 0; - - virtual size_t mem_reqd () const = 0; + virtual void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self = false, void *parent = 0) const = 0; bool in_repository; }; +/** + * @brief Memory statistics for ArrayBase + */ +inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const ArrayBase &x, bool no_self, void *parent) +{ + x.mem_stat (stat, purpose, cat, no_self, parent); +} + /** * @brief The array base class (internal) */ @@ -259,9 +265,7 @@ public: } } - size_t mem_used () const; - - size_t mem_reqd () const; + void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self = false, void *parent = 0) const; private: repositories m_reps; @@ -269,6 +273,15 @@ private: void clear (); }; +/** + * @brief Collect memory statistics + */ +inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const ArrayRepository &x, bool no_self = false, void *parent = 0) +{ + x.mem_stat (stat, purpose, cat, no_self, parent); +} + + /** * @brief The array iterator specialization for the regular case (internal) * @@ -534,14 +547,11 @@ struct regular_array return true; } - virtual size_t mem_used () const + virtual void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const { - return sizeof (*this); - } - - virtual size_t mem_reqd () const - { - return sizeof (*this); + if (!no_self) { + stat->add (typeid (*this), (void *) this, sizeof (*this), sizeof (*this), parent, purpose, cat); + } } virtual unsigned int type () const @@ -652,6 +662,13 @@ struct regular_complex_array return regular_array::less (b); } + virtual void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const + { + if (!no_self) { + stat->add (typeid (*this), (void *) this, sizeof (*this), sizeof (*this), parent, purpose, cat); + } + } + virtual complex_trans_type complex_trans (const simple_trans_type &s) const { return complex_trans_type (s, m_acos, m_mag); @@ -909,14 +926,12 @@ struct iterated_array return false; } - virtual size_t mem_used () const + virtual void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const { - return sizeof (*this) + db::mem_used (m_v) - sizeof (m_v); - } - - virtual size_t mem_reqd () const - { - return sizeof (*this) + db::mem_reqd (m_v) - sizeof (m_v); + if (!no_self) { + stat->add (typeid (*this), (void *) this, sizeof (*this), sizeof (*this), parent, purpose, cat); + } + db::mem_stat (stat, purpose, cat, m_v, true, (void *) this); } virtual unsigned int type () const @@ -1133,14 +1148,11 @@ struct single_complex_inst return false; } - virtual size_t mem_used () const + virtual void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const { - return sizeof (*this); - } - - virtual size_t mem_reqd () const - { - return sizeof (*this); + if (!no_self) { + stat->add (typeid (*this), (void *) this, sizeof (*this), sizeof (*this), parent, purpose, cat); + } } virtual complex_trans_type complex_trans (const simple_trans_type &s) const @@ -2071,22 +2083,6 @@ struct array } } - /** - * @brief Collect memory usage statistics - */ - size_t mem_used () const - { - return sizeof (m_trans) + sizeof (mp_base) + db::mem_used (m_obj) + (mp_base ? mp_base->mem_used () : 0); - } - - /** - * @brief Collect memory requirement statistics - */ - size_t mem_reqd () const - { - return sizeof (m_trans) + sizeof (mp_base) + db::mem_reqd (m_obj) + (mp_base ? mp_base->mem_reqd () : 0); - } - /** * @brief Swap with another object * @@ -2208,6 +2204,17 @@ struct array return a; } + void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const + { + if (! no_self) { + stat->add (typeid (array), (void *) this, sizeof (array), sizeof (array), parent, purpose, cat); + } + db::mem_stat (stat, purpose, cat, m_obj, true, (void *) this); + if (mp_base) { + db::mem_stat (stat, purpose, cat, *mp_base, false, (void *) this); + } + } + private: Obj m_obj; trans_type m_trans; @@ -2404,16 +2411,13 @@ private: } }; -template -size_t mem_used (const array &x) +/** + * @brief Collect memory statistics + */ +template +inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const array &x, bool no_self = false, void *parent = 0) { - return x.mem_used (); -} - -template -size_t mem_reqd (const array &x) -{ - return x.mem_reqd (); + x.mem_stat (stat, purpose, cat, no_self, parent); } } diff --git a/src/db/db/dbBoxTree.h b/src/db/db/dbBoxTree.h index 46ae45f43..b560b5b03 100644 --- a/src/db/db/dbBoxTree.h +++ b/src/db/db/dbBoxTree.h @@ -232,15 +232,16 @@ public: return (int)(size_t (mp_parent) & 3); } - size_t mem_used () const + void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) { - size_t m = sizeof (*this); + if (!no_self) { + stat->add (typeid (*this), (void *) this, sizeof (*this), sizeof (*this), parent, purpose, cat); + } for (int i = 0; i < 4; ++i) { if (mp_children [i]) { - m += mp_children [i]->mem_used (); + mp_children [i]->mem_stat (stat, purpose, cat, no_self, parent); } } - return m; } const point_type ¢er () const @@ -1090,6 +1091,18 @@ public: return mp_root; } + /** + * @brief Collect memory statistics + */ + void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self = false, void *parent = 0) const + { + if (!no_self) { + stat->add (typeid (*this), (void *) this, sizeof (*this), sizeof (*this), parent, purpose, cat); + } + db::mem_stat (stat, purpose, cat, m_objects, true, (void *) this); + db::mem_stat (stat, purpose, cat, m_elements, true, (void *) this); + } + private: /// The basic object and element vector @@ -1238,23 +1251,13 @@ private: }; -template -size_t mem_used (const db::box_tree &bt) +/** + * @brief Collect memory statistics + */ +template +inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const box_tree &x, bool no_self = false, void *parent = 0) { - return mem_used (bt.elements ()) + - mem_used (bt.objects ()) + - sizeof (void *) + - (bt.root () ? bt.root ()->mem_used () : 0); -} - -template -size_t mem_reqd (const db::box_tree &bt) -{ - return mem_reqd (bt.elements ()) + - mem_reqd (bt.objects ()) + - sizeof (box_tree_node > *) + - sizeof (void *) + - (bt.root () ? bt.root ()->mem_used () : 0); + x.mem_stat (stat, purpose, cat, no_self, parent); } /** @@ -2033,6 +2036,17 @@ public: return mp_root; } + /** + * @brief Collect memory statistics + */ + void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self = false, void *parent = 0) const + { + if (! no_self) { + stat->add (typeid (*this), (void *) this, sizeof (*this), sizeof (*this), parent, purpose, cat); + } + db::mem_stat (stat, purpose, cat, m_objects, true, (void *) this); + } + private: /// The basic object and element vector obj_vector_type m_objects; @@ -2171,24 +2185,15 @@ private: }; +/** + * @brief Collect memory statistics + */ template -size_t mem_used (const db::unstable_box_tree &bt) +inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const db::unstable_box_tree &x, bool no_self = false, void *parent = 0) { - return mem_used (bt.objects ()) + - sizeof (void *) + - (bt.root () ? bt.root ()->mem_used () : 0); + x.mem_stat (stat, purpose, cat, no_self, parent); } -template -size_t mem_reqd (const db::unstable_box_tree &bt) -{ - return mem_reqd (bt.objects ()) + - sizeof (box_tree_node > *) + - sizeof (void *) + - (bt.root () ? bt.root ()->mem_used () : 0); -} - - } #endif diff --git a/src/db/db/dbCell.cc b/src/db/db/dbCell.cc index e833261c8..8d1499b75 100644 --- a/src/db/db/dbCell.cc +++ b/src/db/db/dbCell.cc @@ -588,21 +588,21 @@ Cell::undo (db::Op *op) } void -Cell::collect_mem_stat (db::MemStatistics &m) const +Cell::mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const { - m.cell_info (m_cell_index); - m.cell_info (mp_layout); - m.cell_info (m_shapes_map); - m.cell_info (m_bbox); - m.cell_info (m_bboxes); - m.cell_info (m_hier_levels); - m.cell_info (m_bbox_needs_update); + if (! no_self) { + stat->add (typeid (Cell), (void *) this, sizeof (Cell), sizeof (Cell), parent, purpose, cat); + } + db::mem_stat (stat, purpose, cat, m_bboxes, true, (void *) this); + db::mem_stat (stat, MemStatistics::Instances, cat, m_instances, true, (void *) this); - m_instances.collect_mem_stat (m); - - for (shapes_map::const_iterator s = m_shapes_map.begin (); s != m_shapes_map.end (); ++s) { - m.cell_info (size_t (-sizeof(s->second)), size_t (-sizeof(s->second))); - s->second.collect_mem_stat (m); + // iterate the shapes separately so we can use the layer for the category + for (shapes_map::const_iterator i = m_shapes_map.begin (); i != m_shapes_map.end (); ++i) { + db::mem_stat (stat, MemStatistics::ShapesInfo, (int) i->first, i->first, false, (void *) this); + db::mem_stat (stat, MemStatistics::ShapesInfo, (int) i->first, i->second, false, (void *) this); +#ifdef __GNUCC__ + stat->add (std::_Rb_tree_node_base, (void *) &i->first, sizeof (std::_Rb_tree_node_base), sizeof (std::_Rb_tree_node_base), (void *) &v, purpose, cat); +#endif } } diff --git a/src/db/db/dbCell.h b/src/db/db/dbCell.h index 12b613da2..370034eda 100644 --- a/src/db/db/dbCell.h +++ b/src/db/db/dbCell.h @@ -882,7 +882,7 @@ public: /** * @brief Collect memory usage statistics */ - virtual void collect_mem_stat (db::MemStatistics &m) const; + void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self = false, void *parent = 0) const; /** * @brief Sets the properties ID @@ -1023,6 +1023,15 @@ private: void sort_inst_tree (); }; +/** + * @brief Collect memory statistics + */ +inline void +mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const db::Cell &x, bool no_self = false, void *parent = 0) +{ + x.mem_stat (stat, purpose, cat, no_self, parent); +} + } // namespace db namespace tl diff --git a/src/db/db/dbInstances.cc b/src/db/db/dbInstances.cc index 2a36fc6ff..eca515d9c 100644 --- a/src/db/db/dbInstances.cc +++ b/src/db/db/dbInstances.cc @@ -1438,33 +1438,30 @@ Instances::cell_instances () const } void -Instances::collect_mem_stat (db::MemStatistics &m) const +Instances::mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const { - m.cell_info (sizeof (mp_cell), sizeof (mp_cell)); - m.cell_info (sizeof (m_parent_insts), sizeof (m_parent_insts)); // need more: see below - m.cell_info (sizeof (m_generic), sizeof (m_generic)); // need more: see below - m.cell_info (sizeof (m_generic_wp), sizeof (m_generic_wp)); // need more: see below - m.cell_info (sizeof (m_insts_by_cell_index), sizeof (m_insts_by_cell_index)); // need more: see below + if (!no_self) { + stat->add (typeid (*this), (void *) this, sizeof (*this), sizeof (*this), parent, purpose, cat); + } + + db::mem_stat (stat, MemStatistics::Instances, cat, m_parent_insts, true, (void *) this); + db::mem_stat (stat, MemStatistics::Instances, cat, m_insts_by_cell_index, true, (void *) this); if (is_editable ()) { if (m_generic.stable_tree) { - m.inst_trees (*m_generic.stable_tree); + db::mem_stat (stat, MemStatistics::Instances, cat, *m_generic.stable_tree, true, (void *) this); } if (m_generic_wp.stable_tree) { - m.inst_trees (*m_generic_wp.stable_tree); + db::mem_stat (stat, MemStatistics::Instances, cat, *m_generic_wp.stable_tree, true, (void *) this); } } else { if (m_generic.unstable_tree) { - m.inst_trees (*m_generic.unstable_tree); + db::mem_stat (stat, MemStatistics::Instances, cat, *m_generic.unstable_tree, true, (void *) this); } if (m_generic_wp.unstable_tree) { - m.inst_trees (*m_generic_wp.unstable_tree); + db::mem_stat (stat, MemStatistics::Instances, cat, *m_generic_wp.unstable_tree, true, (void *) this); } } - - m.instances (m_parent_insts); - m.instances (m_insts_by_cell_index); - m.instances (-sizeof (m_parent_insts), -sizeof (m_parent_insts)); // the actual object is counted for cell, not for instances (see above) } Instances::instance_type diff --git a/src/db/db/dbInstances.h b/src/db/db/dbInstances.h index 6d4d6b430..b1642b120 100644 --- a/src/db/db/dbInstances.h +++ b/src/db/db/dbInstances.h @@ -1718,8 +1718,7 @@ public: /** * @brief Collect memory usage statistics */ - void - collect_mem_stat (db::MemStatistics &m) const; + void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const; /** * @brief Returns true, if this Instances container belongs to an editable cell @@ -1907,6 +1906,15 @@ private: void clear_insts (ET editable_tag); }; +/** + * @brief Collect memory statistics + */ +inline void +mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const Instances &x, bool no_self, void *parent) +{ + x.mem_stat (stat, purpose, cat, no_self, parent); +} + template inline NormalInstanceIteratorTraits::instance_type NormalInstanceIteratorTraits::instance_from_stable_iter (const Iter &iter) const diff --git a/src/db/db/dbLayer.h b/src/db/db/dbLayer.h index 635a5a50c..9a6513aaf 100644 --- a/src/db/db/dbLayer.h +++ b/src/db/db/dbLayer.h @@ -443,11 +443,12 @@ struct layer return m_box_tree.empty (); } - void - collect_mem_stat (db::MemStatistics &m) const + void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const { - m.shapes_info (sizeof (*this), sizeof (*this)); - m.shapes_info (db::mem_used (m_box_tree), db::mem_reqd (m_box_tree)); + if (! no_self) { + stat->add (typeid (layer), (void *) this, sizeof (layer), sizeof (layer), parent, purpose, cat); + } + db::mem_stat (stat, purpose, cat, m_box_tree, true, (void *) this); } private: @@ -457,6 +458,16 @@ private: bool m_tree_dirty : 8; }; +/** + * @brief Collect memory statistics + */ +template +inline void +mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const layer &x, bool no_self, void *parent) +{ + x.mem_stat (stat, purpose, cat, no_self, parent); +} + } #endif diff --git a/src/db/db/dbLayout.cc b/src/db/db/dbLayout.cc index 8f09cf238..69cef4a56 100644 --- a/src/db/db/dbLayout.cc +++ b/src/db/db/dbLayout.cc @@ -429,38 +429,38 @@ Layout::operator= (const Layout &d) } void -Layout::collect_mem_stat (db::MemStatistics &m) const +Layout::mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const { - m.layout_info (*((db::LayoutStateModel *) this)); - m.layout_info (m_cells_size); - m.layout_info (m_cell_ptrs); - m.layout_info (m_invalid); - m.layout_info (m_top_cells); - m.layout_info (m_top_down_list); - m.layout_info (m_free_indices); - m.layout_info (m_layer_states); - m.layout_info (m_lib_proxy_map); - m.layout_info (m_pcell_ids); - m.layout_info (m_pcells); + if (!no_self) { + stat->add (typeid (*this), (void *) this, sizeof (*this), sizeof (*this), parent, purpose, cat); + } - // this does not count the internal memory footprint of the cells - m.layout_info (m_cells); + db::mem_stat (stat, purpose, cat, m_cell_ptrs, true, (void *) this); + db::mem_stat (stat, purpose, cat, m_free_cell_indices, true, (void *) this); + db::mem_stat (stat, purpose, cat, m_top_down_list, true, (void *) this); + db::mem_stat (stat, purpose, cat, m_free_indices, true, (void *) this); + db::mem_stat (stat, purpose, cat, m_layer_states, true, (void *) this); + db::mem_stat (stat, purpose, cat, m_cell_names, true, (void *) this); + db::mem_stat (stat, purpose, cat, m_cell_map, true, (void *) this); + db::mem_stat (stat, purpose, cat, m_layer_props, true, (void *) this); + db::mem_stat (stat, purpose, cat, m_pcells, true, (void *) this); + db::mem_stat (stat, purpose, cat, m_pcell_ids, true, (void *) this); + db::mem_stat (stat, purpose, cat, m_lib_proxy_map, true, (void *) this); + db::mem_stat (stat, purpose, cat, m_meta_info, true, (void *) this); + db::mem_stat (stat, purpose, cat, m_string_repository, true, (void *) this); + db::mem_stat (stat, purpose, cat, m_shape_repository, true, (void *) this); + db::mem_stat (stat, purpose, cat, m_properties_repository, true, (void *) this); + db::mem_stat (stat, purpose, cat, m_array_repository, true, (void *) this); + for (std::vector::const_iterator i = m_cell_names.begin (); i != m_cell_names.end (); ++i) { + stat->add (typeid (char []), (void *) *i, strlen (*i) + 1, strlen (*i) + 1, (void *) this, purpose, cat); + } for (cell_list::const_iterator i = m_cells.begin (); i != m_cells.end (); ++i) { - i->collect_mem_stat (m); + db::mem_stat (stat, MemStatistics::CellInfo, int (i->id ()), *i, false, (void *) this); } - - for (std::vector::const_iterator p = m_cell_names.begin (); p != m_cell_names.end (); ++p) { - size_t l = strlen (*p) + 1; - m.layout_info (l, l); + for (std::vector::const_iterator i = m_pcells.begin (); i != m_pcells.end (); ++i) { + db::mem_stat (stat, MemStatistics::CellInfo, 0, **i, false, (void *) this); } - m.layout_info (m_cell_names); - m.layout_info (m_layer_props); - m.layout_info (m_cell_map); - m.layout_info (m_dbu); - m.shapes_cache (m_shape_repository); - m.shapes_cache (m_array_repository); - m.layout_info (m_meta_info); } void diff --git a/src/db/db/dbLayout.h b/src/db/db/dbLayout.h index 2506b0558..b3d832e2f 100644 --- a/src/db/db/dbLayout.h +++ b/src/db/db/dbLayout.h @@ -575,7 +575,7 @@ public: /** * @brief Collect memory statistics */ - void collect_mem_stat (db::MemStatistics &m) const; + void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self = false, void *parent = 0) const; /** * @brief Sets the properties ID @@ -1684,6 +1684,15 @@ private: void do_prune_cells_or_subcells (const std::set &ids, int levels, bool subcells); }; +/** + * @brief Collect memory statistics + */ +inline void +mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const Layout &x, bool no_self, void *parent) +{ + x.mem_stat (stat, purpose, cat, no_self, parent); +} + /** * @brief A nice helper class that employs RAII for locking the layout against updates * diff --git a/src/db/db/dbMemStatistics.cc b/src/db/db/dbMemStatistics.cc index 0ac9bfd31..061ba8275 100644 --- a/src/db/db/dbMemStatistics.cc +++ b/src/db/db/dbMemStatistics.cc @@ -27,51 +27,96 @@ namespace db { -size_t mem_used (const std::string &s) +void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const std::string &x, bool no_self, void *parent) { - return sizeof (std::string) + s.capacity (); + if (! no_self) { + stat->add (typeid (std::string), (void *) &x, sizeof (std::string), sizeof (std::string), parent, purpose, cat); + } + stat->add (typeid (char []), (void *) x.c_str (), x.capacity (), x.size (), (void *) &x, purpose, cat); } -size_t mem_reqd (const std::string &s) +void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const tl::Variant &x, bool no_self, void *parent) { - return sizeof (std::string) + s.size (); + if (! no_self) { + stat->add (typeid (tl::Variant), (void *) &x, sizeof (tl::Variant), sizeof (tl::Variant), parent, purpose, cat); + } + // TODO: add content } -size_t mem_used (const std::vector &v) +void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const std::vector &x, bool no_self, void *parent) { - return sizeof (std::vector) + v.capacity () / 8; -} - -size_t mem_reqd (const std::vector &v) -{ - return sizeof (std::vector) + v.size () / 8; + if (! no_self) { + stat->add (typeid (std::vector), (void *) &x, sizeof (std::vector), sizeof (std::vector), parent, purpose, cat); + } + stat->add (typeid (bool []), (void *) 0 /*n/a*/, x.capacity () / 8, x.size () / 8, (void *) &x, purpose, cat); } +// -------------------------------------------------------------------------------------- MemStatistics::MemStatistics () { - m_layout_info_used = m_layout_info_reqd = 0; - m_cell_info_used = m_cell_info_reqd = 0; - m_inst_trees_used = m_inst_trees_reqd = 0; - m_shapes_info_used = m_shapes_info_reqd = 0; - m_shapes_cache_used = m_shapes_cache_reqd = 0; - m_shape_trees_used = m_shape_trees_reqd = 0; - m_instances_used = m_instances_reqd = 0; + // .. nothing yet .. } -void -MemStatistics::print () const +// -------------------------------------------------------------------------------------- + +MemStatisticsCollector::MemStatisticsCollector (bool detailed) + : m_detailed (detailed) { - tl::info << "Memory usage:"; - tl::info << " Layout info " << m_layout_info_used << " (used) " << m_layout_info_reqd << " (reqd)"; - tl::info << " Cell info " << m_cell_info_used << " (used) " << m_cell_info_reqd << " (reqd) "; - tl::info << " Instances " << m_instances_used << " (used) " << m_instances_reqd << " (reqd) "; - tl::info << " Instance trees " << m_inst_trees_used << " (used) " << m_inst_trees_reqd << " (reqd) "; - tl::info << " Shapes info " << m_shapes_info_used << " (used) " << m_shapes_info_reqd << " (reqd) "; - tl::info << " Shapes cache " << m_shapes_cache_used << " (used) " << m_shapes_cache_reqd << " (reqd) "; - tl::info << " Shape trees " << m_shape_trees_used << " (used) " << m_shape_trees_reqd << " (reqd) "; - tl::info << " Total " << (m_layout_info_used + m_cell_info_used + m_instances_used + m_inst_trees_used + m_shapes_info_used + m_shapes_cache_used + m_shape_trees_used) << " (used) " - << (m_layout_info_reqd + m_cell_info_reqd + m_instances_reqd + m_inst_trees_reqd + m_shapes_info_reqd + m_shapes_cache_reqd + m_shape_trees_reqd) << " (reqd) "; + // .. nothing yet .. +} + +void +MemStatisticsCollector::print () +{ + std::map p2s; + p2s[None] = "(none) "; + p2s[LayoutInfo] = "Layout info "; + p2s[CellInfo] = "Cell info "; + p2s[Instances] = "Instances "; + p2s[InstTrees] = "Instance trees "; + p2s[ShapesInfo] = "Shapes info "; + p2s[ShapesCache] = "Shapes cache "; + p2s[ShapeTrees] = "Shape trees "; + + if (detailed) { + + tl::info << "Memory usage per type:"; + for (std::map >::const_iterator t = m_per_type.begin (); t != m_per_type.end (); ++t) { + tl::info << " " << t->first->name () << ": " << t->second.first << " (used) " << t->second.second << " (reqd)"; + } + + tl::info << "Memory usage per category:"; + for (std::map, std::pair >::const_iterator t = m_per_cat.begin (); t != m_per_cat.end (); ++t) { + tl::info << " " << p2s[t->first.first] << "[" << t->first.second << "]: " << t->second.first << " (used) " << t->second.second << " (reqd)"; + } + + } + + tl::info << "Memory usage per master category:"; + for (std::map >::const_iterator t = m_per_purpose.begin (); t != m_per_purpose.end (); ++t) { + tl::info << " " << p2s[t->first] << ": " << t->second.first << " (used) " << t->second.second << " (reqd)"; + } + tl::info << tl::endl << " Total : " << tot.first << " (used) " << tot.second << " (reqd)"; +} + +void +MemStatisticsCollector::add (const std::type_info &ti, void * /*ptr*/, size_t size, size_t used, void * /*parent*/, purpose_t purpose, int cat) +{ + if (m_detailed) { + + m_per_type[&ti].first += used; + m_per_type[&ti].second += size; + + std::pair &i = m_per_cat [std::make_pair (purpose, cat)]; + i.first += used; + i.second += size; + + } + + std::pair &j = m_per_purpose [purpose]; + j.first += used; + j.second += size; } } diff --git a/src/db/db/dbMemStatistics.h b/src/db/db/dbMemStatistics.h index a10ef722d..9ae6bd4aa 100644 --- a/src/db/db/dbMemStatistics.h +++ b/src/db/db/dbMemStatistics.h @@ -33,286 +33,189 @@ #include #include #include +#include +#include "tlReuseVector.h" namespace tl { template class vector; template class reuse_vector; + class Variant; } namespace db { -template -size_t mem_used (const X &) -{ - return sizeof (X); -} - -template -size_t mem_reqd (const X &) -{ - return sizeof (X); -} - -size_t mem_used (const std::string &s); -size_t mem_reqd (const std::string &s); - -template -size_t mem_used (const tl::reuse_vector &v) -{ - size_t s = v.mem_used (); - for (typename tl::reuse_vector::const_iterator e = v.begin (); e != v.end (); ++e) { - s += mem_used (*e); - } - return s; -} - -template -size_t mem_reqd (const tl::reuse_vector &v) -{ - size_t s = v.mem_reqd (); - for (typename tl::reuse_vector::const_iterator e = v.begin (); e != v.end (); ++e) { - s += mem_used (*e); - } - return s; -} - -template -size_t mem_used (const tl::vector &v) -{ - size_t s = sizeof (tl::vector); - size_t i = 0; - for (i = 0; i < v.size (); ++i) { - s += mem_used (v[i]); - } - s += sizeof (X) * (v.capacity () - v.size ()); - return s; -} - -template -size_t mem_reqd (const tl::vector &v) -{ - size_t s = sizeof (tl::vector); - size_t i = 0; - for (i = 0; i < v.size (); ++i) { - s += mem_reqd (v[i]); - } - return s; -} - -template -size_t mem_used (const std::vector &v) -{ - size_t s = sizeof (std::vector); - size_t i = 0; - for (i = 0; i < v.size (); ++i) { - s += mem_used (v[i]); - } - s += sizeof (X) * (v.capacity () - v.size ()); - return s; -} - -template -size_t mem_reqd (const std::vector &v) -{ - size_t s = sizeof (std::vector); - size_t i = 0; - for (i = 0; i < v.size (); ++i) { - s += mem_reqd (v[i]); - } - return s; -} - -size_t mem_used (const std::vector &v); -size_t mem_reqd (const std::vector &v); - -template -size_t mem_used (const std::map &m) -{ - size_t s = sizeof (std::map); - for (typename std::map::const_iterator i = m.begin (); i != m.end (); ++i) { - s += mem_used(i->first) + mem_used(i->second); -#ifdef __GNUCC__ - s += sizeof (std::_Rb_tree_node_base); -#endif - } - return s; -} - -template -size_t mem_reqd (const std::map &m) -{ - size_t s = sizeof (std::map); - for (typename std::map::const_iterator i = m.begin (); i != m.end (); ++i) { - s += mem_reqd(i->first) + mem_reqd(i->second); -#ifdef __GNUCC__ - s += sizeof (std::_Rb_tree_node_base); -#endif - } - return s; -} - -template -size_t mem_used (const std::set &x) -{ - size_t s = sizeof (std::set); - for (typename std::set::const_iterator i = x.begin (); i != x.end (); ++i) { - s += mem_used(*i); -#ifdef __GNUCC__ - s += sizeof (std::_Rb_tree_node_base); -#endif - } - return s; -} - -template -size_t mem_reqd (const std::set &x) -{ - size_t s = sizeof (std::set); - for (typename std::set::const_iterator i = x.begin (); i != x.end (); ++i) { - s += mem_reqd(*i); -#ifdef __GNUCC__ - s += sizeof (std::_Rb_tree_node_base); -#endif - } - return s; -} - -template -size_t mem_used (const std::list &l) -{ - size_t s = sizeof (std::list); - for (typename std::list::const_iterator i = l.begin (); i != l.end (); ++i) { - s += mem_used(*i); -#ifdef __GNUCC__ - s += sizeof (std::_List_node_base); -#endif - } - return s; -} - -template -size_t mem_reqd (const std::list &l) -{ - size_t s = sizeof (std::list); - for (typename std::list::const_iterator i = l.begin (); i != l.end (); ++i) { - s += mem_reqd(*i); -#ifdef __GNUCC__ - s += sizeof (std::_List_node_base); -#endif - } - return s; -} - +/** + * @brief A collector for memory statistics + * This interface implements the collector for memory statistics. + */ class DB_PUBLIC MemStatistics { public: MemStatistics (); - void print () const; - - void layout_info (size_t u, size_t r) + enum purpose_t { - m_layout_info_used += u; - m_layout_info_reqd += r; - } + None, + LayoutInfo, + CellInfo, + Instances, + InstTrees, + ShapesInfo, + ShapesCache, + ShapeTrees + }; - template - void layout_info (const X &x) - { - m_layout_info_used += mem_used (x); - m_layout_info_reqd += mem_reqd (x); - } + /** + * @brief Adds a memory block for a specific object + * The object has a purpose (general category), a detailed category (i.e. + * cell index, layer index etc.), a type, a pointer and a size. + * "used" can be a value less than "size" to indicate that no + * all of the chunk is used. "parent" is a parent object. This pointer + * can indicate that the chunk is a part of another object. + * "purpose" and "cat can be inherited by the parent. + */ + virtual void add (const std::type_info & /*ti*/, void * /*ptr*/, size_t /*size*/, size_t /*used*/, void * /*parent*/, purpose_t /*purpose*/ = None, int /*cat*/ = 0) { } +}; - void cell_info (size_t u, size_t r) - { - m_cell_info_used += u; - m_cell_info_reqd += r; - } +/** + * @brief A generic memory statistics collector + * This collector will collect the summary of memory usage only. + */ +class DB_PUBLIC MemStatisticsCollector + : public MemStatistics +{ +public: + MemStatisticsCollector (bool detailed); - template - void cell_info (const X &x) - { - m_cell_info_used += mem_used (x); - m_cell_info_reqd += mem_reqd (x); - } + /** + * @brief Prints the statistics + */ + void print (); - void instances (size_t u, size_t r) - { - m_instances_used += u; - m_instances_reqd += r; - } - - template - void instances (const X &x) - { - m_instances_used += mem_used (x); - m_instances_reqd += mem_reqd (x); - } - - void inst_trees (size_t u, size_t r) - { - m_inst_trees_used += u; - m_inst_trees_reqd += r; - } - - template - void inst_trees (const X &x) - { - m_inst_trees_used += mem_used (x); - m_inst_trees_reqd += mem_reqd (x); - } - - void shapes_info (size_t u, size_t r) - { - m_shapes_info_used += u; - m_shapes_info_reqd += r; - } - - template - void shapes_info (const X &x) - { - m_shapes_info_used += mem_used (x); - m_shapes_info_reqd += mem_reqd (x); - } - - void shapes_cache (size_t u, size_t r) - { - m_shapes_cache_used += u; - m_shapes_cache_reqd += r; - } - - template - void shapes_cache (const X &x) - { - m_shapes_cache_used += mem_used (x); - m_shapes_cache_reqd += mem_reqd (x); - } - - void shape_trees (size_t u, size_t r) - { - m_shape_trees_used += u; - m_shape_trees_reqd += r; - } - - template - void shape_trees (const X &x) - { - m_shape_trees_used += mem_used (x); - m_shape_trees_reqd += mem_reqd (x); - } + virtual void add (const std::type_info &ti, void *ptr, size_t size, size_t used, void *parent, purpose_t purpose, int cat); private: - size_t m_layout_info_used, m_layout_info_reqd; - size_t m_cell_info_used, m_cell_info_reqd; - size_t m_inst_trees_used, m_inst_trees_reqd; - size_t m_shapes_info_used, m_shapes_info_reqd; - size_t m_shapes_cache_used, m_shapes_cache_reqd; - size_t m_shape_trees_used, m_shape_trees_reqd; - size_t m_instances_used, m_instances_reqd; + bool m_detailed; + std::map > m_per_type; + std::map, std::pair > m_per_cat; + std::map > m_per_purpose; }; +// Some standard templates to collect the information +template +void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const X &x, bool no_self = false, void *parent = 0) +{ + if (! no_self) { + stat->add (typeid (X), (void *) &x, sizeof (X), sizeof (X), parent, purpose, cat); + } +} + +void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const std::string &x, bool no_self = false, void *parent = 0); + +void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const tl::Variant &x, bool no_self = false, void *parent = 0); + +template +void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const tl::reuse_vector &v, bool no_self = false, void *parent = 0) +{ + if (! no_self) { + stat->add (typeid (tl::reuse_vector), (void *) &v, sizeof (tl::reuse_vector), sizeof (tl::reuse_vector), parent, purpose, cat); + } + if (! v.empty ()) { + stat->add (typeid (X[]), (void *) v.begin ().operator-> (), sizeof (X) * v.capacity (), sizeof (X) * v.size (), (void *) &v, purpose, cat); + } + if (v.reuse_data ()) { + stat->add (typeid (tl::ReuseData), (void *) v.reuse_data (), v.reuse_data ()->mem_reqd (), v.reuse_data ()->mem_used (), (void *) &v, purpose, cat); + } + for (typename tl::reuse_vector::const_iterator e = v.begin (); e != v.end (); ++e) { + mem_stat (stat, purpose, cat, *e, true, (void *) &v); + } +} + +template +void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const tl::vector &v, bool no_self = false, void *parent = 0) +{ + if (! no_self) { + stat->add (typeid (tl::vector), (void *) &v, sizeof (tl::vector), sizeof (tl::vector), parent, purpose, cat); + } + if (! v.empty ()) { + stat->add (typeid (X[]), (void *) &v.front (), sizeof (X) * v.capacity (), sizeof (X) * v.size (), (void *) &v, purpose, cat); + } + for (size_t i = 0; i < v.size (); ++i) { + mem_stat (stat, purpose, cat, v[i], true, (void *) &v); + } +} + +template +void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const std::vector &v, bool no_self = false, void *parent = 0) +{ + if (! no_self) { + stat->add (typeid (std::vector), (void *) &v, sizeof (std::vector), sizeof (std::vector), parent, purpose, cat); + } + if (! v.empty ()) { + stat->add (typeid (X[]), (void *) &v.front (), sizeof (X) * v.capacity (), sizeof (X) * v.size (), (void *) &v, purpose, cat); + } + for (size_t i = 0; i < v.size (); ++i) { + mem_stat (stat, purpose, cat, v[i], true, (void *) &v); + } +} + +void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const std::vector &x, bool no_self = false, void *parent = 0); + +template +void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const std::map &v, bool no_self = false, void *parent = 0) +{ + if (! no_self) { + stat->add (typeid (std::map), (void *) &v, sizeof (std::map), sizeof (std::map), parent, purpose, cat); + } + for (typename std::map::const_iterator i = v.begin (); i != v.end (); ++i) { + mem_stat (stat, purpose, cat, i->first, false, (void *) &v); + mem_stat (stat, purpose, cat, i->second, false, (void *) &v); +#ifdef __GNUCC__ + stat->add (std::_Rb_tree_node_base, (void *) &i->first, sizeof (std::_Rb_tree_node_base), sizeof (std::_Rb_tree_node_base), (void *) &v, purpose, cat); +#endif + } +} + +template +void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const std::set &v, bool no_self = false, void *parent = 0) +{ + if (! no_self) { + stat->add (typeid (std::set), (void *) &v, sizeof (std::set), sizeof (std::set), parent, purpose, cat); + } + for (typename std::set::const_iterator i = v.begin (); i != v.end (); ++i) { + mem_stat (stat, purpose, cat, *i, false, (void *) &v); +#ifdef __GNUCC__ + stat->add (std::_Rb_tree_node_base, (void *) &i.operator-> (), sizeof (std::_Rb_tree_node_base), sizeof (std::_Rb_tree_node_base), (void *) &v, purpose, cat); +#endif + } +} + +template +void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const std::list &v, bool no_self = false, void *parent = 0) +{ + if (! no_self) { + stat->add (typeid (std::list), (void *) &v, sizeof (std::list), sizeof (std::list), parent, purpose, cat); + } + for (typename std::list::const_iterator i = v.begin (); i != v.end (); ++i) { + mem_stat (stat, purpose, cat, *i, false, (void *) &v); +#ifdef __GNUCC__ + stat->add (std::_List_node_base, (void *) &i.operator-> (), sizeof (std::_List_node_base), sizeof (std::_List_node_base), (void *) &v, purpose, cat); +#endif + } +} + +template +void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const std::pair &v, bool no_self = false, void *parent = 0) +{ + if (! no_self) { + stat->add (typeid (std::pair), (void *) &v, sizeof (std::pair), sizeof (std::pair), parent, purpose, cat); + } + mem_stat (stat, purpose, cat, v.first, true, (void *) &v); + mem_stat (stat, purpose, cat, v.second, true, (void *) &v); +} + } #endif diff --git a/src/db/db/dbMetaInfo.h b/src/db/db/dbMetaInfo.h index cf7de8baf..60ca12908 100644 --- a/src/db/db/dbMetaInfo.h +++ b/src/db/db/dbMetaInfo.h @@ -25,6 +25,7 @@ #define HDR_dbMetaInfo #include "dbCommon.h" +#include "dbMemStatistics.h" #include namespace db @@ -57,6 +58,16 @@ struct DB_PUBLIC MetaInfo std::string value; }; +/** + * @brief Collect memory statistics + */ +inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const MetaInfo &v, bool no_self, void *parent) +{ + db::mem_stat (stat, purpose, cat, v.name, no_self, parent); + db::mem_stat (stat, purpose, cat, v.description, no_self, parent); + db::mem_stat (stat, purpose, cat, v.value, no_self, parent); +} + } #endif diff --git a/src/db/db/dbPath.h b/src/db/db/dbPath.h index 408c755ea..b5dce53c8 100644 --- a/src/db/db/dbPath.h +++ b/src/db/db/dbPath.h @@ -859,14 +859,12 @@ public: // .. nothing .. } - size_t mem_used () const + void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const { - return db::mem_used (m_width) + db::mem_used (m_bgn_ext) + db::mem_used (m_end_ext) + db::mem_used (m_points); - } - - size_t mem_reqd () const - { - return db::mem_reqd (m_width) + db::mem_reqd (m_bgn_ext) + db::mem_reqd (m_end_ext) + db::mem_reqd (m_points); + if (!no_self) { + stat->add (typeid (*this), (void *) this, sizeof (*this), sizeof (*this), parent, purpose, cat); + } + db::mem_stat (stat, purpose, cat, m_points, true, (void *) this); } private: @@ -895,6 +893,15 @@ private: void create_shifted_points (coord_type start, coord_type end, coord_type width, bool forward, Iter from, Iter to, int ncircle, Inserter pts) const; }; +/** + * @brief Collect memory statistics + */ +template +inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const path &x, bool no_self = false, void *parent = 0) +{ + x.mem_stat (stat, purpose, cat, no_self, parent); +} + /** * @brief Binary * operator (transformation) * @@ -948,18 +955,6 @@ typedef path Path; */ typedef path DPath; -template -size_t mem_used (const path &x) -{ - return x.mem_used (); -} - -template -size_t mem_reqd (const path &x) -{ - return x.mem_reqd (); -} - /** * @brief A path reference * diff --git a/src/db/db/dbPolygon.h b/src/db/db/dbPolygon.h index b80f644c0..9c42d807a 100644 --- a/src/db/db/dbPolygon.h +++ b/src/db/db/dbPolygon.h @@ -984,14 +984,15 @@ public: std::swap (mp_points, d.mp_points); } - size_t mem_used () const + /** + * @brief Collect memory statistics + */ + void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self = false, void *parent = 0) const { - return sizeof (polygon_contour) + sizeof (point_type) * m_size; - } - - size_t mem_reqd () const - { - return sizeof (polygon_contour) + sizeof (point_type) * m_size; + if (! no_self) { + stat->add (typeid (*this), (void *) this, sizeof (*this), sizeof (*this), parent, purpose, cat); + } + stat->add (typeid (point_type []), (void *) mp_points, sizeof (point_type) * m_size, sizeof (point_type) * m_size, (void *) this, purpose, cat); } private: @@ -2269,14 +2270,10 @@ public: return copy; } - size_t mem_used () const + void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self = false, void *parent = 0) const { - return sizeof (m_bbox) + db::mem_used (m_ctrs); - } - - size_t mem_reqd () const - { - return sizeof (m_bbox) + db::mem_reqd (m_ctrs); + db::mem_stat (stat, purpose, cat, &m_ctrs, no_self, parent); + db::mem_stat (stat, purpose, cat, &m_bbox, no_self, parent); } private: @@ -2935,14 +2932,10 @@ public: return m_hull.size (); } - size_t mem_used () const + void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self = false, void *parent = 0) const { - return sizeof (m_bbox) + db::mem_used (m_hull); - } - - size_t mem_reqd () const - { - return sizeof (m_bbox) + db::mem_reqd (m_hull); + db::mem_stat (stat, purpose, cat, &m_hull, no_self, parent); + db::mem_stat (stat, purpose, cat, &m_bbox, no_self, parent); } private: @@ -3344,41 +3337,31 @@ typedef polygon_ref SimplePolygonPtr; */ typedef polygon_ref DSimplePolygonPtr; - +/** + * @brief Collect memory statistics + */ template -size_t mem_used (const polygon_contour &x) +inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const polygon_contour &x, bool no_self = false, void *parent = 0) { - return x.mem_used (); + x.mem_stat (stat, purpose, cat, no_self, parent); } +/** + * @brief Collect memory statistics + */ template -size_t mem_reqd (const polygon_contour &x) +inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const polygon &x, bool no_self = false, void *parent = 0) { - return x.mem_reqd (); + x.mem_stat (stat, purpose, cat, no_self, parent); } +/** + * @brief Collect memory statistics + */ template -size_t mem_used (const polygon &x) +inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const simple_polygon &x, bool no_self = false, void *parent = 0) { - return x.mem_used (); -} - -template -size_t mem_reqd (const polygon &x) -{ - return x.mem_reqd (); -} - -template -size_t mem_used (const simple_polygon &x) -{ - return x.mem_used (); -} - -template -size_t mem_reqd (const simple_polygon &x) -{ - return x.mem_reqd (); + x.mem_stat (stat, purpose, cat, no_self, parent); } } // namespace db diff --git a/src/db/db/dbPropertiesRepository.h b/src/db/db/dbPropertiesRepository.h index 3b5f13eae..ed8a051e6 100644 --- a/src/db/db/dbPropertiesRepository.h +++ b/src/db/db/dbPropertiesRepository.h @@ -25,9 +25,10 @@ #define HDR_dbPropertiesRepository #include "dbCommon.h" +#include "dbTypes.h" +#include "dbMemStatistics.h" #include "tlVariant.h" -#include "dbTypes.h" #include #include @@ -206,6 +207,22 @@ public: */ properties_id_type translate (const PropertiesRepository &rep, properties_id_type id); + /** + * @brief Collect memory statistics + */ + void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self = false, void *parent = 0) const + { + if (!no_self) { + stat->add (typeid (*this), (void *) this, sizeof (*this), sizeof (*this), parent, purpose, cat); + } + + db::mem_stat (stat, purpose, cat, m_propnames_by_id, true, parent); + db::mem_stat (stat, purpose, cat, m_propname_ids_by_name, true, parent); + db::mem_stat (stat, purpose, cat, m_properties_by_id, true, parent); + db::mem_stat (stat, purpose, cat, m_properties_ids_by_set, true, parent); + db::mem_stat (stat, purpose, cat, m_properties_component_table, true, parent); + } + private: std::map m_propnames_by_id; std::map m_propname_ids_by_name; @@ -219,6 +236,14 @@ private: PropertiesRepository (const PropertiesRepository &d); }; +/** + * @brief Collect memory statistics + */ +inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const PropertiesRepository &x, bool no_self = false, void *parent = 0) +{ + x.mem_stat (stat, purpose, cat, no_self, parent); +} + } // namespace db #endif diff --git a/src/db/db/dbShape.h b/src/db/db/dbShape.h index 2b5ea7a3b..63446c641 100644 --- a/src/db/db/dbShape.h +++ b/src/db/db/dbShape.h @@ -2547,16 +2547,6 @@ public: return m_trans < d.m_trans; } - size_t mem_used () const - { - return sizeof (*this); - } - - size_t mem_reqd () const - { - return sizeof (*this); - } - /** * @brief Convert to a string */ @@ -2620,18 +2610,6 @@ public: object_type m_type : 16; }; -template -size_t mem_used (const Shape &s) -{ - return s.mem_used (); -} - -template -size_t mem_reqd (const Shape &s) -{ - return s.mem_reqd (); -} - } // namespace db #endif diff --git a/src/db/db/dbShapeRepository.h b/src/db/db/dbShapeRepository.h index 57442003b..19db40d96 100644 --- a/src/db/db/dbShapeRepository.h +++ b/src/db/db/dbShapeRepository.h @@ -113,33 +113,24 @@ public: return m_set.end (); } - size_t mem_used () const + void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const { - return db::mem_used (m_set); - } - - size_t mem_reqd () const - { - return db::mem_reqd (m_set); + db::mem_stat (stat, purpose, cat, m_set, no_self, parent); } private: set_type m_set; }; +/** + * @brief Collect memory statistics + */ template -size_t mem_used (const repository &s) +inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const repository &x, bool no_self = false, void *parent = 0) { - return s.mem_used (); + x.mem_stat (stat, purpose, cat, no_self, parent); } -template -size_t mem_reqd (const repository &s) -{ - return s.mem_reqd (); -} - - /** * @brief A repository for many shape types * @@ -185,20 +176,12 @@ public: return m_text_repository; } - size_t mem_used () const + void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const { - return db::mem_used (m_polygon_repository) + - db::mem_used (m_simple_polygon_repository) + - db::mem_used (m_path_repository) + - db::mem_used (m_text_repository); - } - - size_t mem_reqd () const - { - return db::mem_reqd (m_polygon_repository) + - db::mem_reqd (m_simple_polygon_repository) + - db::mem_reqd (m_path_repository) + - db::mem_reqd (m_text_repository); + db::mem_stat (stat, purpose, cat, m_polygon_repository, no_self, parent); + db::mem_stat (stat, purpose, cat, m_simple_polygon_repository, no_self, parent); + db::mem_stat (stat, purpose, cat, m_path_repository, no_self, parent); + db::mem_stat (stat, purpose, cat, m_text_repository, no_self, parent); } private: @@ -208,19 +191,15 @@ private: db::repository< db::text > m_text_repository; }; +/** + * @brief Collect memory statistics + */ template -size_t mem_used (const generic_repository &s) +inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const generic_repository &x, bool no_self = false, void *parent = 0) { - return s.mem_used (); + x.mem_stat (stat, purpose, cat, no_self, parent); } -template -size_t mem_reqd (const generic_repository &s) -{ - return s.mem_reqd (); -} - - /** * @brief Standard repository typedef */ @@ -459,14 +438,17 @@ struct shape_ref return obj ().to_string () + "->" + m_trans.to_string (); } - size_t mem_used () const + /** + * @brief Collect memory statistics + */ + void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const { - return sizeof (shape_ref) + (m_ptr ? db::mem_used (*m_ptr) : 0); - } - - size_t mem_reqd () const - { - return sizeof (shape_ref) + (m_ptr ? db::mem_reqd (*m_ptr) : 0); + if (!no_self) { + stat->add (typeid (shape_ref), (void *) this, sizeof (shape_ref), sizeof (shape_ref), parent, purpose, cat); + } + if (m_ptr) { + db::mem_stat (stat, purpose, cat, *m_ptr, false, (void *) this); + } } private: @@ -474,16 +456,13 @@ private: trans_type m_trans; }; +/** + * @brief Collect memory statistics + */ template -size_t mem_used (const shape_ref &s) +inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const shape_ref &x, bool no_self = false, void *parent = 0) { - return s.mem_used (); -} - -template -size_t mem_reqd (const shape_ref &s) -{ - return s.mem_reqd (); + x.mem_stat (stat, purpose, cat, no_self, parent); } /** diff --git a/src/db/db/dbShapes.cc b/src/db/db/dbShapes.cc index ef848cdc1..1e6b032d3 100644 --- a/src/db/db/dbShapes.cc +++ b/src/db/db/dbShapes.cc @@ -33,7 +33,26 @@ namespace db { - + +// ------------------------------------------------------------------------------- + +LayerBase::LayerBase () +{ + // .. nothing yet .. +} + +// instantiates the vtable +LayerBase::~LayerBase () +{ + // .. nothing yet .. +} + +void +LayerBase::mem_stat (MemStatistics * /*stat*/, MemStatistics::purpose_t /*purpose*/, int /*cat*/, bool /*no_self*/, void * /*parent*/) const +{ + // .. nothing yet .. +} + // ------------------------------------------------------------------------------- // some utilities @@ -935,13 +954,15 @@ Shapes::undo (db::Op *op) } void -Shapes::collect_mem_stat (db::MemStatistics &m) const +Shapes::mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const { - m.cell_info (m_layers); - m.cell_info (mp_cell); - + if (! no_self) { + stat->add (typeid (*this), (void *) this, sizeof (*this), sizeof (*this), parent, purpose, cat); + } + db::mem_stat (stat, purpose, cat, m_layers, true, (void *) this); + db::mem_stat (stat, purpose, cat, mp_cell, true, (void *) this); for (tl::vector::const_iterator l = m_layers.begin (); l != m_layers.end (); ++l) { - (*l)->collect_mem_stat (m); + (*l)->mem_stat (stat, purpose, cat, false, (void *) this); } } diff --git a/src/db/db/dbShapes.h b/src/db/db/dbShapes.h index 2511bef69..63710d548 100644 --- a/src/db/db/dbShapes.h +++ b/src/db/db/dbShapes.h @@ -439,7 +439,8 @@ public: typedef db::Box box_type; typedef db::Coord coord_type; - virtual ~LayerBase () { } + LayerBase (); + virtual ~LayerBase (); virtual box_type bbox () const = 0; virtual void update_bbox () = 0; @@ -463,7 +464,7 @@ public: virtual void deref_and_transform_into (Shapes *target, const ICplxTrans &trans, pm_delegate_type &pm) = 0; virtual unsigned int type_mask () const = 0; - virtual void collect_mem_stat (db::MemStatistics &m) const = 0; + virtual void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const; }; /** @@ -1422,7 +1423,7 @@ public: /** * @brief Collect memory usage */ - void collect_mem_stat (db::MemStatistics &m) const; + void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self = false, void *parent = 0) const; private: friend class ShapeIterator; @@ -1586,6 +1587,14 @@ public: virtual void redo (Shapes *shapes) = 0; }; +/** + * @brief Collect memory usage + */ +inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const db::Shapes &x, bool no_self, void *parent) +{ + x.mem_stat (stat, purpose, cat, no_self, parent); +} + /** * @brief A undo/redo queue object for the layer * diff --git a/src/db/db/dbShapes2.h b/src/db/db/dbShapes2.h index e85f0fe09..2bf33a88a 100644 --- a/src/db/db/dbShapes2.h +++ b/src/db/db/dbShapes2.h @@ -156,11 +156,9 @@ public: virtual void deref_and_transform_into (Shapes *target, const ICplxTrans &trans); virtual void deref_and_transform_into (Shapes *target, const ICplxTrans &trans, pm_delegate_type &pm); - virtual void - collect_mem_stat (db::MemStatistics &m) const + virtual void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const { - m.shapes_info ((const LayerBase &)(*this)); // base class contribution - m_layer.collect_mem_stat (m); + db::mem_stat (stat, purpose, cat, m_layer, no_self, parent); } unsigned int type_mask () const; @@ -169,6 +167,12 @@ private: layer_type m_layer; }; +template +void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const layer_class &x, bool no_self, void *parent) +{ + x.mem_stat (stat, purpose, cat, no_self, parent); +} + } #endif diff --git a/src/db/db/dbText.h b/src/db/db/dbText.h index e044e47f4..fe9ce4de0 100644 --- a/src/db/db/dbText.h +++ b/src/db/db/dbText.h @@ -110,6 +110,14 @@ public: return mp_rep; } + void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self = false, void *parent = 0) const + { + if (! no_self) { + stat->add (typeid (*this), (void *) this, sizeof (*this), sizeof (*this), parent, purpose, cat); + } + db::mem_stat (stat, purpose, cat, m_value, true, (void *) this); + } + private: friend class StringRepository; StringRepository *mp_rep; @@ -134,6 +142,14 @@ private: StringRef operator= (const StringRef &d); }; +/** + * @brief Collect memory usage + */ +inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const StringRef &x, bool no_self = false, void *parent = 0) +{ + x.mem_stat (stat, purpose, cat, no_self, parent); +} + /** * @brief A string repository class * @@ -200,6 +216,17 @@ public: return m_string_refs.size (); } + void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self = false, void *parent = 0) const + { + if (! no_self) { + stat->add (typeid (*this), (void *) this, sizeof (*this), sizeof (*this), parent, purpose, cat); + } + db::mem_stat (stat, purpose, cat, &m_string_refs, true, (void *) this); + for (std::set::const_iterator r = m_string_refs.begin (); r != m_string_refs.end (); ++r) { + db::mem_stat (stat, purpose, cat, **r, true, parent); + } + } + private: friend class StringRef; @@ -213,6 +240,14 @@ private: } }; +/** + * @brief Collect memory statistics + */ +inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const StringRepository &x, bool no_self = false, void *parent = 0) +{ + x.mem_stat (stat, purpose, cat, no_self, parent); +} + /** * @brief A text object * @@ -733,21 +768,20 @@ public: // .. nothing .. } - size_t mem_used () const + /** + * @brief Collect memory statistics + */ + void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const { + if (! no_self) { + stat->add (typeid (text), (void *) this, sizeof (text), sizeof (text), parent, purpose, cat); + } size_t p = (size_t) mp_ptr; if (! (p & 1) && mp_ptr != 0) { - return sizeof (char *) + strlen (mp_ptr) + db::mem_used (m_trans) + db::mem_used (m_size) + db::mem_used (m_font); - } else { - return sizeof (char *) + db::mem_used (m_trans) + db::mem_used (m_size) + db::mem_used (m_font); + stat->add (typeid (char *), (void *) mp_ptr, strlen (mp_ptr) + 1, strlen (mp_ptr) + 1, (void *) this, purpose, cat); } } - size_t mem_reqd () const - { - return mem_used (); - } - private: template friend class text; @@ -1042,17 +1076,13 @@ typedef text_ref TextPtr; */ typedef text_ref DTextPtr; - +/** + * @brief Collect memory usage + */ template -size_t mem_used (const text &x) +inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const text &x, bool no_self = false, void *parent = 0) { - return x.mem_used (); -} - -template -size_t mem_reqd (const text &x) -{ - return x.mem_reqd (); + x.mem_stat (stat, purpose, cat, no_self, parent); } } // namespace db diff --git a/src/db/db/dbUserObject.h b/src/db/db/dbUserObject.h index 55a9028b3..4c4eac41c 100644 --- a/src/db/db/dbUserObject.h +++ b/src/db/db/dbUserObject.h @@ -32,6 +32,7 @@ #include "dbTrans.h" #include "dbObjectTag.h" #include "dbBox.h" +#include "dbMemStatistics.h" #include "tlClassRegistry.h" #include @@ -157,14 +158,9 @@ public: virtual std::string to_string () const { return std::string (); } /** - * @brief Return the memory used in bytes + * @brief Collect memory statistics */ - virtual size_t mem_used () const = 0; - - /** - * @brief Return the memory required in bytes - */ - virtual size_t mem_reqd () const = 0; + virtual void mem_stat (db::MemStatistics * /*stat*/, db::MemStatistics::purpose_t /*purpose*/, int /*cat*/, bool /*no_self*/, void * /*parent*/) const { } }; template @@ -361,14 +357,14 @@ public: std::swap (mp_obj, other.mp_obj); } - size_t mem_used () const + void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const { - return sizeof (user_object) + mp_obj->mem_used (); - } - - size_t mem_reqd () const - { - return sizeof (user_object) + mp_obj->mem_reqd (); + if (! no_self) { + stat->add (typeid (*this), (void *) this, sizeof (*this), sizeof (*this), parent, purpose, cat); + } + if (mp_obj) { + mp_obj->mem_stat (stat, purpose, cat, false, (void *) this); + } } private: @@ -467,16 +463,13 @@ public: } }; +/** + * @brief Collect memory statistics + */ template -size_t mem_used (const user_object &x) +inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const user_object &x, bool no_self = false, void *parent = 0) { - return x.mem_used (); -} - -template -size_t mem_reqd (const user_object &x) -{ - return x.mem_reqd (); + x.mem_stat (stat, purpose, cat, no_self, parent); } /** diff --git a/src/db/db/gsiDeclDbCell.cc b/src/db/db/gsiDeclDbCell.cc index bdc97c797..d7b83f654 100644 --- a/src/db/db/gsiDeclDbCell.cc +++ b/src/db/db/gsiDeclDbCell.cc @@ -704,10 +704,10 @@ static void check_is_editable (const db::Cell *cell) // --------------------------------------------------------------- // db::Cell binding -static void dump_mem_statistics (const db::Cell *cell) +static void dump_mem_statistics (const db::Cell *cell, bool detailed) { - db::MemStatistics ms; - cell->collect_mem_stat (ms); + db::MemStatisticsCollector ms (detailed); + cell->mem_stat (&ms, db::MemStatistics::CellInfo, 0); ms.print (); } @@ -3025,7 +3025,7 @@ Class decl_Cell ("Cell", "\n" "This method has been introduced in version 0.20.\n" ) + - gsi::method_ext ("dump_mem_statistics", &dump_mem_statistics, + gsi::method_ext ("dump_mem_statistics", &dump_mem_statistics, gsi::arg ("detailed", false), "@hide" ), "@brief A cell\n" diff --git a/src/db/db/gsiDeclDbLayout.cc b/src/db/db/gsiDeclDbLayout.cc index 211d07b91..2016fca89 100644 --- a/src/db/db/gsiDeclDbLayout.cc +++ b/src/db/db/gsiDeclDbLayout.cc @@ -253,10 +253,10 @@ Class decl_LayerInfo ("LayerInfo", // --------------------------------------------------------------- // db::Layout binding -static void dump_mem_statistics (const db::Layout *layout) +static void dump_mem_statistics (const db::Layout *layout, bool detailed) { - db::MemStatistics ms; - layout->collect_mem_stat (ms); + db::MemStatisticsCollector ms (detailed); + layout->mem_stat (&ms, db::MemStatistics::LayoutInfo, 0 /*cat*/); ms.print (); } @@ -1952,7 +1952,7 @@ Class decl_Layout ("Layout", "\n" "This method has been introduced in version 0.22.\n" ) + - gsi::method_ext ("dump_mem_statistics", &dump_mem_statistics, + gsi::method_ext ("dump_mem_statistics", &dump_mem_statistics, gsi::arg ("detailed", false), "@hide" ), "@brief The layout object\n" diff --git a/src/db/db/gsiDeclDbShapes.cc b/src/db/db/gsiDeclDbShapes.cc index f51606d75..db14da3a6 100644 --- a/src/db/db/gsiDeclDbShapes.cc +++ b/src/db/db/gsiDeclDbShapes.cc @@ -43,10 +43,10 @@ static double shapes_dbu (const db::Shapes *shapes) return shapes->layout ()->dbu (); } -static void dump_mem_statistics (const db::Shapes *shapes) +static void dump_mem_statistics (const db::Shapes *shapes, bool detailed) { - db::MemStatistics ms; - shapes->collect_mem_stat (ms); + db::MemStatisticsCollector ms (detailed); + shapes->mem_stat (&ms, db::MemStatistics::ShapesInfo, 0); ms.print (); } @@ -1011,7 +1011,7 @@ Class decl_Shapes ("Shapes", gsi::method ("SProperties|#s_properties", &s_properties, "@brief Indicates that only shapes with properties shall be retrieved" ) + - gsi::method_ext ("dump_mem_statistics", &dump_mem_statistics, + gsi::method_ext ("dump_mem_statistics", &dump_mem_statistics, gsi::arg ("detailed", false), "@hide" ), "@brief A collection of shapes\n" diff --git a/src/db/unit_tests/dbBoxTree.cc b/src/db/unit_tests/dbBoxTree.cc index 8b169c5ab..e9663db14 100644 --- a/src/db/unit_tests/dbBoxTree.cc +++ b/src/db/unit_tests/dbBoxTree.cc @@ -249,6 +249,34 @@ inline db::Box rbox () return db::Box (x, y, x + rvalue () % 200, y + rvalue () % 200); } +namespace +{ + +class TestMemStatistics + : public db::MemStatistics +{ +public: + TestMemStatistics () + : used (0), reqd (0) + { } + + virtual void add (const std::type_info & /*ti*/, void * /*ptr*/, size_t r, size_t u, void * /*parent*/, purpose_t /*purpose*/ = None, int /*cat*/ = 0) + { + used += u; + reqd += r; + } + + void clear () + { + used = reqd = 0; + } + +public: + size_t used, reqd; +}; + +} + TEST(0) { Box2Box conv; @@ -520,7 +548,9 @@ TEST(4) } } - tl::info << "Memory: " << db::mem_used (t); + TestMemStatistics ms; + t.mem_stat (&ms, db::MemStatistics::None, 0); + tl::info << "Memory: " << ms.used; } TEST(4A) @@ -576,7 +606,9 @@ TEST(4A) } } - tl::info << "Memory: " << db::mem_used (t); + TestMemStatistics ms; + t.mem_stat (&ms, db::MemStatistics::None, 0); + tl::info << "Memory: " << ms.used; } TEST(4B) @@ -632,7 +664,9 @@ TEST(4B) } } - tl::info << "Memory: " << db::mem_used (t); + TestMemStatistics ms; + t.mem_stat (&ms, db::MemStatistics::None, 0); + tl::info << "Memory: " << ms.used; } TEST(5) @@ -663,7 +697,9 @@ TEST(5) EXPECT_EQ (n, t.size () * 10); } - tl::info << "Memory: " << db::mem_used (t); + TestMemStatistics ms; + t.mem_stat (&ms, db::MemStatistics::None, 0); + tl::info << "Memory: " << ms.used; } TEST(0U) @@ -919,7 +955,9 @@ TEST(4U) } } - tl::info << "Memory: " << db::mem_used (t); + TestMemStatistics ms; + t.mem_stat (&ms, db::MemStatistics::None, 0); + tl::info << "Memory: " << ms.used; } TEST(5U) @@ -950,7 +988,9 @@ TEST(5U) EXPECT_EQ (n, t.size () * 10); } - tl::info << "Memory: " << db::mem_used (t); + TestMemStatistics ms; + t.mem_stat (&ms, db::MemStatistics::None, 0); + tl::info << "Memory: " << ms.used; } TEST(6) diff --git a/src/db/unit_tests/dbPolygon.cc b/src/db/unit_tests/dbPolygon.cc index 7248bb7b1..782035ed9 100644 --- a/src/db/unit_tests/dbPolygon.cc +++ b/src/db/unit_tests/dbPolygon.cc @@ -33,7 +33,35 @@ #include -TEST(1) +namespace +{ + +class TestMemStatistics + : public db::MemStatistics +{ +public: + TestMemStatistics () + : used (0), reqd (0) + { } + + virtual void add (const std::type_info & /*ti*/, void * /*ptr*/, size_t r, size_t u, void * /*parent*/, purpose_t /*purpose*/ = None, int /*cat*/ = 0) + { + used += u; + reqd += r; + } + + void clear () + { + used = reqd = 0; + } + +public: + size_t used, reqd; +}; + +} + +TEST(1) { db::Polygon p; db::Polygon empty; @@ -180,7 +208,6 @@ TEST(2) EXPECT_EQ (p, empty); } - TEST(3) { db::Point pts [] = { @@ -207,9 +234,13 @@ TEST(3) } contour.assign (c1.begin (), c1.end (), false); + TestMemStatistics ms; + EXPECT_EQ (contour.size (), size_t (6)); EXPECT_EQ (contour.is_hole (), false); - EXPECT_EQ (contour.mem_used (), 3 * sizeof(db::Point) + sizeof(Ctr)); + ms.clear (); + contour.mem_stat (&ms, db::MemStatistics::None, 0); + EXPECT_EQ (ms.used, 3 * sizeof(db::Point) + sizeof(Ctr)); EXPECT_EQ (contour[0], db::Point (100,100)); EXPECT_EQ (contour[1], db::Point (100,200)); EXPECT_EQ (contour[2], db::Point (0,200)); @@ -221,7 +252,9 @@ TEST(3) EXPECT_EQ (contour.size (), size_t (6)); EXPECT_EQ (contour.is_hole (), true); - EXPECT_EQ (contour.mem_used (), 3 * sizeof(db::Point) + sizeof(Ctr)); + ms.clear (); + contour.mem_stat (&ms, db::MemStatistics::None, 0); + EXPECT_EQ (ms.used, 3 * sizeof(db::Point) + sizeof(Ctr)); EXPECT_EQ (contour[0], db::Point (100,100)); EXPECT_EQ (contour[1], db::Point (300,100)); EXPECT_EQ (contour[2], db::Point (300,300)); @@ -240,7 +273,9 @@ TEST(3) EXPECT_EQ (contour2.size (), size_t (6)); EXPECT_EQ (contour2.is_hole (), true); - EXPECT_EQ (contour2.mem_used (), 3 * sizeof(db::Point) + sizeof(Ctr)); + ms.clear (); + contour.mem_stat (&ms, db::MemStatistics::None, 0); + EXPECT_EQ (ms.used, 3 * sizeof(db::Point) + sizeof(Ctr)); EXPECT_EQ (contour2[0], db::Point (100,100)); EXPECT_EQ (contour2[1], db::Point (300,100)); EXPECT_EQ (contour2[2], db::Point (300,300)); @@ -254,6 +289,8 @@ TEST(3) TEST(4) { + TestMemStatistics ms; + db::Point pts [] = { db::Point (100, 150), db::Point (100, 200), @@ -276,7 +313,9 @@ TEST(4) EXPECT_EQ (contour.size (), size_t (5)); EXPECT_EQ (contour.is_hole (), false); - EXPECT_EQ (contour.mem_used (), 5 * sizeof(db::Point) + sizeof(Ctr)); + ms.clear (); + contour.mem_stat (&ms, db::MemStatistics::None, 0); + EXPECT_EQ (ms.used, 5 * sizeof(db::Point) + sizeof(Ctr)); EXPECT_EQ (contour[0], db::Point (100,100)); EXPECT_EQ (contour[1], db::Point (100,200)); EXPECT_EQ (contour[2], db::Point (0,300)); @@ -287,7 +326,9 @@ TEST(4) EXPECT_EQ (contour.size (), size_t (5)); EXPECT_EQ (contour.is_hole (), true); - EXPECT_EQ (contour.mem_used (), 5 * sizeof(db::Point) + sizeof(Ctr)); + ms.clear (); + contour.mem_stat (&ms, db::MemStatistics::None, 0); + EXPECT_EQ (ms.used, 5 * sizeof(db::Point) + sizeof(Ctr)); EXPECT_EQ (contour[0], db::Point (100,100)); EXPECT_EQ (contour[1], db::Point (300,100)); EXPECT_EQ (contour[2], db::Point (300,300)); @@ -306,7 +347,9 @@ TEST(4) EXPECT_EQ (contour2.size (), size_t (5)); EXPECT_EQ (contour2.is_hole (), true); - EXPECT_EQ (contour2.mem_used (), 5 * sizeof(db::Point) + sizeof(Ctr)); + ms.clear (); + contour.mem_stat (&ms, db::MemStatistics::None, 0); + EXPECT_EQ (ms.used, 5 * sizeof(db::Point) + sizeof(Ctr)); EXPECT_EQ (contour2[0], db::Point (100,100)); EXPECT_EQ (contour2[1], db::Point (300,100)); EXPECT_EQ (contour2[2], db::Point (300,300)); @@ -531,6 +574,8 @@ TEST(6) TEST(7) { + TestMemStatistics ms; + db::Point pts [] = { db::Point (0, 0), db::Point (0, 4), @@ -553,7 +598,9 @@ TEST(7) EXPECT_EQ (contour.size (), size_t (6)); EXPECT_EQ (contour.is_hole (), false); - EXPECT_EQ (contour.mem_used (), 6 * sizeof(db::Point) + sizeof(Ctr)); + ms.clear (); + contour.mem_stat (&ms, db::MemStatistics::None, 0); + EXPECT_EQ (ms.used, 6 * sizeof(db::Point) + sizeof(Ctr)); EXPECT_EQ (contour[0], db::Point (0,0)); EXPECT_EQ (contour[1], db::Point (0,4)); EXPECT_EQ (contour[2], db::Point (4,4)); @@ -565,7 +612,9 @@ TEST(7) EXPECT_EQ (contour.size (), size_t (6)); EXPECT_EQ (contour.is_hole (), true); - EXPECT_EQ (contour.mem_used (), 6 * sizeof(db::Point) + sizeof(Ctr)); + ms.clear (); + contour.mem_stat (&ms, db::MemStatistics::None, 0); + EXPECT_EQ (ms.used, 6 * sizeof(db::Point) + sizeof(Ctr)); EXPECT_EQ (contour[0], db::Point (0,0)); EXPECT_EQ (contour[1], db::Point (0,4)); EXPECT_EQ (contour[2], db::Point (4,4)); @@ -584,7 +633,9 @@ TEST(7) EXPECT_EQ (contour2.size (), size_t (6)); EXPECT_EQ (contour2.is_hole (), true); - EXPECT_EQ (contour2.mem_used (), 6 * sizeof(db::Point) + sizeof(Ctr)); + ms.clear (); + contour.mem_stat (&ms, db::MemStatistics::None, 0); + EXPECT_EQ (ms.used, 6 * sizeof(db::Point) + sizeof(Ctr)); EXPECT_EQ (contour2[0], db::Point (0,0)); EXPECT_EQ (contour2[1], db::Point (0,4)); EXPECT_EQ (contour2[2], db::Point (4,4)); @@ -1143,6 +1194,8 @@ TEST(20) TEST(21) { + TestMemStatistics ms; + { db::Box box (0,0,2048,1536); db::Polygon poly (box); @@ -1151,7 +1204,9 @@ TEST(21) poly.transform (t); EXPECT_EQ (poly.to_string (), "(123,-10152;-7480,-2549;2657,7588;10260,-15)"); #if !defined(_MSC_VER) - EXPECT_EQ (poly.mem_reqd (), (sizeof(void *)-4)*5+68); + ms.clear (); + poly.mem_stat (&ms, db::MemStatistics::None, 0); + EXPECT_EQ (ms.reqd, (sizeof(void *)-4)*5+68); #endif } @@ -1163,7 +1218,9 @@ TEST(21) poly.transform (t); EXPECT_EQ (poly.to_string (), "(123,-10152;123,600;14459,600;14459,-10152)"); #if !defined(_MSC_VER) - EXPECT_EQ (poly.mem_reqd (), (sizeof(void *)-4)*5+52); + ms.clear (); + poly.mem_stat (&ms, db::MemStatistics::None, 0); + EXPECT_EQ (ms.reqd, (sizeof(void *)-4)*5+52); #endif } { @@ -1176,7 +1233,9 @@ TEST(21) EXPECT_EQ (poly.is_box (), false); EXPECT_EQ (poly.to_string (), "(123.88147866,-10152.0640046;-7503.56940256,-2524.61312338;2666.36510573,7645.32138492;10293.815987,17.8705036972)"); #if !defined(_MSC_VER) - EXPECT_EQ (poly.mem_reqd (), (sizeof(void *)-4)*5+116); + ms.clear (); + poly.mem_stat (&ms, db::MemStatistics::None, 0); + EXPECT_EQ (ms.reqd, (sizeof(void *)-4)*5+116); #endif } @@ -1189,7 +1248,9 @@ TEST(21) poly.transform (t); EXPECT_EQ (poly.to_string (), "(123.88147866,-10152.0640046;123.88147866,634.78047796;14506.3407887,634.78047796;14506.3407887,-10152.0640046)"); #if !defined(_MSC_VER) - EXPECT_EQ (poly.mem_reqd (), (sizeof(void *)-4)*5+116); // no compression for doubles! + ms.clear (); + poly.mem_stat (&ms, db::MemStatistics::None, 0); + EXPECT_EQ (ms.reqd, (sizeof(void *)-4)*5+116); // no compression for doubles! #endif } } diff --git a/src/gsi/gsi/gsiTypes.h b/src/gsi/gsi/gsiTypes.h index 50a3ad551..5f6be7439 100644 --- a/src/gsi/gsi/gsiTypes.h +++ b/src/gsi/gsi/gsiTypes.h @@ -1214,7 +1214,7 @@ public: : ArgSpecBase (name, true, init_doc), mp_init (new T (init)) { } - ~ArgSpecImpl () + virtual ~ArgSpecImpl () { if (mp_init) { delete mp_init; diff --git a/src/img/img/imgObject.cc b/src/img/img/imgObject.cc index eb45a1668..5af774576 100644 --- a/src/img/img/imgObject.cc +++ b/src/img/img/imgObject.cc @@ -607,30 +607,31 @@ public: return true; } - size_t mem_used () const + void mem_stat (db::MemStatistics *stat, db::MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const { - size_t data_size = 0; + if (! no_self) { + stat->add (typeid (*this), (void *) this, sizeof (*this), sizeof (*this), parent, purpose, cat); + } + size_t n = data_length (); for (unsigned int i = 0; i < 3; ++i) { if (mp_color_data[i]) { - data_size += n * sizeof (float); + stat->add (typeid (float []), (void *) mp_color_data[i], sizeof (n * sizeof (float)), sizeof (n * sizeof (float)), (void *) this, purpose, cat); } if (mp_color_byte_data[i]) { - data_size += n * sizeof (unsigned char); + stat->add (typeid (unsigned char []), (void *) mp_color_byte_data[i], sizeof (n * sizeof (unsigned char)), sizeof (n * sizeof (unsigned char)), (void *) this, purpose, cat); } } if (mp_mask) { - data_size += n * sizeof (unsigned char); + stat->add (typeid (unsigned char []), (void *) mp_mask, sizeof (n * sizeof (unsigned char)), sizeof (n * sizeof (unsigned char)), (void *) this, purpose, cat); } if (mp_data) { - data_size += n * sizeof (float); + stat->add (typeid (float []), (void *) mp_data, sizeof (n * sizeof (float)), sizeof (n * sizeof (float)), (void *) this, purpose, cat); } if (mp_byte_data) { - data_size += n * sizeof (unsigned char); + stat->add (typeid (unsigned char []), (void *) mp_byte_data, sizeof (n * sizeof (unsigned char)), sizeof (n * sizeof (unsigned char)), (void *) this, purpose, cat); } - - return data_size; } private: @@ -2180,10 +2181,15 @@ Object::is_valid_matrix (const db::Matrix3d &matrix) return true; } -size_t -Object::mem_used () const +void +Object::mem_stat (db::MemStatistics *stat, db::MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const { - return sizeof (*this) + (mp_data ? mp_data->mem_used () : 0); + if (! no_self) { + stat->add (typeid (*this), (void *) this, sizeof (*this), sizeof (*this), parent, purpose, cat); + } + if (mp_data) { + mp_data->mem_stat (stat, purpose, cat, false, (void *) this); + } } const char * diff --git a/src/img/img/imgObject.h b/src/img/img/imgObject.h index dce7701ae..362b896d0 100644 --- a/src/img/img/imgObject.h +++ b/src/img/img/imgObject.h @@ -940,15 +940,7 @@ public: /** * @brief Return the memory used in bytes */ - virtual size_t mem_used () const; - - /** - * @brief Return the memory required in bytes - */ - virtual size_t mem_reqd () const - { - return mem_used (); - } + virtual void mem_stat (db::MemStatistics *stat, db::MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const; protected: /** diff --git a/src/laybasic/laybasic/layAnnotationShapes.cc b/src/laybasic/laybasic/layAnnotationShapes.cc index 6512edcea..80444373d 100644 --- a/src/laybasic/laybasic/layAnnotationShapes.cc +++ b/src/laybasic/laybasic/layAnnotationShapes.cc @@ -175,9 +175,9 @@ AnnotationShapes::undo (db::Op *op) } void -AnnotationShapes::collect_mem_stat (db::MemStatistics &m) const +AnnotationShapes::mem_stat (db::MemStatistics *stat, db::MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const { - m_layer.collect_mem_stat (m); + m_layer.mem_stat (stat, purpose, cat, no_self, parent); } void diff --git a/src/laybasic/laybasic/layAnnotationShapes.h b/src/laybasic/laybasic/layAnnotationShapes.h index f56670c88..c0663f5e0 100644 --- a/src/laybasic/laybasic/layAnnotationShapes.h +++ b/src/laybasic/laybasic/layAnnotationShapes.h @@ -347,7 +347,7 @@ public: /** * @brief Collect memory usage */ - void collect_mem_stat (db::MemStatistics &m) const; + void mem_stat (db::MemStatistics *stat, db::MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const; private: void invalidate_state () @@ -360,6 +360,15 @@ private: layer_type m_layer; }; +/** + * @brief Collect memory usage + */ +inline void mem_stat (db::MemStatistics *stat, db::MemStatistics::purpose_t purpose, int cat, const AnnotationShapes &x, bool no_self = false, void *parent = 0) +{ + x.mem_stat (stat, purpose, cat, no_self, parent); +} + + } #endif diff --git a/src/laybasic/laybasic/layLayoutView.cc b/src/laybasic/laybasic/layLayoutView.cc index 7a4c2b5c6..fc06d5685 100644 --- a/src/laybasic/laybasic/layLayoutView.cc +++ b/src/laybasic/laybasic/layLayoutView.cc @@ -2883,8 +2883,8 @@ LayoutView::reload_layout (unsigned int cv_index) // print the memory statistics now. if (tl::verbosity () >= 31) { - db::MemStatistics m; - cv->layout ().collect_mem_stat (m); + db::MemStatisticsCollector m (false); + cv->layout ().mem_stat (&m, db::MemStatistics::LayoutInfo, 0); m.print (); } @@ -3120,8 +3120,8 @@ LayoutView::load_layout (const std::string &filename, const db::LoadLayoutOption // print the memory statistics now. if (tl::verbosity () >= 31) { - db::MemStatistics m; - cv->layout ().collect_mem_stat (m); + db::MemStatisticsCollector m (false); + cv->layout ().mem_stat (&m, db::MemStatistics::LayoutInfo, 0); m.print (); } diff --git a/src/laybasic/unit_tests/layAnnotationShapes.cc b/src/laybasic/unit_tests/layAnnotationShapes.cc index e4f08d599..53c8b87b2 100644 --- a/src/laybasic/unit_tests/layAnnotationShapes.cc +++ b/src/laybasic/unit_tests/layAnnotationShapes.cc @@ -81,8 +81,13 @@ public: const Sh &shape () const { return m_shape; } - size_t mem_used () const { return 0; } - size_t mem_reqd () const { return 0; } + virtual void mem_stat (db::MemStatistics *stat, db::MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const + { + if (! no_self) { + stat->add (typeid (*this), (void *) this, sizeof (*this), sizeof (*this), parent, purpose, cat); + } + db::mem_stat (stat, purpose, cat, m_shape, true, (void *) this); + } private: Sh m_shape; diff --git a/src/tl/tl/tlReuseVector.h b/src/tl/tl/tlReuseVector.h index 3b857b9a4..294e27254 100644 --- a/src/tl/tl/tlReuseVector.h +++ b/src/tl/tl/tlReuseVector.h @@ -887,14 +887,12 @@ public: init (); } - size_t mem_reqd () const + /** + * @brief For diagnostics purposes only + */ + ReuseData *reuse_data () const { - return (mp_capacity - mp_start) * sizeof (Value) + (mp_rdata != 0 ? mp_rdata->mem_reqd () : 0); - } - - size_t mem_used () const - { - return (mp_finish - mp_start) * sizeof (Value) + (mp_rdata != 0 ? mp_rdata->mem_used () : 0); + return mp_rdata; } private: diff --git a/src/tl/tl/tlVector.cc b/src/tl/tl/tlVector.cc new file mode 100644 index 000000000..e69de29bb diff --git a/src/tl/unit_tests/tlVector.cc b/src/tl/unit_tests/tlVector.cc new file mode 100644 index 000000000..e69de29bb