diff options
Diffstat (limited to 'lldb/source/Target/Memory.cpp')
| -rw-r--r-- | lldb/source/Target/Memory.cpp | 459 |
1 files changed, 0 insertions, 459 deletions
diff --git a/lldb/source/Target/Memory.cpp b/lldb/source/Target/Memory.cpp deleted file mode 100644 index 16fcdcafb96d..000000000000 --- a/lldb/source/Target/Memory.cpp +++ /dev/null @@ -1,459 +0,0 @@ -//===-- Memory.cpp ----------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lldb/Target/Memory.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/State.h" -#include "lldb/Core/Log.h" -#include "lldb/Target/Process.h" - -using namespace lldb; -using namespace lldb_private; - -//---------------------------------------------------------------------- -// MemoryCache constructor -//---------------------------------------------------------------------- -MemoryCache::MemoryCache(Process &process) : - m_process (process), - m_cache_line_byte_size (512), - m_mutex (Mutex::eMutexTypeRecursive), - m_cache (), - m_invalid_ranges () -{ -} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -MemoryCache::~MemoryCache() -{ -} - -void -MemoryCache::Clear() -{ - Mutex::Locker locker (m_mutex); - m_cache.clear(); -} - -void -MemoryCache::Flush (addr_t addr, size_t size) -{ - if (size == 0) - return; - - Mutex::Locker locker (m_mutex); - if (m_cache.empty()) - return; - - const uint32_t cache_line_byte_size = m_cache_line_byte_size; - const addr_t end_addr = (addr + size - 1); - const addr_t first_cache_line_addr = addr - (addr % cache_line_byte_size); - const addr_t last_cache_line_addr = end_addr - (end_addr % cache_line_byte_size); - // Watch for overflow where size will cause us to go off the end of the - // 64 bit address space - uint32_t num_cache_lines; - if (last_cache_line_addr >= first_cache_line_addr) - num_cache_lines = ((last_cache_line_addr - first_cache_line_addr)/cache_line_byte_size) + 1; - else - num_cache_lines = (UINT64_MAX - first_cache_line_addr + 1)/cache_line_byte_size; - - //printf ("MemoryCache::Flush (0x%16.16llx, %zu (0x%zx))\n", addr, size, size); - - uint32_t cache_idx = 0; - for (addr_t curr_addr = first_cache_line_addr; - cache_idx < num_cache_lines; - curr_addr += cache_line_byte_size, ++cache_idx) - { - //printf ("flushing: 0x%16.16llx\n", curr_addr); /// REMOVE THIS PRIOR TO CHECKIN!!!! - BlockMap::iterator pos = m_cache.find (curr_addr); - if (pos != m_cache.end()) - m_cache.erase(pos); - } -} - -void -MemoryCache::AddInvalidRange (lldb::addr_t base_addr, lldb::addr_t byte_size) -{ - if (byte_size > 0) - { - Mutex::Locker locker (m_mutex); - InvalidRanges::Entry range (base_addr, byte_size); - m_invalid_ranges.Append(range); - m_invalid_ranges.Sort(); - } -} - -bool -MemoryCache::RemoveInvalidRange (lldb::addr_t base_addr, lldb::addr_t byte_size) -{ - if (byte_size > 0) - { - Mutex::Locker locker (m_mutex); - const uint32_t idx = m_invalid_ranges.FindEntryIndexThatContains(base_addr); - if (idx != UINT32_MAX) - { - const InvalidRanges::Entry *entry = m_invalid_ranges.GetEntryAtIndex (idx); - if (entry->GetRangeBase() == base_addr && entry->GetByteSize() == byte_size) - return m_invalid_ranges.RemoveEntrtAtIndex (idx); - } - } - return false; -} - - - -size_t -MemoryCache::Read (addr_t addr, - void *dst, - size_t dst_len, - Error &error) -{ - size_t bytes_left = dst_len; - if (dst && bytes_left > 0) - { - const uint32_t cache_line_byte_size = m_cache_line_byte_size; - uint8_t *dst_buf = (uint8_t *)dst; - addr_t curr_addr = addr - (addr % cache_line_byte_size); - addr_t cache_offset = addr - curr_addr; - Mutex::Locker locker (m_mutex); - - while (bytes_left > 0) - { - if (m_invalid_ranges.FindEntryThatContains(curr_addr)) - return dst_len - bytes_left; - - BlockMap::const_iterator pos = m_cache.find (curr_addr); - BlockMap::const_iterator end = m_cache.end (); - - if (pos != end) - { - size_t curr_read_size = cache_line_byte_size - cache_offset; - if (curr_read_size > bytes_left) - curr_read_size = bytes_left; - - memcpy (dst_buf + dst_len - bytes_left, pos->second->GetBytes() + cache_offset, curr_read_size); - - bytes_left -= curr_read_size; - curr_addr += curr_read_size + cache_offset; - cache_offset = 0; - - if (bytes_left > 0) - { - // Get sequential cache page hits - for (++pos; (pos != end) && (bytes_left > 0); ++pos) - { - assert ((curr_addr % cache_line_byte_size) == 0); - - if (pos->first != curr_addr) - break; - - curr_read_size = pos->second->GetByteSize(); - if (curr_read_size > bytes_left) - curr_read_size = bytes_left; - - memcpy (dst_buf + dst_len - bytes_left, pos->second->GetBytes(), curr_read_size); - - bytes_left -= curr_read_size; - curr_addr += curr_read_size; - - // We have a cache page that succeeded to read some bytes - // but not an entire page. If this happens, we must cap - // off how much data we are able to read... - if (pos->second->GetByteSize() != cache_line_byte_size) - return dst_len - bytes_left; - } - } - } - - // We need to read from the process - - if (bytes_left > 0) - { - assert ((curr_addr % cache_line_byte_size) == 0); - std::auto_ptr<DataBufferHeap> data_buffer_heap_ap(new DataBufferHeap (cache_line_byte_size, 0)); - size_t process_bytes_read = m_process.ReadMemoryFromInferior (curr_addr, - data_buffer_heap_ap->GetBytes(), - data_buffer_heap_ap->GetByteSize(), - error); - if (process_bytes_read == 0) - return dst_len - bytes_left; - - if (process_bytes_read != cache_line_byte_size) - data_buffer_heap_ap->SetByteSize (process_bytes_read); - m_cache[curr_addr] = DataBufferSP (data_buffer_heap_ap.release()); - // We have read data and put it into the cache, continue through the - // loop again to get the data out of the cache... - } - } - } - - return dst_len - bytes_left; -} - - - -AllocatedBlock::AllocatedBlock (lldb::addr_t addr, - uint32_t byte_size, - uint32_t permissions, - uint32_t chunk_size) : - m_addr (addr), - m_byte_size (byte_size), - m_permissions (permissions), - m_chunk_size (chunk_size), - m_offset_to_chunk_size () -// m_allocated (byte_size / chunk_size) -{ - assert (byte_size > chunk_size); -} - -AllocatedBlock::~AllocatedBlock () -{ -} - -lldb::addr_t -AllocatedBlock::ReserveBlock (uint32_t size) -{ - addr_t addr = LLDB_INVALID_ADDRESS; - if (size <= m_byte_size) - { - const uint32_t needed_chunks = CalculateChunksNeededForSize (size); - LogSP log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE)); - - if (m_offset_to_chunk_size.empty()) - { - m_offset_to_chunk_size[0] = needed_chunks; - if (log) - log->Printf ("[1] AllocatedBlock::ReserveBlock (size = %u (0x%x)) => offset = 0x%x, %u %u bit chunks", size, size, 0, needed_chunks, m_chunk_size); - addr = m_addr; - } - else - { - uint32_t last_offset = 0; - OffsetToChunkSize::const_iterator pos = m_offset_to_chunk_size.begin(); - OffsetToChunkSize::const_iterator end = m_offset_to_chunk_size.end(); - while (pos != end) - { - if (pos->first > last_offset) - { - const uint32_t bytes_available = pos->first - last_offset; - const uint32_t num_chunks = CalculateChunksNeededForSize (bytes_available); - if (num_chunks >= needed_chunks) - { - m_offset_to_chunk_size[last_offset] = needed_chunks; - if (log) - log->Printf ("[2] AllocatedBlock::ReserveBlock (size = %u (0x%x)) => offset = 0x%x, %u %u bit chunks", size, size, last_offset, needed_chunks, m_chunk_size); - addr = m_addr + last_offset; - break; - } - } - - last_offset = pos->first + pos->second * m_chunk_size; - - if (++pos == end) - { - // Last entry... - const uint32_t chunks_left = CalculateChunksNeededForSize (m_byte_size - last_offset); - if (chunks_left >= needed_chunks) - { - m_offset_to_chunk_size[last_offset] = needed_chunks; - if (log) - log->Printf ("[3] AllocatedBlock::ReserveBlock (size = %u (0x%x)) => offset = 0x%x, %u %u bit chunks", size, size, last_offset, needed_chunks, m_chunk_size); - addr = m_addr + last_offset; - break; - } - } - } - } -// const uint32_t total_chunks = m_allocated.size (); -// uint32_t unallocated_idx = 0; -// uint32_t allocated_idx = m_allocated.find_first(); -// uint32_t first_chunk_idx = UINT32_MAX; -// uint32_t num_chunks; -// while (1) -// { -// if (allocated_idx == UINT32_MAX) -// { -// // No more bits are set starting from unallocated_idx, so we -// // either have enough chunks for the request, or we don't. -// // Eiter way we break out of the while loop... -// num_chunks = total_chunks - unallocated_idx; -// if (needed_chunks <= num_chunks) -// first_chunk_idx = unallocated_idx; -// break; -// } -// else if (allocated_idx > unallocated_idx) -// { -// // We have some allocated chunks, check if there are enough -// // free chunks to satisfy the request? -// num_chunks = allocated_idx - unallocated_idx; -// if (needed_chunks <= num_chunks) -// { -// // Yep, we have enough! -// first_chunk_idx = unallocated_idx; -// break; -// } -// } -// -// while (unallocated_idx < total_chunks) -// { -// if (m_allocated[unallocated_idx]) -// ++unallocated_idx; -// else -// break; -// } -// -// if (unallocated_idx >= total_chunks) -// break; -// -// allocated_idx = m_allocated.find_next(unallocated_idx); -// } -// -// if (first_chunk_idx != UINT32_MAX) -// { -// const uint32_t end_bit_idx = unallocated_idx + needed_chunks; -// for (uint32_t idx = first_chunk_idx; idx < end_bit_idx; ++idx) -// m_allocated.set(idx); -// return m_addr + m_chunk_size * first_chunk_idx; -// } - } - LogSP log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE)); - if (log) - log->Printf ("AllocatedBlock::ReserveBlock (size = %u (0x%x)) => 0x%16.16llx", size, size, (uint64_t)addr); - return addr; -} - -bool -AllocatedBlock::FreeBlock (addr_t addr) -{ - uint32_t offset = addr - m_addr; - OffsetToChunkSize::iterator pos = m_offset_to_chunk_size.find (offset); - bool success = false; - if (pos != m_offset_to_chunk_size.end()) - { - m_offset_to_chunk_size.erase (pos); - success = true; - } - LogSP log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE)); - if (log) - log->Printf ("AllocatedBlock::FreeBlock (addr = 0x%16.16llx) => %i", (uint64_t)addr, success); - return success; -} - - -AllocatedMemoryCache::AllocatedMemoryCache (Process &process) : - m_process (process), - m_mutex (Mutex::eMutexTypeRecursive), - m_memory_map() -{ -} - -AllocatedMemoryCache::~AllocatedMemoryCache () -{ -} - - -void -AllocatedMemoryCache::Clear() -{ - Mutex::Locker locker (m_mutex); - if (m_process.IsAlive()) - { - PermissionsToBlockMap::iterator pos, end = m_memory_map.end(); - for (pos = m_memory_map.begin(); pos != end; ++pos) - m_process.DoDeallocateMemory(pos->second->GetBaseAddress()); - } - m_memory_map.clear(); -} - - -AllocatedMemoryCache::AllocatedBlockSP -AllocatedMemoryCache::AllocatePage (uint32_t byte_size, - uint32_t permissions, - uint32_t chunk_size, - Error &error) -{ - AllocatedBlockSP block_sp; - const size_t page_size = 4096; - const size_t num_pages = (byte_size + page_size - 1) / page_size; - const size_t page_byte_size = num_pages * page_size; - - addr_t addr = m_process.DoAllocateMemory(page_byte_size, permissions, error); - - LogSP log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); - if (log) - { - log->Printf ("Process::DoAllocateMemory (byte_size = 0x%8.8zx, permissions = %s) => 0x%16.16llx", - page_byte_size, - GetPermissionsAsCString(permissions), - (uint64_t)addr); - } - - if (addr != LLDB_INVALID_ADDRESS) - { - block_sp.reset (new AllocatedBlock (addr, page_byte_size, permissions, chunk_size)); - m_memory_map.insert (std::make_pair (permissions, block_sp)); - } - return block_sp; -} - -lldb::addr_t -AllocatedMemoryCache::AllocateMemory (size_t byte_size, - uint32_t permissions, - Error &error) -{ - Mutex::Locker locker (m_mutex); - - addr_t addr = LLDB_INVALID_ADDRESS; - std::pair<PermissionsToBlockMap::iterator, PermissionsToBlockMap::iterator> range = m_memory_map.equal_range (permissions); - - for (PermissionsToBlockMap::iterator pos = range.first; pos != range.second; ++pos) - { - addr = (*pos).second->ReserveBlock (byte_size); - } - - if (addr == LLDB_INVALID_ADDRESS) - { - AllocatedBlockSP block_sp (AllocatePage (byte_size, permissions, 16, error)); - - if (block_sp) - addr = block_sp->ReserveBlock (byte_size); - } - LogSP log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); - if (log) - log->Printf ("AllocatedMemoryCache::AllocateMemory (byte_size = 0x%8.8zx, permissions = %s) => 0x%16.16llx", byte_size, GetPermissionsAsCString(permissions), (uint64_t)addr); - return addr; -} - -bool -AllocatedMemoryCache::DeallocateMemory (lldb::addr_t addr) -{ - Mutex::Locker locker (m_mutex); - - PermissionsToBlockMap::iterator pos, end = m_memory_map.end(); - bool success = false; - for (pos = m_memory_map.begin(); pos != end; ++pos) - { - if (pos->second->Contains (addr)) - { - success = pos->second->FreeBlock (addr); - break; - } - } - LogSP log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); - if (log) - log->Printf("AllocatedMemoryCache::DeallocateMemory (addr = 0x%16.16llx) => %i", (uint64_t)addr, success); - return success; -} - - |
