Commit 20ec7366 authored by Chris Toshok's avatar Chris Toshok

use a binary search to find/insert CompiledFunction*'s into the registry

parent 2748c606
......@@ -88,19 +88,55 @@ void parseEhFrame(uint64_t start_addr, uint64_t size, uint64_t* out_data, uint64
class CFRegistry {
private:
// TODO use a binary search tree
std::vector<CompiledFunction*> cfs;
public:
void registerCF(CompiledFunction* cf) { cfs.push_back(cf); }
// similar to Java's Array.binarySearch:
// return values are either:
// >= 0 : the index where a given item was found
// < 0 : a negative number that can be transformed (using "-num-1") into the insertion point
//
// addr is the return address of the callsite, so we will check it against
// the region (start, end] (opposite-endedness of normal half-open regions)
CompiledFunction* getCFForAddress(uint64_t addr) {
for (auto* cf : cfs) {
if (cf->code_start < addr && addr <= cf->code_start + cf->code_size)
return cf;
//
int find_cf(uint64_t addr) {
int l = 0;
int r = cfs.size() - 1;
while (l <= r) {
int mid = l + (r - l) / 2;
auto mid_cf = cfs[mid];
if (addr <= mid_cf->code_start) {
r = mid - 1;
} else if (addr > mid_cf->code_start + mid_cf->code_size) {
l = mid + 1;
} else {
return mid;
}
}
return -(l + 1);
}
public:
void registerCF(CompiledFunction* cf) {
if (cfs.empty()) {
cfs.push_back(cf);
return;
}
int idx = find_cf((uint64_t)cf->code_start);
if (idx >= 0)
RELEASE_ASSERT(0, "CompiledFunction registered twice?");
cfs.insert(cfs.begin() + (-idx - 1), cf);
}
CompiledFunction* getCFForAddress(uint64_t addr) {
if (cfs.empty())
return NULL;
int idx = find_cf(addr);
if (idx >= 0)
return cfs[idx];
return NULL;
}
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment