DFGGenerationInfo.h [plain text]
#ifndef DFGGenerationInfo_h
#define DFGGenerationInfo_h
#if ENABLE(DFG_JIT)
#include "DataFormat.h"
#include <dfg/DFGJITCompiler.h>
namespace JSC { namespace DFG {
class GenerationInfo {
public:
GenerationInfo()
: m_nodeIndex(NoNode)
, m_useCount(0)
, m_registerFormat(DataFormatNone)
, m_spillFormat(DataFormatNone)
, m_canFill(false)
{
}
void initConstant(NodeIndex nodeIndex, uint32_t useCount)
{
m_nodeIndex = nodeIndex;
m_useCount = useCount;
m_registerFormat = DataFormatNone;
m_spillFormat = DataFormatNone;
m_canFill = true;
ASSERT(m_useCount);
}
void initInteger(NodeIndex nodeIndex, uint32_t useCount, GPRReg gpr)
{
m_nodeIndex = nodeIndex;
m_useCount = useCount;
m_registerFormat = DataFormatInteger;
m_spillFormat = DataFormatNone;
m_canFill = false;
u.gpr = gpr;
ASSERT(m_useCount);
}
#if USE(JSVALUE64)
void initJSValue(NodeIndex nodeIndex, uint32_t useCount, GPRReg gpr, DataFormat format = DataFormatJS)
{
ASSERT(format & DataFormatJS);
m_nodeIndex = nodeIndex;
m_useCount = useCount;
m_registerFormat = format;
m_spillFormat = DataFormatNone;
m_canFill = false;
u.gpr = gpr;
ASSERT(m_useCount);
}
#elif USE(JSVALUE32_64)
void initJSValue(NodeIndex nodeIndex, uint32_t useCount, GPRReg tagGPR, GPRReg payloadGPR, DataFormat format = DataFormatJS)
{
ASSERT(format & DataFormatJS);
m_nodeIndex = nodeIndex;
m_useCount = useCount;
m_registerFormat = format;
m_spillFormat = DataFormatNone;
m_canFill = false;
u.v.tagGPR = tagGPR;
u.v.payloadGPR = payloadGPR;
ASSERT(m_useCount);
}
#endif
void initCell(NodeIndex nodeIndex, uint32_t useCount, GPRReg gpr)
{
m_nodeIndex = nodeIndex;
m_useCount = useCount;
m_registerFormat = DataFormatCell;
m_spillFormat = DataFormatNone;
m_canFill = false;
u.gpr = gpr;
ASSERT(m_useCount);
}
void initBoolean(NodeIndex nodeIndex, uint32_t useCount, GPRReg gpr)
{
m_nodeIndex = nodeIndex;
m_useCount = useCount;
m_registerFormat = DataFormatBoolean;
m_spillFormat = DataFormatNone;
m_canFill = false;
u.gpr = gpr;
ASSERT(m_useCount);
}
void initDouble(NodeIndex nodeIndex, uint32_t useCount, FPRReg fpr)
{
ASSERT(fpr != InvalidFPRReg);
m_nodeIndex = nodeIndex;
m_useCount = useCount;
m_registerFormat = DataFormatDouble;
m_spillFormat = DataFormatNone;
m_canFill = false;
u.fpr = fpr;
ASSERT(m_useCount);
}
void initStorage(NodeIndex nodeIndex, uint32_t useCount, GPRReg gpr)
{
m_nodeIndex = nodeIndex;
m_useCount = useCount;
m_registerFormat = DataFormatStorage;
m_spillFormat = DataFormatNone;
m_canFill = false;
u.gpr = gpr;
ASSERT(m_useCount);
}
NodeIndex nodeIndex() { return m_nodeIndex; }
bool use()
{
ASSERT(m_useCount);
return !--m_useCount;
}
bool canReuse()
{
ASSERT(m_useCount);
return m_useCount == 1;
}
DataFormat registerFormat() { return m_registerFormat; }
DataFormat spillFormat() { return m_spillFormat; }
bool isJSFormat(DataFormat expectedFormat)
{
return JSC::isJSFormat(registerFormat(), expectedFormat) || JSC::isJSFormat(spillFormat(), expectedFormat);
}
bool isJSInteger()
{
return isJSFormat(DataFormatJSInteger);
}
bool isJSDouble()
{
return isJSFormat(DataFormatJSDouble);
}
bool isJSCell()
{
return isJSFormat(DataFormatJSCell);
}
bool isJSBoolean()
{
return isJSFormat(DataFormatJSBoolean);
}
bool isUnknownJS()
{
return spillFormat() == DataFormatNone
? registerFormat() == DataFormatJS || registerFormat() == DataFormatNone
: spillFormat() == DataFormatJS;
}
#if USE(JSVALUE64)
GPRReg gpr() { ASSERT(m_registerFormat && m_registerFormat != DataFormatDouble); return u.gpr; }
FPRReg fpr() { ASSERT(m_registerFormat == DataFormatDouble); return u.fpr; }
JSValueRegs jsValueRegs() { ASSERT(m_registerFormat & DataFormatJS); return JSValueRegs(u.gpr); }
#elif USE(JSVALUE32_64)
GPRReg gpr() { ASSERT(!(m_registerFormat & DataFormatJS) && m_registerFormat != DataFormatDouble); return u.gpr; }
GPRReg tagGPR() { ASSERT(m_registerFormat & DataFormatJS); return u.v.tagGPR; }
GPRReg payloadGPR() { ASSERT(m_registerFormat & DataFormatJS); return u.v.payloadGPR; }
FPRReg fpr() { ASSERT(m_registerFormat == DataFormatDouble || m_registerFormat == DataFormatJSDouble); return u.fpr; }
JSValueRegs jsValueRegs() { ASSERT(m_registerFormat & DataFormatJS); return JSValueRegs(u.v.tagGPR, u.v.payloadGPR); }
#endif
bool needsSpill()
{
ASSERT(m_registerFormat != DataFormatNone);
return !m_canFill;
}
void spill(DataFormat spillFormat)
{
ASSERT(!m_canFill);
ASSERT(m_spillFormat == DataFormatNone);
ASSERT(m_registerFormat != DataFormatNone);
m_registerFormat = DataFormatNone;
m_spillFormat = spillFormat;
m_canFill = true;
}
void setSpilled()
{
ASSERT(m_canFill && m_registerFormat != DataFormatNone);
m_registerFormat = DataFormatNone;
}
void killSpilled()
{
m_spillFormat = DataFormatNone;
m_canFill = false;
}
#if USE(JSVALUE64)
void fillJSValue(GPRReg gpr, DataFormat format = DataFormatJS)
{
ASSERT(format & DataFormatJS);
m_registerFormat = format;
u.gpr = gpr;
}
#elif USE(JSVALUE32_64)
void fillJSValue(GPRReg tagGPR, GPRReg payloadGPR, DataFormat format = DataFormatJS)
{
ASSERT(format & DataFormatJS);
m_registerFormat = format;
u.v.tagGPR = tagGPR; u.v.payloadGPR = payloadGPR;
}
void fillCell(GPRReg gpr)
{
m_registerFormat = DataFormatCell;
u.gpr = gpr;
}
#endif
void fillInteger(GPRReg gpr)
{
m_registerFormat = DataFormatInteger;
u.gpr = gpr;
}
void fillBoolean(GPRReg gpr)
{
m_registerFormat = DataFormatBoolean;
u.gpr = gpr;
}
void fillDouble(FPRReg fpr)
{
ASSERT(fpr != InvalidFPRReg);
m_registerFormat = DataFormatDouble;
u.fpr = fpr;
}
void fillStorage(GPRReg gpr)
{
m_registerFormat = DataFormatStorage;
u.gpr = gpr;
}
bool alive()
{
return m_useCount;
}
private:
NodeIndex m_nodeIndex;
uint32_t m_useCount;
DataFormat m_registerFormat;
DataFormat m_spillFormat;
bool m_canFill;
union {
GPRReg gpr;
FPRReg fpr;
#if USE(JSVALUE32_64)
struct {
GPRReg tagGPR;
GPRReg payloadGPR;
} v;
#endif
} u;
};
} }
#endif
#endif