/*
- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#ifndef DFGEdge_h
#define DFGEdge_h
-#include <wtf/Platform.h>
-
#if ENABLE(DFG_JIT)
#include "DFGCommon.h"
class Edge {
public:
- explicit Edge(Node* node = 0, UseKind useKind = UntypedUse, ProofStatus proofStatus = NeedsCheck)
+ explicit Edge(Node* node = 0, UseKind useKind = UntypedUse, ProofStatus proofStatus = NeedsCheck, KillStatus killStatus = DoesNotKill)
#if USE(JSVALUE64)
- : m_encodedWord(makeWord(node, useKind, proofStatus))
+ : m_encodedWord(makeWord(node, useKind, proofStatus, killStatus))
#else
: m_node(node)
- , m_encodedWord(makeWord(useKind, proofStatus))
+ , m_encodedWord(makeWord(useKind, proofStatus, killStatus))
#endif
{
}
void setNode(Node* node)
{
#if USE(JSVALUE64)
- m_encodedWord = makeWord(node, useKind(), proofStatus());
+ m_encodedWord = makeWord(node, useKind(), proofStatus(), killStatus());
#else
m_node = node;
#endif
{
#if USE(JSVALUE64)
unsigned masked = m_encodedWord & (((1 << shift()) - 1));
- unsigned shifted = masked >> 1;
+ unsigned shifted = masked >> 2;
#else
- unsigned shifted = static_cast<UseKind>(m_encodedWord) >> 1;
+ unsigned shifted = static_cast<UseKind>(m_encodedWord) >> 2;
#endif
ASSERT(shifted < static_cast<unsigned>(LastUseKind));
UseKind result = static_cast<UseKind>(shifted);
{
ASSERT(node());
#if USE(JSVALUE64)
- m_encodedWord = makeWord(node(), useKind, proofStatus());
+ m_encodedWord = makeWord(node(), useKind, proofStatus(), killStatus());
#else
- m_encodedWord = makeWord(useKind, proofStatus());
+ m_encodedWord = makeWord(useKind, proofStatus(), killStatus());
#endif
}
{
ASSERT(node());
#if USE(JSVALUE64)
- m_encodedWord = makeWord(node(), useKind(), proofStatus);
+ m_encodedWord = makeWord(node(), useKind(), proofStatus, killStatus());
#else
- m_encodedWord = makeWord(useKind(), proofStatus);
+ m_encodedWord = makeWord(useKind(), proofStatus, killStatus());
#endif
}
bool isProved() const
return proofStatus() == NeedsCheck;
}
+ bool willNotHaveCheck() const
+ {
+ return isProved() || shouldNotHaveTypeCheck(useKind());
+ }
+ bool willHaveCheck() const
+ {
+ return !willNotHaveCheck();
+ }
+
+ KillStatus killStatusUnchecked() const
+ {
+ return killStatusForDoesKill(m_encodedWord & 2);
+ }
+ KillStatus killStatus() const
+ {
+ ASSERT(node());
+ return killStatusUnchecked();
+ }
+ void setKillStatus(KillStatus killStatus)
+ {
+ ASSERT(node());
+#if USE(JSVALUE64)
+ m_encodedWord = makeWord(node(), useKind(), proofStatus(), killStatus);
+#else
+ m_encodedWord = makeWord(useKind(), proofStatus(), killStatus);
+#endif
+ }
+ bool doesKill() const { return DFG::doesKill(killStatus()); }
+ bool doesNotKill() const { return !doesKill(); }
+
bool isSet() const { return !!node(); }
+
+ Edge sanitized() const
+ {
+ Edge result = *this;
+#if USE(JSVALUE64)
+ result.m_encodedWord = makeWord(node(), useKindUnchecked(), NeedsCheck, DoesNotKill);
+#else
+ result.m_encodedWord = makeWord(useKindUnchecked(), NeedsCheck, DoesNotKill);
+#endif
+ return result;
+ }
typedef void* Edge::*UnspecifiedBoolType;
operator UnspecifiedBoolType*() const { return reinterpret_cast<UnspecifiedBoolType*>(isSet()); }
}
void dump(PrintStream&) const;
+
+ unsigned hash() const
+ {
+#if USE(JSVALUE64)
+ return IntHash<uintptr_t>::hash(m_encodedWord);
+#else
+ return PtrHash<Node*>::hash(m_node) + m_encodedWord;
+#endif
+ }
private:
friend class AdjacencyList;
#if USE(JSVALUE64)
- static uint32_t shift() { return 6; }
+ static uint32_t shift() { return 7; }
- static uintptr_t makeWord(Node* node, UseKind useKind, ProofStatus proofStatus)
+ static uintptr_t makeWord(Node* node, UseKind useKind, ProofStatus proofStatus, KillStatus killStatus)
{
ASSERT(sizeof(node) == 8);
uintptr_t shiftedValue = bitwise_cast<uintptr_t>(node) << shift();
ASSERT((shiftedValue >> shift()) == bitwise_cast<uintptr_t>(node));
ASSERT(useKind >= 0 && useKind < LastUseKind);
- ASSERT((static_cast<uintptr_t>(LastUseKind) << 1) <= (static_cast<uintptr_t>(1) << shift()));
- return shiftedValue | (static_cast<uintptr_t>(useKind) << 1) | DFG::isProved(proofStatus);
+ ASSERT((static_cast<uintptr_t>(LastUseKind) << 2) <= (static_cast<uintptr_t>(2) << shift()));
+ return shiftedValue | (static_cast<uintptr_t>(useKind) << 2) | (DFG::doesKill(killStatus) << 1) | DFG::isProved(proofStatus);
}
#else
- static uintptr_t makeWord(UseKind useKind, ProofStatus proofStatus)
+ static uintptr_t makeWord(UseKind useKind, ProofStatus proofStatus, KillStatus killStatus)
{
- return (static_cast<uintptr_t>(useKind) << 1) | DFG::isProved(proofStatus);
+ return (static_cast<uintptr_t>(useKind) << 2) | (DFG::doesKill(killStatus) << 1) | DFG::isProved(proofStatus);
}
Node* m_node;