]>
git.saurik.com Git - apple/javascriptcore.git/blob - dfg/DFGEdge.h
2 * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
31 #include "DFGCommon.h"
32 #include "DFGUseKind.h"
34 namespace JSC
{ namespace DFG
{
40 explicit Edge(Node
* node
= 0, UseKind useKind
= UntypedUse
, ProofStatus proofStatus
= NeedsCheck
, KillStatus killStatus
= DoesNotKill
)
42 : m_encodedWord(makeWord(node
, useKind
, proofStatus
, killStatus
))
45 , m_encodedWord(makeWord(useKind
, proofStatus
, killStatus
))
51 Node
* node() const { return bitwise_cast
<Node
*>(m_encodedWord
>> shift()); }
53 Node
* node() const { return m_node
; }
56 Node
& operator*() const { return *node(); }
57 Node
* operator->() const { return node(); }
59 void setNode(Node
* node
)
62 m_encodedWord
= makeWord(node
, useKind(), proofStatus(), killStatus());
68 UseKind
useKindUnchecked() const
71 unsigned masked
= m_encodedWord
& (((1 << shift()) - 1));
72 unsigned shifted
= masked
>> 2;
74 unsigned shifted
= static_cast<UseKind
>(m_encodedWord
) >> 2;
76 ASSERT(shifted
< static_cast<unsigned>(LastUseKind
));
77 UseKind result
= static_cast<UseKind
>(shifted
);
78 ASSERT(node() || result
== UntypedUse
);
81 UseKind
useKind() const
84 return useKindUnchecked();
86 void setUseKind(UseKind useKind
)
90 m_encodedWord
= makeWord(node(), useKind
, proofStatus(), killStatus());
92 m_encodedWord
= makeWord(useKind
, proofStatus(), killStatus());
96 ProofStatus
proofStatusUnchecked() const
98 return proofStatusForIsProved(m_encodedWord
& 1);
100 ProofStatus
proofStatus() const
103 return proofStatusUnchecked();
105 void setProofStatus(ProofStatus proofStatus
)
109 m_encodedWord
= makeWord(node(), useKind(), proofStatus
, killStatus());
111 m_encodedWord
= makeWord(useKind(), proofStatus
, killStatus());
114 bool isProved() const
116 return proofStatus() == IsProved
;
118 bool needsCheck() const
120 return proofStatus() == NeedsCheck
;
123 bool willNotHaveCheck() const
125 return isProved() || shouldNotHaveTypeCheck(useKind());
127 bool willHaveCheck() const
129 return !willNotHaveCheck();
132 KillStatus
killStatusUnchecked() const
134 return killStatusForDoesKill(m_encodedWord
& 2);
136 KillStatus
killStatus() const
139 return killStatusUnchecked();
141 void setKillStatus(KillStatus killStatus
)
145 m_encodedWord
= makeWord(node(), useKind(), proofStatus(), killStatus
);
147 m_encodedWord
= makeWord(useKind(), proofStatus(), killStatus
);
150 bool doesKill() const { return DFG::doesKill(killStatus()); }
151 bool doesNotKill() const { return !doesKill(); }
153 bool isSet() const { return !!node(); }
155 Edge
sanitized() const
159 result
.m_encodedWord
= makeWord(node(), useKindUnchecked(), NeedsCheck
, DoesNotKill
);
161 result
.m_encodedWord
= makeWord(useKindUnchecked(), NeedsCheck
, DoesNotKill
);
166 typedef void* Edge::*UnspecifiedBoolType
;
167 operator UnspecifiedBoolType
*() const { return reinterpret_cast<UnspecifiedBoolType
*>(isSet()); }
169 bool operator!() const { return !isSet(); }
171 bool operator==(Edge other
) const
174 return m_encodedWord
== other
.m_encodedWord
;
176 return m_node
== other
.m_node
&& m_encodedWord
== other
.m_encodedWord
;
179 bool operator!=(Edge other
) const
181 return !(*this == other
);
184 void dump(PrintStream
&) const;
186 unsigned hash() const
189 return IntHash
<uintptr_t>::hash(m_encodedWord
);
191 return PtrHash
<Node
*>::hash(m_node
) + m_encodedWord
;
196 friend class AdjacencyList
;
199 static uint32_t shift() { return 7; }
201 static uintptr_t makeWord(Node
* node
, UseKind useKind
, ProofStatus proofStatus
, KillStatus killStatus
)
203 ASSERT(sizeof(node
) == 8);
204 uintptr_t shiftedValue
= bitwise_cast
<uintptr_t>(node
) << shift();
205 ASSERT((shiftedValue
>> shift()) == bitwise_cast
<uintptr_t>(node
));
206 ASSERT(useKind
>= 0 && useKind
< LastUseKind
);
207 ASSERT((static_cast<uintptr_t>(LastUseKind
) << 2) <= (static_cast<uintptr_t>(2) << shift()));
208 return shiftedValue
| (static_cast<uintptr_t>(useKind
) << 2) | (DFG::doesKill(killStatus
) << 1) | DFG::isProved(proofStatus
);
212 static uintptr_t makeWord(UseKind useKind
, ProofStatus proofStatus
, KillStatus killStatus
)
214 return (static_cast<uintptr_t>(useKind
) << 2) | (DFG::doesKill(killStatus
) << 1) | DFG::isProved(proofStatus
);
219 // On 64-bit this holds both the pointer and the use kind, while on 32-bit
220 // this just holds the use kind. In both cases this may be hijacked by
221 // AdjacencyList for storing firstChild and numChildren.
222 uintptr_t m_encodedWord
;
225 inline bool operator==(Edge edge
, Node
* node
)
227 return edge
.node() == node
;
229 inline bool operator==(Node
* node
, Edge edge
)
231 return edge
.node() == node
;
233 inline bool operator!=(Edge edge
, Node
* node
)
235 return edge
.node() != node
;
237 inline bool operator!=(Node
* node
, Edge edge
)
239 return edge
.node() != node
;
242 } } // namespace JSC::DFG
244 #endif // ENABLE(DFG_JIT)