Skip to content

Commit

Permalink
Assorted cleanup. Fixed infinite loop in IBSTree_fast::find.
Browse files Browse the repository at this point in the history
  • Loading branch information
wrwilliams committed Oct 19, 2016
1 parent 4a62242 commit 8697646
Show file tree
Hide file tree
Showing 11 changed files with 256 additions and 171 deletions.
261 changes: 132 additions & 129 deletions common/h/IBSTree-fast.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,153 +35,156 @@
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/mem_fun.hpp>
#include <boost/multi_index/identity.hpp>
#include <iostream>

namespace Dyninst
{
template <typename ITYPE = interval<> >
class IBSTree_fast
{
typedef typename ITYPE::type interval_type;
template <typename ITYPE = interval<> >
class IBSTree_fast
{
typedef typename ITYPE::type interval_type;

IBSTree<ITYPE> overlapping_intervals;
typedef boost::multi_index_container<ITYPE*,
boost::multi_index::indexed_by<
boost::multi_index::ordered_unique<
boost::multi_index::const_mem_fun<ITYPE, interval_type, &ITYPE::high> >
> > interval_set;

//typedef std::set<ITYPE*, order_by_lower<ITYPE> > interval_set;
interval_set unique_intervals;
IBSTree<ITYPE> overlapping_intervals;
typedef boost::multi_index_container<ITYPE*,
boost::multi_index::indexed_by<
boost::multi_index::ordered_unique<
boost::multi_index::const_mem_fun<ITYPE, interval_type, &ITYPE::high> >
> > interval_set;

public:
IBSTree_fast()
{
}
~IBSTree_fast()
{
}
int size() const
{
return overlapping_intervals.size() + unique_intervals.size();
}
bool empty() const
{
return unique_intervals.empty() && overlapping_intervals.empty();
}
void insert(ITYPE*);
void remove(ITYPE*);
int find(interval_type, std::set<ITYPE*> &) const;
int find(ITYPE* I, std::set<ITYPE*>&) const;
void successor(interval_type X, std::set<ITYPE*>& ) const;
ITYPE* successor(interval_type X) const;
void clear();

};

template <class ITYPE>
void IBSTree_fast<ITYPE>::insert(ITYPE* entry)
{
// find in overlapping first
std::set<ITYPE*> dummy;
if(overlapping_intervals.find(entry, dummy))
{
overlapping_intervals.insert(entry);
return;
}
typename interval_set::iterator lower =
unique_intervals.upper_bound(entry->low());
// lower.high first >= entry.low
if(lower != unique_intervals.end() && *lower == entry) return;
auto upper = lower;
while(upper != unique_intervals.end() &&
(*upper)->low() <= entry->high())
{
overlapping_intervals.insert(*upper);
++upper;
}
if(upper != lower)
//typedef std::set<ITYPE*, order_by_lower<ITYPE> > interval_set;
interval_set unique_intervals;

public:
IBSTree_fast()
{
}
~IBSTree_fast()
{
std::cerr << "Fast interval tree had " << unique_intervals.size() << " unique intervals and " << overlapping_intervals.size() << " overlapping" << std::endl;
}
int size() const
{
return overlapping_intervals.size() + unique_intervals.size();
}
bool empty() const
{
return unique_intervals.empty() && overlapping_intervals.empty();
}
void insert(ITYPE*);
void remove(ITYPE*);
int find(interval_type, std::set<ITYPE*> &) const;
int find(ITYPE* I, std::set<ITYPE*>&) const;
void successor(interval_type X, std::set<ITYPE*>& ) const;
ITYPE* successor(interval_type X) const;
void clear();

};

template <class ITYPE>
void IBSTree_fast<ITYPE>::insert(ITYPE* entry)
{
unique_intervals.erase(lower, upper);
overlapping_intervals.insert(entry);
// find in overlapping first
std::set<ITYPE*> dummy;
if(overlapping_intervals.find(entry, dummy))
{
overlapping_intervals.insert(entry);
return;
}
typename interval_set::iterator lower =
unique_intervals.upper_bound(entry->low());
// lower.high first >= entry.low
if(lower != unique_intervals.end() && (**lower == *entry)) return;
auto upper = lower;
while(upper != unique_intervals.end() &&
(*upper)->low() <= entry->high())
{
overlapping_intervals.insert(*upper);
++upper;
}
if(upper != lower)
{
unique_intervals.erase(lower, upper);
overlapping_intervals.insert(entry);
}
else
{
unique_intervals.insert(entry);
}
}
else
template <class ITYPE>
void IBSTree_fast<ITYPE>::remove(ITYPE* entry)
{
unique_intervals.insert(entry);
overlapping_intervals.remove(entry);
auto found = unique_intervals.find(entry->high());
if(found != unique_intervals.end() && *found == entry) unique_intervals.erase(found);
}
}
template <class ITYPE>
void IBSTree_fast<ITYPE>::remove(ITYPE* entry)
{
overlapping_intervals.remove(entry);
auto found = unique_intervals.find(entry->high());
if(found != unique_intervals.end() && *found == entry) unique_intervals.erase(found);
}
template<class ITYPE>
int IBSTree_fast<ITYPE>::find(interval_type X, std::set<ITYPE*> &results) const
{
int num_old_results = results.size();

int num_overlapping = overlapping_intervals.find(X, results);
if(num_overlapping > 0) return num_overlapping;

typename interval_set::const_iterator found_unique = unique_intervals.upper_bound(X);
if(found_unique != unique_intervals.end())
template<class ITYPE>
int IBSTree_fast<ITYPE>::find(interval_type X, std::set<ITYPE*> &results) const
{
if((*found_unique)->low() > X) return 0;
results.insert(*found_unique);
int num_old_results = results.size();

int num_overlapping = overlapping_intervals.find(X, results);
if(num_overlapping > 0) return num_overlapping;

typename interval_set::const_iterator found_unique = unique_intervals.upper_bound(X);
if(found_unique != unique_intervals.end())
{
if((*found_unique)->low() > X) return 0;
results.insert(*found_unique);
}
return results.size() - num_old_results;
}
return results.size() - num_old_results;
}
template <typename ITYPE>
int IBSTree_fast<ITYPE>::find(ITYPE* I, std::set<ITYPE*>&results) const
{
int num_old_results = results.size();
int num_overlapping = overlapping_intervals.find(I, results);
if(num_overlapping) return num_overlapping;
typename interval_set::const_iterator lb = unique_intervals.upper_bound(I->low());
auto ub = lb;
while(ub != unique_intervals.end() && (*ub)->low() < I->high())
template <typename ITYPE>
int IBSTree_fast<ITYPE>::find(ITYPE* I, std::set<ITYPE*>&results) const
{
results.insert(*ub);
int num_old_results = results.size();
int num_overlapping = overlapping_intervals.find(I, results);
if(num_overlapping) return num_overlapping;
typename interval_set::const_iterator lb = unique_intervals.upper_bound(I->low());
auto ub = lb;
while(ub != unique_intervals.end() && (*ub)->low() < I->high())
{
results.insert(*ub);
++ub;
}
return results.size() - num_old_results;
}
return results.size() - num_old_results;
}
template<typename ITYPE>
void IBSTree_fast<ITYPE>::successor(interval_type X, std::set<ITYPE*>& results) const
{
ITYPE* overlapping_ub = overlapping_intervals.successor(X);

typename interval_set::const_iterator unique_ub = unique_intervals.upper_bound(X);
if(overlapping_ub && (unique_ub != unique_intervals.end()))
template<typename ITYPE>
void IBSTree_fast<ITYPE>::successor(interval_type X, std::set<ITYPE*>& results) const
{
results.insert(overlapping_ub->low() < (*unique_ub)->low() ? overlapping_ub : *unique_ub);
ITYPE* overlapping_ub = overlapping_intervals.successor(X);

typename interval_set::const_iterator unique_ub = unique_intervals.upper_bound(X);
if(overlapping_ub && (unique_ub != unique_intervals.end()))
{
results.insert(overlapping_ub->low() < (*unique_ub)->low() ? overlapping_ub : *unique_ub);
}
else if(overlapping_ub)
{
results.insert(overlapping_ub);
}
else if(unique_ub != unique_intervals.end())
{
results.insert(*unique_ub);
}
}
else if(overlapping_ub)
template <typename ITYPE>
ITYPE* IBSTree_fast<ITYPE>::successor(interval_type X) const
{
results.insert(overlapping_ub);
std::set<ITYPE*> tmp;
successor(X, tmp);
assert(tmp.size() <= 1);
if(tmp.empty()) return NULL;
return *tmp.begin();

}
else if(unique_ub != unique_intervals.end())
template <typename ITYPE>
void IBSTree_fast<ITYPE>::clear()
{
results.insert(*unique_ub);
overlapping_intervals.clear();
unique_intervals.clear();
}
}
template <typename ITYPE>
ITYPE* IBSTree_fast<ITYPE>::successor(interval_type X) const
{
std::set<ITYPE*> tmp;
successor(X, tmp);
assert(tmp.size() <= 1);
if(tmp.empty()) return NULL;
return *tmp.begin();

}
template <typename ITYPE>
void IBSTree_fast<ITYPE>::clear()
{
overlapping_intervals.clear();
unique_intervals.clear();
}




}
#endif
20 changes: 17 additions & 3 deletions parseAPI/h/CFG.h
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,12 @@ class PARSER_EXPORT Block : public Dyninst::interval<Address>,
};

