Remove the process's reservation cache and don't

bother checking if a region is safe to use.  In
cases where regions need to be synthesized rather
than properly allocated, the memory reads required
to determine whether the area is used are

- insufficient, because intermediate locations
  could be in use, and

- unsafe, because on some platforms reading from
  memory can trigger events.

All this only makes a difference on platforms
where memory allocation in the target is impossible.
Behavior on platforms where it is possible should
stay the same.

<rdar://problem/14023970>

llvm-svn: 185046
This commit is contained in:
Sean Callanan 2013-06-27 00:10:26 +00:00
parent ba2c0b9de1
commit 70cac8fd81
3 changed files with 2 additions and 148 deletions

View File

@ -3526,72 +3526,6 @@ public:
return m_public_run_lock;
}
//------------------------------------------------------------------
// This is a cache of reserved and available memory address ranges
// for a single modification ID (see m_mod_id). It's meant for use
// by IRMemoryMap, but to stick with the process. These memory
// ranges happen to be unallocated in the underlying process, but we
// make no guarantee that at a future modification ID they won't be
// gone. This is only useful if the underlying process can't
// allocate memory.
//
// When a memory space is determined to be available it is
// registered as reserved at the current modification. If it is
// freed later, it is added to the free list if the modification ID
// hasn't changed. Then clients can simply query the free list for
// the size they want.
//------------------------------------------------------------------
class ReservationCache
{
public:
ReservationCache (Process &process);
//------------------------------------------------------------------
// Mark that a particular range of addresses is in use. Adds it
// to the reserved map, implicitly tying it to the current
// modification ID.
//------------------------------------------------------------------
void
Reserve (lldb::addr_t addr, size_t size);
//------------------------------------------------------------------
// Mark that a range is no longer in use. If it's found in the
// reservation list, that means that the modification ID hasn't
// changed since it was reserved, so it can be safely added to the
// free list.
//------------------------------------------------------------------
void
Unreserve (lldb::addr_t addr);
//------------------------------------------------------------------
// Try to find an unused range of the given size in the free list.
//------------------------------------------------------------------
lldb::addr_t
Find (size_t size);
private:
//------------------------------------------------------------------
// Clear all lists if the modification ID has changed.
//------------------------------------------------------------------
void CheckModID();
typedef std::map <lldb::addr_t, size_t> ReservedMap;
typedef std::vector <lldb::addr_t> FreeList;
typedef std::map <size_t, FreeList> FreeMap;
ReservedMap m_reserved_cache;
FreeMap m_free_cache;
Process &m_process;
ProcessModID m_mod_id;
};
ReservationCache &
GetReservationCache ()
{
return m_reservation_cache;
}
private:
ReservationCache m_reservation_cache;
protected:
//------------------------------------------------------------------
// NextEventAction provides a way to register an action on the next

View File

@ -66,14 +66,6 @@ IRMemoryMap::FindSpace (size_t size)
return ret;
}
if (process_sp)
{
ret = process_sp->GetReservationCache().Find(size);
if (ret != LLDB_INVALID_ADDRESS)
return ret;
}
for (int iterations = 0; iterations < 16; ++iterations)
{
lldb::addr_t candidate = LLDB_INVALID_ADDRESS;
@ -101,21 +93,9 @@ IRMemoryMap::FindSpace (size_t size)
if (IntersectsAllocation(candidate, size))
continue;
char buf[1];
Error err;
if (process_sp &&
(process_sp->ReadMemory(candidate, buf, 1, err) == 1 ||
process_sp->ReadMemory(candidate + size, buf, 1, err) == 1))
continue;
ret = candidate;
if (process_sp)
process_sp->GetReservationCache().Reserve(candidate, size);
return ret;
}
@ -416,8 +396,6 @@ IRMemoryMap::Free (lldb::addr_t process_address, Error &error)
{
if (process_sp->CanJIT() && process_sp->IsAlive())
process_sp->DeallocateMemory(allocation.m_process_alloc); // FindSpace allocated this for real
else
process_sp->GetReservationCache().Unreserve(allocation.m_process_alloc); // FindSpace registered this memory
}
break;

View File

@ -996,7 +996,6 @@ Process::Process(Target &target, Listener &listener) :
ProcessProperties (false),
UserID (LLDB_INVALID_PROCESS_ID),
Broadcaster (&(target.GetDebugger()), "lldb.process"),
m_reservation_cache (*this),
m_target (target),
m_public_state (eStateUnloaded),
m_private_state (eStateUnloaded),
@ -5590,60 +5589,3 @@ Process::DidExec ()
DoDidExec();
CompleteAttach ();
}
Process::ReservationCache::ReservationCache (Process &process) : m_process(process)
{
m_mod_id = process.GetModID();
}
void
Process::ReservationCache::Reserve (lldb::addr_t addr, size_t size)
{
CheckModID();
m_reserved_cache[addr] = size;
}
void
Process::ReservationCache::Unreserve (lldb::addr_t addr)
{
CheckModID();
ReservedMap::iterator iter = m_reserved_cache.find(addr);
if (iter != m_reserved_cache.end())
{
size_t size = iter->second;
m_reserved_cache.erase(iter);
m_free_cache[size].push_back(addr);
}
}
lldb::addr_t
Process::ReservationCache::Find (size_t size)
{
CheckModID();
lldb::addr_t ret = LLDB_INVALID_ADDRESS;
FreeMap::iterator map_iter = m_free_cache.find(size);
if (map_iter != m_free_cache.end())
{
if (!map_iter->second.empty())
{
ret = map_iter->second.back();
map_iter->second.pop_back();
m_reserved_cache[ret] = size;
}
}
return ret;
}
void
Process::ReservationCache::CheckModID()
{
if (m_mod_id != m_process.GetModID())
{
// wipe all our caches, they're invalid
m_reserved_cache.clear();
m_free_cache.clear();
m_mod_id = m_process.GetModID();
}
}