22 #include "pedigree/kernel/LockGuard.h" 23 #include "pedigree/kernel/Log.h" 24 #include "pedigree/kernel/Spinlock.h" 25 #include "pedigree/kernel/process/MemoryPressureManager.h" 26 #include "pedigree/kernel/process/Process.h" 27 #include "pedigree/kernel/process/Thread.h" 28 #include "pedigree/kernel/process/Uninterruptible.h" 29 #include "pedigree/kernel/processor/PhysicalMemoryManager.h" 30 #include "pedigree/kernel/processor/Processor.h" 31 #include "pedigree/kernel/processor/ProcessorInformation.h" 32 #include "pedigree/kernel/processor/VirtualAddressSpace.h" 33 #include "pedigree/kernel/utilities/Iterator.h" 34 #include "pedigree/kernel/utilities/MemoryAllocator.h" 35 #include "pedigree/kernel/utilities/assert.h" 36 #include "pedigree/kernel/utilities/utility.h" 40 physical_uintptr_t AnonymousMemoryMap::m_Zero = 0;
44 MemoryMappedObject::~MemoryMappedObject()
48 AnonymousMemoryMap::AnonymousMemoryMap(
63 m_Zero, reinterpret_cast<void *>(address),
66 reinterpret_cast<void *>(address), 0,
68 va.
unmap(reinterpret_cast<void *>(address));
86 if (at < m_Address || at >= (m_Address + m_Length))
89 "AnonymousMemoryMap::split() given bad at parameter (at=" 90 << at <<
", address=" << m_Address
91 <<
", end=" << (m_Address + m_Length) <<
")");
97 ERROR(
"AnonymousMemoryMap::split() misused, at == base address");
102 size_t oldLength = m_Length;
103 m_Length = at - m_Address;
111 it != m_Mappings.end();)
113 uintptr_t v =
reinterpret_cast<uintptr_t
>(*it);
117 it = m_Mappings.erase(it);
133 if (length & (pageSz - 1))
136 length &= ~(pageSz - 1);
139 if (length >= m_Length)
150 it != m_Mappings.end();)
152 uintptr_t virt =
reinterpret_cast<uintptr_t
>(*it);
153 if (virt >= m_Address)
160 physical_uintptr_t phys;
168 it = m_Mappings.erase(it);
180 if (perms == MemoryMappedObject::None)
188 it != m_Mappings.end(); ++it)
193 physical_uintptr_t p;
202 if (perms & MemoryMappedObject::Write)
207 if (perms & MemoryMappedObject::Exec)
214 else if (perms & MemoryMappedObject::Exec)
223 m_Permissions = perms;
237 #ifdef DEBUG_MMOBJECTS 238 NOTICE(
"AnonymousMemoryMap::trap(" << address <<
", " << bWrite <<
")");
245 address = address & ~(pageSz - 1);
248 if (bWrite && !(m_Permissions & Write))
250 #ifdef DEBUG_MMOBJECTS 251 NOTICE(
" -> no write permission");
255 else if ((!bWrite) && !(m_Permissions & Read))
257 #ifdef DEBUG_MMOBJECTS 258 NOTICE(
" -> no read permission");
264 size_t extraFlags = 0;
265 if (m_Permissions & Exec)
270 if (va.
isMapped(reinterpret_cast<void *>(address)))
272 ERROR(
"trapped on a currently-mapped page!");
277 m_Zero, reinterpret_cast<void *>(address),
280 "map() failed for AnonymousMemoryMap::trap() - read @" 283 m_Mappings.pushBack(reinterpret_cast<void *>(address));
288 if (va.
isMapped(reinterpret_cast<void *>(address)))
290 va.
unmap(reinterpret_cast<void *>(address));
298 m_Mappings.pushBack(reinterpret_cast<void *>(address));
302 physical_uintptr_t newPage =
305 newPage, reinterpret_cast<void *>(address),
307 ERROR(
"map() failed in AnonymousMemoryMap::trap() - write");
309 reinterpret_cast<void *>(address), 0,
316 void AnonymousMemoryMap::unmapUnlocked()
318 #ifdef DEBUG_MMOBJECTS 319 NOTICE(
"AnonymousMemoryMap::unmap()");
331 physical_uintptr_t phys;
345 MemoryMappedFile::MemoryMappedFile(
346 uintptr_t address,
size_t length,
size_t offset,
File *backing,
349 m_pBacking(backing), m_Offset(offset), m_Mappings(), m_Lock(
false)
354 MemoryMappedFile::~MemoryMappedFile()
364 m_Address, m_Length, m_Offset, m_pBacking, m_bCopyOnWrite,
368 for (
auto it = m_Mappings.begin(); it != m_Mappings.end(); ++it)
371 size_t fileOffset = (it.key() - m_Address) + m_Offset;
372 if (it.value() == ~0UL)
373 m_pBacking->getPhysicalPage(fileOffset);
385 if (at < m_Address || at >= (m_Address + m_Length))
388 "MemoryMappedFile::split() given bad at parameter (at=" 389 << at <<
", address=" << m_Address
390 <<
", end=" << (m_Address + m_Length) <<
")");
396 ERROR(
"MemoryMappedFile::split() misused, at == base address");
400 uintptr_t oldEnd = m_Address + m_Length;
403 size_t oldLength = m_Length;
404 m_Length = at - m_Address;
408 at, oldLength - m_Length, m_Offset + m_Length, m_pBacking,
409 m_bCopyOnWrite, m_Permissions);
412 for (uintptr_t virt = at; virt < oldEnd; virt += pageSz)
414 physical_uintptr_t old = getMapping(virt);
415 untrackMapping(virt);
430 if (length & (pageSz - 1))
433 length &= ~(pageSz - 1);
436 if (length >= m_Length)
442 uintptr_t oldStart = m_Address;
443 size_t oldOffset = m_Offset;
450 for (uintptr_t virt = oldStart; virt < m_Address; virt += pageSz)
452 void *v =
reinterpret_cast<void *
>(virt);
456 physical_uintptr_t phys;
461 physical_uintptr_t p = getMapping(virt);
464 size_t fileOffset = (virt - oldStart) + oldOffset;
465 m_pBacking->returnPhysicalPage(fileOffset);
470 VirtualAddressSpace::Write)
471 m_pBacking->sync(fileOffset,
true);
477 untrackMapping(virt);
489 if (perms == MemoryMappedObject::None)
496 for (
auto it = m_Mappings.begin(); it != m_Mappings.end(); ++it)
498 void *v =
reinterpret_cast<void *
>(it.key());
501 physical_uintptr_t p;
506 if (perms & MemoryMappedObject::Exec)
517 if (perms & MemoryMappedObject::Write)
527 if (perms & MemoryMappedObject::Write)
538 m_Permissions = perms;
541 static physical_uintptr_t
542 getBackingPage(
File *pBacking,
size_t fileOffset,
Spinlock &lock)
556 if ((actual = pBacking->
read(fileOffset, pageSz, 0)) != pageSz)
559 "Short read of " << pBacking->
getName()
560 <<
" in getBackingPage() - wanted " << pageSz
561 <<
" bytes but got " << actual <<
" instead");
569 "*** Could not manage to get a physical page for a " 571 << pBacking->
getName() <<
") - read got " << actual
585 if (at < m_Address || at >= (m_Address + m_Length))
588 "MemoryMappedFile::sync() given bad at parameter (at=" 589 << at <<
", address=" << m_Address
590 <<
", end=" << (m_Address + m_Length) <<
")");
594 void *v =
reinterpret_cast<void *
>(at);
598 physical_uintptr_t phys = 0;
606 size_t fileOffset = (at - m_Address) + m_Offset;
608 physical_uintptr_t p = getMapping(at);
611 m_pBacking->sync(fileOffset, async);
628 if (at < m_Address || at >= (m_Address + m_Length))
631 "MemoryMappedFile::invalidate() given bad at parameter (at=" 632 << at <<
", address=" << m_Address
633 <<
", end=" << (m_Address + m_Length) <<
")");
638 size_t extraFlags = 0;
639 if (m_Permissions & Exec)
642 size_t fileOffset = (at - m_Address) + m_Offset;
645 physical_uintptr_t p = getMapping(at);
650 void *v =
reinterpret_cast<void *
>(at);
660 physical_uintptr_t newBacking =
661 getBackingPage(m_pBacking, fileOffset, m_Lock);
662 if (newBacking == ~0UL)
664 ERROR(
"MemoryMappedFile::invalidate() couldn't bring in new " 671 trackMapping(at, ~0UL);
687 #ifdef DEBUG_MMOBJECTS 688 NOTICE(
"MemoryMappedFile::trap(" << address <<
", " << bWrite <<
")");
695 address = address & ~(pageSz - 1);
696 size_t mappingOffset = (address - m_Address);
697 size_t fileOffset = m_Offset + mappingOffset;
699 bool bWillEof = (mappingOffset + pageSz) > m_Length;
700 bool bShouldCopy = m_bCopyOnWrite && (bWillEof || bWrite);
703 if (bWrite && !(m_Permissions & Write))
705 #ifdef DEBUG_MMOBJECTS 707 " -> ignoring, was a write and this is not a writable mapping.");
711 else if ((!bWrite) && !(m_Permissions & Read))
713 #ifdef DEBUG_MMOBJECTS 715 " -> ignoring, was a read and this is not a readable mapping.");
720 #ifdef DEBUG_MMOBJECTS 722 " -> mapping offset is " << mappingOffset
723 <<
", file offset: " << fileOffset);
724 DEBUG_LOG(
" -> will eof: " << bWillEof <<
", should copy: " << bShouldCopy);
728 size_t extraFlags = 0;
729 if (m_Permissions & Exec)
735 physical_uintptr_t phys =
736 getBackingPage(m_pBacking, fileOffset, m_Lock);
739 ERROR(
"MemoryMappedFile::trap couldn't get a backing page");
750 va.
map(phys, reinterpret_cast<void *>(address), flags | extraFlags);
753 ERROR(
"map() failed in MemoryMappedFile::trap (no-copy)");
757 trackMapping(address, ~0);
762 if (va.
isMapped(reinterpret_cast<void *>(address)))
764 va.
unmap(reinterpret_cast<void *>(address));
767 m_pBacking->returnPhysicalPage(fileOffset);
768 untrackMapping(address);
772 physical_uintptr_t newPhys =
775 newPhys, reinterpret_cast<void *>(address),
779 ERROR(
"map() failed in MemoryMappedFile::trap (copy)");
783 size_t nBytes = m_Length - mappingOffset;
791 size_t nRead = m_pBacking->read(fileOffset, nBytes, address);
797 reinterpret_cast<void *>(address + nRead), 0,
801 trackMapping(address, newPhys);
815 uintptr_t base = m_Address;
816 uintptr_t end = base + m_Length;
818 bool bReleased =
false;
822 if ((m_Permissions & Write) && !m_bCopyOnWrite)
825 for (uintptr_t addr = base; addr < end; addr += pageSz)
827 physical_uintptr_t p = getMapping(addr);
832 physical_uintptr_t phys = 0;
833 va.
getMapping(reinterpret_cast<void *>(addr), phys, flags);
839 size_t mappingOffset = (addr - m_Address);
840 size_t fileOffset = m_Offset + mappingOffset;
843 m_pBacking->sync(fileOffset,
false);
846 va.
unmap(reinterpret_cast<void *>(addr));
849 m_pBacking->returnPhysicalPage(fileOffset);
850 untrackMapping(addr);
859 for (uintptr_t addr = base; addr < end; addr += pageSz)
861 physical_uintptr_t p = getMapping(addr);
866 physical_uintptr_t phys = 0;
867 va.
getMapping(reinterpret_cast<void *>(addr), phys, flags);
873 size_t mappingOffset = (addr - m_Address);
874 size_t fileOffset = m_Offset + mappingOffset;
877 va.
unmap(reinterpret_cast<void *>(addr));
880 m_pBacking->returnPhysicalPage(fileOffset);
881 untrackMapping(addr);
890 void MemoryMappedFile::unmapUnlocked()
892 #ifdef DEBUG_MMOBJECTS 893 NOTICE(
"MemoryMappedFile::unmap()");
898 if (!getMappingCount())
901 for (
auto it = m_Mappings.begin(); it != m_Mappings.end(); ++it)
903 void *v =
reinterpret_cast<void *
>(it.key());
908 physical_uintptr_t phys = 0;
912 physical_uintptr_t p = it.value();
915 size_t fileOffset = (it.key() - m_Address) + m_Offset;
916 m_pBacking->returnPhysicalPage(fileOffset);
921 VirtualAddressSpace::Write)
922 m_pBacking->sync(fileOffset,
true);
933 m_Mappings.insert(addr, phys);
938 m_Mappings.remove(addr);
943 return m_Mappings.lookup(addr);
948 return m_Mappings.count();
960 MemoryPressureManager::HighPriority,
this);
963 MemoryMapManager::~MemoryMapManager()
969 File *pFile, uintptr_t &address,
size_t length,
977 size_t actualLength = length;
978 if (length & (pageSz - 1))
981 length &= ~(pageSz - 1);
988 remove(address, length);
990 #ifdef DEBUG_MMOBJECTS 992 "MemoryMapManager::mapFile: " << address <<
" length " << actualLength
993 <<
" for " << pFile->
getName());
996 address, actualLength, offset, pFile, bCopyOnWrite, perms);
1009 pMmObjectList->
pushBack(pMappedFile);
1024 if (length & (pageSz - 1))
1027 length &= ~(pageSz - 1);
1034 remove(address, length);
1036 #ifdef DEBUG_MMOBJECTS 1037 NOTICE(
"MemoryMapManager::mapAnon: " << address <<
" length " << length);
1071 if (!pMmObjectList2)
1078 it != pMmObjectList->
end(); it++)
1082 pMmObjectList2->
pushBack(pNewObject);
1088 #ifdef DEBUG_MMOBJECTS 1089 NOTICE(
"MemoryMapManager::remove(" << base <<
", " << length <<
")");
1095 size_t nAffected = 0;
1097 if (length & (pageSz - 1))
1100 length &= ~(pageSz - 1);
1103 uintptr_t removeEnd = base + length;
1115 it != pMmObjectList->
end();)
1121 bool bErased =
false;
1125 #ifdef DEBUG_MMOBJECTS 1127 "MemoryMapManager::remove() - object at " 1128 << pObject->
address() <<
" -> " << objEnd <<
".");
1131 uintptr_t objAlignEnd = objEnd;
1132 if (objAlignEnd & (pageSz - 1))
1134 objAlignEnd += pageSz;
1135 objAlignEnd &= ~(pageSz - 1);
1139 if (pObject->
address() == removeEnd)
1146 else if (pObject->
address() == base)
1148 #ifdef DEBUG_MMOBJECTS 1149 NOTICE(
"MemoryMapManager::remove() - a direct removal");
1151 bool bAll = pObject->
remove(length);
1154 it = pMmObjectList->
erase(it);
1161 else if ((pObject->
address() < base) && (removeEnd <= objAlignEnd))
1163 #ifdef DEBUG_MMOBJECTS 1164 NOTICE(
"MemoryMapManager::remove() - fully enclosed removal");
1167 bool bAll = pNewObject->
remove(removeEnd - base);
1171 pMmObjectList->
pushBack(pNewObject);
1177 (pObject->
address() > base) && (objEnd >= base) &&
1178 (objEnd <= removeEnd))
1180 #ifdef DEBUG_MMOBJECTS 1181 NOTICE(
"MemoryMapManager::remove() - begin before start, end after " 1187 it = pMmObjectList->
erase(it);
1194 (pObject->
address() > base) && (removeEnd >= pObject->
address()) &&
1195 (removeEnd <= objEnd))
1197 #ifdef DEBUG_MMOBJECTS 1198 NOTICE(
"MemoryMapManager::remove() - begin outside, end inside");
1204 it = pMmObjectList->
erase(it);
1208 pMmObjectList->
pushBack(pNewObject);
1213 (pObject->
address() < base) && (base < objEnd) &&
1214 (removeEnd >= objEnd))
1216 #ifdef DEBUG_MMOBJECTS 1217 NOTICE(
"MemoryMapManager::remove() - begin inside, end outside");
1220 pNewObject->
unmap();
1227 #ifdef DEBUG_MMOBJECTS 1228 NOTICE(
"MemoryMapManager::remove() - doing nothing!");
1250 #ifdef DEBUG_MMOBJECTS 1252 "MemoryMapManager::setPermissions(" << base <<
", " << length <<
")");
1258 size_t nAffected = 0;
1260 if (length & (pageSz - 1))
1263 length &= ~(pageSz - 1);
1266 uintptr_t removeEnd = base + length;
1278 it != pMmObjectList->
end(); ++it)
1284 #ifdef DEBUG_MMOBJECTS 1286 "MemoryMapManager::setPermissions() - object at " 1287 << pObject->
address() <<
" -> " << objEnd <<
".");
1290 uintptr_t objAlignEnd = objEnd;
1291 if (objAlignEnd & (pageSz - 1))
1293 objAlignEnd += pageSz;
1294 objAlignEnd &= ~(pageSz - 1);
1298 if (pObject->
address() == removeEnd)
1304 else if (pObject->
address() == base)
1306 #ifdef DEBUG_MMOBJECTS 1307 NOTICE(
"MemoryMapManager::setPermissions() - a direct set");
1309 if (pObject->
length() > length)
1313 pMmObjectList->
pushBack(pNewObject);
1320 else if ((pObject->
address() < base) && (removeEnd <= objAlignEnd))
1322 #ifdef DEBUG_MMOBJECTS 1323 NOTICE(
"MemoryMapManager::setPermissions() - fully enclosed set");
1327 if (removeEnd < objAlignEnd)
1330 pMmObjectList->
pushBack(pTailObject);
1334 pMmObjectList->
pushBack(pNewObject);
1339 (pObject->
address() > base) && (objEnd >= base) &&
1340 (objEnd <= removeEnd))
1342 #ifdef DEBUG_MMOBJECTS 1343 NOTICE(
"MemoryMapManager::setPermissions() - begin before start, " 1344 "end after object end");
1352 (pObject->
address() > base) && (removeEnd >= pObject->
address()) &&
1353 (removeEnd <= objEnd))
1355 #ifdef DEBUG_MMOBJECTS 1356 NOTICE(
"MemoryMapManager::setPermissions() - begin outside, end " 1362 pMmObjectList->
pushBack(pNewObject);
1367 (pObject->
address() < base) && (base < objEnd) &&
1368 (removeEnd >= objEnd))
1370 #ifdef DEBUG_MMOBJECTS 1371 NOTICE(
"MemoryMapManager::setPermissions() - begin inside, end " 1376 pMmObjectList->
pushBack(pNewObject);
1382 #ifdef DEBUG_MMOBJECTS 1383 NOTICE(
"MemoryMapManager::setPermissions() - doing nothing!");
1409 for (uintptr_t address = base; address < (base + length); address += pageSz)
1412 it != pMmObjectList->
end(); it++)
1415 if (pObject->
matches(address & ~(pageSz - 1)))
1425 void MemoryMapManager::op(
1426 MemoryMapManager::Ops what, uintptr_t base,
size_t length,
bool async)
1440 for (uintptr_t address = base; address < (base + length); address += pageSz)
1443 it != pMmObjectList->
end(); it++)
1446 if (pObject->
matches(address & ~(pageSz - 1)))
1451 pObject->
sync(address, async);
1457 WARNING(
"Bad 'what' in MemoryMapManager::op()");
1468 op(Sync, base, length, async);
1473 op(Invalidate, base, length,
false);
1487 it != pMmObjectList->
end(); ++it)
1495 pMmObjectList->
erase(it);
1508 InterruptState &state, uintptr_t address,
bool bIsWrite)
1514 #ifdef DEBUG_MMOBJECTS 1517 <<
Hex << address <<
", pid:tid " <<
Dec 1526 #ifdef DEBUG_MMOBJECTS 1527 NOTICE_NOLOCK(
"trap: got lock");
1537 #ifdef DEBUG_MMOBJECTS 1539 "trap: lookup complete " << reinterpret_cast<uintptr_t>(pMmObjectList));
1543 it != pMmObjectList->
end(); it++)
1546 #ifdef DEBUG_MMOBJECTS 1547 NOTICE_NOLOCK(
"mmobj=" << reinterpret_cast<uintptr_t>(pObject));
1550 NOTICE_NOLOCK(
"bad mmobj, should create a real #PF and backtrace");
1559 if (pObject->
matches(address & ~(pageSz - 1)))
1562 return pObject->
trap(address, bIsWrite);
1566 #ifdef DEBUG_MMOBJECTS 1567 ERROR(
"MemoryMapManager::trap() could not find an object for " << address);
1584 length + pageSz, address))
1586 length + pageSz, address))
1589 if (address & (pageSz - 1))
1591 address = (address + pageSz) & ~(pageSz - 1);
1613 bool bCompact =
false;
1621 it2 != it.value()->end(); ++it2)
1623 bCompact = (*it2)->compact();
1639 NOTICE(
" -> success, hoping for Cache eviction...");
1647 FATAL(
"MemoryMapManager::unmapAllUnlocked must be called with the lock " 1658 it != pMmObjectList->
end(); it = pMmObjectList->
begin())
1663 pMmObjectList->
erase(it);
1666 delete pMmObjectList;
static MemoryMapManager m_Instance
virtual MemoryMappedObject * clone()
void pushBack(const T &value)
virtual void unmap(void *virtualAddress)=0
static size_t getPageSize() PURE
virtual bool trap(uintptr_t address, bool bWrite)=0
static PhysicalMemoryManager & instance()
Iterator erase(Iterator &Iter)
virtual void pin(physical_uintptr_t page)=0
virtual void setPermissions(MemoryMappedObject::Permissions perms)
virtual void getMapping(void *virtualAddress, physical_uintptr_t &physicalAddress, size_t &flags)=0
virtual physical_uintptr_t getPhysicalPage(size_t offset)
MemoryMappedObject * mapAnon(uintptr_t &address, size_t length, MemoryMappedObject::Permissions perms)
virtual void setPermissions(MemoryMappedObject::Permissions perms)
virtual void setFlags(void *virtualAddress, size_t newFlags)=0
virtual void setPermissions(Permissions perms)=0
virtual physical_uintptr_t allocatePage(size_t pageConstraints=0)=0
virtual MemoryMappedObject * clone()
List< void * > m_Mappings
virtual bool trap(InterruptState &state, uintptr_t address, bool bIsWrite)
virtual bool isMapped(void *virtualAddress)=0
Tree< VirtualAddressSpace *, MmObjectList * > m_MmObjectLists
static const size_t Execute
virtual bool map(physical_uintptr_t physicalAddress, void *virtualAddress, size_t flags)=0
bool acquire(bool recurse=false, bool safe=true)
bool matches(uintptr_t address)
static ProcessorInformation & information()
static void switchAddressSpace(VirtualAddressSpace &AddressSpace)
bool allocate(T length, T &address)
virtual void sync(uintptr_t at, bool async)
void unmap(MemoryMappedObject *pObj)
virtual bool remove(size_t length)=0
size_t setPermissions(uintptr_t base, size_t length, MemoryMappedObject::Permissions perms)
static PageFaultHandler & instance()
virtual bool trap(uintptr_t address, bool bWrite)
static const size_t Write
void invalidate(uintptr_t base, size_t length)
void sync(uintptr_t base, size_t length, bool async)
uintptr_t address() const
virtual bool remove(size_t length)
Memory-mapped file interface.
MemoryAllocator & getDynamicSpaceAllocator()
static const size_t Shared
virtual MemoryMappedObject * split(uintptr_t at)
Tree< uintptr_t, physical_uintptr_t > m_Mappings
::Iterator< T, node_t > Iterator
bool allocateSpecific(T address, T length)
virtual MemoryMappedObject * split(uintptr_t at)=0
MemoryMappedObject * mapFile(File *pFile, uintptr_t &address, size_t length, MemoryMappedObject::Permissions perms, size_t offset=0, bool bCopyOnWrite=true)
void registerHandler(MemoryTrapHandler *pHandler)
virtual uint64_t read(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true) final
virtual void invalidate(uintptr_t at)
bool contains(uintptr_t base, size_t length)
physical_uintptr_t getMapping(uintptr_t)
bool sanitiseAddress(uintptr_t &address, size_t length)
void clone(Process *pTarget)
VirtualAddressSpace * getAddressSpace()
virtual MemoryMappedObject * split(uintptr_t at)
void trackMapping(uintptr_t, physical_uintptr_t)
virtual void sync(uintptr_t at, bool async)
virtual MemoryMappedObject * clone()=0
virtual void freePage(physical_uintptr_t page)=0
An iterator applicable for many data structures.
virtual void invalidate(uintptr_t at)
virtual bool trap(uintptr_t address, bool bWrite)
void removeHandler(MemoryPressureHandler *pHandler)
virtual bool remove(size_t length)
size_t remove(uintptr_t base, size_t length)
void registerHandler(size_t prio, MemoryPressureHandler *pHandler)
MemoryAllocator & getSpaceAllocator()
void untrackMapping(uintptr_t)