static void destroy(Block *b);

private:

bool operator==(const Block &rhs) const;

bool operator!=(const Block &rhs) const;

private:
void addSource(Edge * e);
void addTarget(Edge * e);
void removeTarget(Edge * e);
Expand Down Expand Up @@ -674,7 +678,17 @@ class PARSER_EXPORT FuncExtent : public Dyninst::interval<Address> {

/* interval implementation */
Address low() const { return _start; }
Address high() const { return _end; }
Address high() const { return _end; }

bool operator==(const FuncExtent &rhs) const {
return _func == rhs._func &&
_start == rhs._start &&
_end == rhs._end;
}

bool operator!=(const FuncExtent &rhs) const {
return !(rhs == *this);
}
};

/** Natural loops
Expand Down
3 changes: 2 additions & 1 deletion parseAPI/h/CFGFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ class PARSER_EXPORT CFGFactory {
};


}

}
}

#endif
15 changes: 15 additions & 0 deletions parseAPI/src/Block.C
Original file line number Diff line number Diff line change
Expand Up @@ -252,3 +252,18 @@ Block::getInsn(Offset a) const {
}


bool Block::operator==(const Block &rhs) const {
return _obj == rhs._obj &&
_region == rhs._region &&
_start == rhs._start &&
_end == rhs._end &&
_lastInsn == rhs._lastInsn &&
_srclist == rhs._srclist &&
_trglist == rhs._trglist &&
_func_cnt == rhs._func_cnt &&
_parsed == rhs._parsed;
}

bool Block::operator!=(const Block &rhs) const {
return !(rhs == *this);
}
4 changes: 2 additions & 2 deletions symtabAPI/h/LineInformation.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ class SYMTAB_EXPORT LineInformation :
void setStrings(StringTablePtr strings_);

protected:
int wasted_compares;
int num_queries;
mutable int wasted_compares;
mutable int num_queries;
};


Expand Down
22 changes: 20 additions & 2 deletions symtabAPI/h/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,11 @@ typedef Statement LineNoTuple;
supportedLanguages language_;
Offset addr_; // starting address of module
Symtab *exec_;
std::vector<std::pair< Dyninst::Address, Dyninst::Address> > ranges;
std::set<AddressRange > ranges;
bool ranges_finalized;
};

void finalizeOneRange(Address ext_s, Address ext_e) const;
};
template <typename OS>
OS& operator<<(OS& os, const Module& m)
{
Expand All @@ -262,6 +264,22 @@ struct ModRange : public interval<Offset>
ModRange(Offset l, Offset h, Module* m) :
low_(l), high_(h), mod_(m)
{}

bool operator==(const ModRange &rhs) const {
return low_ == rhs.low_ &&
high_ == rhs.high_ &&
mod_ == rhs.mod_;
}

bool operator!=(const ModRange &rhs) const {
return !(rhs == *this);
}
bool contains(const ModRange& rhs) const {
return (rhs.low() >= low()) &&
(rhs.high() <= high()) &&
(rhs.mod() == mod() );
}

Offset low() const { return low_; }
Offset high() const { return high_; }
Module* mod() const { return mod_;}
Expand Down

0 comments on commit 8697646

Please sign in to comment.