blob: bbff1b6b425d4aa6accf8d665847601d4de0d99d [file] [log] [blame]
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00001/*
2 * Copyright (C) 2012 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 "DFGFixupPhase.h"
28
29#if ENABLE(DFG_JIT)
30
31#include "DFGGraph.h"
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +000032#include "DFGInsertionSet.h"
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000033#include "DFGPhase.h"
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +000034#include "Operations.h"
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000035
36namespace JSC { namespace DFG {
37
38class FixupPhase : public Phase {
39public:
40 FixupPhase(Graph& graph)
41 : Phase(graph, "fixup")
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +000042 , m_insertionSet(graph)
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000043 {
44 }
45
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +000046 bool run()
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000047 {
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +000048 for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex)
49 fixupBlock(m_graph.m_blocks[blockIndex].get());
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +000050 return true;
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000051 }
52
53private:
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +000054 void fixupBlock(BasicBlock* block)
55 {
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +000056 if (!block)
57 return;
58 ASSERT(block->isReachable);
fpizlo@apple.comf10d0722012-12-03 09:21:22 +000059 m_block = block;
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +000060 for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
61 m_compileIndex = block->at(m_indexInBlock);
62 fixupNode(m_graph[m_compileIndex]);
63 }
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +000064 m_insertionSet.execute(block);
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +000065 }
66
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000067 void fixupNode(Node& node)
68 {
69 if (!node.shouldGenerate())
70 return;
71
72 NodeType op = node.op();
73
74#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
fpizlo@apple.com01902c82012-11-22 04:23:36 +000075 dataLogF(" %s @%u: ", Graph::opName(op), m_compileIndex);
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000076#endif
77
78 switch (op) {
79 case GetById: {
fpizlo@apple.com04c19742012-08-26 22:35:26 +000080 if (m_graph.m_fixpointState > BeforeFixpoint)
81 break;
82
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +000083 Node* nodePtr = &node;
84
fpizlo@apple.com62336162012-06-07 01:35:59 +000085 if (!isInt32Speculation(m_graph[m_compileIndex].prediction()))
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000086 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +000087 if (codeBlock()->identifier(nodePtr->identifierNumber()) != globalData().propertyNames->length)
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000088 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +000089 ArrayProfile* arrayProfile =
90 m_graph.baselineCodeBlockFor(nodePtr->codeOrigin)->getArrayProfile(
91 nodePtr->codeOrigin.bytecodeIndex);
fpizlo@apple.com34d1f082012-10-28 06:13:23 +000092 ArrayMode arrayMode = ArrayMode(Array::SelectUsingPredictions);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +000093 if (arrayProfile) {
fpizlo@apple.com99f37622012-10-29 04:02:08 +000094 arrayProfile->computeUpdatedPrediction(m_graph.baselineCodeBlockFor(node.codeOrigin));
fpizlo@apple.com34d1f082012-10-28 06:13:23 +000095 arrayMode = ArrayMode::fromObserved(arrayProfile, Array::Read, false);
96 arrayMode = arrayMode.refine(
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +000097 m_graph[node.child1()].prediction(),
fpizlo@apple.com4cafdbd2012-09-11 20:00:31 +000098 m_graph[m_compileIndex].prediction());
fpizlo@apple.com34d1f082012-10-28 06:13:23 +000099 if (arrayMode.supportsLength() && arrayProfile->hasDefiniteStructure()) {
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +0000100 m_insertionSet.insertNode(
101 m_indexInBlock, RefChildren, DontRefNode, SpecNone, CheckStructure,
102 nodePtr->codeOrigin, OpInfo(m_graph.addStructureSet(arrayProfile->expectedStructure())),
103 nodePtr->child1().index());
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000104 nodePtr = &m_graph[m_compileIndex];
105 }
106 } else {
fpizlo@apple.com34d1f082012-10-28 06:13:23 +0000107 arrayMode = arrayMode.refine(
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000108 m_graph[node.child1()].prediction(),
109 m_graph[m_compileIndex].prediction());
fpizlo@apple.comf24804c2012-08-15 02:48:35 +0000110 }
fpizlo@apple.com34d1f082012-10-28 06:13:23 +0000111 if (!arrayMode.supportsLength())
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000112 break;
113 nodePtr->setOp(GetArrayLength);
114 ASSERT(nodePtr->flags() & NodeMustGenerate);
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +0000115 nodePtr->clearFlags(NodeMustGenerate | NodeClobbersWorld);
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000116 m_graph.deref(m_compileIndex);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000117 nodePtr->setArrayMode(arrayMode);
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000118
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000119 NodeIndex storage = checkArray(arrayMode, nodePtr->codeOrigin, nodePtr->child1().index(), NoNode, lengthNeedsStorage, nodePtr->shouldGenerate());
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000120 if (storage == NoNode)
121 break;
122
123 nodePtr = &m_graph[m_compileIndex];
124 nodePtr->children.child2() = Edge(storage);
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000125 break;
126 }
127 case GetIndexedPropertyStorage: {
fpizlo@apple.com34d1f082012-10-28 06:13:23 +0000128 ASSERT(node.arrayMode().canCSEStorage());
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000129 break;
130 }
fpizlo@apple.coma387b6a2012-11-01 07:41:43 +0000131 case GetByVal: {
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000132 node.setArrayMode(
fpizlo@apple.com34d1f082012-10-28 06:13:23 +0000133 node.arrayMode().refine(
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000134 m_graph[node.child1()].prediction(),
fpizlo@apple.comf10d0722012-12-03 09:21:22 +0000135 m_graph[node.child2()].prediction(),
136 SpecNone, node.flags()));
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000137
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000138 blessArrayOperation(node.child1(), node.child2(), 2);
fpizlo@apple.com94e84e92012-11-11 02:56:12 +0000139
fpizlo@apple.comf999d222012-11-14 23:34:19 +0000140 Node* nodePtr = &m_graph[m_compileIndex];
141 ArrayMode arrayMode = nodePtr->arrayMode();
fpizlo@apple.com94e84e92012-11-11 02:56:12 +0000142 if (arrayMode.type() == Array::Double
143 && arrayMode.arrayClass() == Array::OriginalArray
144 && arrayMode.speculation() == Array::InBounds
145 && arrayMode.conversion() == Array::AsIs
fpizlo@apple.comf999d222012-11-14 23:34:19 +0000146 && m_graph.globalObjectFor(nodePtr->codeOrigin)->arrayPrototypeChainIsSane()
147 && !(nodePtr->flags() & NodeUsedAsOther))
148 nodePtr->setArrayMode(arrayMode.withSpeculation(Array::SaneChain));
fpizlo@apple.com94e84e92012-11-11 02:56:12 +0000149
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000150 break;
151 }
fpizlo@apple.coma387b6a2012-11-01 07:41:43 +0000152 case StringCharAt:
153 case StringCharCodeAt: {
154 // Currently we have no good way of refining these.
155 ASSERT(node.arrayMode() == ArrayMode(Array::String));
156 blessArrayOperation(node.child1(), node.child2(), 2);
157 break;
158 }
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000159
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000160 case ArrayPush: {
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000161 // May need to refine the array mode in case the value prediction contravenes
162 // the array prediction. For example, we may have evidence showing that the
163 // array is in Int32 mode, but the value we're storing is likely to be a double.
164 // Then we should turn this into a conversion to Double array followed by the
165 // push. On the other hand, we absolutely don't want to refine based on the
166 // base prediction. If it has non-cell garbage in it, then we want that to be
167 // ignored. That's because ArrayPush can't handle any array modes that aren't
168 // array-related - so if refine() turned this into a "Generic" ArrayPush then
169 // that would break things.
170 node.setArrayMode(
171 node.arrayMode().refine(
172 m_graph[node.child1()].prediction() & SpecCell,
173 SpecInt32,
174 m_graph[node.child2()].prediction()));
fpizlo@apple.comc1363652012-12-10 06:54:30 +0000175 blessArrayOperation(node.child1(), Edge(), 2);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000176
177 Node* nodePtr = &m_graph[m_compileIndex];
178 switch (nodePtr->arrayMode().type()) {
179 case Array::Double:
180 fixDoubleEdge(1);
181 break;
182 default:
183 break;
184 }
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000185 break;
186 }
187
188 case ArrayPop: {
fpizlo@apple.comc1363652012-12-10 06:54:30 +0000189 blessArrayOperation(node.child1(), Edge(), 1);
fpizlo@apple.com8fd79212012-10-16 21:59:35 +0000190 break;
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000191 }
192
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000193 case ValueToInt32: {
fpizlo@apple.com888325a2012-06-12 23:16:51 +0000194 if (m_graph[node.child1()].shouldSpeculateNumber()
195 && node.mustGenerate()) {
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000196 node.clearFlags(NodeMustGenerate);
197 m_graph.deref(m_compileIndex);
198 }
199 break;
200 }
201
202 case BitAnd:
203 case BitOr:
204 case BitXor:
205 case BitRShift:
206 case BitLShift:
207 case BitURShift: {
208 fixIntEdge(node.children.child1());
209 fixIntEdge(node.children.child2());
210 break;
211 }
212
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000213 case CompareEq:
214 case CompareLess:
215 case CompareLessEq:
216 case CompareGreater:
217 case CompareGreaterEq:
218 case CompareStrictEq: {
219 if (Node::shouldSpeculateInteger(m_graph[node.child1()], m_graph[node.child2()]))
220 break;
221 if (!Node::shouldSpeculateNumber(m_graph[node.child1()], m_graph[node.child2()]))
222 break;
223 fixDoubleEdge(0);
224 fixDoubleEdge(1);
225 break;
226 }
227
228 case LogicalNot: {
229 if (m_graph[node.child1()].shouldSpeculateInteger())
230 break;
231 if (!m_graph[node.child1()].shouldSpeculateNumber())
232 break;
233 fixDoubleEdge(0);
234 break;
235 }
236
237 case Branch: {
fpizlo@apple.come2967fd2012-04-04 21:14:48 +0000238 if (!m_graph[node.child1()].shouldSpeculateInteger()
239 && m_graph[node.child1()].shouldSpeculateNumber())
240 fixDoubleEdge(0);
241
242 Node& myNode = m_graph[m_compileIndex]; // reload because the graph may have changed
243 Edge logicalNotEdge = myNode.child1();
244 Node& logicalNot = m_graph[logicalNotEdge];
245 if (logicalNot.op() == LogicalNot
246 && logicalNot.adjustedRefCount() == 1) {
247 Edge newChildEdge = logicalNot.child1();
fpizlo@apple.coma6c889b2012-04-12 04:19:07 +0000248 if (m_graph[newChildEdge].hasBooleanResult()) {
249 m_graph.ref(newChildEdge);
250 m_graph.deref(logicalNotEdge);
251 myNode.children.setChild1(newChildEdge);
252
253 BlockIndex toBeTaken = myNode.notTakenBlockIndex();
254 BlockIndex toBeNotTaken = myNode.takenBlockIndex();
255 myNode.setTakenBlockIndex(toBeTaken);
256 myNode.setNotTakenBlockIndex(toBeNotTaken);
257 }
fpizlo@apple.come2967fd2012-04-04 21:14:48 +0000258 }
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000259 break;
260 }
261
262 case SetLocal: {
fpizlo@apple.com1688cc12012-05-23 07:29:02 +0000263 if (node.variableAccessData()->isCaptured())
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000264 break;
265 if (!node.variableAccessData()->shouldUseDoubleFormat())
266 break;
267 fixDoubleEdge(0);
268 break;
269 }
270
271 case ArithAdd:
272 case ValueAdd: {
273 if (m_graph.addShouldSpeculateInteger(node))
274 break;
fpizlo@apple.com81f75372012-11-08 22:55:27 +0000275 if (!Node::shouldSpeculateNumberExpectingDefined(m_graph[node.child1()], m_graph[node.child2()]))
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000276 break;
277 fixDoubleEdge(0);
278 fixDoubleEdge(1);
279 break;
280 }
281
282 case ArithSub: {
283 if (m_graph.addShouldSpeculateInteger(node)
284 && node.canSpeculateInteger())
285 break;
286 fixDoubleEdge(0);
287 fixDoubleEdge(1);
288 break;
289 }
290
291 case ArithNegate: {
292 if (m_graph.negateShouldSpeculateInteger(node))
293 break;
294 fixDoubleEdge(0);
295 break;
296 }
297
298 case ArithMin:
299 case ArithMax:
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000300 case ArithMod: {
fpizlo@apple.com81f75372012-11-08 22:55:27 +0000301 if (Node::shouldSpeculateIntegerForArithmetic(m_graph[node.child1()], m_graph[node.child2()])
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000302 && node.canSpeculateInteger())
303 break;
304 fixDoubleEdge(0);
305 fixDoubleEdge(1);
306 break;
307 }
308
fpizlo@apple.comfa9f10c2012-05-22 17:18:21 +0000309 case ArithMul: {
310 if (m_graph.mulShouldSpeculateInteger(node))
311 break;
312 fixDoubleEdge(0);
313 fixDoubleEdge(1);
314 break;
315 }
316
fpizlo@apple.com0cf017f2012-04-18 22:31:54 +0000317 case ArithDiv: {
fpizlo@apple.com81f75372012-11-08 22:55:27 +0000318 if (Node::shouldSpeculateIntegerForArithmetic(m_graph[node.child1()], m_graph[node.child2()])
fpizlo@apple.com3d223382012-04-24 19:19:35 +0000319 && node.canSpeculateInteger()) {
320 if (isX86())
321 break;
msaboff@apple.com268bb442013-01-18 21:45:06 +0000322 injectInt32ToDoubleNode(0);
323 injectInt32ToDoubleNode(1);
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +0000324
325 // We don't need to do ref'ing on the children because we're stealing them from
326 // the original division.
327 NodeIndex newDivisionIndex = m_insertionSet.insertNode(
328 m_indexInBlock, DontRefChildren, RefNode, SpecDouble, m_graph[m_compileIndex]);
fpizlo@apple.com3d223382012-04-24 19:19:35 +0000329
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +0000330 m_graph[m_compileIndex].setOp(DoubleAsInt32);
331 m_graph[m_compileIndex].children.initialize(Edge(newDivisionIndex, DoubleUse), Edge(), Edge());
fpizlo@apple.com3d223382012-04-24 19:19:35 +0000332
fpizlo@apple.com0cf017f2012-04-18 22:31:54 +0000333 break;
fpizlo@apple.com3d223382012-04-24 19:19:35 +0000334 }
fpizlo@apple.com0cf017f2012-04-18 22:31:54 +0000335 fixDoubleEdge(0);
336 fixDoubleEdge(1);
337 break;
338 }
339
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000340 case ArithAbs: {
fpizlo@apple.com81f75372012-11-08 22:55:27 +0000341 if (m_graph[node.child1()].shouldSpeculateIntegerForArithmetic()
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000342 && node.canSpeculateInteger())
343 break;
344 fixDoubleEdge(0);
345 break;
346 }
347
348 case ArithSqrt: {
349 fixDoubleEdge(0);
350 break;
351 }
352
fpizlo@apple.com270a7ad2012-08-02 01:28:10 +0000353 case PutByVal:
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000354 case PutByValAlias: {
fpizlo@apple.coma4eaa8a2012-07-15 05:23:58 +0000355 Edge child1 = m_graph.varArgChild(node, 0);
356 Edge child2 = m_graph.varArgChild(node, 1);
357 Edge child3 = m_graph.varArgChild(node, 2);
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000358
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000359 node.setArrayMode(
fpizlo@apple.com34d1f082012-10-28 06:13:23 +0000360 node.arrayMode().refine(
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000361 m_graph[child1].prediction(),
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000362 m_graph[child2].prediction(),
363 m_graph[child3].prediction()));
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000364
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000365 blessArrayOperation(child1, child2, 3);
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000366
367 Node* nodePtr = &m_graph[m_compileIndex];
368
fpizlo@apple.com34d1f082012-10-28 06:13:23 +0000369 switch (nodePtr->arrayMode().modeForPut().type()) {
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000370 case Array::Double:
371 fixDoubleEdge(2);
372 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000373 case Array::Int8Array:
374 case Array::Int16Array:
375 case Array::Int32Array:
376 case Array::Uint8Array:
377 case Array::Uint8ClampedArray:
378 case Array::Uint16Array:
379 case Array::Uint32Array:
380 if (!m_graph[child3].shouldSpeculateInteger())
381 fixDoubleEdge(2);
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000382 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000383 case Array::Float32Array:
384 case Array::Float64Array:
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000385 fixDoubleEdge(2);
386 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000387 default:
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000388 break;
389 }
390 break;
391 }
392
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000393 case NewArray: {
394 for (unsigned i = m_graph.varArgNumChildren(node); i--;) {
395 node.setIndexingType(
396 leastUpperBoundOfIndexingTypeAndType(
397 node.indexingType(), m_graph[m_graph.varArgChild(node, i)].prediction()));
398 }
399 if (node.indexingType() == ArrayWithDouble) {
400 for (unsigned i = m_graph.varArgNumChildren(node); i--;)
401 fixDoubleEdge(i);
402 }
403 break;
404 }
405
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000406 default:
407 break;
408 }
409
410#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
msaboff@apple.comb744a172013-01-19 01:53:36 +0000411 Node* nodePtr = &m_graph[m_compileIndex];
412 if (!(nodePtr->flags() & NodeHasVarArgs)) {
fpizlo@apple.com01902c82012-11-22 04:23:36 +0000413 dataLogF("new children: ");
msaboff@apple.comb744a172013-01-19 01:53:36 +0000414 nodePtr->dumpChildren(WTF::dataFile());
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000415 }
fpizlo@apple.com01902c82012-11-22 04:23:36 +0000416 dataLogF("\n");
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000417#endif
418 }
419
fpizlo@apple.com34d1f082012-10-28 06:13:23 +0000420 NodeIndex checkArray(ArrayMode arrayMode, CodeOrigin codeOrigin, NodeIndex array, NodeIndex index, bool (*storageCheck)(const ArrayMode&) = canCSEStorage, bool shouldGenerate = true)
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000421 {
fpizlo@apple.com34d1f082012-10-28 06:13:23 +0000422 ASSERT(arrayMode.isSpecific());
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000423
fpizlo@apple.com3f1a01b2012-11-10 05:54:11 +0000424 Structure* structure = arrayMode.originalArrayStructure(m_graph, codeOrigin);
425
fpizlo@apple.com34d1f082012-10-28 06:13:23 +0000426 if (arrayMode.doesConversion()) {
fpizlo@apple.com99f37622012-10-29 04:02:08 +0000427 if (structure) {
fpizlo@apple.comf10d0722012-12-03 09:21:22 +0000428 if (m_indexInBlock > 0) {
429 // If the previous node was a CheckStructure inserted because of stuff
430 // that the array profile told us, then remove it.
431 Node& previousNode = m_graph[m_block->at(m_indexInBlock - 1)];
432 if (previousNode.op() == CheckStructure
433 && previousNode.child1() == array
434 && previousNode.codeOrigin == codeOrigin)
435 previousNode.setOpAndDefaultFlags(Phantom);
436 }
437
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +0000438 m_insertionSet.insertNode(
439 m_indexInBlock, RefChildren, DontRefNode, SpecNone, ArrayifyToStructure, codeOrigin,
440 OpInfo(structure), OpInfo(arrayMode.asWord()), array, index);
fpizlo@apple.com99f37622012-10-29 04:02:08 +0000441 } else {
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +0000442 m_insertionSet.insertNode(
443 m_indexInBlock, RefChildren, DontRefNode, SpecNone, Arrayify, codeOrigin,
444 OpInfo(arrayMode.asWord()), array, index);
fpizlo@apple.com99f37622012-10-29 04:02:08 +0000445 }
446 } else {
fpizlo@apple.com3f1a01b2012-11-10 05:54:11 +0000447 if (structure) {
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +0000448 m_insertionSet.insertNode(
449 m_indexInBlock, RefChildren, DontRefNode, SpecNone, CheckStructure, codeOrigin,
450 OpInfo(m_graph.addStructureSet(structure)), array);
fpizlo@apple.com3f1a01b2012-11-10 05:54:11 +0000451 } else {
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +0000452 m_insertionSet.insertNode(
453 m_indexInBlock, RefChildren, DontRefNode, SpecNone, CheckArray, codeOrigin,
454 OpInfo(arrayMode.asWord()), array);
fpizlo@apple.com3f1a01b2012-11-10 05:54:11 +0000455 }
fpizlo@apple.com497c7512012-09-19 01:20:52 +0000456 }
457
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000458 if (!storageCheck(arrayMode))
459 return NoNode;
460
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +0000461 if (arrayMode.usesButterfly()) {
462 return m_insertionSet.insertNode(
463 m_indexInBlock,
464 shouldGenerate ? RefChildren : DontRefChildren,
465 shouldGenerate ? RefNode : DontRefNode,
466 SpecNone, GetButterfly, codeOrigin, array);
467 }
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000468
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +0000469 return m_insertionSet.insertNode(
470 m_indexInBlock,
471 shouldGenerate ? RefChildren : DontRefChildren,
472 shouldGenerate ? RefNode : DontRefNode,
473 SpecNone, GetIndexedPropertyStorage, codeOrigin, OpInfo(arrayMode.asWord()), array);
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000474 }
475
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000476 void blessArrayOperation(Edge base, Edge index, unsigned storageChildIdx)
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000477 {
478 if (m_graph.m_fixpointState > BeforeFixpoint)
479 return;
480
481 Node* nodePtr = &m_graph[m_compileIndex];
482
fpizlo@apple.com34d1f082012-10-28 06:13:23 +0000483 switch (nodePtr->arrayMode().type()) {
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000484 case Array::ForceExit: {
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +0000485 m_insertionSet.insertNode(
486 m_indexInBlock, DontRefChildren, DontRefNode, SpecNone, ForceOSRExit,
487 nodePtr->codeOrigin);
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000488 return;
489 }
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000490
fpizlo@apple.coma0ec0592012-10-22 23:52:15 +0000491 case Array::SelectUsingPredictions:
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000492 case Array::Unprofiled:
493 ASSERT_NOT_REACHED();
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000494 return;
495
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000496 case Array::Generic:
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000497 return;
498
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000499 default: {
500 NodeIndex storage = checkArray(nodePtr->arrayMode(), nodePtr->codeOrigin, base.index(), index.indexUnchecked());
501 if (storage == NoNode)
502 return;
503
504 m_graph.child(m_graph[m_compileIndex], storageChildIdx) = Edge(storage);
505 return;
506 } }
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000507 }
508
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000509 void fixIntEdge(Edge& edge)
510 {
511 Node& node = m_graph[edge];
512 if (node.op() != ValueToInt32)
513 return;
514
515 if (!m_graph[node.child1()].shouldSpeculateInteger())
516 return;
517
518 Edge oldEdge = edge;
519 Edge newEdge = node.child1();
520
521 m_graph.ref(newEdge);
522 m_graph.deref(oldEdge);
523
524 edge = newEdge;
525 }
526
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000527 void fixDoubleEdge(unsigned childIndex)
528 {
529 Node& source = m_graph[m_compileIndex];
fpizlo@apple.coma4eaa8a2012-07-15 05:23:58 +0000530 Edge& edge = m_graph.child(source, childIndex);
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000531
msaboff@apple.comde22d5f2013-01-18 21:28:30 +0000532 if (m_graph[edge].prediction() & SpecDouble) {
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000533 edge.setUseKind(DoubleUse);
534 return;
535 }
536
msaboff@apple.com268bb442013-01-18 21:45:06 +0000537 injectInt32ToDoubleNode(childIndex);
538 }
539
540 void injectInt32ToDoubleNode(unsigned childIndex)
541 {
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +0000542 NodeIndex resultIndex = m_insertionSet.insertNode(
543 m_indexInBlock, DontRefChildren, RefNode, SpecDouble, Int32ToDouble,
544 m_graph[m_compileIndex].codeOrigin,
545 m_graph.child(m_graph[m_compileIndex], childIndex).index());
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000546
547#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +0000548 dataLogF(
549 "(replacing @%u->@%u with @%u->@%u) ",
550 m_compileIndex, m_graph.child(m_graph[m_compileIndex], childIndex).index(), m_compileIndex, resultIndex);
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000551#endif
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000552
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +0000553 m_graph.child(m_graph[m_compileIndex], childIndex) = Edge(resultIndex, DoubleUse);
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000554 }
fpizlo@apple.comf10d0722012-12-03 09:21:22 +0000555
556 BasicBlock* m_block;
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000557 unsigned m_indexInBlock;
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000558 NodeIndex m_compileIndex;
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +0000559 InsertionSet m_insertionSet;
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000560};
561
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +0000562bool performFixup(Graph& graph)
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000563{
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000564 SamplingRegion samplingRegion("DFG Fixup Phase");
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +0000565 return runPhase<FixupPhase>(graph);
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000566}
567
568} } // namespace JSC::DFG
569
570#endif // ENABLE(DFG_JIT)
571