{
return identity ();
}
+
+ inline ::Dwarf_Off cost () const
+ {
+ return 0;
+ }
};
class attr_value
{
die_info_pair *_m_parent;
std::queue<value::value_reference *> _m_refs;
+ ::Dwarf_Off _m_original_cost;
std::bitset<2> _m_with_sibling;
unsigned int _m_uses;
inline die_info ()
- : _m_parent (NULL), _m_refs (), _m_with_sibling (), _m_uses (0)
+ : _m_parent (NULL), _m_refs (),
+ _m_original_cost (0), _m_with_sibling (), _m_uses (0)
{}
inline ~die_info ()
std::cout << std::dec << elt.second._m_uses
<< "\thash=" << std::hex << subr::hash_this (elt.first)
<< "\t(" << elt.second._m_with_sibling.to_string () << ")\t"
- << to_string (elt.first) << "\n";
+ << std::dec << elt.second._m_original_cost;
+ if (elt.second._m_uses > 1)
+ std::cout << " ("
+ << (double (elt.second._m_original_cost)
+ / double (elt.second._m_uses - 1))
+ << ")";
+ std::cout << "\t" << to_string (elt.first) << "\n";
}
public:
: public value::value_dispatch
{
::Dwarf_Off _m_offset; // XXX debugging only
+ ::Dwarf_Off _m_cost; // For statistics only.
// Set if we are building this in the copying walk right now.
entry_copier *_m_building;
_m_building != NULL && refs_dangling);
dump (false, true) << " final done\n";
+
+ _m_final->second._m_original_cost += _m_cost;
}
/* This is called from pending_entry::final when resolving
if (unlikely (_m_in->_m_building != NULL))
throw std::runtime_error ("detected cycle in logical DWARF tree");
_m_in->_m_building = this;
+ _m_in->_m_cost = in.cost ();
}
// On destruction, we clear _m_building.
return dec_string (size (), "{", " line entries}");
}
};
+\f
+::Dwarf_Off
+dwarf::debug_info_entry::cost () const
+{
+ Dwarf_Die next;
+ int result = dwarf_siblingof (thisdie (), &next);
+ xif (result < 0);
+ if (result == 0)
+ return (const char *) next.addr - (const char *) _m_die.addr;
+ if (next.addr != NULL)
+ return (const char *) next.addr - (const char *) _m_die.addr + 1;
+ return _m_die.cu->end - dwarf_dieoffset (thisdie ());
+}