]> git.saurik.com Git - apple/javascriptcore.git/blame - dfg/DFGEdge.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / dfg / DFGEdge.h
CommitLineData
6fe7ccc8 1/*
81345200 2 * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
6fe7ccc8
A
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
6fe7ccc8
A
29#if ENABLE(DFG_JIT)
30
31#include "DFGCommon.h"
93a37866 32#include "DFGUseKind.h"
6fe7ccc8
A
33
34namespace JSC { namespace DFG {
35
36class AdjacencyList;
37
38class Edge {
39public:
81345200 40 explicit Edge(Node* node = 0, UseKind useKind = UntypedUse, ProofStatus proofStatus = NeedsCheck, KillStatus killStatus = DoesNotKill)
93a37866 41#if USE(JSVALUE64)
81345200 42 : m_encodedWord(makeWord(node, useKind, proofStatus, killStatus))
93a37866
A
43#else
44 : m_node(node)
81345200 45 , m_encodedWord(makeWord(useKind, proofStatus, killStatus))
93a37866 46#endif
6fe7ccc8
A
47 {
48 }
49
93a37866
A
50#if USE(JSVALUE64)
51 Node* node() const { return bitwise_cast<Node*>(m_encodedWord >> shift()); }
52#else
53 Node* node() const { return m_node; }
54#endif
55
56 Node& operator*() const { return *node(); }
57 Node* operator->() const { return node(); }
58
59 void setNode(Node* node)
6fe7ccc8 60 {
93a37866 61#if USE(JSVALUE64)
81345200 62 m_encodedWord = makeWord(node, useKind(), proofStatus(), killStatus());
93a37866
A
63#else
64 m_node = node;
65#endif
6fe7ccc8
A
66 }
67
93a37866 68 UseKind useKindUnchecked() const
6fe7ccc8 69 {
93a37866
A
70#if USE(JSVALUE64)
71 unsigned masked = m_encodedWord & (((1 << shift()) - 1));
81345200 72 unsigned shifted = masked >> 2;
93a37866 73#else
81345200 74 unsigned shifted = static_cast<UseKind>(m_encodedWord) >> 2;
93a37866
A
75#endif
76 ASSERT(shifted < static_cast<unsigned>(LastUseKind));
77 UseKind result = static_cast<UseKind>(shifted);
78 ASSERT(node() || result == UntypedUse);
79 return result;
6fe7ccc8 80 }
93a37866 81 UseKind useKind() const
6fe7ccc8 82 {
93a37866
A
83 ASSERT(node());
84 return useKindUnchecked();
6fe7ccc8 85 }
93a37866 86 void setUseKind(UseKind useKind)
6fe7ccc8 87 {
93a37866
A
88 ASSERT(node());
89#if USE(JSVALUE64)
81345200 90 m_encodedWord = makeWord(node(), useKind, proofStatus(), killStatus());
93a37866 91#else
81345200 92 m_encodedWord = makeWord(useKind, proofStatus(), killStatus());
93a37866 93#endif
6fe7ccc8
A
94 }
95
93a37866 96 ProofStatus proofStatusUnchecked() const
6fe7ccc8 97 {
93a37866 98 return proofStatusForIsProved(m_encodedWord & 1);
6fe7ccc8 99 }
93a37866
A
100 ProofStatus proofStatus() const
101 {
102 ASSERT(node());
103 return proofStatusUnchecked();
104 }
105 void setProofStatus(ProofStatus proofStatus)
6fe7ccc8 106 {
93a37866
A
107 ASSERT(node());
108#if USE(JSVALUE64)
81345200 109 m_encodedWord = makeWord(node(), useKind(), proofStatus, killStatus());
93a37866 110#else
81345200 111 m_encodedWord = makeWord(useKind(), proofStatus, killStatus());
93a37866 112#endif
6fe7ccc8 113 }
93a37866
A
114 bool isProved() const
115 {
116 return proofStatus() == IsProved;
117 }
93a37866 118
81345200
A
119 bool willNotHaveCheck() const
120 {
121 return isProved() || shouldNotHaveTypeCheck(useKind());
122 }
123 bool willHaveCheck() const
124 {
125 return !willNotHaveCheck();
126 }
127
128 KillStatus killStatusUnchecked() const
129 {
130 return killStatusForDoesKill(m_encodedWord & 2);
131 }
132 KillStatus killStatus() const
133 {
134 ASSERT(node());
135 return killStatusUnchecked();
136 }
137 void setKillStatus(KillStatus killStatus)
138 {
139 ASSERT(node());
140#if USE(JSVALUE64)
141 m_encodedWord = makeWord(node(), useKind(), proofStatus(), killStatus);
142#else
143 m_encodedWord = makeWord(useKind(), proofStatus(), killStatus);
144#endif
145 }
146 bool doesKill() const { return DFG::doesKill(killStatus()); }
147 bool doesNotKill() const { return !doesKill(); }
148
93a37866 149 bool isSet() const { return !!node(); }
81345200
A
150
151 Edge sanitized() const
152 {
153 Edge result = *this;
154#if USE(JSVALUE64)
155 result.m_encodedWord = makeWord(node(), useKindUnchecked(), NeedsCheck, DoesNotKill);
156#else
157 result.m_encodedWord = makeWord(useKindUnchecked(), NeedsCheck, DoesNotKill);
158#endif
159 return result;
160 }
93a37866
A
161
162 typedef void* Edge::*UnspecifiedBoolType;
163 operator UnspecifiedBoolType*() const { return reinterpret_cast<UnspecifiedBoolType*>(isSet()); }
6fe7ccc8 164
6fe7ccc8
A
165 bool operator!() const { return !isSet(); }
166
167 bool operator==(Edge other) const
168 {
93a37866 169#if USE(JSVALUE64)
6fe7ccc8 170 return m_encodedWord == other.m_encodedWord;
93a37866
A
171#else
172 return m_node == other.m_node && m_encodedWord == other.m_encodedWord;
173#endif
6fe7ccc8
A
174 }
175 bool operator!=(Edge other) const
176 {
93a37866 177 return !(*this == other);
6fe7ccc8 178 }
93a37866
A
179
180 void dump(PrintStream&) const;
81345200
A
181
182 unsigned hash() const
183 {
184#if USE(JSVALUE64)
185 return IntHash<uintptr_t>::hash(m_encodedWord);
186#else
187 return PtrHash<Node*>::hash(m_node) + m_encodedWord;
188#endif
189 }
6fe7ccc8
A
190
191private:
192 friend class AdjacencyList;
193
93a37866 194#if USE(JSVALUE64)
81345200 195 static uint32_t shift() { return 7; }
6fe7ccc8 196
81345200 197 static uintptr_t makeWord(Node* node, UseKind useKind, ProofStatus proofStatus, KillStatus killStatus)
6fe7ccc8 198 {
93a37866
A
199 ASSERT(sizeof(node) == 8);
200 uintptr_t shiftedValue = bitwise_cast<uintptr_t>(node) << shift();
201 ASSERT((shiftedValue >> shift()) == bitwise_cast<uintptr_t>(node));
6fe7ccc8 202 ASSERT(useKind >= 0 && useKind < LastUseKind);
81345200 203 ASSERT((static_cast<uintptr_t>(LastUseKind) << 2) <= (static_cast<uintptr_t>(2) << shift()));
ed1e77d3 204 return shiftedValue | (static_cast<uintptr_t>(useKind) << 2) | (DFG::doesKill(killStatus) << 1) | static_cast<uintptr_t>(DFG::isProved(proofStatus));
93a37866
A
205 }
206
207#else
81345200 208 static uintptr_t makeWord(UseKind useKind, ProofStatus proofStatus, KillStatus killStatus)
93a37866 209 {
ed1e77d3 210 return (static_cast<uintptr_t>(useKind) << 2) | (DFG::doesKill(killStatus) << 1) | static_cast<uintptr_t>(DFG::isProved(proofStatus));
6fe7ccc8
A
211 }
212
93a37866
A
213 Node* m_node;
214#endif
215 // On 64-bit this holds both the pointer and the use kind, while on 32-bit
216 // this just holds the use kind. In both cases this may be hijacked by
217 // AdjacencyList for storing firstChild and numChildren.
218 uintptr_t m_encodedWord;
6fe7ccc8
A
219};
220
93a37866 221inline bool operator==(Edge edge, Node* node)
6fe7ccc8 222{
93a37866 223 return edge.node() == node;
6fe7ccc8 224}
93a37866 225inline bool operator==(Node* node, Edge edge)
6fe7ccc8 226{
93a37866 227 return edge.node() == node;
6fe7ccc8 228}
93a37866 229inline bool operator!=(Edge edge, Node* node)
6fe7ccc8 230{
93a37866 231 return edge.node() != node;
6fe7ccc8 232}
93a37866 233inline bool operator!=(Node* node, Edge edge)
6fe7ccc8 234{
93a37866 235 return edge.node() != node;
6fe7ccc8
A
236}
237
238} } // namespace JSC::DFG
239
240#endif // ENABLE(DFG_JIT)
241
242#endif // DFGEdge_h
243