15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- MemoryArea.cpp -----------------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/RegionFactory.h>
105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryArea.h>
115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h>
12affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/FileHandle.h>
13affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h>
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===--------------------------------------------------------------------===//
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// MemoryArea
1967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao//===--------------------------------------------------------------------===//
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
21affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// MemoryArea - special constructor
22affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// This constructor is used for *SPECIAL* situation. I'm sorry I can not
23affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// reveal what is the special situation.
24affc150dc44fab1911775a49636d0ce85333b634Zonr ChangMemoryArea::MemoryArea(RegionFactory& pRegionFactory, Space& pUniverse)
25affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  : m_RegionFactory(pRegionFactory), m_pFileHandle(NULL) {
26affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  m_SpaceList.push_back(&pUniverse);
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
29affc150dc44fab1911775a49636d0ce85333b634Zonr ChangMemoryArea::MemoryArea(RegionFactory& pRegionFactory, FileHandle& pFileHandle)
30affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  : m_RegionFactory(pRegionFactory), m_pFileHandle(&pFileHandle) {
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
33affc150dc44fab1911775a49636d0ce85333b634Zonr ChangMemoryArea::~MemoryArea()
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// The layout of MemorySpace in the virtual memory space
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// |  : page boundary
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// [,]: MemoryRegion
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// -  : fillment
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// =  : data
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// |---[=|====|====|==]--|
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// ^   ^              ^  ^
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// |   |              |  |
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// | r_start      +r_len |
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// space.data      +space.size
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// space.file_offset is the offset of the mapped file segment from the start of
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// the file. if the MemorySpace's type is ALLOCATED_ARRAY, the distances of
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// (space.data, r_start) and (r_len, space.size) are zero.
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMemoryRegion* MemoryArea::request(size_t pOffset, size_t pLength)
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Space* space = find(pOffset, pLength);
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == space) {
58affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // not found
59affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (NULL == m_pFileHandle) {
60affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // if m_pFileHandle is NULL, clients delegate us an universal Space and
61affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // we never remove it. In that way, space can not be NULL.
6267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao      unreachable(diag::err_out_of_range_region) << pOffset << pLength;
63affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
65affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    space = Space::createSpace(*m_pFileHandle, pOffset, pLength);
66affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_SpaceList.push_back(space);
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
69affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // adjust r_start
70affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  off_t distance = pOffset - space->start();
71affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  void* r_start = space->memory() + distance;
72affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // now, we have a legal space to hold the new MemoryRegion
74affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return m_RegionFactory.produce(*space, r_start, pLength);
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// release - release a MemoryRegion
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MemoryArea::release(MemoryRegion* pRegion)
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL == pRegion)
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return;
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Space *space = pRegion->parent();
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_RegionFactory.destruct(pRegion);
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
86affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (0 == space->numOfRegions()) {
87affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
88affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (NULL != m_pFileHandle) {
89affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // if m_pFileHandle is NULL, clients delegate us an universal Space and
90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // we never remove it. Otherwise, we have to synchronize and release
91affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // Space.
92affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (m_pFileHandle->isWritable()) {
93affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // synchronize writable space before we release it.
94affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        Space::syncSpace(space, *m_pFileHandle);
95affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
96affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      Space::releaseSpace(space, *m_pFileHandle);
9767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao      m_SpaceList.erase(space);
98affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
102affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// clear - release all MemoryRegions
103affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid MemoryArea::clear()
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
105affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL == m_pFileHandle)
106affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return;
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
108affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (m_pFileHandle->isWritable()) {
109affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SpaceList::iterator space, sEnd = m_SpaceList.end();
110affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    for (space = m_SpaceList.begin(); space != sEnd; ++space) {
111affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      Space::syncSpace(space, *m_pFileHandle);
112affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      Space::releaseSpace(space, *m_pFileHandle);
113affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
115affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else {
116affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SpaceList::iterator space, sEnd = m_SpaceList.end();
117affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    for (space = m_SpaceList.begin(); space != sEnd; ++space)
118affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      Space::releaseSpace(space, *m_pFileHandle);
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
120affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
121affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  m_SpaceList.clear();
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
124affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===--------------------------------------------------------------------===//
125affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// SpaceList methods
126affc150dc44fab1911775a49636d0ce85333b634Zonr ChangSpace* MemoryArea::find(size_t pOffset, size_t pLength)
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  SpaceList::iterator sIter, sEnd = m_SpaceList.end();
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (sIter = m_SpaceList.begin(); sIter!=sEnd; ++sIter) {
130affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (sIter->start() <= pOffset &&
131affc150dc44fab1911775a49636d0ce85333b634Zonr Chang       (pOffset+pLength) <= (sIter->start()+sIter->size()) ) {
132affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // within
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return sIter;
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return NULL;
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
139affc150dc44fab1911775a49636d0ce85333b634Zonr Changconst Space* MemoryArea::find(size_t pOffset, size_t pLength) const
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
141affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  SpaceList::const_iterator sIter, sEnd = m_SpaceList.end();
142affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  for (sIter = m_SpaceList.begin(); sIter!=sEnd; ++sIter) {
143affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (sIter->start() <= pOffset &&
144affc150dc44fab1911775a49636d0ce85333b634Zonr Chang       (pOffset+pLength) <= (sIter->start()+sIter->size()) ) {
145affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // within
146affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return sIter;
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
149affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return NULL;
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
152