DFGEdge.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /*
  2. * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
  14. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
  17. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  18. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  19. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  20. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  21. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  23. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #ifndef DFGEdge_h
  26. #define DFGEdge_h
  27. #include <wtf/Platform.h>
  28. #if ENABLE(DFG_JIT)
  29. #include "DFGCommon.h"
  30. #include "DFGUseKind.h"
  31. namespace JSC { namespace DFG {
  32. class AdjacencyList;
  33. class Edge {
  34. public:
  35. explicit Edge(Node* node = 0, UseKind useKind = UntypedUse, ProofStatus proofStatus = NeedsCheck)
  36. #if USE(JSVALUE64)
  37. : m_encodedWord(makeWord(node, useKind, proofStatus))
  38. #else
  39. : m_node(node)
  40. , m_encodedWord(makeWord(useKind, proofStatus))
  41. #endif
  42. {
  43. }
  44. #if USE(JSVALUE64)
  45. Node* node() const { return bitwise_cast<Node*>(m_encodedWord >> shift()); }
  46. #else
  47. Node* node() const { return m_node; }
  48. #endif
  49. Node& operator*() const { return *node(); }
  50. Node* operator->() const { return node(); }
  51. void setNode(Node* node)
  52. {
  53. #if USE(JSVALUE64)
  54. m_encodedWord = makeWord(node, useKind(), proofStatus());
  55. #else
  56. m_node = node;
  57. #endif
  58. }
  59. UseKind useKindUnchecked() const
  60. {
  61. #if USE(JSVALUE64)
  62. unsigned masked = m_encodedWord & (((1 << shift()) - 1));
  63. unsigned shifted = masked >> 1;
  64. #else
  65. unsigned shifted = static_cast<UseKind>(m_encodedWord) >> 1;
  66. #endif
  67. ASSERT(shifted < static_cast<unsigned>(LastUseKind));
  68. UseKind result = static_cast<UseKind>(shifted);
  69. ASSERT(node() || result == UntypedUse);
  70. return result;
  71. }
  72. UseKind useKind() const
  73. {
  74. ASSERT(node());
  75. return useKindUnchecked();
  76. }
  77. void setUseKind(UseKind useKind)
  78. {
  79. ASSERT(node());
  80. #if USE(JSVALUE64)
  81. m_encodedWord = makeWord(node(), useKind, proofStatus());
  82. #else
  83. m_encodedWord = makeWord(useKind, proofStatus());
  84. #endif
  85. }
  86. ProofStatus proofStatusUnchecked() const
  87. {
  88. return proofStatusForIsProved(m_encodedWord & 1);
  89. }
  90. ProofStatus proofStatus() const
  91. {
  92. ASSERT(node());
  93. return proofStatusUnchecked();
  94. }
  95. void setProofStatus(ProofStatus proofStatus)
  96. {
  97. ASSERT(node());
  98. #if USE(JSVALUE64)
  99. m_encodedWord = makeWord(node(), useKind(), proofStatus);
  100. #else
  101. m_encodedWord = makeWord(useKind(), proofStatus);
  102. #endif
  103. }
  104. bool isProved() const
  105. {
  106. return proofStatus() == IsProved;
  107. }
  108. bool needsCheck() const
  109. {
  110. return proofStatus() == NeedsCheck;
  111. }
  112. bool isSet() const { return !!node(); }
  113. typedef void* Edge::*UnspecifiedBoolType;
  114. operator UnspecifiedBoolType*() const { return reinterpret_cast<UnspecifiedBoolType*>(isSet()); }
  115. bool operator!() const { return !isSet(); }
  116. bool operator==(Edge other) const
  117. {
  118. #if USE(JSVALUE64)
  119. return m_encodedWord == other.m_encodedWord;
  120. #else
  121. return m_node == other.m_node && m_encodedWord == other.m_encodedWord;
  122. #endif
  123. }
  124. bool operator!=(Edge other) const
  125. {
  126. return !(*this == other);
  127. }
  128. void dump(PrintStream&) const;
  129. private:
  130. friend class AdjacencyList;
  131. #if USE(JSVALUE64)
  132. static uint32_t shift() { return 6; }
  133. static uintptr_t makeWord(Node* node, UseKind useKind, ProofStatus proofStatus)
  134. {
  135. ASSERT(sizeof(node) == 8);
  136. uintptr_t shiftedValue = bitwise_cast<uintptr_t>(node) << shift();
  137. ASSERT((shiftedValue >> shift()) == bitwise_cast<uintptr_t>(node));
  138. ASSERT(useKind >= 0 && useKind < LastUseKind);
  139. ASSERT((static_cast<uintptr_t>(LastUseKind) << 1) <= (static_cast<uintptr_t>(1) << shift()));
  140. return shiftedValue | (static_cast<uintptr_t>(useKind) << 1) | DFG::isProved(proofStatus);
  141. }
  142. #else
  143. static uintptr_t makeWord(UseKind useKind, ProofStatus proofStatus)
  144. {
  145. return (static_cast<uintptr_t>(useKind) << 1) | DFG::isProved(proofStatus);
  146. }
  147. Node* m_node;
  148. #endif
  149. // On 64-bit this holds both the pointer and the use kind, while on 32-bit
  150. // this just holds the use kind. In both cases this may be hijacked by
  151. // AdjacencyList for storing firstChild and numChildren.
  152. uintptr_t m_encodedWord;
  153. };
  154. inline bool operator==(Edge edge, Node* node)
  155. {
  156. return edge.node() == node;
  157. }
  158. inline bool operator==(Node* node, Edge edge)
  159. {
  160. return edge.node() == node;
  161. }
  162. inline bool operator!=(Edge edge, Node* node)
  163. {
  164. return edge.node() != node;
  165. }
  166. inline bool operator!=(Node* node, Edge edge)
  167. {
  168. return edge.node() != node;
  169. }
  170. } } // namespace JSC::DFG
  171. #endif // ENABLE(DFG_JIT)
  172. #endif // DFGEdge_h