MemoryArea.h revision f7ac0f19a1c8d0ad14bcf6456ce368b830fea886
1//===- MemoryArea.h -------------------------------------------------------===// 2// 3// The MCLinker Project 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9#ifndef MCLD_SUPPORT_MEMORY_AREA_H 10#define MCLD_SUPPORT_MEMORY_AREA_H 11#ifdef ENABLE_UNITTEST 12#include <gtest.h> 13#endif 14 15#include <mcld/ADT/Uncopyable.h> 16#include <cstddef> 17#include <map> 18 19#if defined(ENABLE_UNITTEST) 20namespace mcldtest { 21 class MemoryAreaTest; 22} // namespace of mcldtest 23#endif 24 25namespace mcld { 26 27class Space; 28class FileHandle; 29class MemoryRegion; 30 31/** \class MemoryArea 32 * \brief MemoryArea is used to manage distinct MemoryRegions of address space. 33 * 34 * Good linkers must well manipulate memory mapped I/O and dynamic memory. 35 * In MCLinker, MemoryArea is the decision-maker to use memory mapped I/O or 36 * dynamic memory. When a client requests MemoryArea for a piece of memory 37 * to hold a part of a file, MemoryArea is going to see whether the requested 38 * part of the file is already in any existing memory which is requested 39 * before. If it is, MemoryArea creates a new MemoryRegion within the memory 40 * requested before. Otherwise, MemoryArea uses memory mapped I/O or dynamic 41 * memory to load the file. 42 * 43 * If the part a file being loaded is larger than 3/4 pages, MemoryArea uses 44 * memory mapped I/O to load the file. Otherwise, MemoryArea uses dynamic 45 * memory to read the content of file into the memory space. 46 */ 47class MemoryArea : private Uncopyable 48{ 49 friend class MemoryAreaFactory; 50public: 51 // constructor by file handler. 52 // If the given file handler is read-only, client can not request a region 53 // that out of the file size. 54 // @param pFileHandle - file handler 55 explicit MemoryArea(FileHandle& pFileHandle); 56 57 // constructor by set universal space. 58 // Client can not request a region that out of the universal space. 59 // @param pUniverse - file handler 60 explicit MemoryArea(Space& pUniverse); 61 62 // destructor 63 ~MemoryArea(); 64 65 // request - create a MemoryRegion within a sufficient space 66 // find an existing space to hold the MemoryRegion. 67 // if MemoryArea does not find such space, then it creates a new space and 68 // assign a MemoryRegion into the space. 69 MemoryRegion* request(size_t pOffset, size_t pLength); 70 71 // release - release a MemoryRegion. 72 // release a MemoryRegion does not cause 73 void release(MemoryRegion* pRegion); 74 75 // clear - release all memory regions. 76 void clear(); 77 78 const FileHandle* handler() const { return m_pFileHandle; } 79 FileHandle* handler() { return m_pFileHandle; } 80 81 bool hasHandler() const { return (NULL != m_pFileHandle); } 82 83 // ----- space list methods ----- // 84 Space* find(size_t pOffset, size_t pLength); 85 86 const Space* find(size_t pOffset, size_t pLength) const; 87 88private: 89 class Key { 90 public: 91 Key(size_t pOffset, size_t pLength) 92 : m_Offset(pOffset), m_Length(pLength) 93 { } 94 95 size_t offset() const { return m_Offset; } 96 97 size_t length() const { return m_Length; } 98 99 struct Compare { 100 bool operator()(const Key& KEY1, const Key& KEY2) const 101 { 102 return KEY1.offset() + KEY1.length() < KEY2.offset() || 103 (KEY1.offset() < KEY2.offset() && 104 (KEY1.offset() + KEY1.length() < KEY2.offset() + KEY2.length())); 105 } 106 }; 107 108 private: 109 size_t m_Offset; 110 size_t m_Length; 111 }; 112 113 typedef std::multimap<Key, Space*, Key::Compare> SpaceMapType; 114 115private: 116 SpaceMapType m_SpaceMap; 117 FileHandle* m_pFileHandle; 118}; 119 120} // namespace of mcld 121 122#endif 123 124