0a2171c9cd6eb0e63e759767051deee7390c1422
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGPureValue.h
1 /*
2  * Copyright (C) 2014 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 #pragma once
27
28 #if ENABLE(DFG_JIT)
29
30 #include "DFGGraph.h"
31 #include "DFGNode.h"
32
33 namespace JSC { namespace DFG {
34
35 class PureValue {
36 public:
37     PureValue()
38         : m_op(LastNodeType)
39         , m_info(0)
40     {
41     }
42     
43     PureValue(NodeType op, const AdjacencyList& children, uintptr_t info)
44         : m_op(op)
45         , m_children(children.sanitized())
46         , m_info(info)
47     {
48         ASSERT(!(defaultFlags(op) & NodeHasVarArgs));
49     }
50     
51     PureValue(NodeType op, const AdjacencyList& children, const void* ptr)
52         : PureValue(op, children, bitwise_cast<uintptr_t>(ptr))
53     {
54     }
55     
56     PureValue(NodeType op, const AdjacencyList& children)
57         : PureValue(op, children, static_cast<uintptr_t>(0))
58     {
59     }
60     
61     PureValue(Node* node, uintptr_t info)
62         : PureValue(node->op(), node->children, info)
63     {
64     }
65     
66     PureValue(Node* node, const void* ptr)
67         : PureValue(node->op(), node->children, ptr)
68     {
69     }
70     
71     PureValue(Node* node)
72         : PureValue(node->op(), node->children)
73     {
74     }
75
76     PureValue(Graph& graph, Node* node, uintptr_t info)
77         : m_op(node->op())
78         , m_children(node->children)
79         , m_info(info)
80         , m_graph(&graph)
81     {
82         ASSERT(node->flags() & NodeHasVarArgs);
83         ASSERT(isVarargs());
84     }
85
86     PureValue(Graph& graph, Node* node)
87         : PureValue(graph, node, static_cast<uintptr_t>(0))
88     {
89     }
90
91     PureValue(WTF::HashTableDeletedValueType)
92         : m_op(LastNodeType)
93         , m_info(1)
94     {
95     }
96     
97     bool operator!() const { return m_op == LastNodeType && !m_info; }
98     
99     NodeType op() const { return m_op; }
100     uintptr_t info() const { return m_info; }
101
102     unsigned hash() const
103     {
104         unsigned hash = WTF::IntHash<int>::hash(static_cast<int>(m_op)) + m_info;
105         if (!isVarargs())
106             return hash ^ m_children.hash();
107         for (unsigned i = 0; i < m_children.numChildren(); ++i)
108             hash ^= m_graph->m_varArgChildren[m_children.firstChild() + i].sanitized().hash();
109         return hash;
110     }
111     
112     bool operator==(const PureValue& other) const
113     {
114         if (isVarargs() != other.isVarargs() || m_op != other.m_op || m_info != other.m_info)
115             return false;
116         if (!isVarargs())
117             return m_children == other.m_children;
118         if (m_children.numChildren() != other.m_children.numChildren())
119             return false;
120         for (unsigned i = 0; i < m_children.numChildren(); ++i) {
121             Edge a = m_graph->m_varArgChildren[m_children.firstChild() + i].sanitized();
122             Edge b = m_graph->m_varArgChildren[other.m_children.firstChild() + i].sanitized();
123             if (a != b)
124                 return false;
125         }
126         return true;
127     }
128     
129     bool isHashTableDeletedValue() const
130     {
131         return m_op == LastNodeType && m_info;
132     }
133     
134     void dump(PrintStream& out) const;
135     
136 private:
137     bool isVarargs() const { return !!m_graph; }
138
139     NodeType m_op;
140     AdjacencyList m_children;
141     uintptr_t m_info;
142     Graph* m_graph { nullptr };
143 };
144
145 struct PureValueHash {
146     static unsigned hash(const PureValue& key) { return key.hash(); }
147     static bool equal(const PureValue& a, const PureValue& b) { return a == b; }
148     static const bool safeToCompareToEmptyOrDeleted = true;
149 };
150
151 } } // namespace JSC::DFG
152
153 namespace WTF {
154
155 template<typename T> struct DefaultHash;
156 template<> struct DefaultHash<JSC::DFG::PureValue> {
157     typedef JSC::DFG::PureValueHash Hash;
158 };
159
160 template<typename T> struct HashTraits;
161 template<> struct HashTraits<JSC::DFG::PureValue> : SimpleClassHashTraits<JSC::DFG::PureValue> {
162     static const bool emptyValueIsZero = false;
163 };
164
165 } // namespace WTF
166
167 namespace JSC { namespace DFG {
168
169 typedef HashMap<PureValue, Node*> PureMap;
170 typedef HashMap<PureValue, Vector<Node*>> PureMultiMap;
171
172 } } // namespace JSC::DFG
173
174 #endif // ENABLE(DFG_JIT)