Index: lldb/trunk/include/lldb/Expression/IRMemoryMap.h =================================================================== --- lldb/trunk/include/lldb/Expression/IRMemoryMap.h +++ lldb/trunk/include/lldb/Expression/IRMemoryMap.h @@ -27,7 +27,8 @@ /// This class encapsulates a group of memory objects that must be readable /// or writable from the host process regardless of whether the process /// exists. This allows the IR interpreter as well as JITted code to access -/// the same memory. +/// the same memory. All allocations made by this class are represented as +/// disjoint intervals. /// /// Point queries against this group of memory objects can be made by the /// address in the tar at which they reside. If the inferior does not @@ -118,7 +119,12 @@ lldb::addr_t FindSpace (size_t size); bool ContainsHostOnlyAllocations (); AllocationMap::iterator FindAllocation (lldb::addr_t addr, size_t size); - bool IntersectsAllocation (lldb::addr_t addr, size_t size); + + // Returns true if the given allocation intersects any allocation in the memory map. + bool IntersectsAllocation (lldb::addr_t addr, size_t size) const; + + // Returns true if the two given allocations intersect each other. + static bool AllocationsIntersect (lldb::addr_t addr1, size_t size1, lldb::addr_t addr2, size_t size2); }; } Index: lldb/trunk/source/Expression/IRMemoryMap.cpp =================================================================== --- lldb/trunk/source/Expression/IRMemoryMap.cpp +++ lldb/trunk/source/Expression/IRMemoryMap.cpp @@ -125,33 +125,48 @@ } bool -IRMemoryMap::IntersectsAllocation (lldb::addr_t addr, size_t size) +IRMemoryMap::IntersectsAllocation (lldb::addr_t addr, size_t size) const { if (addr == LLDB_INVALID_ADDRESS) return false; - AllocationMap::iterator iter = m_allocations.lower_bound (addr); + AllocationMap::const_iterator iter = m_allocations.lower_bound (addr); - if (iter == m_allocations.end() || - iter->first > addr) - { - if (iter == m_allocations.begin()) - return false; - - iter--; + // Since we only know that the returned interval begins at a location greater than or + // equal to where the given interval begins, it's possible that the given interval + // intersects either the returned interval or the previous interval. Thus, we need to + // check both. Note that we only need to check these two intervals. Since all intervals + // are disjoint it is not possible that an adjacent interval does not intersect, but a + // non-adjacent interval does intersect. + if (iter != m_allocations.end()) { + if (IntersectsAllocation(addr, size, iter->second.m_process_start, iter->second.m_size)) + return true; } - - while (iter != m_allocations.end() && iter->second.m_process_alloc < addr + size) - { - if (iter->second.m_process_start + iter->second.m_size > addr) + + if (iter != m_allocations.begin()) { + --iter; + if (IntersectsAllocation(addr, size, iter->second.m_process_start, iter->second.m_size)) return true; - - ++iter; } - + return false; } +bool +IRMemoryMap::AllocationsIntersect(lldb::addr_t addr1, size_t size1, lldb::addr_t addr2, size_t size2) { + // Given two half open intervals [A, B) and [X, Y), the only 6 permutations that satisfy + // A