From 6ff1095159bebe287a898b07eace357be171dca7 Mon Sep 17 00:00:00 2001 From: whh8b <whh8b@git.zephyr-software.com> Date: Fri, 24 Oct 2014 17:36:08 +0000 Subject: [PATCH] Implement binary search for memory space free ranges --- include/memory_space.h | 12 +++++-- include/range.h | 4 +-- src/memory_space.cpp | 75 ++++++++++++++++++++++++++++++++++++++++++ src/zipr.cpp | 3 ++ 4 files changed, 90 insertions(+), 4 deletions(-) diff --git a/include/memory_space.h b/include/memory_space.h index 8133d21..1b466bd 100644 --- a/include/memory_space.h +++ b/include/memory_space.h @@ -36,8 +36,8 @@ class Options_t; class MemorySpace_t { public: - MemorySpace_t():m_opts(NULL) { } - MemorySpace_t(Options_t *opts):m_opts(opts) { } + MemorySpace_t():m_opts(NULL),m_is_sorted(false),free_ranges_ptrs(NULL) { } + MemorySpace_t(Options_t *opts):m_opts(opts),m_is_sorted(false),free_ranges_ptrs(NULL) { } // range operatations void SplitFreeRange(RangeAddress_t addr); @@ -53,10 +53,18 @@ class MemorySpace_t int GetRangeCount(); + void Sort(); + void PrintMemorySpace(std::ostream &out); protected: std::list<Range_t> free_ranges; // keep ordered Options_t *m_opts; + bool m_is_sorted; + private: + std::list<Range_t>::iterator FindFreeRangeB(int startIndex, int stopIndex, + RangeAddress_t addr); + std::list<Range_t>::iterator **free_ranges_ptrs; + int free_ranges_ptrs_size; }; #endif diff --git a/include/range.h b/include/range.h index e0ec3b7..ce8b45b 100644 --- a/include/range.h +++ b/include/range.h @@ -40,8 +40,8 @@ class Range_t Range_t(RangeAddress_t p_s, RangeAddress_t p_e) : m_start(p_s), m_end(p_e) { } Range_t() : m_start(0), m_end(0) { } - RangeAddress_t GetStart() { return m_start; } - RangeAddress_t GetEnd() { return m_end; } + RangeAddress_t GetStart() const { return m_start; } + RangeAddress_t GetEnd() const { return m_end; } bool Is2ByteRange() { diff --git a/src/memory_space.cpp b/src/memory_space.cpp index c63ff25..6195896 100644 --- a/src/memory_space.cpp +++ b/src/memory_space.cpp @@ -6,6 +6,35 @@ using namespace zipr; using namespace std; +static bool range_compare(const Range_t first, const Range_t second) +{ + return first.GetStart() < second.GetStart(); +} + +void MemorySpace_t::Sort() +{ + int i = 0; + list<Range_t>::iterator it; + + if (free_ranges_ptrs != NULL) + { + for (int j = 0; j<free_ranges_ptrs_size; j++) + delete free_ranges_ptrs[j]; + free(free_ranges_ptrs); + } + + free_ranges.sort(range_compare); + + free_ranges_ptrs = (std::list<Range_t>::iterator**)malloc(sizeof(std::list<Range_t>::iterator*)*free_ranges.size()); + for(i=0,it=free_ranges.begin();it!=free_ranges.end();++it,++i) + { + free_ranges_ptrs[i] = new std::list<Range_t>::iterator(it); + } + + m_is_sorted = true; + free_ranges_ptrs_size = free_ranges.size(); +} + void MemorySpace_t::SplitFreeRange(RangeAddress_t addr) { list<Range_t>::iterator it=FindFreeRange(addr); @@ -13,6 +42,8 @@ void MemorySpace_t::SplitFreeRange(RangeAddress_t addr) Range_t r=*it; + m_is_sorted = false; + if(r.GetStart()==r.GetEnd()) { assert(addr==r.GetEnd()); @@ -50,6 +81,9 @@ void MemorySpace_t::MergeFreeRange(RangeAddress_t addr) Range_t nr(addr, addr); bool merged = false; list<Range_t>::iterator it=free_ranges.begin(); + + m_is_sorted = false; + for(;it!=free_ranges.end();++it) { Range_t r=*it; @@ -154,8 +188,48 @@ void MemorySpace_t::PrintMemorySpace(std::ostream &out) } } +std::list<Range_t>::iterator MemorySpace_t::FindFreeRangeB( + int startIndex, + int stopIndex, + RangeAddress_t addr) +{ + std::list<Range_t>::iterator *start = free_ranges_ptrs[startIndex]; + std::list<Range_t>::iterator *stop = free_ranges_ptrs[stopIndex]; + Range_t startRange = **start; + Range_t stopRange = **stop; + if (startIndex == stopIndex) + return free_ranges.end(); + else if (startRange.GetStart() <= addr && addr <=startRange.GetEnd()) + return *start; + else if (stopRange.GetStart() <= addr && addr <=stopRange.GetEnd()) + return *stop; + else + { + /* + * mid startIndex - stopIndex + */ + int midIndex = startIndex + ((stopIndex-startIndex)/2); + Range_t mid = **(free_ranges_ptrs[midIndex]); + + if (mid.GetStart() <= addr && addr <=mid.GetEnd()) + return *free_ranges_ptrs[midIndex]; + else if (addr <= mid.GetStart()) { + return FindFreeRangeB(startIndex, std::max(0, std::max(--midIndex, startIndex)), addr); + } + else + { + return FindFreeRangeB(std::min(++midIndex, stopIndex), stopIndex, addr); + } + } +} + std::list<Range_t>::iterator MemorySpace_t::FindFreeRange(RangeAddress_t addr) { + if (m_is_sorted) + { + return FindFreeRangeB(0, free_ranges.size()-1, addr); + } + for( list<Range_t>::iterator it=free_ranges.begin(); it!=free_ranges.end(); ++it) @@ -203,6 +277,7 @@ bool MemorySpace_t::IsByteFree(RangeAddress_t addr) void MemorySpace_t::AddFreeRange(Range_t newRange) { + m_is_sorted = false; free_ranges.push_back(Range_t(newRange.GetStart(), newRange.GetEnd())); } int MemorySpace_t::GetRangeCount() diff --git a/src/zipr.cpp b/src/zipr.cpp index 6acd690..55591c6 100644 --- a/src/zipr.cpp +++ b/src/zipr.cpp @@ -95,8 +95,10 @@ void Zipr_t::CreateBinaryFile(const std::string &name) printf("Going to Re PreReserve2ByteJumpTargets.\n"); PreReserve2ByteJumpTargets(); } + memory_space.Sort(); } + // Convert all 5-byte pins into full fragments OptimizePinnedInstructions(); @@ -108,6 +110,7 @@ void Zipr_t::CreateBinaryFile(const std::string &name) UpdateCallbacks(); m_stats->total_free_ranges = memory_space.GetRangeCount(); + memory_space.Sort(); // write binary file to disk OutputBinaryFile(name); -- GitLab