Better memory statistics.

This commit is contained in:
Matthias Koefferlein 2018-04-15 00:54:30 +02:00
parent d35c713c9c
commit e1922da3b2
39 changed files with 832 additions and 733 deletions

View File

@ -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

View File

@ -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);
}
}

View File

@ -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<Coord>::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<Obj, Trans>), (void *) this, sizeof (array<Obj, Trans>), sizeof (array<Obj, Trans>), 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 <class Obj>
size_t mem_used (const array<Obj, Trans> &x)
/**
* @brief Collect memory statistics
*/
template <class Obj, class Trans>
inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const array<Obj, Trans> &x, bool no_self = false, void *parent = 0)
{
return x.mem_used ();
}
template <class Obj>
size_t mem_reqd (const array<Obj, Trans> &x)
{
return x.mem_reqd ();
x.mem_stat (stat, purpose, cat, no_self, parent);
}
}

View File

@ -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 &center () 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 <class Box, class Obj, class BoxConv>
size_t mem_used (const db::box_tree<Box, Obj, BoxConv> &bt)
/**
* @brief Collect memory statistics
*/
template <class Box, class Obj, class BoxConv, size_t min_bin, size_t min_quads>
inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const box_tree<Box, Obj, BoxConv, min_bin, min_quads> &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 <class Box, class Obj, class BoxConv>
size_t mem_reqd (const db::box_tree<Box, Obj, BoxConv> &bt)
{
return mem_reqd (bt.elements ()) +
mem_reqd (bt.objects ()) +
sizeof (box_tree_node<db::box_tree<Box, Obj, BoxConv> > *) +
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 <class Box, class Obj, class BoxConv>
size_t mem_used (const db::unstable_box_tree<Box, Obj, BoxConv> &bt)
inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const db::unstable_box_tree<Box, Obj, BoxConv> &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 <class Box, class Obj, class BoxConv>
size_t mem_reqd (const db::unstable_box_tree<Box, Obj, BoxConv> &bt)
{
return mem_reqd (bt.objects ()) +
sizeof (box_tree_node<db::box_tree<Box, Obj, BoxConv> > *) +
sizeof (void *) +
(bt.root () ? bt.root ()->mem_used () : 0);
}
}
#endif

View File

@ -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
}
}

View File

@ -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

View File

@ -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

View File

@ -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 <class Iter>
inline NormalInstanceIteratorTraits::instance_type
NormalInstanceIteratorTraits::instance_from_stable_iter (const Iter &iter) const

View File

@ -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 <class Sh, class StableTag>
inline void
mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const layer<Sh, StableTag> &x, bool no_self, void *parent)
{
x.mem_stat (stat, purpose, cat, no_self, parent);
}
}
#endif

View File

@ -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 char *>::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 char *>::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<pcell_header_type *>::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

View File

@ -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<cell_index_type> &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
*

View File

@ -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<bool> &v)
void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const std::vector<bool> &x, bool no_self, void *parent)
{
return sizeof (std::vector<bool>) + v.capacity () / 8;
}
size_t mem_reqd (const std::vector<bool> &v)
{
return sizeof (std::vector<bool>) + v.size () / 8;
if (! no_self) {
stat->add (typeid (std::vector<bool>), (void *) &x, sizeof (std::vector<bool>), sizeof (std::vector<bool>), 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<purpose_t, std::string> 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 std::type_info *, std::pair<size_t, size_t> >::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<purpose_t, int>, std::pair<size_t, size_t> >::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<purpose_t, std::pair<size_t, size_t> >::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<size_t, size_t> &i = m_per_cat [std::make_pair (purpose, cat)];
i.first += used;
i.second += size;
}
std::pair<size_t, size_t> &j = m_per_purpose [purpose];
j.first += used;
j.second += size;
}
}

View File

