#ifndef AllocationSpace_h
#define AllocationSpace_h
#include "MarkedBlockSet.h"
#include "MarkedSpace.h"
#include <wtf/HashSet.h>
namespace JSC {
class Heap;
class MarkedBlock;
class AllocationSpace {
public:
AllocationSpace(Heap* heap)
: m_heap(heap)
, m_markedSpace(heap)
{
}
typedef HashSet<MarkedBlock*>::iterator BlockIterator;
MarkedBlockSet& blocks() { return m_blocks; }
MarkedSpace::SizeClass& sizeClassFor(size_t bytes) { return m_markedSpace.sizeClassFor(bytes); }
void setHighWaterMark(size_t bytes) { m_markedSpace.setHighWaterMark(bytes); }
size_t highWaterMark() { return m_markedSpace.highWaterMark(); }
#if ENABLE(GGC)
void gatherDirtyCells(MarkedBlock::DirtyCellVector&);
#endif
template<typename Functor> typename Functor::ReturnType forEachCell(Functor&);
template<typename Functor> typename Functor::ReturnType forEachCell();
template<typename Functor> typename Functor::ReturnType forEachBlock(Functor&);
template<typename Functor> typename Functor::ReturnType forEachBlock();
void canonicalizeCellLivenessData() { m_markedSpace.canonicalizeCellLivenessData(); }
void resetAllocator() { m_markedSpace.resetAllocator(); }
void* allocate(size_t);
void freeBlocks(MarkedBlock*);
void shrink();
private:
enum AllocationEffort { AllocationMustSucceed, AllocationCanFail };
void* allocate(MarkedSpace::SizeClass&);
void* tryAllocate(MarkedSpace::SizeClass&);
void* allocateSlowCase(MarkedSpace::SizeClass&);
MarkedBlock* allocateBlock(size_t cellSize, AllocationEffort);
Heap* m_heap;
MarkedSpace m_markedSpace;
MarkedBlockSet m_blocks;
};
template<typename Functor> inline typename Functor::ReturnType AllocationSpace::forEachCell(Functor& functor)
{
canonicalizeCellLivenessData();
BlockIterator end = m_blocks.set().end();
for (BlockIterator it = m_blocks.set().begin(); it != end; ++it)
(*it)->forEachCell(functor);
return functor.returnValue();
}
template<typename Functor> inline typename Functor::ReturnType AllocationSpace::forEachCell()
{
Functor functor;
return forEachCell(functor);
}
template<typename Functor> inline typename Functor::ReturnType AllocationSpace::forEachBlock(Functor& functor)
{
BlockIterator end = m_blocks.set().end();
for (BlockIterator it = m_blocks.set().begin(); it != end; ++it)
functor(*it);
return functor.returnValue();
}
template<typename Functor> inline typename Functor::ReturnType AllocationSpace::forEachBlock()
{
Functor functor;
return forEachBlock(functor);
}
inline void* AllocationSpace::allocate(MarkedSpace::SizeClass& sizeClass)
{
MarkedBlock::FreeCell* firstFreeCell = sizeClass.firstFreeCell;
if (UNLIKELY(!firstFreeCell))
return allocateSlowCase(sizeClass);
sizeClass.firstFreeCell = firstFreeCell->next;
return firstFreeCell;
}
inline void* AllocationSpace::allocate(size_t bytes)
{
MarkedSpace::SizeClass& sizeClass = sizeClassFor(bytes);
return allocate(sizeClass);
}
}
#endif