]>
git.saurik.com Git - apple/javascriptcore.git/blob - dfg/DFGEdge.h
7a05fabae05e4faf329ecfa86735ebf60c741765
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
;
119 bool willNotHaveCheck() const
121 return isProved() || shouldNotHaveTypeCheck(useKind());
123 bool willHaveCheck() const
125 return !willNotHaveCheck();
128 KillStatus
killStatusUnchecked() const
130 return killStatusForDoesKill(m_encodedWord
& 2);
132 KillStatus
killStatus() const
135 return killStatusUnchecked();
137 void setKillStatus(KillStatus killStatus
)
141 m_encodedWord
= makeWord(node(), useKind(), proofStatus(), killStatus
);
143 m_encodedWord
= makeWord(useKind(), proofStatus(), killStatus
);
146 bool doesKill() const { return DFG::doesKill(killStatus()); }
147 bool doesNotKill() const { return !doesKill(); }
149 bool isSet() const { return !!node(); }
151 Edge
sanitized() const
155 result
.m_encodedWord
= makeWord(node(), useKindUnchecked(), NeedsCheck
, DoesNotKill
);
157 result
.m_encodedWord
= makeWord(useKindUnchecked(), NeedsCheck
, DoesNotKill
);
162 typedef void* Edge::*UnspecifiedBoolType
;
163 operator UnspecifiedBoolType
*() const { return reinterpret_cast<UnspecifiedBoolType
*>(isSet()); }
165 bool operator!() const { return !isSet(); }
167 bool operator==(Edge other
) const
170 return m_encodedWord
== other
.m_encodedWord
;
172 return m_node
== other
.m_node
&& m_encodedWord
== other
.m_encodedWord
;
175 bool operator!=(Edge other
) const
177 return !(*this == other
);
180 void dump(PrintStream
&) const;
182 unsigned hash() const
185 return IntHash
<uintptr_t>::hash(m_encodedWord
);
187 return PtrHash
<Node
*>::hash(m_node
) + m_encodedWord
;
192 friend class AdjacencyList
;
195 static uint32_t shift() { return 7; }
197 static uintptr_t makeWord(Node
* node
, UseKind useKind
, ProofStatus proofStatus
, KillStatus killStatus
)
199 ASSERT(sizeof(node
) == 8);
200 uintptr_t shiftedValue
= bitwise_cast
<uintptr_t>(node
) << shift();
201 ASSERT((shiftedValue
>> shift()) == bitwise_cast
<uintptr_t>(node
));
202 ASSERT(useKind
>= 0 && useKind
< LastUseKind
);
203 ASSERT((static_cast<uintptr_t>(LastUseKind
) << 2) <= (static_cast<uintptr_t>(2) << shift()));
204 return shiftedValue
| (static_cast<uintptr_t>(useKind
) << 2) | (DFG::doesKill(killStatus
) << 1) | static_cast<uintptr_t>(DFG::isProved(proofStatus
));
208 static uintptr_t makeWord(UseKind useKind
, ProofStatus proofStatus
, KillStatus killStatus
)
210 return (static_cast<uintptr_t>(useKind
) << 2) | (DFG::doesKill(killStatus
) << 1) | static_cast<uintptr_t>(DFG::isProved(proofStatus
));
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
;
221 inline bool operator==(Edge edge
, Node
* node
)
223 return edge
.node() == node
;
225 inline bool operator==(Node
* node
, Edge edge
)
227 return edge
.node() == node
;
229 inline bool operator!=(Edge edge
, Node
* node
)
231 return edge
.node() != node
;
233 inline bool operator!=(Node
* node
, Edge edge
)
235 return edge
.node() != node
;
238 } } // namespace JSC::DFG
240 #endif // ENABLE(DFG_JIT)