#ifndef RegisterFile_h
#define RegisterFile_h
#include "ExecutableAllocator.h"
#include "Register.h"
#include <wtf/Noncopyable.h>
#include <wtf/PageReservation.h>
#include <wtf/VMTags.h>
namespace JSC {
class ConservativeRoots;
class DFGCodeBlocks;
class LLIntOffsetsExtractor;
class RegisterFile {
WTF_MAKE_NONCOPYABLE(RegisterFile);
public:
enum CallFrameHeaderEntry {
CallFrameHeaderSize = 6,
ArgumentCount = -6,
CallerFrame = -5,
Callee = -4,
ScopeChain = -3,
ReturnPC = -2, CodeBlock = -1,
};
static const size_t defaultCapacity = 512 * 1024;
static const size_t commitSize = 16 * 1024;
static const ptrdiff_t maxExcessCapacity = 8 * 1024;
RegisterFile(size_t capacity = defaultCapacity);
~RegisterFile();
void gatherConservativeRoots(ConservativeRoots&);
void gatherConservativeRoots(ConservativeRoots&, DFGCodeBlocks&);
Register* begin() const { return static_cast<Register*>(m_reservation.base()); }
Register* end() const { return m_end; }
size_t size() const { return end() - begin(); }
bool grow(Register*);
void shrink(Register*);
static size_t committedByteCount();
static void initializeThreading();
Register* const * addressOfEnd() const
{
return &m_end;
}
private:
friend class LLIntOffsetsExtractor;
bool growSlowCase(Register*);
void releaseExcessCapacity();
void addToCommittedByteCount(long);
Register* m_end;
Register* m_commitEnd;
PageReservation m_reservation;
};
inline RegisterFile::RegisterFile(size_t capacity)
: m_end(0)
{
ASSERT(capacity && isPageAligned(capacity));
m_reservation = PageReservation::reserve(roundUpAllocationSize(capacity * sizeof(Register), commitSize), OSAllocator::JSVMStackPages);
m_end = static_cast<Register*>(m_reservation.base());
m_commitEnd = static_cast<Register*>(m_reservation.base());
}
inline void RegisterFile::shrink(Register* newEnd)
{
if (newEnd >= m_end)
return;
m_end = newEnd;
if (m_end == m_reservation.base() && (m_commitEnd - begin()) >= maxExcessCapacity)
releaseExcessCapacity();
}
inline bool RegisterFile::grow(Register* newEnd)
{
if (newEnd <= m_end)
return true;
return growSlowCase(newEnd);
}
}
#endif // RegisterFile_h