20 #ifdef SLAM_USE_DEBUG_ALLOCATOR 22 #include "pedigree/kernel/LockGuard.h" 23 #include "pedigree/kernel/core/SlamAllocator.h" 24 #include "pedigree/kernel/processor/PhysicalMemoryManager.h" 25 #include "pedigree/kernel/processor/Processor.h" 26 #include "pedigree/kernel/processor/VirtualAddressSpace.h" 27 #include "pedigree/kernel/utilities/MemoryTracing.h" 28 #include "pedigree/kernel/utilities/assert.h" 31 #include "pedigree/kernel/process/Process.h" 32 #include "pedigree/kernel/process/Thread.h" 37 inline uintptr_t getHeapBase()
42 inline uintptr_t getHeapEnd()
47 inline size_t getPageSize()
52 inline void allocateAndMapAt(
void *addr)
54 size_t standardFlags =
57 static physical_uintptr_t physZero = 0;
62 if (!va.
map(phys, addr, standardFlags))
64 FATAL(
"SlamAllocator: failed to allocate and map at " << addr);
68 inline void unmap(
void *addr)
74 physical_uintptr_t phys;
82 inline bool isMapped(
void *addr)
88 inline void markReadOnly(
void *addr)
95 : m_PartialLists(), m_ObjectSize(0), m_SlabSize(0), m_FirstSlab()
120 void SlamCache::push(
138 bool SlamCache::isPointerValid(uintptr_t
object)
const 144 uintptr_t SlamCache::getSlab()
150 void SlamCache::freeSlab(uintptr_t slab)
167 #if CRIPPLINGLY_VIGILANT 168 void SlamCache::check()
173 void SlamCache::trackSlab(uintptr_t slab)
179 SlamAllocator::SlamAllocator()
180 : m_bInitialised(false), m_bVigilant(false),
182 m_SlabRegionLock(false),
184 m_HeapPageCount(0), m_SlabRegionBitmap(), m_SlabRegionBitmapEntries(0),
189 SlamAllocator::~SlamAllocator()
197 void SlamAllocator::initialise()
206 m_Base = getHeapBase();
207 m_bInitialised =
true;
215 uintptr_t SlamAllocator::getSlab(
size_t fullSize)
221 void SlamAllocator::freeSlab(uintptr_t address,
size_t length)
226 size_t SlamAllocator::recovery(
size_t maxSlabs)
244 uintptr_t mapStart = 0, mapEnd = 0, result = 0;
245 size_t nTotalBytes = 0, numPages = 0;
247 numPages = nBytes / getPageSize();
248 if (nBytes % getPageSize())
256 nTotalBytes = numPages * getPageSize();
261 m_Base += getPageSize();
263 m_Base += getPageSize();
266 m_Base += numPages * getPageSize();
270 for (uintptr_t addr = mapStart; addr < mapEnd; addr += getPageSize())
272 allocateAndMapAt(reinterpret_cast<void *>(addr));
277 *((
size_t *) (result -
sizeof(
size_t))) = numPages;
280 markReadOnly(reinterpret_cast<void *>(mapStart));
288 pThread->
getParent()->trackHeap(nTotalBytes);
293 #ifdef MEMORY_TRACING 295 reinterpret_cast<void *>(result), MemoryTracing::Allocation,
302 size_t SlamAllocator::allocSize(uintptr_t
mem)
314 return *((
size_t *) (mem -
sizeof(
size_t))) * getPageSize();
317 void SlamAllocator::free(uintptr_t mem)
326 #ifdef MEMORY_TRACING 330 traceAllocation(reinterpret_cast<void *>(mem), MemoryTracing::Free, 0);
333 assert(isMapped(reinterpret_cast<void *>(mem)));
335 if (!isPointerValid(mem))
340 size_t numPages = *((
size_t *) (mem -
sizeof(
size_t)));
341 size_t nBytes = numPages * getPageSize();
343 uintptr_t unmapStart = mem - getPageSize();
344 uintptr_t unmapEnd = mem + nBytes;
346 for (uintptr_t addr = unmapStart; addr < unmapEnd; addr += getPageSize())
348 unmap(reinterpret_cast<void *>(addr));
359 pThread->
getParent()->trackHeap(-nBytes);
364 #ifdef MEMORY_TRACING 365 traceAllocation(reinterpret_cast<void *>(mem), MemoryTracing::Free, 0);
369 bool SlamAllocator::isPointerValid(uintptr_t mem)
381 reinterpret_cast<void *>(mem)))
383 #if VERBOSE_ISPOINTERVALID 385 "SlamAllocator::isPointerValid: memory " 386 <<
Hex << mem <<
" is not in the heap region.");
391 if (!isMapped(reinterpret_cast<void *>(mem)))
393 #if VERBOSE_ISPOINTERVALID 395 "SlamAllocator::isPointerValid: memory " 396 <<
Hex << mem <<
" is not mapped [current base = " <<
Hex << m_Base
401 #if VERBOSE_ISPOINTERVALID 402 WARNING(
" (pointer being deleted is beyond the end of the heap " 412 bool SlamAllocator::isWithinHeap(uintptr_t mem)
const 415 reinterpret_cast<void *>(mem)))
417 #if VERBOSE_ISPOINTERVALID 419 "SlamAllocator::isWithinHeap: memory " 420 <<
Hex << mem <<
" is not in the heap region.");
428 bool _assert_ptr_valid(uintptr_t ptr)
430 return SlamAllocator::instance().isPointerValid(ptr);
433 #endif // defined(SLAM_USE_DEBUG_ALLOCATOR) virtual void unmap(void *virtualAddress)=0
static size_t getPageSize() PURE
uintptr_t allocate(size_t nBytes)
static PhysicalMemoryManager & instance()
static EXPORTED_PUBLIC SlamAllocator m_Instance
virtual void getMapping(void *virtualAddress, physical_uintptr_t &physicalAddress, size_t &flags)=0
void free(uintptr_t object)
virtual void setFlags(void *virtualAddress, size_t newFlags)=0
virtual uintptr_t getKernelHeapEnd() const =0
virtual physical_uintptr_t allocatePage(size_t pageConstraints=0)=0
virtual bool isMapped(void *virtualAddress)=0
virtual bool map(physical_uintptr_t physicalAddress, void *virtualAddress, size_t flags)=0
static EXPORTED_PUBLIC VirtualAddressSpace & getKernelAddressSpace()
static ProcessorInformation & information()
static size_t m_Initialised
static const size_t Write
static const size_t KernelMode
size_t recovery(size_t maxSlabs)
virtual uintptr_t getKernelHeapStart() const =0
Process * getParent() const
void initialise(SlamAllocator *parent, size_t objectSize)
virtual void freePage(physical_uintptr_t page)=0