//===-- Memory.h ------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_TARGET_MEMORY_H
#define LLDB_TARGET_MEMORY_H

#include "lldb/Utility/RangeMap.h"
#include "lldb/lldb-private.h"
#include <map>
#include <mutex>
#include <vector>

namespace lldb_private {
// A class to track memory that was read from a live process between
// runs.
class MemoryCache {
public:
  // Constructors and Destructors
  MemoryCache(Process &process);

  ~MemoryCache();

  void Clear(bool clear_invalid_ranges = false);

  void Flush(lldb::addr_t addr, size_t size);

  size_t Read(lldb::addr_t addr, void *dst, size_t dst_len, Status &error);

  uint32_t GetMemoryCacheLineSize() const { return m_L2_cache_line_byte_size; }

  void AddInvalidRange(lldb::addr_t base_addr, lldb::addr_t byte_size);

  bool RemoveInvalidRange(lldb::addr_t base_addr, lldb::addr_t byte_size);

  // Allow external sources to populate data into the L1 memory cache
  void AddL1CacheData(lldb::addr_t addr, const void *src, size_t src_len);

  void AddL1CacheData(lldb::addr_t addr,
                      const lldb::DataBufferSP &data_buffer_sp);

protected:
  typedef std::map<lldb::addr_t, lldb::DataBufferSP> BlockMap;
  typedef RangeVector<lldb::addr_t, lldb::addr_t, 4> InvalidRanges;
  typedef Range<lldb::addr_t, lldb::addr_t> AddrRange;
  // Classes that inherit from MemoryCache can see and modify these
  std::recursive_mutex m_mutex;
  BlockMap m_L1_cache; // A first level memory cache whose chunk sizes vary that
                       // will be used only if the memory read fits entirely in
                       // a chunk
  BlockMap m_L2_cache; // A memory cache of fixed size chinks
                       // (m_L2_cache_line_byte_size bytes in size each)
  InvalidRanges m_invalid_ranges;
  Process &m_process;
  uint32_t m_L2_cache_line_byte_size;

private:
  MemoryCache(const MemoryCache &) = delete;
  const MemoryCache &operator=(const MemoryCache &) = delete;
};

    

class AllocatedBlock {
public:
  AllocatedBlock(lldb::addr_t addr, uint32_t byte_size, uint32_t permissions,
                 uint32_t chunk_size);

  ~AllocatedBlock();

  lldb::addr_t ReserveBlock(uint32_t size);

  bool FreeBlock(lldb::addr_t addr);

  lldb::addr_t GetBaseAddress() const { return m_range.GetRangeBase(); }

  uint32_t GetByteSize() const { return m_range.GetByteSize(); }

  uint32_t GetPermissions() const { return m_permissions; }

  uint32_t GetChunkSize() const { return m_chunk_size; }

  bool Contains(lldb::addr_t addr) const {
    return m_range.Contains(addr);
  }

protected:
  uint32_t TotalChunks() const { return GetByteSize() / GetChunkSize(); }

  uint32_t CalculateChunksNeededForSize(uint32_t size) const {
    return (size + m_chunk_size - 1) / m_chunk_size;
  }
  // Base address of this block of memory 4GB of chunk should be enough.
  Range<lldb::addr_t, uint32_t> m_range;
  // Permissions for this memory (logical OR of lldb::Permissions bits)
  const uint32_t m_permissions;
  // The size of chunks that the memory at m_addr is divied up into.
  const uint32_t m_chunk_size;
  // A sorted list of free address ranges.
  RangeVector<lldb::addr_t, uint32_t> m_free_blocks;
  // A sorted list of reserved address.
  RangeVector<lldb::addr_t, uint32_t> m_reserved_blocks;
};

// A class that can track allocated memory and give out allocated memory
// without us having to make an allocate/deallocate call every time we need
// some memory in a process that is being debugged.
class AllocatedMemoryCache {
public:
  // Constructors and Destructors
  AllocatedMemoryCache(Process &process);

  ~AllocatedMemoryCache();

  void Clear();

  lldb::addr_t AllocateMemory(size_t byte_size, uint32_t permissions,
                              Status &error);

  bool DeallocateMemory(lldb::addr_t ptr);

protected:
  typedef std::shared_ptr<AllocatedBlock> AllocatedBlockSP;

  AllocatedBlockSP AllocatePage(uint32_t byte_size, uint32_t permissions,
                                uint32_t chunk_size, Status &error);

  // Classes that inherit from MemoryCache can see and modify these
  Process &m_process;
  std::recursive_mutex m_mutex;
  typedef std::multimap<uint32_t, AllocatedBlockSP> PermissionsToBlockMap;
  PermissionsToBlockMap m_memory_map;

private:
  AllocatedMemoryCache(const AllocatedMemoryCache &) = delete;
  const AllocatedMemoryCache &operator=(const AllocatedMemoryCache &) = delete;
};

} // namespace lldb_private

#endif // LLDB_TARGET_MEMORY_H
