#ifndef CopiedAllocator_h
#define CopiedAllocator_h
#include "CopiedBlock.h"
namespace JSC {
class CopiedAllocator {
friend class JIT;
public:
CopiedAllocator();
void* allocate(size_t);
bool fitsInCurrentBlock(size_t);
bool wasLastAllocation(void*, size_t);
void startedCopying();
void resetCurrentBlock(CopiedBlock*);
size_t currentCapacity();
private:
CopiedBlock* currentBlock() { return m_currentBlock; }
char* m_currentOffset;
CopiedBlock* m_currentBlock;
};
inline CopiedAllocator::CopiedAllocator()
: m_currentOffset(0)
, m_currentBlock(0)
{
}
inline void* CopiedAllocator::allocate(size_t bytes)
{
ASSERT(m_currentOffset);
ASSERT(is8ByteAligned(reinterpret_cast<void*>(bytes)));
ASSERT(fitsInCurrentBlock(bytes));
void* ptr = static_cast<void*>(m_currentOffset);
m_currentOffset += bytes;
ASSERT(is8ByteAligned(ptr));
return ptr;
}
inline bool CopiedAllocator::fitsInCurrentBlock(size_t bytes)
{
return m_currentOffset + bytes < reinterpret_cast<char*>(m_currentBlock) + HeapBlock::s_blockSize && m_currentOffset + bytes > m_currentOffset;
}
inline bool CopiedAllocator::wasLastAllocation(void* ptr, size_t size)
{
return static_cast<char*>(ptr) + size == m_currentOffset && ptr > m_currentBlock && ptr < reinterpret_cast<char*>(m_currentBlock) + HeapBlock::s_blockSize;
}
inline void CopiedAllocator::startedCopying()
{
if (m_currentBlock)
m_currentBlock->m_offset = static_cast<void*>(m_currentOffset);
m_currentOffset = 0;
m_currentBlock = 0;
}
inline void CopiedAllocator::resetCurrentBlock(CopiedBlock* newBlock)
{
if (m_currentBlock)
m_currentBlock->m_offset = static_cast<void*>(m_currentOffset);
m_currentBlock = newBlock;
m_currentOffset = static_cast<char*>(newBlock->m_offset);
}
inline size_t CopiedAllocator::currentCapacity()
{
return m_currentBlock->capacity();
}
}
#endif