From fea88eec668d1d8dd930a93a4b56fae6bdc67e4e Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 7 Jul 2009 03:36:34 -0700 Subject: [PATCH] Some tracker refactoring. --- libdw/c++/dwarf_comparator | 20 +++++++++----------- libdw/c++/dwarf_data | 6 ++++++ libdw/c++/dwarf_output | 38 +++++++++++++++++++++++++++++++++++--- libdw/c++/dwarf_tracker | 37 ++++++++++++++++++++++++++++++------- src/dwarfcmp.cc | 18 ++++++++++++++---- 5 files changed, 94 insertions(+), 25 deletions(-) diff --git a/libdw/c++/dwarf_comparator b/libdw/c++/dwarf_comparator index 7465dab52..9bba00586 100644 --- a/libdw/c++/dwarf_comparator +++ b/libdw/c++/dwarf_comparator @@ -173,7 +173,7 @@ namespace elfutils : public std::binary_function { private: - tracker _m_tracker; + tracker &_m_tracker; template struct matcher : public std::binary_function @@ -491,11 +491,12 @@ namespace elfutils new one, in case of any reference attributes in their subtrees. The new tracker jump-starts its walk to the referenced DIE from the root of the CU. */ - bool result = !has_children || (dwarf_comparator (tracker (_m_tracker, - matched, - lhs, ref1, - rhs, ref2)) - .match (a.children (), b.children ())); + bool result = !has_children; + if (has_children) + { + tracker t (_m_tracker, matched, lhs, ref1, rhs, ref2); + result = dwarf_comparator (t).match (a.children (), b.children ()); + } // Let the tracker cache a result for its reference_matched. matched.notice_match (ref2, result); @@ -503,12 +504,9 @@ namespace elfutils return result; } - inline explicit dwarf_comparator (const tracker &t) - : _m_tracker (t) - {} - public: - inline dwarf_comparator () + inline explicit dwarf_comparator (tracker &t) + : _m_tracker (t) {} inline bool operator () (const dwarf1 &a, const dwarf2 &b) diff --git a/libdw/c++/dwarf_data b/libdw/c++/dwarf_data index c49360ce9..94c64f981 100644 --- a/libdw/c++/dwarf_data +++ b/libdw/c++/dwarf_data @@ -115,6 +115,12 @@ namespace elfutils impl::debug_info_entry::set (die, arg); } + explicit inline compile_unit () + : impl::debug_info_entry () + { + this->_m_tag = ::DW_TAG_compile_unit; + } + public: // Fetch the CU's DW_AT_stmt_list. diff --git a/libdw/c++/dwarf_output b/libdw/c++/dwarf_output index 8fed59403..b688b38b4 100644 --- a/libdw/c++/dwarf_output +++ b/libdw/c++/dwarf_output @@ -52,6 +52,7 @@ #include "dwarf_edit" #include "dwarf_ref_maker" +#include "dwarf_tracker" #include #include #include @@ -723,6 +724,8 @@ namespace elfutils friend class dwarf_output; private: + dwarf_path_finder _m_tracker; + typedef dwarf_output::debug_info_entry die_type; typedef die_type::children_type::const_iterator die_ptr; typedef die_type::attributes_type attrs_type; @@ -798,24 +801,53 @@ namespace elfutils shape_map _m_shapes; void add_shape (die_type &die, bool last_sibling); - }; - template + template class dwarf_output::copier : public dwarf_ref_maker // XXX temporary { friend class dwarf_output; private: + + struct tracker + : public dwarf_ref_tracker + { + typedef dwarf_ref_tracker _base; + + inline tracker (const dwarf_output_collector &c) + : _base (c._m_tracker) + {} + + inline tracker (const tracker &proto, + typename _base::reference_match &matched, + const typename _base::left_context_type &lhs, + const typename _base::die1 &a, + const typename _base::right_context_type &rhs, + const typename _base::die2 &b) + : _base (proto, matched, lhs, a, b) + {} + + }; + dwarf_output_collector *_m_collector; + tracker *_m_tracker; inline copier () - : _m_collector (NULL) + : _m_collector (NULL), _m_tracker (NULL) {} + inline ~copier () + { + if (_m_tracker != NULL) + delete _m_tracker; + } + copier &operator () (dwarf_output_collector &c) { _m_collector = &c; + assert (_m_tracker == NULL); + _m_tracker = new tracker (c); return *this; } diff --git a/libdw/c++/dwarf_tracker b/libdw/c++/dwarf_tracker index 1a442a42f..ff20d3800 100644 --- a/libdw/c++/dwarf_tracker +++ b/libdw/c++/dwarf_tracker @@ -94,13 +94,23 @@ namespace elfutils die_path _m_path; + explicit dwarf_path_finder (const dwarf_path_finder &) + { + throw std::logic_error ("not copy-constructible"); + } + public: // Default constructor: an original tracker. inline dwarf_path_finder () : _m_seen (new die_map), _m_delete_seen (true) {} - // Construct a derived tracker: does its own walk, but sharing caches. + // Construct a derived tracker: does its own whole walk, but sharing caches. + inline dwarf_path_finder (const dwarf_path_finder &proto, bool) + : _m_seen (proto._m_seen), _m_delete_seen (false) + {} + + // Construct a derived tracker that jump-starts a walk. inline dwarf_path_finder (const dwarf_path_finder &proto, const die_path &context, const die &there) : _m_seen (proto._m_seen), _m_delete_seen (false), @@ -324,6 +334,12 @@ namespace elfutils private: typedef dwarf_tracker_base _base; + explicit dwarf_ref_tracker (const dwarf_ref_tracker &) + : _base () + { + throw std::logic_error ("not copy-constructible"); + } + public: typedef typename _base::cu1 cu1; typedef typename _base::cu2 cu2; @@ -331,7 +347,7 @@ namespace elfutils typedef typename _base::die2 die2; typedef typename _base::dwarf1_ref dwarf1_ref; - private: + protected: typedef dwarf_path_finder tracker1; typedef dwarf_path_finder tracker2; @@ -353,9 +369,11 @@ namespace elfutils { inline bool operator () (const die1 &a, const die2 &b) { - return (a->tag () == b->tag () - && (dwarf_comparator () - .equals (a->attributes (), b->attributes ()))); + if (a->tag () != b->tag ()) + return false; + dwarf_tracker_base t; + return (dwarf_comparator (t) + .equals (a->attributes (), b->attributes ())); } }; @@ -364,6 +382,11 @@ namespace elfutils : _m_equiv (new equiv_map), _m_delete_equiv (true) {} + inline dwarf_ref_tracker (const tracker1 &proto) + : _m_left (proto, true), + _m_equiv (new equiv_map), _m_delete_equiv (true) + {} + inline void reset () { _m_equiv->clear (); @@ -484,8 +507,8 @@ namespace elfutils inline dwarf_ref_tracker (const dwarf_ref_tracker &proto, reference_match &, const left_context_type &lhs, const die1 &a, const right_context_type &rhs, const die2 &b) - : _m_left (tracker1 (proto._m_left, lhs, a)), - _m_right (tracker2 (proto._m_right, rhs, b)), + : _m_left (proto._m_left, lhs, a), + _m_right (proto._m_right, rhs, b), _m_equiv (proto._m_equiv), _m_delete_equiv (false) { // We are starting a recursive consideration of a vs b. diff --git a/src/dwarfcmp.cc b/src/dwarfcmp.cc index 6ac78aab4..6d3ee0647 100644 --- a/src/dwarfcmp.cc +++ b/src/dwarfcmp.cc @@ -212,16 +212,26 @@ struct talker : public dwarf_ref_tracker } }; +template +struct cmp + : public dwarf_comparator +{ + tracker _m_tracker; + inline cmp () + : dwarf_comparator (_m_tracker) + {} +}; + // For a silent comparison we just use the standard ref tracker. template -struct quiet_cmp : public dwarf_comparator > +struct quiet_cmp + : public cmp > {}; // To be noisy, the talker wraps the standard tracker with verbosity hooks. template -struct noisy_cmp : public dwarf_comparator > +struct noisy_cmp + : public cmp > {}; -- 2.47.2