]> git.saurik.com Git - apple/javascriptcore.git/blob - dfg/DFGNode.cpp
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / dfg / DFGNode.cpp
1 /*
2 * Copyright (C) 2013, 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 #include "config.h"
27 #include "DFGNode.h"
28
29 #if ENABLE(DFG_JIT)
30
31 #include "DFGGraph.h"
32 #include "DFGNodeAllocator.h"
33 #include "DFGPromotedHeapLocation.h"
34 #include "JSCInlines.h"
35
36 namespace JSC { namespace DFG {
37
38 bool MultiPutByOffsetData::writesStructures() const
39 {
40 for (unsigned i = variants.size(); i--;) {
41 if (variants[i].writesStructures())
42 return true;
43 }
44 return false;
45 }
46
47 bool MultiPutByOffsetData::reallocatesStorage() const
48 {
49 for (unsigned i = variants.size(); i--;) {
50 if (variants[i].reallocatesStorage())
51 return true;
52 }
53 return false;
54 }
55
56 void BranchTarget::dump(PrintStream& out) const
57 {
58 if (!block)
59 return;
60
61 out.print(*block);
62
63 if (count == count) // If the count is not NaN, then print it.
64 out.print("/w:", count);
65 }
66
67 unsigned Node::index() const
68 {
69 return NodeAllocator::allocatorOf(this)->indexOf(this);
70 }
71
72 bool Node::hasVariableAccessData(Graph& graph)
73 {
74 switch (op()) {
75 case Phi:
76 return graph.m_form != SSA;
77 case GetLocal:
78 case SetLocal:
79 case SetArgument:
80 case Flush:
81 case PhantomLocal:
82 return true;
83 default:
84 return false;
85 }
86 }
87
88 void Node::remove()
89 {
90 ASSERT(!(flags() & NodeHasVarArgs));
91
92 children = children.justChecks();
93
94 setOpAndDefaultFlags(Check);
95 }
96
97 void Node::convertToIdentity()
98 {
99 RELEASE_ASSERT(child1());
100 RELEASE_ASSERT(!child2());
101 NodeFlags result = canonicalResultRepresentation(this->result());
102 setOpAndDefaultFlags(Identity);
103 setResult(result);
104 }
105
106 void Node::convertToIdentityOn(Node* child)
107 {
108 children.reset();
109 child1() = child->defaultEdge();
110 NodeFlags output = canonicalResultRepresentation(this->result());
111 NodeFlags input = canonicalResultRepresentation(child->result());
112 if (output == input) {
113 setOpAndDefaultFlags(Identity);
114 setResult(output);
115 return;
116 }
117 switch (output) {
118 case NodeResultDouble:
119 setOpAndDefaultFlags(DoubleRep);
120 switch (input) {
121 case NodeResultInt52:
122 child1().setUseKind(Int52RepUse);
123 return;
124 case NodeResultJS:
125 child1().setUseKind(NumberUse);
126 return;
127 default:
128 RELEASE_ASSERT_NOT_REACHED();
129 return;
130 }
131 case NodeResultInt52:
132 setOpAndDefaultFlags(Int52Rep);
133 switch (input) {
134 case NodeResultDouble:
135 child1().setUseKind(DoubleRepMachineIntUse);
136 return;
137 case NodeResultJS:
138 child1().setUseKind(MachineIntUse);
139 return;
140 default:
141 RELEASE_ASSERT_NOT_REACHED();
142 return;
143 }
144 case NodeResultJS:
145 setOpAndDefaultFlags(ValueRep);
146 switch (input) {
147 case NodeResultDouble:
148 child1().setUseKind(DoubleRepUse);
149 return;
150 case NodeResultInt52:
151 child1().setUseKind(Int52RepUse);
152 return;
153 default:
154 RELEASE_ASSERT_NOT_REACHED();
155 return;
156 }
157 default:
158 RELEASE_ASSERT_NOT_REACHED();
159 return;
160 }
161 }
162
163 void Node::convertToPutHint(const PromotedLocationDescriptor& descriptor, Node* base, Node* value)
164 {
165 m_op = PutHint;
166 m_opInfo = descriptor.imm1().m_value;
167 m_opInfo2 = descriptor.imm2().m_value;
168 child1() = base->defaultEdge();
169 child2() = value->defaultEdge();
170 child3() = Edge();
171 }
172
173 void Node::convertToPutStructureHint(Node* structure)
174 {
175 ASSERT(m_op == PutStructure);
176 ASSERT(structure->castConstant<Structure*>() == transition()->next);
177 convertToPutHint(StructurePLoc, child1().node(), structure);
178 }
179
180 void Node::convertToPutByOffsetHint()
181 {
182 ASSERT(m_op == PutByOffset);
183 convertToPutHint(
184 PromotedLocationDescriptor(NamedPropertyPLoc, storageAccessData().identifierNumber),
185 child2().node(), child3().node());
186 }
187
188 void Node::convertToPutClosureVarHint()
189 {
190 ASSERT(m_op == PutClosureVar);
191 convertToPutHint(
192 PromotedLocationDescriptor(ClosureVarPLoc, scopeOffset().offset()),
193 child1().node(), child2().node());
194 }
195
196 PromotedLocationDescriptor Node::promotedLocationDescriptor()
197 {
198 return PromotedLocationDescriptor(static_cast<PromotedLocationKind>(m_opInfo), m_opInfo2);
199 }
200
201 } } // namespace JSC::DFG
202
203 namespace WTF {
204
205 using namespace JSC;
206 using namespace JSC::DFG;
207
208 void printInternal(PrintStream& out, SwitchKind kind)
209 {
210 switch (kind) {
211 case SwitchImm:
212 out.print("SwitchImm");
213 return;
214 case SwitchChar:
215 out.print("SwitchChar");
216 return;
217 case SwitchString:
218 out.print("SwitchString");
219 return;
220 case SwitchCell:
221 out.print("SwitchCell");
222 return;
223 }
224 RELEASE_ASSERT_NOT_REACHED();
225 }
226
227 void printInternal(PrintStream& out, Node* node)
228 {
229 if (!node) {
230 out.print("-");
231 return;
232 }
233 out.print("@", node->index());
234 if (node->hasDoubleResult())
235 out.print("<Double>");
236 else if (node->hasInt52Result())
237 out.print("<Int52>");
238 }
239
240 } // namespace WTF
241
242 #endif // ENABLE(DFG_JIT)
243