#ifndef DFGAvailability_h
#define DFGAvailability_h
#if ENABLE(DFG_JIT)
#include "DFGFlushedAt.h"
#include "DFGVariableAccessData.h"
namespace JSC { namespace DFG {
struct Node;
class Availability {
public:
Availability()
: m_node(0)
, m_flushedAt(DeadFlush)
{
}
explicit Availability(Node* node)
: m_node(node)
, m_flushedAt(ConflictingFlush)
{
}
explicit Availability(FlushedAt flushedAt)
: m_node(unavailableMarker())
, m_flushedAt(flushedAt)
{
}
Availability(Node* node, FlushedAt flushedAt)
: m_node(node)
, m_flushedAt(flushedAt)
{
}
static Availability unavailable()
{
return Availability(unavailableMarker(), FlushedAt(ConflictingFlush));
}
Availability withFlush(FlushedAt flush) const
{
return Availability(m_node, flush);
}
Availability withNode(Node* node) const
{
return Availability(node, m_flushedAt);
}
Availability withUnavailableNode() const
{
return withNode(unavailableMarker());
}
void setFlush(FlushedAt flushedAt)
{
m_flushedAt = flushedAt;
}
void setNode(Node* node)
{
m_node = node;
}
void setNodeUnavailable()
{
m_node = unavailableMarker();
}
bool nodeIsUndecided() const { return !m_node; }
bool nodeIsUnavailable() const { return m_node == unavailableMarker(); }
bool hasNode() const { return !nodeIsUndecided() && !nodeIsUnavailable(); }
bool shouldUseNode() const { return !isFlushUseful() && hasNode(); }
Node* node() const
{
ASSERT(!nodeIsUndecided());
ASSERT(!nodeIsUnavailable());
return m_node;
}
FlushedAt flushedAt() const { return m_flushedAt; }
bool isFlushUseful() const
{
return flushedAt().format() != DeadFlush && flushedAt().format() != ConflictingFlush;
}
bool isDead() const { return !isFlushUseful() && !hasNode(); }
bool operator!() const { return nodeIsUnavailable() && flushedAt().format() == ConflictingFlush; }
bool operator==(const Availability& other) const
{
return m_node == other.m_node
&& m_flushedAt == other.m_flushedAt;
}
bool operator!=(const Availability& other) const
{
return !(*this == other);
}
Availability merge(const Availability& other) const
{
return Availability(
mergeNodes(m_node, other.m_node),
m_flushedAt.merge(other.m_flushedAt));
}
void dump(PrintStream&) const;
void dumpInContext(PrintStream&, DumpContext*) const;
private:
static Node* mergeNodes(Node* a, Node* b)
{
if (!a)
return b;
if (!b)
return a;
if (a == b)
return a;
return unavailableMarker();
}
static Node* unavailableMarker()
{
return bitwise_cast<Node*>(static_cast<intptr_t>(1));
}
Node* m_node;
FlushedAt m_flushedAt;
};
} }
#endif // ENABLE(DFG_JIT)
#endif // DFGAvailability_h