//===-- 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;

    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)
    {
        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.16" PRIx64, 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.16" PRIx64 ") => %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.16" PRIx64,
                     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.16" PRIx64, 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.16" PRIx64 ") => %i", (uint64_t)addr, success);
    return success;
}


