#ifndef SmallPage_h
#define SmallPage_h
#include "BAssert.h"
#include "List.h"
#include "Mutex.h"
#include "VMAllocate.h"
#include <mutex>
namespace bmalloc {
class SmallLine;
class SmallPage : public ListNode<SmallPage> {
public:
void ref(std::unique_lock<Mutex>&);
bool deref(std::unique_lock<Mutex>&);
unsigned refCount(std::unique_lock<Mutex>&) { return m_refCount; }
size_t sizeClass() { return m_sizeClass; }
void setSizeClass(size_t sizeClass) { m_sizeClass = sizeClass; }
bool hasFreeLines(std::unique_lock<Mutex>&) const { return m_hasFreeLines; }
void setHasFreeLines(std::unique_lock<Mutex>&, bool hasFreeLines) { m_hasFreeLines = hasFreeLines; }
bool hasPhysicalPages() { return m_hasPhysicalPages; }
void setHasPhysicalPages(bool hasPhysicalPages) { m_hasPhysicalPages = hasPhysicalPages; }
SmallLine* begin();
unsigned char slide() const { return m_slide; }
void setSlide(unsigned char slide) { m_slide = slide; }
private:
unsigned char m_hasFreeLines: 1;
unsigned char m_hasPhysicalPages: 1;
unsigned char m_refCount: 7;
unsigned char m_sizeClass;
unsigned char m_slide;
static_assert(
sizeClassCount <= std::numeric_limits<decltype(m_sizeClass)>::max(),
"Largest size class must fit in SmallPage metadata");
};
using LineCache = std::array<List<SmallPage>, sizeClassCount>;
inline void SmallPage::ref(std::unique_lock<Mutex>&)
{
BASSERT(!m_slide);
++m_refCount;
BASSERT(m_refCount);
}
inline bool SmallPage::deref(std::unique_lock<Mutex>&)
{
BASSERT(!m_slide);
BASSERT(m_refCount);
--m_refCount;
return !m_refCount;
}
}
#endif // SmallPage_h