Fix the L1 cache search in MemoryCache::Read to use the

stl upper_bound method instead of lower_bound - we were
failing to find some cached data in the L1 cache resulting
in extra memory read packets while stepping.

The bug with the existing code looked like this:
If the L1 cache has 8 bytes at address 0x1000 and 8 bytes
at address 0x2000 and we are searching for 4 bytes at 0x2004,
the use of lower_bound would return the end() of the container
and so we would incorrectly treat the memory as uncached.

(the L1 cache is memory seeded from debugserver in the T aka
questionmark packet, where debugserver will send up the stack
memory that likely contains the caller's stack pointer and 
frame pointer values.)

<rdar://problem/23869227> 

llvm-svn: 255421
This commit is contained in:
Jason Molenda 2015-12-12 03:06:10 +00:00
parent 97047d8cb6
commit a38312a9a4
1 changed files with 9 additions and 17 deletions

View File

@ -164,24 +164,16 @@ MemoryCache::Read (addr_t addr,
if (!m_L1_cache.empty()) if (!m_L1_cache.empty())
{ {
AddrRange read_range(addr, dst_len); AddrRange read_range(addr, dst_len);
BlockMap::iterator pos = m_L1_cache.lower_bound(addr); BlockMap::iterator pos = m_L1_cache.upper_bound(addr);
if (pos != m_L1_cache.end()) if (pos != m_L1_cache.begin ())
{ {
AddrRange chunk_range(pos->first, pos->second->GetByteSize()); --pos;
bool match = chunk_range.Contains(read_range); }
if (!match && pos != m_L1_cache.begin()) AddrRange chunk_range(pos->first, pos->second->GetByteSize());
{ if (chunk_range.Contains(read_range))
--pos; {
chunk_range.SetRangeBase(pos->first); memcpy(dst, pos->second->GetBytes() + addr - chunk_range.GetRangeBase(), dst_len);
chunk_range.SetByteSize(pos->second->GetByteSize()); return dst_len;
match = chunk_range.Contains(read_range);
}
if (match)
{
memcpy(dst, pos->second->GetBytes() + addr - chunk_range.GetRangeBase(), dst_len);
return dst_len;
}
} }
} }