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