]> git.saurik.com Git - apple/javascriptcore.git/blob - dfg/DFGEdge.h
JavaScriptCore-1218.33.tar.gz
[apple/javascriptcore.git] / dfg / DFGEdge.h
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
26 #ifndef DFGEdge_h
27 #define DFGEdge_h
28
29 #include <wtf/Platform.h>
30
31 #if ENABLE(DFG_JIT)
32
33 #include "DFGCommon.h"
34 #include "DFGUseKind.h"
35
36 namespace JSC { namespace DFG {
37
38 class AdjacencyList;
39
40 class Edge {
41 public:
42 explicit Edge(Node* node = 0, UseKind useKind = UntypedUse, ProofStatus proofStatus = NeedsCheck)
43 #if USE(JSVALUE64)
44 : m_encodedWord(makeWord(node, useKind, proofStatus))
45 #else
46 : m_node(node)
47 , m_encodedWord(makeWord(useKind, proofStatus))
48 #endif
49 {
50 }
51
52 #if USE(JSVALUE64)
53 Node* node() const { return bitwise_cast<Node*>(m_encodedWord >> shift()); }
54 #else
55 Node* node() const { return m_node; }
56 #endif
57
58 Node& operator*() const { return *node(); }
59 Node* operator->() const { return node(); }
60
61 void setNode(Node* node)
62 {
63 #if USE(JSVALUE64)
64 m_encodedWord = makeWord(node, useKind(), proofStatus());
65 #else
66 m_node = node;
67 #endif
68 }
69
70 UseKind useKindUnchecked() const
71 {
72 #if USE(JSVALUE64)
73 unsigned masked = m_encodedWord & (((1 << shift()) - 1));
74 unsigned shifted = masked >> 1;
75 #else
76 unsigned shifted = static_cast<UseKind>(m_encodedWord) >> 1;
77 #endif
78 ASSERT(shifted < static_cast<unsigned>(LastUseKind));
79 UseKind result = static_cast<UseKind>(shifted);
80 ASSERT(node() || result == UntypedUse);
81 return result;
82 }
83 UseKind useKind() const
84 {
85 ASSERT(node());
86 return useKindUnchecked();
87 }
88 void setUseKind(UseKind useKind)
89 {
90 ASSERT(node());
91 #if USE(JSVALUE64)
92 m_encodedWord = makeWord(node(), useKind, proofStatus());
93 #else
94 m_encodedWord = makeWord(useKind, proofStatus());
95 #endif
96 }
97
98 ProofStatus proofStatusUnchecked() const
99 {
100 return proofStatusForIsProved(m_encodedWord & 1);
101 }
102 ProofStatus proofStatus() const
103 {
104 ASSERT(node());
105 return proofStatusUnchecked();
106 }
107 void setProofStatus(ProofStatus proofStatus)
108 {
109 ASSERT(node());
110 #if USE(JSVALUE64)
111 m_encodedWord = makeWord(node(), useKind(), proofStatus);
112 #else
113 m_encodedWord = makeWord(useKind(), proofStatus);
114 #endif
115 }
116 bool isProved() const
117 {
118 return proofStatus() == IsProved;
119 }
120 bool needsCheck() const
121 {
122 return proofStatus() == NeedsCheck;
123 }
124
125 bool isSet() const { return !!node(); }
126
127 typedef void* Edge::*UnspecifiedBoolType;
128 operator UnspecifiedBoolType*() const { return reinterpret_cast<UnspecifiedBoolType*>(isSet()); }
129
130 bool operator!() const { return !isSet(); }
131
132 bool operator==(Edge other) const
133 {
134 #if USE(JSVALUE64)
135 return m_encodedWord == other.m_encodedWord;
136 #else
137 return m_node == other.m_node && m_encodedWord == other.m_encodedWord;
138 #endif
139 }
140 bool operator!=(Edge other) const
141 {
142 return !(*this == other);
143 }
144
145 void dump(PrintStream&) const;
146
147 private:
148 friend class AdjacencyList;
149
150 #if USE(JSVALUE64)
151 static uint32_t shift() { return 6; }
152
153 static uintptr_t makeWord(Node* node, UseKind useKind, ProofStatus proofStatus)
154 {
155 ASSERT(sizeof(node) == 8);
156 uintptr_t shiftedValue = bitwise_cast<uintptr_t>(node) << shift();
157 ASSERT((shiftedValue >> shift()) == bitwise_cast<uintptr_t>(node));
158 ASSERT(useKind >= 0 && useKind < LastUseKind);
159 ASSERT((static_cast<uintptr_t>(LastUseKind) << 1) <= (static_cast<uintptr_t>(1) << shift()));
160 return shiftedValue | (static_cast<uintptr_t>(useKind) << 1) | DFG::isProved(proofStatus);
161 }
162
163 #else
164 static uintptr_t makeWord(UseKind useKind, ProofStatus proofStatus)
165 {
166 return (static_cast<uintptr_t>(useKind) << 1) | DFG::isProved(proofStatus);
167 }
168
169 Node* m_node;
170 #endif
171 // On 64-bit this holds both the pointer and the use kind, while on 32-bit
172 // this just holds the use kind. In both cases this may be hijacked by
173 // AdjacencyList for storing firstChild and numChildren.
174 uintptr_t m_encodedWord;
175 };
176
177 inline bool operator==(Edge edge, Node* node)
178 {
179 return edge.node() == node;
180 }
181 inline bool operator==(Node* node, Edge edge)
182 {
183 return edge.node() == node;
184 }
185 inline bool operator!=(Edge edge, Node* node)
186 {
187 return edge.node() != node;
188 }
189 inline bool operator!=(Node* node, Edge edge)
190 {
191 return edge.node() != node;
192 }
193
194 } } // namespace JSC::DFG
195
196 #endif // ENABLE(DFG_JIT)
197
198 #endif // DFGEdge_h
199