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