//===- MemoryRegion.h -----------------------------------------------------===//
//
// The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LD_MEMORY_REGION_H
#define LD_MEMORY_REGION_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
#include <mcld/Config/Config.h>
#include <mcld/ADT/Uncopyable.h>
#include <mcld/Support/Allocators.h>
#include <mcld/Support/Space.h>
namespace mcld {
class MemoryArea;
/** \class MemoryRegion
* \brief MemoryRegion is a range of virtual memory which is mapped onto a
* range of files which is opened by MemoryArea.
*
* MemoryArea maps a file onto virtual memory. Clients can get a range of
* mapped memory space by requesting a MemoryRegion from MemoryArea, and
* read/write the mapped file through the MemoryRegion.
*
* When two different MemoryRegion may overlap memory space, race condition
* may occurs. Clients must call MemoryRegion::sync() explicit to tell the
* MemoryArea when to synchronize the virtual memory space with the mapped
* file.
*/
class MemoryRegion : private Uncopyable
{
friend class Chunk<MemoryRegion, MCLD_REGION_CHUNK_SIZE>;
friend class RegionFactory;
friend class MemoryArea;
public:
typedef Space::Address Address;
typedef Space::ConstAddress ConstAddress;
private:
MemoryRegion();
MemoryRegion(const Address pVMAStart, size_t pSize);
~MemoryRegion();
void setParent(Space& pSpace) { m_pParent = &pSpace; }
public:
/// Create - To wrap a piece of memory and to create a new region.
/// This function wraps a piece of memory and to create a new region. Region
/// is just a wraper, it is not responsible for deallocate the given memory.
///
/// @param pStart [in] The start address of a piece of memory
/// @param pSize [in] The size of the given memory
static MemoryRegion* Create(void* pStart, size_t pSize);
/// Create - To wrap a piece of memory and to create a new region.
/// This function wraps a piece of memory and to create a new region. Region
/// is just a wraper, it is not responsible for deallocate the given memory.
///
/// If a wrapped memory comes from a Space, then we say the space is the
/// parent of the region. pSpace is a memory counting container. It remembers
/// the number of regions in it. A space which has no region will be removed
/// quickly.
///
/// The wrapped memory will be deallocated by Space when the space has no
/// region used it.
///
/// @param pStart [in] The start address of a piece of memory
/// @param pSize [in] The size of the given memory
/// @param pSpace [in] The parent space.
static MemoryRegion* Create(void* pStart, size_t pSize, Space& pSpace);
/// Destroy - To destroy the region
/// If the region has a parent space, it will be also remove from the space.
///
/// @param pRegion [in, out] pRegion is set to NULL if the destruction is
/// success.
static void Destroy(MemoryRegion*& pRegion);
const Space* parent() const { return m_pParent; }
Space* parent() { return m_pParent; }
bool hasParent() const { return (NULL != m_pParent); }
ConstAddress start() const { return m_VMAStart; }
Address start() { return m_VMAStart; }
ConstAddress end() const { return m_VMAStart+m_Length; }
Address end() { return m_VMAStart+m_Length; }
size_t size() const { return m_Length; }
ConstAddress getBuffer(size_t pOffset = 0) const
{ return m_VMAStart+pOffset; }
Address getBuffer(size_t pOffset = 0)
{ return m_VMAStart+pOffset; }
private:
Space* m_pParent;
Address m_VMAStart;
size_t m_Length;
};
} // namespace of mcld
#endif