@ -33,286 +33,189 @@
#include <map>
#include <set>
#include <list>
#include <typeinfo>
#include "tlReuseVector.h"
namespace tl
{
template <class X> class vector;
template <class X> class reuse_vector;
class Variant;
}
namespace db
{
template <class X>
size_t mem_used (const X &)
{
return sizeof (X);
}
template <class X>
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 <class X>
size_t mem_used (const tl::reuse_vector<X> &v)
{
size_t s = v.mem_used ();
for (typename tl::reuse_vector<X>::const_iterator e = v.begin (); e != v.end (); ++e) {
s += mem_used (*e);
}
return s;
}
template <class X>
size_t mem_reqd (const tl::reuse_vector<X> &v)
{
size_t s = v.mem_reqd ();
for (typename tl::reuse_vector<X>::const_iterator e = v.begin (); e != v.end (); ++e) {
s += mem_used (*e);
}
return s;
}
template <class X>
size_t mem_used (const tl::vector<X> &v)
{
size_t s = sizeof (tl::vector<X>);
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 <class X>
size_t mem_reqd (const tl::vector<X> &v)
{
size_t s = sizeof (tl::vector<X>);
size_t i = 0;
for (i = 0; i < v.size (); ++i) {
s += mem_reqd (v[i]);
}
return s;
}
template <class X>
size_t mem_used (const std::vector<X> &v)
{
size_t s = sizeof (std::vector<X>);
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 <class X>
size_t mem_reqd (const std::vector<X> &v)
{
size_t s = sizeof (std::vector<X>);
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<bool> &v);
size_t mem_reqd (const std::vector<bool> &v);
template <class X, class Y>
size_t mem_used (const std::map<X, Y> &m)
{
size_t s = sizeof (std::map<X, Y>);
for (typename std::map<X, Y>::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 <class X, class Y>
size_t mem_reqd (const std::map<X, Y> &m)
{
size_t s = sizeof (std::map<X, Y>);
for (typename std::map<X, Y>::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 <class X>
size_t mem_used (const std::set<X> &x)
{
size_t s = sizeof (std::set<X>);
for (typename std::set<X>::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 <class X>
size_t mem_reqd (const std::set<X> &x)
{
size_t s = sizeof (std::set<X>);
for (typename std::set<X>::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 <class X>
size_t mem_used (const std::list<X> &l)
{
size_t s = sizeof (std::list<X>);
for (typename std::list<X>::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 <class X>
size_t mem_reqd (const std::list<X> &l)
{
size_t s = sizeof (std::list<X>);
for (typename std::list<X>::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 <class X>
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 <class X>
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 <class X>
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 <class X>
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 <class X>
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 <class X>
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 <class X>
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<const std::type_info *, std::pair<size_t, size_t> > m_per_type;
std::map<std::pair<purpose_t, int>, std::pair<size_t, size_t> > m_per_cat;
std::map<purpose_t, std::pair<size_t, size_t> > m_per_purpose;
};
// Some standard templates to collect the information
template <class X>
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 <class X>
void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const tl::reuse_vector<X> &v, bool no_self = false, void *parent = 0)
{
if (! no_self) {
stat->add (typeid (tl::reuse_vector<X>), (void *) &v, sizeof (tl::reuse_vector<X>), sizeof (tl::reuse_vector<X>), 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<X>::const_iterator e = v.begin (); e != v.end (); ++e) {
mem_stat (stat, purpose, cat, *e, true, (void *) &v);
}
}
template <class X>
void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const tl::vector<X> &v, bool no_self = false, void *parent = 0)
{
if (! no_self) {
stat->add (typeid (tl::vector<X>), (void *) &v, sizeof (tl::vector<X>), sizeof (tl::vector<X>), 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 <class X>
void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const std::vector<X> &v, bool no_self = false, void *parent = 0)
{
if (! no_self) {
stat->add (typeid (std::vector<X>), (void *) &v, sizeof (std::vector<X>), sizeof (std::vector<X>), 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<bool> &x, bool no_self = false, void *parent = 0);
template <class X, class Y>
void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const std::map<X, Y> &v, bool no_self = false, void *parent = 0)
{
if (! no_self) {
stat->add (typeid (std::map<X, Y>), (void *) &v, sizeof (std::map<X, Y>), sizeof (std::map<X, Y>), parent, purpose, cat);
}
for (typename std::map<X, Y>::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 <class X>
void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const std::set<X> &v, bool no_self = false, void *parent = 0)
{
if (! no_self) {
stat->add (typeid (std::set<X>), (void *) &v, sizeof (std::set<X>), sizeof (std::set<X>), parent, purpose, cat);
}
for (typename std::set<X>::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 <class X>
void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const std::list<X> &v, bool no_self = false, void *parent = 0)
{
if (! no_self) {
stat->add (typeid (std::list<X>), (void *) &v, sizeof (std::list<X>), sizeof (std::list<X>), parent, purpose, cat);
}
for (typename std::list<X>::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 <class X, class Y>
void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const std::pair<X, Y> &v, bool no_self = false, void *parent = 0)
{
if (! no_self) {
stat->add (typeid (std::pair<X, Y>), (void *) &v, sizeof (std::pair<X, Y>), sizeof (std::pair<X, Y>), parent, purpose, cat);
}
mem_stat (stat, purpose, cat, v.first, true, (void *) &v);
mem_stat (stat, purpose, cat, v.second, true, (void *) &v);
}
}
#endif

View File

@ -25,6 +25,7 @@
#define HDR_dbMetaInfo
#include "dbCommon.h"
#include "dbMemStatistics.h"
#include <string>
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

View File

@ -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 <class C>
inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const path<C> &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<db::Coord> Path;
*/
typedef path<db::DCoord> DPath;
template <class X>
size_t mem_used (const path<X> &x)
{
return x.mem_used ();
}
template <class X>
size_t mem_reqd (const path<X> &x)
{
return x.mem_reqd ();
}
/**
* @brief A path reference
*

View File

@ -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<SimplePolygon, UnitTrans> SimplePolygonPtr;
*/
typedef polygon_ref<DSimplePolygon, DUnitTrans> DSimplePolygonPtr;
/**
* @brief Collect memory statistics
*/
template <class X>
size_t mem_used (const polygon_contour<X> &x)
inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const polygon_contour<X> &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 <class X>
size_t mem_reqd (const polygon_contour<X> &x)
inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const polygon<X> &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 <class X>
size_t mem_used (const polygon<X> &x)
inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const simple_polygon<X> &x, bool no_self = false, void *parent = 0)
{
return x.mem_used ();
}
template <class X>
size_t mem_reqd (const polygon<X> &x)
{
return x.mem_reqd ();
}
template <class X>
size_t mem_used (const simple_polygon<X> &x)
{
return x.mem_used ();
}
template <class X>
size_t mem_reqd (const simple_polygon<X> &x)
{
return x.mem_reqd ();
x.mem_stat (stat, purpose, cat, no_self, parent);
}
} // namespace db

View File

@ -25,9 +25,10 @@
#define HDR_dbPropertiesRepository
#include "dbCommon.h"
#include "dbTypes.h"
#include "dbMemStatistics.h"
#include "tlVariant.h"
#include "dbTypes.h"
#include <vector>
#include <string>
@ -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 <property_names_id_type, tl::Variant> m_propnames_by_id;
std::map <tl::Variant, property_names_id_type> 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

View File

@ -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 <class C>
size_t mem_used (const Shape &s)
{
return s.mem_used ();
}
template <class C>
size_t mem_reqd (const Shape &s)
{
return s.mem_reqd ();
}
} // namespace db
#endif

View File

@ -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 <class Sh>
size_t mem_used (const repository<Sh> &s)
inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const repository<Sh> &x, bool no_self = false, void *parent = 0)
{
return s.mem_used ();
x.mem_stat (stat, purpose, cat, no_self, parent);
}
template <class Sh>
size_t mem_reqd (const repository<Sh> &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<C> > m_text_repository;
};
/**
* @brief Collect memory statistics
*/
template <class C>
size_t mem_used (const generic_repository<C> &s)
inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const generic_repository<C> &x, bool no_self = false, void *parent = 0)
{
return s.mem_used ();
x.mem_stat (stat, purpose, cat, no_self, parent);
}
template <class C>
size_t mem_reqd (const generic_repository<C> &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<Sh, Trans>), (void *) this, sizeof (shape_ref<Sh, Trans>), sizeof (shape_ref<Sh, Trans>), 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 <class Sh, class Tr>
size_t mem_used (const shape_ref<Sh, Tr> &s)
inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const shape_ref<Sh, Tr> &x, bool no_self = false, void *parent = 0)
{
return s.mem_used ();
}
template <class Sh, class Tr>
size_t mem_reqd (const shape_ref<Sh, Tr> &s)
{
return s.mem_reqd ();
x.mem_stat (stat, purpose, cat, no_self, parent);
}
/**

View File

@ -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<LayerBase *>::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);
}
}

View File

@ -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
*

View File

@ -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 <class Sh, class Stable>
void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const layer_class<Sh, Stable> &x, bool no_self, void *parent)
{
x.mem_stat (stat, purpose, cat, no_self, parent);
}
}
#endif

View File

@ -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<StringRef *>::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<C>), (void *) this, sizeof (text<C>), sizeof (text<C>), 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 <class D> friend class text;
@ -1042,17 +1076,13 @@ typedef text_ref<Text, UnitTrans> TextPtr;
*/
typedef text_ref<DText, DUnitTrans> DTextPtr;
/**
* @brief Collect memory usage
*/
template <class X>
size_t mem_used (const text<X> &x)
inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const text<X> &x, bool no_self = false, void *parent = 0)
{
return x.mem_used ();
}
template <class X>
size_t mem_reqd (const text<X> &x)
{
return x.mem_reqd ();
x.mem_stat (stat, purpose, cat, no_self, parent);
}
} // namespace db

View File

@ -32,6 +32,7 @@
#include "dbTrans.h"
#include "dbObjectTag.h"
#include "dbBox.h"
#include "dbMemStatistics.h"
#include "tlClassRegistry.h"
#include <string>
@ -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 <class C>
@ -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<C>) + mp_obj->mem_used ();
}
size_t mem_reqd () const
{
return sizeof (user_object<C>) + 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 <class X>
size_t mem_used (const user_object<X> &x)
inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const user_object<X> &x, bool no_self = false, void *parent = 0)
{
return x.mem_used ();
}
template <class X>
size_t mem_reqd (const user_object<X> &x)
{
return x.mem_reqd ();
x.mem_stat (stat, purpose, cat, no_self, parent);
}
/**

View File

@ -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<db::Cell> 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<bool> ("detailed", false),
"@hide"
),
"@brief A cell\n"

View File

@ -253,10 +253,10 @@ Class<db::LayerProperties> 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<db::Layout> 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<bool> ("detailed", false),
"@hide"
),
"@brief The layout object\n"

View File

@ -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<db::Shapes> 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<bool> ("detailed", false),
"@hide"
),
"@brief A collection of shapes\n"

View File

@ -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)

View File

@ -33,7 +33,35 @@
#include <vector>
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
}
}

View File

@ -1214,7 +1214,7 @@ public:
: ArgSpecBase (name, true, init_doc), mp_init (new T (init))
{ }
~ArgSpecImpl ()
virtual ~ArgSpecImpl ()
{
if (mp_init) {
delete mp_init;

View File

@ -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 *

View File

@ -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:
/**

View File

@ -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

View File

@ -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

View File

@ -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 ();
}

View File

@ -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;

View File

@ -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:

0
src/tl/tl/tlVector.cc Normal file
View File

View File