blob: c815f4cd86f1a3e917eda47a5179a1c6a5f51797 [file] [log] [blame]
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00001/*
mark.lam@apple.comeb19fea2014-01-23 23:13:23 +00002 * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00003 *
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"
ossy@webkit.orgbeb0de42014-02-17 19:00:03 +000027#include "DFGFixupPhase.h"
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000028
29#if ENABLE(DFG_JIT)
30
fpizlo@apple.com0bef2a12014-02-10 19:26:29 +000031#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.com7e5ed6e2013-03-20 22:37:09 +000034#include "DFGPredictionPropagationPhase.h"
fpizlo@apple.com0bef2a12014-02-10 19:26:29 +000035#include "DFGVariableAccessDataDump.h"
fpizlo@apple.comfb7eff22014-02-11 01:45:50 +000036#include "JSCInlines.h"
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000037
38namespace JSC { namespace DFG {
39
40class FixupPhase : public Phase {
41public:
42 FixupPhase(Graph& graph)
43 : Phase(graph, "fixup")
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +000044 , m_insertionSet(graph)
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000045 {
46 }
47
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +000048 bool run()
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000049 {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +000050 ASSERT(m_graph.m_fixpointState == BeforeFixpoint);
51 ASSERT(m_graph.m_form == ThreadedCPS);
52
fpizlo@apple.combbaf6192013-02-27 01:45:28 +000053 m_profitabilityChanged = false;
oliver@apple.com426f5b02013-07-25 04:04:27 +000054 for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
55 fixupBlock(m_graph.block(blockIndex));
fpizlo@apple.combbaf6192013-02-27 01:45:28 +000056
57 while (m_profitabilityChanged) {
58 m_profitabilityChanged = false;
59
60 for (unsigned i = m_graph.m_argumentPositions.size(); i--;)
61 m_graph.m_argumentPositions[i].mergeArgumentUnboxingAwareness();
62
oliver@apple.com426f5b02013-07-25 04:04:27 +000063 for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
64 fixupSetLocalsInBlock(m_graph.block(blockIndex));
fpizlo@apple.combbaf6192013-02-27 01:45:28 +000065 }
66
fpizlo@apple.com6921b292013-09-18 17:14:02 +000067 for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
68 fixupUntypedSetLocalsInBlock(m_graph.block(blockIndex));
69
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +000070 return true;
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000071 }
72
73private:
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +000074 void fixupBlock(BasicBlock* block)
75 {
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +000076 if (!block)
77 return;
78 ASSERT(block->isReachable);
fpizlo@apple.comf10d0722012-12-03 09:21:22 +000079 m_block = block;
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +000080 for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +000081 m_currentNode = block->at(m_indexInBlock);
82 fixupNode(m_currentNode);
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +000083 }
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +000084 m_insertionSet.execute(block);
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +000085 }
86
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +000087 void fixupNode(Node* node)
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000088 {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +000089 NodeType op = node->op();
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000090
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000091 switch (op) {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +000092 case SetLocal: {
fpizlo@apple.combbaf6192013-02-27 01:45:28 +000093 // This gets handled by fixupSetLocalsInBlock().
fpizlo@apple.com6921b292013-09-18 17:14:02 +000094 return;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +000095 }
96
97 case BitAnd:
fpizlo@apple.com027ed672014-01-08 00:27:06 +000098 case BitOr:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +000099 case BitXor:
100 case BitRShift:
101 case BitLShift:
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000102 case BitURShift: {
msaboff@apple.com95894332014-01-29 19:18:54 +0000103 fixIntEdge(node->child1());
104 fixIntEdge(node->child2());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000105 break;
106 }
fpizlo@apple.com027ed672014-01-08 00:27:06 +0000107
oliver@apple.com64367322013-04-26 00:41:38 +0000108 case ArithIMul: {
msaboff@apple.com95894332014-01-29 19:18:54 +0000109 fixIntEdge(node->child1());
110 fixIntEdge(node->child2());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000111 node->setOp(ArithMul);
112 node->setArithMode(Arith::Unchecked);
113 node->child1().setUseKind(Int32Use);
114 node->child2().setUseKind(Int32Use);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000115 break;
116 }
117
118 case UInt32ToNumber: {
fpizlo@apple.com027ed672014-01-08 00:27:06 +0000119 fixIntEdge(node->child1());
fpizlo@apple.com9089acb2013-12-14 06:33:42 +0000120 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
121 node->convertToIdentity();
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000122 else if (nodeCanSpeculateInt32(node->arithNodeFlags()))
123 node->setArithMode(Arith::CheckOverflow);
124 else
125 node->setArithMode(Arith::DoOverflow);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000126 break;
127 }
128
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000129 case ValueAdd: {
fpizlo@apple.com97756552014-01-02 20:15:25 +0000130 if (attemptToMakeIntegerAdd(node)) {
131 node->setOp(ArithAdd);
132 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000133 break;
fpizlo@apple.com97756552014-01-02 20:15:25 +0000134 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000135 if (Node::shouldSpeculateNumberExpectingDefined(node->child1().node(), node->child2().node())) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000136 fixEdge<NumberUse>(node->child1());
137 fixEdge<NumberUse>(node->child2());
fpizlo@apple.com97756552014-01-02 20:15:25 +0000138 node->setOp(ArithAdd);
139 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000140 break;
141 }
fpizlo@apple.com8d225912013-03-19 00:44:57 +0000142
143 // FIXME: Optimize for the case where one of the operands is the
144 // empty string. Also consider optimizing for the case where we don't
145 // believe either side is the emtpy string. Both of these things should
146 // be easy.
147
148 if (node->child1()->shouldSpeculateString()
149 && attemptToMakeFastStringAdd<StringUse>(node, node->child1(), node->child2()))
150 break;
151 if (node->child2()->shouldSpeculateString()
152 && attemptToMakeFastStringAdd<StringUse>(node, node->child2(), node->child1()))
153 break;
154 if (node->child1()->shouldSpeculateStringObject()
155 && attemptToMakeFastStringAdd<StringObjectUse>(node, node->child1(), node->child2()))
156 break;
157 if (node->child2()->shouldSpeculateStringObject()
158 && attemptToMakeFastStringAdd<StringObjectUse>(node, node->child2(), node->child1()))
159 break;
160 if (node->child1()->shouldSpeculateStringOrStringObject()
161 && attemptToMakeFastStringAdd<StringOrStringObjectUse>(node, node->child1(), node->child2()))
162 break;
163 if (node->child2()->shouldSpeculateStringOrStringObject()
164 && attemptToMakeFastStringAdd<StringOrStringObjectUse>(node, node->child2(), node->child1()))
165 break;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000166 break;
167 }
168
fpizlo@apple.com4463e442013-03-20 20:29:37 +0000169 case MakeRope: {
170 fixupMakeRope(node);
171 break;
172 }
173
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000174 case ArithAdd:
175 case ArithSub: {
176 if (attemptToMakeIntegerAdd(node))
177 break;
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000178 fixEdge<NumberUse>(node->child1());
179 fixEdge<NumberUse>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000180 break;
181 }
182
183 case ArithNegate: {
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000184 if (m_graph.negateShouldSpeculateInt32(node)) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000185 fixEdge<Int32Use>(node->child1());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000186 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
187 node->setArithMode(Arith::Unchecked);
188 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
189 node->setArithMode(Arith::CheckOverflow);
190 else
191 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000192 break;
193 }
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000194 if (m_graph.negateShouldSpeculateMachineInt(node)) {
195 fixEdge<MachineIntUse>(node->child1());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000196 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
197 node->setArithMode(Arith::CheckOverflow);
198 else
199 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000200 break;
201 }
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000202 fixEdge<NumberUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000203 break;
204 }
205
206 case ArithMul: {
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000207 if (m_graph.mulShouldSpeculateInt32(node)) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000208 fixEdge<Int32Use>(node->child1());
209 fixEdge<Int32Use>(node->child2());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000210 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
211 node->setArithMode(Arith::Unchecked);
212 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
213 node->setArithMode(Arith::CheckOverflow);
214 else
215 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000216 break;
217 }
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000218 if (m_graph.mulShouldSpeculateMachineInt(node)) {
219 fixEdge<MachineIntUse>(node->child1());
220 fixEdge<MachineIntUse>(node->child2());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000221 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
222 node->setArithMode(Arith::CheckOverflow);
223 else
224 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000225 break;
226 }
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000227 fixEdge<NumberUse>(node->child1());
228 fixEdge<NumberUse>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000229 break;
230 }
231
oliver@apple.comf4443a72013-07-25 04:01:11 +0000232 case ArithDiv:
233 case ArithMod: {
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000234 if (Node::shouldSpeculateInt32ForArithmetic(node->child1().node(), node->child2().node())
235 && node->canSpeculateInt32()) {
fpizlo@apple.com51204922013-12-11 06:50:19 +0000236 if (optimizeForX86() || optimizeForARM64() || optimizeForARMv7s()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000237 fixEdge<Int32Use>(node->child1());
238 fixEdge<Int32Use>(node->child2());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000239 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
240 node->setArithMode(Arith::Unchecked);
241 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
242 node->setArithMode(Arith::CheckOverflow);
243 else
244 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000245 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000246 }
fpizlo@apple.com51204922013-12-11 06:50:19 +0000247 Edge child1 = node->child1();
248 Edge child2 = node->child2();
249
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000250 injectInt32ToDoubleNode(node->child1());
251 injectInt32ToDoubleNode(node->child2());
252
253 // We don't need to do ref'ing on the children because we're stealing them from
254 // the original division.
255 Node* newDivision = m_insertionSet.insertNode(
fpizlo@apple.com06f82b52013-03-06 02:27:16 +0000256 m_indexInBlock, SpecDouble, *node);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000257
258 node->setOp(DoubleAsInt32);
259 node->children.initialize(Edge(newDivision, KnownNumberUse), Edge(), Edge());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000260 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
261 node->setArithMode(Arith::CheckOverflow);
262 else
263 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
fpizlo@apple.com51204922013-12-11 06:50:19 +0000264
fpizlo@apple.com6793a322014-02-12 05:42:32 +0000265 m_insertionSet.insertNode(m_indexInBlock + 1, SpecNone, Phantom, node->origin, child1, child2);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000266 break;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000267 }
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000268 fixEdge<NumberUse>(node->child1());
269 fixEdge<NumberUse>(node->child2());
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000270 break;
271 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000272
273 case ArithMin:
oliver@apple.comf4443a72013-07-25 04:01:11 +0000274 case ArithMax: {
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000275 if (Node::shouldSpeculateInt32ForArithmetic(node->child1().node(), node->child2().node())
276 && node->canSpeculateInt32()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000277 fixEdge<Int32Use>(node->child1());
278 fixEdge<Int32Use>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000279 break;
280 }
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000281 fixEdge<NumberUse>(node->child1());
282 fixEdge<NumberUse>(node->child2());
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000283 break;
284 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000285
286 case ArithAbs: {
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000287 if (node->child1()->shouldSpeculateInt32ForArithmetic()
288 && node->canSpeculateInt32()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000289 fixEdge<Int32Use>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000290 break;
291 }
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000292 fixEdge<NumberUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000293 break;
294 }
295
fpizlo@apple.comb3336c72013-10-31 19:19:15 +0000296 case ArithSqrt:
297 case ArithSin:
298 case ArithCos: {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000299 fixEdge<NumberUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000300 break;
301 }
302
303 case LogicalNot: {
304 if (node->child1()->shouldSpeculateBoolean())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000305 fixEdge<BooleanUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000306 else if (node->child1()->shouldSpeculateObjectOrOther())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000307 fixEdge<ObjectOrOtherUse>(node->child1());
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000308 else if (node->child1()->shouldSpeculateInt32())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000309 fixEdge<Int32Use>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000310 else if (node->child1()->shouldSpeculateNumber())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000311 fixEdge<NumberUse>(node->child1());
commit-queue@webkit.org008e8dc2013-10-12 02:21:45 +0000312 else if (node->child1()->shouldSpeculateString())
313 fixEdge<StringUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000314 break;
315 }
316
317 case TypeOf: {
318 if (node->child1()->shouldSpeculateString())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000319 fixEdge<StringUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000320 else if (node->child1()->shouldSpeculateCell())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000321 fixEdge<CellUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000322 break;
323 }
324
fpizlo@apple.comee10e452013-04-09 00:10:16 +0000325 case CompareEqConstant: {
326 break;
327 }
328
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000329 case CompareEq:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000330 case CompareLess:
331 case CompareLessEq:
332 case CompareGreater:
333 case CompareGreaterEq: {
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000334 if (Node::shouldSpeculateInt32(node->child1().node(), node->child2().node())) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000335 fixEdge<Int32Use>(node->child1());
336 fixEdge<Int32Use>(node->child2());
fpizlo@apple.com97756552014-01-02 20:15:25 +0000337 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000338 break;
339 }
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000340 if (enableInt52()
341 && Node::shouldSpeculateMachineInt(node->child1().node(), node->child2().node())) {
342 fixEdge<MachineIntUse>(node->child1());
343 fixEdge<MachineIntUse>(node->child2());
fpizlo@apple.com97756552014-01-02 20:15:25 +0000344 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000345 break;
346 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000347 if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000348 fixEdge<NumberUse>(node->child1());
349 fixEdge<NumberUse>(node->child2());
fpizlo@apple.com97756552014-01-02 20:15:25 +0000350 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000351 break;
352 }
353 if (node->op() != CompareEq)
354 break;
ggaren@apple.com0f001eb2013-04-24 15:48:55 +0000355 if (Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000356 fixEdge<BooleanUse>(node->child1());
357 fixEdge<BooleanUse>(node->child2());
fpizlo@apple.com97756552014-01-02 20:15:25 +0000358 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
ggaren@apple.com0f001eb2013-04-24 15:48:55 +0000359 break;
360 }
oliver@apple.combd15be82013-07-25 04:03:42 +0000361 if (node->child1()->shouldSpeculateStringIdent() && node->child2()->shouldSpeculateStringIdent()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000362 fixEdge<StringIdentUse>(node->child1());
363 fixEdge<StringIdentUse>(node->child2());
fpizlo@apple.com97756552014-01-02 20:15:25 +0000364 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
oliver@apple.combd15be82013-07-25 04:03:42 +0000365 break;
366 }
fpizlo@apple.comee10e452013-04-09 00:10:16 +0000367 if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && GPRInfo::numberOfRegisters >= 7) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000368 fixEdge<StringUse>(node->child1());
369 fixEdge<StringUse>(node->child2());
fpizlo@apple.com97756552014-01-02 20:15:25 +0000370 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000371 break;
fpizlo@apple.comee10e452013-04-09 00:10:16 +0000372 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000373 if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000374 fixEdge<ObjectUse>(node->child1());
375 fixEdge<ObjectUse>(node->child2());
fpizlo@apple.com97756552014-01-02 20:15:25 +0000376 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000377 break;
378 }
379 if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObjectOrOther()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000380 fixEdge<ObjectUse>(node->child1());
381 fixEdge<ObjectOrOtherUse>(node->child2());
fpizlo@apple.com97756552014-01-02 20:15:25 +0000382 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000383 break;
384 }
385 if (node->child1()->shouldSpeculateObjectOrOther() && node->child2()->shouldSpeculateObject()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000386 fixEdge<ObjectOrOtherUse>(node->child1());
387 fixEdge<ObjectUse>(node->child2());
fpizlo@apple.com97756552014-01-02 20:15:25 +0000388 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000389 break;
390 }
391 break;
392 }
393
fpizlo@apple.comee10e452013-04-09 00:10:16 +0000394 case CompareStrictEq: {
ggaren@apple.com0f001eb2013-04-24 15:48:55 +0000395 if (Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000396 fixEdge<BooleanUse>(node->child1());
397 fixEdge<BooleanUse>(node->child2());
ggaren@apple.com0f001eb2013-04-24 15:48:55 +0000398 break;
399 }
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000400 if (Node::shouldSpeculateInt32(node->child1().node(), node->child2().node())) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000401 fixEdge<Int32Use>(node->child1());
402 fixEdge<Int32Use>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000403 break;
404 }
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000405 if (enableInt52()
406 && Node::shouldSpeculateMachineInt(node->child1().node(), node->child2().node())) {
407 fixEdge<MachineIntUse>(node->child1());
408 fixEdge<MachineIntUse>(node->child2());
409 break;
410 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000411 if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000412 fixEdge<NumberUse>(node->child1());
413 fixEdge<NumberUse>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000414 break;
415 }
oliver@apple.combd15be82013-07-25 04:03:42 +0000416 if (node->child1()->shouldSpeculateStringIdent() && node->child2()->shouldSpeculateStringIdent()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000417 fixEdge<StringIdentUse>(node->child1());
418 fixEdge<StringIdentUse>(node->child2());
oliver@apple.combd15be82013-07-25 04:03:42 +0000419 break;
420 }
fpizlo@apple.com322ad4f2014-03-19 20:36:45 +0000421 if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && (GPRInfo::numberOfRegisters >= 7 || isFTL(m_graph.m_plan.mode))) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000422 fixEdge<StringUse>(node->child1());
423 fixEdge<StringUse>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000424 break;
fpizlo@apple.comee10e452013-04-09 00:10:16 +0000425 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000426 if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000427 fixEdge<ObjectUse>(node->child1());
428 fixEdge<ObjectUse>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000429 break;
430 }
fpizlo@apple.com312efcd2014-03-10 22:11:35 +0000431 if (node->child1()->shouldSpeculateMisc()) {
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000432 fixEdge<MiscUse>(node->child1());
fpizlo@apple.com312efcd2014-03-10 22:11:35 +0000433 break;
434 }
435 if (node->child2()->shouldSpeculateMisc()) {
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000436 fixEdge<MiscUse>(node->child2());
437 break;
438 }
fpizlo@apple.com385a33a2014-03-18 20:53:07 +0000439 if (node->child1()->shouldSpeculateStringIdent()
440 && node->child2()->shouldSpeculateNotStringVar()) {
441 fixEdge<StringIdentUse>(node->child1());
442 fixEdge<NotStringVarUse>(node->child2());
443 break;
444 }
445 if (node->child2()->shouldSpeculateStringIdent()
446 && node->child1()->shouldSpeculateNotStringVar()) {
447 fixEdge<StringIdentUse>(node->child2());
448 fixEdge<NotStringVarUse>(node->child1());
449 break;
450 }
fpizlo@apple.com322ad4f2014-03-19 20:36:45 +0000451 if (node->child1()->shouldSpeculateString() && (GPRInfo::numberOfRegisters >= 8 || isFTL(m_graph.m_plan.mode))) {
fpizlo@apple.com385a33a2014-03-18 20:53:07 +0000452 fixEdge<StringUse>(node->child1());
453 break;
454 }
fpizlo@apple.com322ad4f2014-03-19 20:36:45 +0000455 if (node->child2()->shouldSpeculateString() && (GPRInfo::numberOfRegisters >= 8 || isFTL(m_graph.m_plan.mode))) {
fpizlo@apple.com385a33a2014-03-18 20:53:07 +0000456 fixEdge<StringUse>(node->child2());
457 break;
458 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000459 break;
460 }
461
commit-queue@webkit.orgaa31a5e2013-04-09 06:45:16 +0000462 case StringFromCharCode:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000463 fixEdge<Int32Use>(node->child1());
commit-queue@webkit.orgaa31a5e2013-04-09 06:45:16 +0000464 break;
465
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000466 case StringCharAt:
467 case StringCharCodeAt: {
468 // Currently we have no good way of refining these.
469 ASSERT(node->arrayMode() == ArrayMode(Array::String));
470 blessArrayOperation(node->child1(), node->child2(), node->child3());
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000471 fixEdge<KnownCellUse>(node->child1());
472 fixEdge<Int32Use>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000473 break;
474 }
475
fpizlo@apple.coma387b6a2012-11-01 07:41:43 +0000476 case GetByVal: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000477 node->setArrayMode(
478 node->arrayMode().refine(
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000479 m_graph, node,
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000480 node->child1()->prediction(),
481 node->child2()->prediction(),
482 SpecNone, node->flags()));
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000483
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000484 blessArrayOperation(node->child1(), node->child2(), node->child3());
fpizlo@apple.com94e84e92012-11-11 02:56:12 +0000485
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000486 ArrayMode arrayMode = node->arrayMode();
oliver@apple.com211b3be2013-07-25 04:03:39 +0000487 switch (arrayMode.type()) {
488 case Array::Double:
489 if (arrayMode.arrayClass() == Array::OriginalArray
490 && arrayMode.speculation() == Array::InBounds
fpizlo@apple.com6793a322014-02-12 05:42:32 +0000491 && m_graph.globalObjectFor(node->origin.semantic)->arrayPrototypeChainIsSane()
fpizlo@apple.comdc36e832013-09-11 03:24:09 +0000492 && !(node->flags() & NodeBytecodeUsesAsOther))
oliver@apple.com211b3be2013-07-25 04:03:39 +0000493 node->setArrayMode(arrayMode.withSpeculation(Array::SaneChain));
494 break;
495
496 case Array::String:
497 if ((node->prediction() & ~SpecString)
fpizlo@apple.com6793a322014-02-12 05:42:32 +0000498 || m_graph.hasExitSite(node->origin.semantic, OutOfBounds))
oliver@apple.com211b3be2013-07-25 04:03:39 +0000499 node->setArrayMode(arrayMode.withSpeculation(Array::OutOfBounds));
500 break;
501
502 default:
503 break;
504 }
fpizlo@apple.com94e84e92012-11-11 02:56:12 +0000505
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000506 switch (node->arrayMode().type()) {
507 case Array::SelectUsingPredictions:
508 case Array::Unprofiled:
509 case Array::Undecided:
510 RELEASE_ASSERT_NOT_REACHED();
511 break;
512 case Array::Generic:
513#if USE(JSVALUE32_64)
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000514 fixEdge<CellUse>(node->child1()); // Speculating cell due to register pressure on 32-bit.
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000515#endif
516 break;
517 case Array::ForceExit:
518 break;
519 default:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000520 fixEdge<KnownCellUse>(node->child1());
521 fixEdge<Int32Use>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000522 break;
523 }
524
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000525 break;
526 }
oliver@apple.come050d642013-10-19 00:09:28 +0000527
528 case PutByValDirect:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000529 case PutByVal:
530 case PutByValAlias: {
531 Edge& child1 = m_graph.varArgChild(node, 0);
532 Edge& child2 = m_graph.varArgChild(node, 1);
533 Edge& child3 = m_graph.varArgChild(node, 2);
534
535 node->setArrayMode(
536 node->arrayMode().refine(
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000537 m_graph, node,
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000538 child1->prediction(),
539 child2->prediction(),
540 child3->prediction()));
541
542 blessArrayOperation(child1, child2, m_graph.varArgChild(node, 3));
543
544 switch (node->arrayMode().modeForPut().type()) {
545 case Array::SelectUsingPredictions:
546 case Array::Unprofiled:
547 case Array::Undecided:
548 RELEASE_ASSERT_NOT_REACHED();
549 break;
550 case Array::ForceExit:
551 case Array::Generic:
552#if USE(JSVALUE32_64)
553 // Due to register pressure on 32-bit, we speculate cell and
554 // ignore the base-is-not-cell case entirely by letting the
555 // baseline JIT handle it.
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000556 fixEdge<CellUse>(child1);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000557#endif
558 break;
559 case Array::Int32:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000560 fixEdge<KnownCellUse>(child1);
561 fixEdge<Int32Use>(child2);
562 fixEdge<Int32Use>(child3);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000563 if (child3->prediction() & SpecInt52)
564 fixEdge<MachineIntUse>(child3);
565 else
566 fixEdge<Int32Use>(child3);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000567 break;
568 case Array::Double:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000569 fixEdge<KnownCellUse>(child1);
570 fixEdge<Int32Use>(child2);
571 fixEdge<RealNumberUse>(child3);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000572 break;
573 case Array::Int8Array:
574 case Array::Int16Array:
575 case Array::Int32Array:
576 case Array::Uint8Array:
577 case Array::Uint8ClampedArray:
578 case Array::Uint16Array:
579 case Array::Uint32Array:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000580 fixEdge<KnownCellUse>(child1);
581 fixEdge<Int32Use>(child2);
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000582 if (child3->shouldSpeculateInt32())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000583 fixEdge<Int32Use>(child3);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000584 else if (child3->shouldSpeculateMachineInt())
585 fixEdge<MachineIntUse>(child3);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000586 else
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000587 fixEdge<NumberUse>(child3);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000588 break;
589 case Array::Float32Array:
590 case Array::Float64Array:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000591 fixEdge<KnownCellUse>(child1);
592 fixEdge<Int32Use>(child2);
593 fixEdge<NumberUse>(child3);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000594 break;
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000595 case Array::Contiguous:
596 case Array::ArrayStorage:
597 case Array::SlowPutArrayStorage:
598 case Array::Arguments:
599 fixEdge<KnownCellUse>(child1);
600 fixEdge<Int32Use>(child2);
mhahnenberg@apple.comf37746e2014-03-10 22:21:44 +0000601 insertStoreBarrier(m_indexInBlock, child1);
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000602 break;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000603 default:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000604 fixEdge<KnownCellUse>(child1);
605 fixEdge<Int32Use>(child2);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000606 break;
607 }
fpizlo@apple.coma387b6a2012-11-01 07:41:43 +0000608 break;
609 }
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000610
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000611 case ArrayPush: {
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000612 // May need to refine the array mode in case the value prediction contravenes
613 // the array prediction. For example, we may have evidence showing that the
614 // array is in Int32 mode, but the value we're storing is likely to be a double.
615 // Then we should turn this into a conversion to Double array followed by the
616 // push. On the other hand, we absolutely don't want to refine based on the
617 // base prediction. If it has non-cell garbage in it, then we want that to be
618 // ignored. That's because ArrayPush can't handle any array modes that aren't
619 // array-related - so if refine() turned this into a "Generic" ArrayPush then
620 // that would break things.
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000621 node->setArrayMode(
622 node->arrayMode().refine(
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000623 m_graph, node,
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000624 node->child1()->prediction() & SpecCell,
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000625 SpecInt32,
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000626 node->child2()->prediction()));
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000627 blessArrayOperation(node->child1(), Edge(), node->child3());
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000628 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000629
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000630 switch (node->arrayMode().type()) {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000631 case Array::Int32:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000632 fixEdge<Int32Use>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000633 break;
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000634 case Array::Double:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000635 fixEdge<RealNumberUse>(node->child2());
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000636 break;
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000637 case Array::Contiguous:
638 case Array::ArrayStorage:
mhahnenberg@apple.comf37746e2014-03-10 22:21:44 +0000639 insertStoreBarrier(m_indexInBlock, node->child1());
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000640 break;
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000641 default:
642 break;
643 }
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000644 break;
645 }
646
647 case ArrayPop: {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000648 blessArrayOperation(node->child1(), Edge(), node->child2());
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000649 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.com8fd79212012-10-16 21:59:35 +0000650 break;
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000651 }
652
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000653 case RegExpExec:
654 case RegExpTest: {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000655 fixEdge<CellUse>(node->child1());
656 fixEdge<CellUse>(node->child2());
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000657 break;
658 }
659
660 case Branch: {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000661 if (node->child1()->shouldSpeculateBoolean())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000662 fixEdge<BooleanUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000663 else if (node->child1()->shouldSpeculateObjectOrOther())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000664 fixEdge<ObjectOrOtherUse>(node->child1());
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000665 else if (node->child1()->shouldSpeculateInt32())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000666 fixEdge<Int32Use>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000667 else if (node->child1()->shouldSpeculateNumber())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000668 fixEdge<NumberUse>(node->child1());
fpizlo@apple.come2967fd2012-04-04 21:14:48 +0000669
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000670 Node* logicalNot = node->child1().node();
fpizlo@apple.com098a1452013-03-01 20:57:37 +0000671 if (logicalNot->op() == LogicalNot) {
fpizlo@apple.com573b9002013-02-13 21:00:01 +0000672
673 // Make sure that OSR exit can't observe the LogicalNot. If it can,
674 // then we must compute it and cannot peephole around it.
675 bool found = false;
676 bool ok = true;
677 for (unsigned i = m_indexInBlock; i--;) {
678 Node* candidate = m_block->at(i);
fpizlo@apple.com573b9002013-02-13 21:00:01 +0000679 if (candidate == logicalNot) {
680 found = true;
681 break;
682 }
683 if (candidate->canExit()) {
684 ok = false;
685 found = true;
686 break;
687 }
688 }
689 ASSERT_UNUSED(found, found);
690
691 if (ok) {
692 Edge newChildEdge = logicalNot->child1();
693 if (newChildEdge->hasBooleanResult()) {
fpizlo@apple.com573b9002013-02-13 21:00:01 +0000694 node->children.setChild1(newChildEdge);
695
fpizlo@apple.comb8377cd2014-02-20 08:00:28 +0000696 BranchData* data = node->branchData();
697 std::swap(data->taken, data->notTaken);
fpizlo@apple.com573b9002013-02-13 21:00:01 +0000698 }
fpizlo@apple.coma6c889b2012-04-12 04:19:07 +0000699 }
fpizlo@apple.come2967fd2012-04-04 21:14:48 +0000700 }
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000701 break;
702 }
703
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000704 case Switch: {
705 SwitchData* data = node->switchData();
706 switch (data->kind) {
707 case SwitchImm:
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000708 if (node->child1()->shouldSpeculateInt32())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000709 fixEdge<Int32Use>(node->child1());
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000710 break;
oliver@apple.com9e1c8092013-07-25 04:03:16 +0000711 case SwitchChar:
712 if (node->child1()->shouldSpeculateString())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000713 fixEdge<StringUse>(node->child1());
oliver@apple.com9e1c8092013-07-25 04:03:16 +0000714 break;
oliver@apple.com5c826c02013-07-25 04:03:51 +0000715 case SwitchString:
716 if (node->child1()->shouldSpeculateStringIdent())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000717 fixEdge<StringIdentUse>(node->child1());
oliver@apple.com5c826c02013-07-25 04:03:51 +0000718 else if (node->child1()->shouldSpeculateString())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000719 fixEdge<StringUse>(node->child1());
oliver@apple.com5c826c02013-07-25 04:03:51 +0000720 break;
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000721 }
722 break;
723 }
724
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000725 case ToPrimitive: {
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +0000726 fixupToPrimitive(node);
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000727 break;
728 }
729
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +0000730 case ToString: {
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +0000731 fixupToString(node);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +0000732 break;
733 }
734
735 case NewStringObject: {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000736 fixEdge<KnownStringUse>(node->child1());
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +0000737 break;
738 }
739
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000740 case NewArray: {
741 for (unsigned i = m_graph.varArgNumChildren(node); i--;) {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000742 node->setIndexingType(
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000743 leastUpperBoundOfIndexingTypeAndType(
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000744 node->indexingType(), m_graph.varArgChild(node, i)->prediction()));
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000745 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000746 switch (node->indexingType()) {
747 case ALL_BLANK_INDEXING_TYPES:
748 CRASH();
749 break;
750 case ALL_UNDECIDED_INDEXING_TYPES:
751 if (node->numChildren()) {
752 // This will only happen if the children have no type predictions. We
753 // would have already exited by now, but insert a forced exit just to
754 // be safe.
755 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +0000756 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000757 }
758 break;
759 case ALL_INT32_INDEXING_TYPES:
760 for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000761 fixEdge<Int32Use>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000762 break;
763 case ALL_DOUBLE_INDEXING_TYPES:
764 for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000765 fixEdge<RealNumberUse>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000766 break;
767 case ALL_CONTIGUOUS_INDEXING_TYPES:
768 case ALL_ARRAY_STORAGE_INDEXING_TYPES:
769 break;
770 default:
771 CRASH();
772 break;
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000773 }
774 break;
775 }
776
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000777 case NewTypedArray: {
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000778 if (node->child1()->shouldSpeculateInt32()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000779 fixEdge<Int32Use>(node->child1());
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000780 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
781 break;
782 }
783 break;
784 }
785
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000786 case NewArrayWithSize: {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000787 fixEdge<Int32Use>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000788 break;
789 }
790
oliver@apple.come2fe4ce2013-07-25 03:59:41 +0000791 case ToThis: {
fpizlo@apple.com6793a322014-02-12 05:42:32 +0000792 ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->isStrictMode() ? StrictMode : NotStrictMode;
oliver@apple.come2fe4ce2013-07-25 03:59:41 +0000793
fpizlo@apple.com312efcd2014-03-10 22:11:35 +0000794 if (node->child1()->shouldSpeculateOther()) {
oliver@apple.come2fe4ce2013-07-25 03:59:41 +0000795 if (ecmaMode == StrictMode) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000796 fixEdge<OtherUse>(node->child1());
oliver@apple.come2fe4ce2013-07-25 03:59:41 +0000797 node->convertToIdentity();
798 break;
799 }
800
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +0000801 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +0000802 m_indexInBlock, SpecNone, Phantom, node->origin,
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +0000803 Edge(node->child1().node(), OtherUse));
804 observeUseKindOnNode<OtherUse>(node->child1().node());
fpizlo@apple.com6793a322014-02-12 05:42:32 +0000805 node->convertToWeakConstant(m_graph.globalThisObjectFor(node->origin.semantic));
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +0000806 break;
807 }
808
oliver@apple.come2fe4ce2013-07-25 03:59:41 +0000809 if (isFinalObjectSpeculation(node->child1()->prediction())) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000810 fixEdge<FinalObjectUse>(node->child1());
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +0000811 node->convertToIdentity();
812 break;
813 }
814
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000815 break;
816 }
817
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000818 case GetMyArgumentByVal:
819 case GetMyArgumentByValSafe: {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000820 fixEdge<Int32Use>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000821 break;
822 }
823
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000824 case PutStructure: {
825 fixEdge<KnownCellUse>(node->child1());
826 insertStoreBarrier(m_indexInBlock, node->child1());
827 break;
828 }
829
830 case PutClosureVar: {
831 fixEdge<KnownCellUse>(node->child1());
mhahnenberg@apple.comf37746e2014-03-10 22:21:44 +0000832 insertStoreBarrier(m_indexInBlock, node->child1());
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000833 break;
834 }
835
oliver@apple.com58c86752013-07-25 04:02:40 +0000836 case GetClosureRegisters:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000837 case SkipTopScope:
838 case SkipScope:
oliver@apple.come17632e2013-07-25 04:05:31 +0000839 case GetScope: {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000840 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000841 break;
842 }
843
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000844 case AllocatePropertyStorage:
845 case ReallocatePropertyStorage: {
846 fixEdge<KnownCellUse>(node->child1());
847 insertStoreBarrier(m_indexInBlock + 1, node->child1());
848 break;
849 }
850
fpizlo@apple.com151e9af2013-08-16 02:30:37 +0000851 case GetById:
852 case GetByIdFlush: {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000853 if (!node->child1()->shouldSpeculateCell())
854 break;
fpizlo@apple.com537a4772013-08-19 23:16:01 +0000855 StringImpl* impl = m_graph.identifiers()[node->identifierNumber()];
856 if (impl == vm().propertyNames->length.impl()) {
fpizlo@apple.comc09dc632013-08-17 05:50:48 +0000857 attemptToMakeGetArrayLength(node);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000858 break;
fpizlo@apple.com151e9af2013-08-16 02:30:37 +0000859 }
fpizlo@apple.com537a4772013-08-19 23:16:01 +0000860 if (impl == vm().propertyNames->byteLength.impl()) {
861 attemptToMakeGetTypedArrayByteLength(node);
862 break;
863 }
864 if (impl == vm().propertyNames->byteOffset.impl()) {
865 attemptToMakeGetTypedArrayByteOffset(node);
fpizlo@apple.comc09dc632013-08-17 05:50:48 +0000866 break;
fpizlo@apple.comcbc41132013-03-19 20:23:01 +0000867 }
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000868 fixEdge<CellUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000869 break;
870 }
871
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000872 case PutById:
oliver@apple.com11ce5ff2014-03-06 21:27:13 +0000873 case PutByIdFlush:
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000874 case PutByIdDirect: {
875 fixEdge<CellUse>(node->child1());
mhahnenberg@apple.comf37746e2014-03-10 22:21:44 +0000876 insertStoreBarrier(m_indexInBlock, node->child1());
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000877 break;
878 }
879
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000880 case CheckExecutable:
881 case CheckStructure:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000882 case StructureTransitionWatchpoint:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000883 case CheckFunction:
oliver@apple.come17632e2013-07-25 04:05:31 +0000884 case CheckHasInstance:
885 case CreateThis:
886 case GetButterfly: {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000887 fixEdge<CellUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000888 break;
889 }
890
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000891 case Arrayify:
892 case ArrayifyToStructure: {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000893 fixEdge<CellUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000894 if (node->child2())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000895 fixEdge<Int32Use>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000896 break;
897 }
898
899 case GetByOffset: {
900 if (!node->child1()->hasStorageResult())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000901 fixEdge<KnownCellUse>(node->child1());
902 fixEdge<KnownCellUse>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000903 break;
904 }
905
fpizlo@apple.com51614cc2014-02-17 06:35:32 +0000906 case MultiGetByOffset: {
907 fixEdge<CellUse>(node->child1());
908 break;
909 }
910
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000911 case PutByOffset: {
912 if (!node->child1()->hasStorageResult())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000913 fixEdge<KnownCellUse>(node->child1());
914 fixEdge<KnownCellUse>(node->child2());
mhahnenberg@apple.comf37746e2014-03-10 22:21:44 +0000915 insertStoreBarrier(m_indexInBlock, node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000916 break;
917 }
918
fpizlo@apple.com43219522014-02-25 02:02:50 +0000919 case MultiPutByOffset: {
920 fixEdge<CellUse>(node->child1());
mhahnenberg@apple.comf37746e2014-03-10 22:21:44 +0000921 insertStoreBarrier(m_indexInBlock, node->child1());
fpizlo@apple.com43219522014-02-25 02:02:50 +0000922 break;
923 }
924
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000925 case InstanceOf: {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000926 if (!(node->child1()->prediction() & ~SpecCell))
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000927 fixEdge<CellUse>(node->child1());
928 fixEdge<CellUse>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000929 break;
930 }
oliver@apple.comb3e5acb2013-07-25 04:02:53 +0000931
932 case In: {
933 // FIXME: We should at some point have array profiling on op_in, in which
934 // case we would be able to turn this into a kind of GetByVal.
935
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000936 fixEdge<CellUse>(node->child2());
oliver@apple.comb3e5acb2013-07-25 04:02:53 +0000937 break;
938 }
fpizlo@apple.com46955912013-04-26 01:18:18 +0000939
940 case Phantom:
fpizlo@apple.com9df7fef2013-12-29 21:50:55 +0000941 case Identity:
942 case Check: {
fpizlo@apple.com46955912013-04-26 01:18:18 +0000943 switch (node->child1().useKind()) {
944 case NumberUse:
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000945 if (node->child1()->shouldSpeculateInt32ForArithmetic())
fpizlo@apple.com46955912013-04-26 01:18:18 +0000946 node->child1().setUseKind(Int32Use);
947 break;
948 default:
949 break;
950 }
951 observeUseKindOnEdge(node->child1());
952 break;
953 }
954
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000955 case GetArrayLength:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000956 case Phi:
oliver@apple.com827d2cf2013-07-25 04:04:45 +0000957 case Upsilon:
958 case GetArgument:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000959 case PhantomPutStructure:
960 case GetIndexedPropertyStorage:
fpizlo@apple.com537a4772013-08-19 23:16:01 +0000961 case GetTypedArrayByteOffset:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000962 case LastNodeType:
fpizlo@apple.com532f1e52013-09-04 06:26:04 +0000963 case CheckTierUpInLoop:
964 case CheckTierUpAtReturn:
965 case CheckTierUpAndOSREnter:
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000966 case Int52ToDouble:
967 case Int52ToValue:
fpizlo@apple.comd84425d2013-10-30 19:58:08 +0000968 case InvalidationPoint:
fpizlo@apple.com97ef5782013-11-05 05:39:03 +0000969 case CheckArray:
fpizlo@apple.com8624c4b2013-12-10 03:24:31 +0000970 case CheckInBounds:
fpizlo@apple.com9ca951e2013-12-09 01:08:53 +0000971 case ConstantStoragePointer:
fpizlo@apple.com027ed672014-01-08 00:27:06 +0000972 case DoubleAsInt32:
973 case Int32ToDouble:
974 case ValueToInt32:
fpizlo@apple.com4c96a842014-02-13 22:46:51 +0000975 case HardPhantom: // HardPhantom would be trivial to handle but anyway we assert that we won't see it here yet.
fpizlo@apple.com9ca951e2013-12-09 01:08:53 +0000976 // These are just nodes that we don't currently expect to see during fixup.
977 // If we ever wanted to insert them prior to fixup, then we just have to create
978 // fixup rules for them.
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000979 RELEASE_ASSERT_NOT_REACHED();
980 break;
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000981
982 case PutGlobalVar: {
fpizlo@apple.com6793a322014-02-12 05:42:32 +0000983 Node* globalObjectNode = m_insertionSet.insertNode(
984 m_indexInBlock, SpecNone, WeakJSConstant, node->origin,
985 OpInfo(m_graph.globalObjectFor(node->origin.semantic)));
986 Node* barrierNode = m_graph.addNode(
mhahnenberg@apple.comf37746e2014-03-10 22:21:44 +0000987 SpecNone, StoreBarrier, m_currentNode->origin,
988 Edge(globalObjectNode, KnownCellUse));
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000989 m_insertionSet.insert(m_indexInBlock, barrierNode);
990 break;
991 }
992
993 case TearOffActivation: {
fpizlo@apple.com6793a322014-02-12 05:42:32 +0000994 Node* barrierNode = m_graph.addNode(
995 SpecNone, StoreBarrierWithNullCheck, m_currentNode->origin,
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000996 Edge(node->child1().node(), UntypedUse));
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000997 m_insertionSet.insert(m_indexInBlock, barrierNode);
998 break;
999 }
commit-queue@webkit.org2faae0e2013-10-07 22:08:53 +00001000
1001 case IsString:
1002 if (node->child1()->shouldSpeculateString()) {
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001003 m_insertionSet.insertNode(
1004 m_indexInBlock, SpecNone, Phantom, node->origin,
commit-queue@webkit.org2faae0e2013-10-07 22:08:53 +00001005 Edge(node->child1().node(), StringUse));
1006 m_graph.convertToConstant(node, jsBoolean(true));
1007 observeUseKindOnNode<StringUse>(node);
1008 }
1009 break;
fpizlo@apple.com9df7fef2013-12-29 21:50:55 +00001010
commit-queue@webkit.org2faae0e2013-10-07 22:08:53 +00001011#if !ASSERT_DISABLED
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001012 // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
1013 case SetArgument:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001014 case JSConstant:
1015 case WeakJSConstant:
1016 case GetLocal:
1017 case GetCallee:
1018 case Flush:
1019 case PhantomLocal:
1020 case GetLocalUnlinked:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001021 case GetMyScope:
oliver@apple.com58c86752013-07-25 04:02:40 +00001022 case GetClosureVar:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001023 case GetGlobalVar:
fpizlo@apple.com86468342013-11-27 02:47:43 +00001024 case NotifyWrite:
1025 case VariableWatchpoint:
oliver@apple.com58c86752013-07-25 04:02:40 +00001026 case VarInjectionWatchpoint:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001027 case AllocationProfileWatchpoint:
1028 case Call:
1029 case Construct:
1030 case NewObject:
1031 case NewArrayBuffer:
1032 case NewRegexp:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001033 case Breakpoint:
mark.lam@apple.comeb19fea2014-01-23 23:13:23 +00001034 case ProfileWillCall:
1035 case ProfileDidCall:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001036 case IsUndefined:
1037 case IsBoolean:
1038 case IsNumber:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001039 case IsObject:
1040 case IsFunction:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001041 case CreateActivation:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001042 case CreateArguments:
1043 case PhantomArguments:
1044 case TearOffArguments:
1045 case GetMyArgumentsLength:
1046 case GetMyArgumentsLengthSafe:
1047 case CheckArgumentsNotCreated:
1048 case NewFunction:
1049 case NewFunctionNoCheck:
1050 case NewFunctionExpression:
1051 case Jump:
1052 case Return:
1053 case Throw:
1054 case ThrowReferenceError:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001055 case CountExecution:
1056 case ForceOSRExit:
mark.lam@apple.com10d23a12013-04-25 02:59:51 +00001057 case CheckWatchdogTimer:
oliver@apple.com1fc04182013-08-19 19:40:13 +00001058 case Unreachable:
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001059 case ExtractOSREntryLocal:
1060 case LoopHint:
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001061 case StoreBarrier:
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001062 case StoreBarrierWithNullCheck:
fpizlo@apple.coma4ea0662013-12-02 19:09:15 +00001063 case FunctionReentryWatchpoint:
fpizlo@apple.comce995b22013-12-08 19:01:17 +00001064 case TypedArrayWatchpoint:
fpizlo@apple.com9df7fef2013-12-29 21:50:55 +00001065 case MovHint:
1066 case ZombieHint:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001067 break;
1068#else
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00001069 default:
1070 break;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001071#endif
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00001072 }
fpizlo@apple.comaa1cc982013-09-12 05:46:49 +00001073
fpizlo@apple.com9df7fef2013-12-29 21:50:55 +00001074 if (!node->containsMovHint())
1075 DFG_NODE_DO_TO_CHILDREN(m_graph, node, observeUntypedEdge);
msaboff@apple.com95894332014-01-29 19:18:54 +00001076
1077 if (node->isTerminal()) {
1078 // Terminal nodes don't need post-phantoms, and inserting them would violate
1079 // the current requirement that a terminal is the last thing in a block. We
1080 // should eventually change that requirement but even if we did, this would
1081 // still be a valid optimization. All terminals accept just one input, and
1082 // if that input is a conversion node then no further speculations will be
1083 // performed.
1084 // FIXME: Get rid of this by allowing Phantoms after terminals.
1085 // https://bugs.webkit.org/show_bug.cgi?id=126778
1086 m_requiredPhantoms.resize(0);
fpizlo@apple.com239e2682014-02-25 17:47:29 +00001087 // Since StoreBarriers are recursively fixed up so that their children look
1088 // identical to that of the node they're barrier-ing, we need to avoid adding
1089 // any Phantoms when processing them because this would invalidate the
1090 // InsertionSet's invariant of inserting things in a monotonically increasing
1091 // order. This should be okay anyways because StoreBarriers can't exit.
msaboff@apple.com95894332014-01-29 19:18:54 +00001092 } else
1093 addPhantomsIfNecessary();
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00001094 }
1095
fpizlo@apple.comaa1cc982013-09-12 05:46:49 +00001096 void observeUntypedEdge(Node*, Edge& edge)
1097 {
1098 if (edge.useKind() != UntypedUse)
1099 return;
1100 fixEdge<UntypedUse>(edge);
1101 }
1102
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001103 template<UseKind useKind>
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001104 void createToString(Node* node, Edge& edge)
fpizlo@apple.comcbc41132013-03-19 20:23:01 +00001105 {
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001106 edge.setNode(m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001107 m_indexInBlock, SpecString, ToString, node->origin,
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001108 Edge(edge.node(), useKind)));
fpizlo@apple.comcbc41132013-03-19 20:23:01 +00001109 }
1110
1111 template<UseKind useKind>
1112 void attemptToForceStringArrayModeByToStringConversion(ArrayMode& arrayMode, Node* node)
1113 {
1114 ASSERT(arrayMode == ArrayMode(Array::Generic));
1115
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001116 if (!canOptimizeStringObjectAccess(node->origin.semantic))
fpizlo@apple.comcbc41132013-03-19 20:23:01 +00001117 return;
1118
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001119 createToString<useKind>(node, node->child1());
fpizlo@apple.comcbc41132013-03-19 20:23:01 +00001120 arrayMode = ArrayMode(Array::String);
1121 }
1122
1123 template<UseKind useKind>
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001124 bool isStringObjectUse()
1125 {
1126 switch (useKind) {
1127 case StringObjectUse:
1128 case StringOrStringObjectUse:
1129 return true;
1130 default:
1131 return false;
1132 }
1133 }
1134
1135 template<UseKind useKind>
1136 void convertStringAddUse(Node* node, Edge& edge)
1137 {
1138 if (useKind == StringUse) {
1139 // This preserves the binaryUseKind() invariant ot ValueAdd: ValueAdd's
1140 // two edges will always have identical use kinds, which makes the
1141 // decision process much easier.
1142 observeUseKindOnNode<StringUse>(edge.node());
1143 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001144 m_indexInBlock, SpecNone, Phantom, node->origin,
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001145 Edge(edge.node(), StringUse));
1146 edge.setUseKind(KnownStringUse);
1147 return;
1148 }
1149
1150 // FIXME: We ought to be able to have a ToPrimitiveToString node.
1151
1152 observeUseKindOnNode<useKind>(edge.node());
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001153 createToString<useKind>(node, edge);
1154 }
1155
1156 void convertToMakeRope(Node* node)
1157 {
1158 node->setOpAndDefaultFlags(MakeRope);
1159 fixupMakeRope(node);
1160 }
1161
1162 void fixupMakeRope(Node* node)
1163 {
1164 for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
1165 Edge& edge = node->children.child(i);
1166 if (!edge)
1167 break;
1168 edge.setUseKind(KnownStringUse);
1169 if (!m_graph.isConstant(edge.node()))
1170 continue;
1171 JSString* string = jsCast<JSString*>(m_graph.valueOfJSConstant(edge.node()).asCell());
1172 if (string->length())
1173 continue;
fpizlo@apple.com4bb938e2013-07-16 21:41:06 +00001174
1175 // Don't allow the MakeRope to have zero children.
1176 if (!i && !node->child2())
1177 break;
1178
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001179 node->children.removeEdge(i--);
1180 }
1181
1182 if (!node->child2()) {
1183 ASSERT(!node->child3());
1184 node->convertToIdentity();
1185 }
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001186 }
1187
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001188 void fixupToPrimitive(Node* node)
1189 {
fpizlo@apple.comefacb612013-09-10 22:16:00 +00001190 if (node->child1()->shouldSpeculateInt32()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001191 fixEdge<Int32Use>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001192 node->convertToIdentity();
1193 return;
1194 }
1195
1196 if (node->child1()->shouldSpeculateString()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001197 fixEdge<StringUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001198 node->convertToIdentity();
1199 return;
1200 }
1201
1202 if (node->child1()->shouldSpeculateStringObject()
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001203 && canOptimizeStringObjectAccess(node->origin.semantic)) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001204 fixEdge<StringObjectUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001205 node->convertToToString();
1206 return;
1207 }
1208
1209 if (node->child1()->shouldSpeculateStringOrStringObject()
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001210 && canOptimizeStringObjectAccess(node->origin.semantic)) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001211 fixEdge<StringOrStringObjectUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001212 node->convertToToString();
1213 return;
1214 }
1215 }
1216
1217 void fixupToString(Node* node)
1218 {
1219 if (node->child1()->shouldSpeculateString()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001220 fixEdge<StringUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001221 node->convertToIdentity();
1222 return;
1223 }
1224
1225 if (node->child1()->shouldSpeculateStringObject()
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001226 && canOptimizeStringObjectAccess(node->origin.semantic)) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001227 fixEdge<StringObjectUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001228 return;
1229 }
1230
1231 if (node->child1()->shouldSpeculateStringOrStringObject()
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001232 && canOptimizeStringObjectAccess(node->origin.semantic)) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001233 fixEdge<StringOrStringObjectUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001234 return;
1235 }
1236
1237 if (node->child1()->shouldSpeculateCell()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001238 fixEdge<CellUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001239 return;
1240 }
1241 }
1242
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001243 template<UseKind leftUseKind>
1244 bool attemptToMakeFastStringAdd(Node* node, Edge& left, Edge& right)
1245 {
fpizlo@apple.comdbeeff32013-07-24 04:51:57 +00001246 Node* originalLeft = left.node();
1247 Node* originalRight = right.node();
1248
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001249 ASSERT(leftUseKind == StringUse || leftUseKind == StringObjectUse || leftUseKind == StringOrStringObjectUse);
1250
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001251 if (isStringObjectUse<leftUseKind>() && !canOptimizeStringObjectAccess(node->origin.semantic))
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001252 return false;
1253
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001254 convertStringAddUse<leftUseKind>(node, left);
1255
1256 if (right->shouldSpeculateString())
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001257 convertStringAddUse<StringUse>(node, right);
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001258 else if (right->shouldSpeculateStringObject() && canOptimizeStringObjectAccess(node->origin.semantic))
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001259 convertStringAddUse<StringObjectUse>(node, right);
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001260 else if (right->shouldSpeculateStringOrStringObject() && canOptimizeStringObjectAccess(node->origin.semantic))
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001261 convertStringAddUse<StringOrStringObjectUse>(node, right);
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001262 else {
1263 // At this point we know that the other operand is something weird. The semantically correct
1264 // way of dealing with this is:
1265 //
1266 // MakeRope(@left, ToString(ToPrimitive(@right)))
1267 //
1268 // So that's what we emit. NB, we need to do all relevant type checks on @left before we do
1269 // anything to @right, since ToPrimitive may be effectful.
1270
1271 Node* toPrimitive = m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001272 m_indexInBlock, resultOfToPrimitive(right->prediction()), ToPrimitive,
1273 node->origin, Edge(right.node()));
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001274 Node* toString = m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001275 m_indexInBlock, SpecString, ToString, node->origin, Edge(toPrimitive));
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001276
1277 fixupToPrimitive(toPrimitive);
1278 fixupToString(toString);
1279
1280 right.setNode(toString);
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001281 }
1282
fpizlo@apple.comdbeeff32013-07-24 04:51:57 +00001283 // We're doing checks up there, so we need to make sure that the
1284 // *original* inputs to the addition are live up to here.
1285 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001286 m_indexInBlock, SpecNone, Phantom, node->origin,
fpizlo@apple.comdbeeff32013-07-24 04:51:57 +00001287 Edge(originalLeft), Edge(originalRight));
1288
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001289 convertToMakeRope(node);
1290 return true;
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001291 }
1292
oliver@apple.com02039462013-07-25 03:59:29 +00001293 bool isStringPrototypeMethodSane(Structure* stringPrototypeStructure, StringImpl* uid)
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001294 {
1295 unsigned attributesUnused;
1296 JSCell* specificValue;
oliver@apple.com22fdb102013-07-25 03:58:56 +00001297 PropertyOffset offset = stringPrototypeStructure->getConcurrently(
oliver@apple.com02039462013-07-25 03:59:29 +00001298 vm(), uid, attributesUnused, specificValue);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001299 if (!isValidOffset(offset))
1300 return false;
1301
1302 if (!specificValue)
1303 return false;
1304
fpizlo@apple.com10ae2d02013-08-14 02:41:47 +00001305 if (!specificValue->inherits(JSFunction::info()))
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001306 return false;
1307
1308 JSFunction* function = jsCast<JSFunction*>(specificValue);
1309 if (function->executable()->intrinsicFor(CodeForCall) != StringPrototypeValueOfIntrinsic)
1310 return false;
1311
1312 return true;
1313 }
1314
1315 bool canOptimizeStringObjectAccess(const CodeOrigin& codeOrigin)
1316 {
1317 if (m_graph.hasExitSite(codeOrigin, NotStringObject))
1318 return false;
1319
1320 Structure* stringObjectStructure = m_graph.globalObjectFor(codeOrigin)->stringObjectStructure();
1321 ASSERT(stringObjectStructure->storedPrototype().isObject());
fpizlo@apple.com10ae2d02013-08-14 02:41:47 +00001322 ASSERT(stringObjectStructure->storedPrototype().asCell()->classInfo() == StringPrototype::info());
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001323
1324 JSObject* stringPrototypeObject = asObject(stringObjectStructure->storedPrototype());
1325 Structure* stringPrototypeStructure = stringPrototypeObject->structure();
oliver@apple.com90fce822013-07-25 04:00:13 +00001326 if (!m_graph.watchpoints().isStillValid(stringPrototypeStructure->transitionWatchpointSet()))
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001327 return false;
1328
1329 if (stringPrototypeStructure->isDictionary())
1330 return false;
1331
1332 // We're being conservative here. We want DFG's ToString on StringObject to be
1333 // used in both numeric contexts (that would call valueOf()) and string contexts
1334 // (that would call toString()). We don't want the DFG to have to distinguish
1335 // between the two, just because that seems like it would get confusing. So we
1336 // just require both methods to be sane.
oliver@apple.com02039462013-07-25 03:59:29 +00001337 if (!isStringPrototypeMethodSane(stringPrototypeStructure, vm().propertyNames->valueOf.impl()))
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001338 return false;
oliver@apple.com02039462013-07-25 03:59:29 +00001339 if (!isStringPrototypeMethodSane(stringPrototypeStructure, vm().propertyNames->toString.impl()))
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001340 return false;
1341
1342 return true;
1343 }
1344
fpizlo@apple.combbaf6192013-02-27 01:45:28 +00001345 void fixupSetLocalsInBlock(BasicBlock* block)
1346 {
1347 if (!block)
1348 return;
1349 ASSERT(block->isReachable);
1350 m_block = block;
1351 for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
1352 Node* node = m_currentNode = block->at(m_indexInBlock);
1353 if (node->op() != SetLocal)
1354 continue;
fpizlo@apple.combbaf6192013-02-27 01:45:28 +00001355
1356 VariableAccessData* variable = node->variableAccessData();
fpizlo@apple.com571d3b22013-09-11 21:24:34 +00001357 switch (variable->flushFormat()) {
1358 case FlushedJSValue:
1359 break;
1360 case FlushedDouble:
fpizlo@apple.comc6bb4a92013-09-30 20:38:46 +00001361 fixEdge<NumberUse>(node->child1());
fpizlo@apple.com571d3b22013-09-11 21:24:34 +00001362 break;
1363 case FlushedInt32:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001364 fixEdge<Int32Use>(node->child1());
fpizlo@apple.com571d3b22013-09-11 21:24:34 +00001365 break;
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001366 case FlushedInt52:
1367 fixEdge<MachineIntUse>(node->child1());
1368 break;
fpizlo@apple.com571d3b22013-09-11 21:24:34 +00001369 case FlushedCell:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001370 fixEdge<CellUse>(node->child1());
fpizlo@apple.com571d3b22013-09-11 21:24:34 +00001371 break;
1372 case FlushedBoolean:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001373 fixEdge<BooleanUse>(node->child1());
fpizlo@apple.com571d3b22013-09-11 21:24:34 +00001374 break;
1375 default:
1376 RELEASE_ASSERT_NOT_REACHED();
1377 break;
1378 }
msaboff@apple.com95894332014-01-29 19:18:54 +00001379 addPhantomsIfNecessary();
fpizlo@apple.combbaf6192013-02-27 01:45:28 +00001380 }
1381 m_insertionSet.execute(block);
1382 }
1383
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001384 void fixupUntypedSetLocalsInBlock(BasicBlock* block)
1385 {
1386 if (!block)
1387 return;
1388 ASSERT(block->isReachable);
1389 m_block = block;
1390 for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
1391 Node* node = m_currentNode = block->at(m_indexInBlock);
1392 if (node->op() != SetLocal)
1393 continue;
1394
msaboff@apple.com95894332014-01-29 19:18:54 +00001395 if (node->child1().useKind() == UntypedUse) {
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001396 fixEdge<UntypedUse>(node->child1());
msaboff@apple.com95894332014-01-29 19:18:54 +00001397 addPhantomsIfNecessary();
1398 }
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001399 }
1400 m_insertionSet.execute(block);
1401 }
1402
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001403 Node* checkArray(ArrayMode arrayMode, const NodeOrigin& origin, Node* array, Node* index, bool (*storageCheck)(const ArrayMode&) = canCSEStorage)
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001404 {
fpizlo@apple.com34d1f082012-10-28 06:13:23 +00001405 ASSERT(arrayMode.isSpecific());
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001406
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00001407 if (arrayMode.type() == Array::String) {
1408 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001409 m_indexInBlock, SpecNone, Phantom, origin, Edge(array, StringUse));
fpizlo@apple.com99f37622012-10-29 04:02:08 +00001410 } else {
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001411 Structure* structure = arrayMode.originalArrayStructure(m_graph, origin.semantic);
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00001412
1413 Edge indexEdge = index ? Edge(index, Int32Use) : Edge();
1414
1415 if (arrayMode.doesConversion()) {
1416 if (structure) {
1417 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001418 m_indexInBlock, SpecNone, ArrayifyToStructure, origin,
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00001419 OpInfo(structure), OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
1420 } else {
1421 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001422 m_indexInBlock, SpecNone, Arrayify, origin,
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00001423 OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
1424 }
fpizlo@apple.com3f1a01b2012-11-10 05:54:11 +00001425 } else {
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00001426 if (structure) {
1427 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001428 m_indexInBlock, SpecNone, CheckStructure, origin,
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00001429 OpInfo(m_graph.addStructureSet(structure)), Edge(array, CellUse));
1430 } else {
1431 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001432 m_indexInBlock, SpecNone, CheckArray, origin,
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00001433 OpInfo(arrayMode.asWord()), Edge(array, CellUse));
1434 }
fpizlo@apple.com3f1a01b2012-11-10 05:54:11 +00001435 }
fpizlo@apple.com497c7512012-09-19 01:20:52 +00001436 }
1437
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001438 if (!storageCheck(arrayMode))
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001439 return 0;
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001440
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +00001441 if (arrayMode.usesButterfly()) {
1442 return m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001443 m_indexInBlock, SpecNone, GetButterfly, origin, Edge(array, CellUse));
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +00001444 }
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001445
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +00001446 return m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001447 m_indexInBlock, SpecNone, GetIndexedPropertyStorage, origin,
fpizlo@apple.com06f82b52013-03-06 02:27:16 +00001448 OpInfo(arrayMode.asWord()), Edge(array, KnownCellUse));
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001449 }
1450
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001451 void blessArrayOperation(Edge base, Edge index, Edge& storageChild)
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001452 {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001453 Node* node = m_currentNode;
1454
1455 switch (node->arrayMode().type()) {
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001456 case Array::ForceExit: {
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +00001457 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001458 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001459 return;
1460 }
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001461
fpizlo@apple.coma0ec0592012-10-22 23:52:15 +00001462 case Array::SelectUsingPredictions:
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001463 case Array::Unprofiled:
oliver@apple.com5598c182013-01-23 22:25:07 +00001464 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001465 return;
1466
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001467 case Array::Generic:
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001468 return;
1469
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001470 default: {
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001471 Node* storage = checkArray(node->arrayMode(), node->origin, base.node(), index.node());
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001472 if (!storage)
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001473 return;
1474
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001475 storageChild = Edge(storage);
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001476 return;
1477 } }
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001478 }
1479
fpizlo@apple.combbaf6192013-02-27 01:45:28 +00001480 bool alwaysUnboxSimplePrimitives()
1481 {
1482#if USE(JSVALUE64)
1483 return false;
1484#else
1485 // Any boolean, int, or cell value is profitable to unbox on 32-bit because it
1486 // reduces traffic.
1487 return true;
1488#endif
1489 }
fpizlo@apple.com46955912013-04-26 01:18:18 +00001490
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00001491 template<UseKind useKind>
1492 void observeUseKindOnNode(Node* node)
1493 {
fpizlo@apple.comaa1cc982013-09-12 05:46:49 +00001494 if (useKind == UntypedUse)
1495 return;
fpizlo@apple.com46955912013-04-26 01:18:18 +00001496 observeUseKindOnNode(node, useKind);
1497 }
1498
1499 void observeUseKindOnEdge(Edge edge)
1500 {
1501 observeUseKindOnNode(edge.node(), edge.useKind());
1502 }
1503
1504 void observeUseKindOnNode(Node* node, UseKind useKind)
1505 {
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00001506 if (node->op() != GetLocal)
1507 return;
1508
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001509 // FIXME: The way this uses alwaysUnboxSimplePrimitives() is suspicious.
1510 // https://bugs.webkit.org/show_bug.cgi?id=121518
1511
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00001512 VariableAccessData* variable = node->variableAccessData();
1513 switch (useKind) {
1514 case Int32Use:
1515 if (alwaysUnboxSimplePrimitives()
1516 || isInt32Speculation(variable->prediction()))
1517 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1518 break;
1519 case NumberUse:
1520 case RealNumberUse:
1521 if (variable->doubleFormatState() == UsingDoubleFormat)
1522 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1523 break;
1524 case BooleanUse:
1525 if (alwaysUnboxSimplePrimitives()
1526 || isBooleanSpeculation(variable->prediction()))
1527 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1528 break;
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001529 case MachineIntUse:
1530 if (isMachineIntSpeculation(variable->prediction()))
1531 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1532 break;
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00001533 case CellUse:
oliver@apple.com176a3472013-07-25 04:00:19 +00001534 case KnownCellUse:
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00001535 case ObjectUse:
1536 case StringUse:
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001537 case KnownStringUse:
1538 case StringObjectUse:
1539 case StringOrStringObjectUse:
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00001540 if (alwaysUnboxSimplePrimitives()
1541 || isCellSpeculation(variable->prediction()))
1542 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1543 break;
1544 default:
1545 break;
1546 }
1547 }
1548
fpizlo@apple.comaa1cc982013-09-12 05:46:49 +00001549 // Set the use kind of the edge and perform any actions that need to be done for
1550 // that use kind, like inserting intermediate conversion nodes. Never call this
1551 // with useKind = UntypedUse explicitly; edges have UntypedUse implicitly and any
1552 // edge that survives fixup and still has UntypedUse will have this method called
1553 // from observeUntypedEdge(). Also, make sure that if you do change the type of an
1554 // edge, you either call fixEdge() or perform the equivalent functionality
1555 // yourself. Obviously, you should have a really good reason if you do the latter.
fpizlo@apple.com35701872013-02-23 01:03:10 +00001556 template<UseKind useKind>
fpizlo@apple.comc6bb4a92013-09-30 20:38:46 +00001557 void fixEdge(Edge& edge)
fpizlo@apple.com35701872013-02-23 01:03:10 +00001558 {
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001559 if (isDouble(useKind)) {
1560 if (edge->shouldSpeculateInt32ForArithmetic()) {
fpizlo@apple.com9df7fef2013-12-29 21:50:55 +00001561 injectInt32ToDoubleNode(edge, useKind);
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001562 return;
1563 }
1564
1565 if (enableInt52() && edge->shouldSpeculateMachineInt()) {
1566 // Make all double uses of int52 values have an intermediate Int52ToDouble.
1567 // This is for the same reason as Int52ToValue (see below) except that
1568 // Int8ToDouble will convert int52's that fit in an int32 into a double
1569 // rather than trying to create a boxed int32 like Int52ToValue does.
1570
msaboff@apple.com95894332014-01-29 19:18:54 +00001571 m_requiredPhantoms.append(edge.node());
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001572 Node* result = m_insertionSet.insertNode(
1573 m_indexInBlock, SpecInt52AsDouble, Int52ToDouble,
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001574 m_currentNode->origin, Edge(edge.node(), NumberUse));
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001575 edge = Edge(result, useKind);
1576 return;
1577 }
1578 }
1579
1580 if (enableInt52() && useKind != MachineIntUse
1581 && edge->shouldSpeculateMachineInt() && !edge->shouldSpeculateInt32()) {
1582 // We make all non-int52 uses of int52 values have an intermediate Int52ToValue
1583 // node to ensure that we handle this properly:
1584 //
1585 // a: SomeInt52
1586 // b: ArithAdd(@a, ...)
1587 // c: Call(..., @a)
1588 // d: ArithAdd(@a, ...)
1589 //
1590 // Without an intermediate node and just labeling the uses, we will get:
1591 //
1592 // a: SomeInt52
1593 // b: ArithAdd(Int52:@a, ...)
1594 // c: Call(..., Untyped:@a)
1595 // d: ArithAdd(Int52:@a, ...)
1596 //
1597 // And now the c->Untyped:@a edge will box the value of @a into a double. This
1598 // is bad, because now the d->Int52:@a edge will either have to do double-to-int
1599 // conversions, or will have to OSR exit unconditionally. Alternatively we could
1600 // have the c->Untyped:@a edge box the value by copying rather than in-place.
1601 // But these boxings are also costly so this wouldn't be great.
1602 //
1603 // The solution we use is to always have non-Int52 uses of predicted Int52's use
1604 // an intervening Int52ToValue node:
1605 //
1606 // a: SomeInt52
1607 // b: ArithAdd(Int52:@a, ...)
1608 // x: Int52ToValue(Int52:@a)
1609 // c: Call(..., Untyped:@x)
1610 // d: ArithAdd(Int52:@a, ...)
1611 //
1612 // Note that even if we had multiple non-int52 uses of @a, the multiple
1613 // Int52ToValue's would get CSE'd together. So the boxing would only happen once.
1614 // At the same time, @a would continue to be represented as a native int52.
1615 //
1616 // An alternative would have been to insert ToNativeInt52 nodes on int52 uses of
1617 // int52's. This would have handled the above example but would fall over for:
1618 //
1619 // a: SomeInt52
1620 // b: Call(..., @a)
1621 // c: ArithAdd(@a, ...)
1622 //
1623 // But the solution we use handles the above gracefully.
1624
msaboff@apple.com95894332014-01-29 19:18:54 +00001625 m_requiredPhantoms.append(edge.node());
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001626 Node* result = m_insertionSet.insertNode(
1627 m_indexInBlock, SpecInt52, Int52ToValue,
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001628 m_currentNode->origin, Edge(edge.node(), UntypedUse));
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001629 edge = Edge(result, useKind);
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001630 return;
1631 }
1632
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00001633 observeUseKindOnNode<useKind>(edge.node());
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001634
fpizlo@apple.com35701872013-02-23 01:03:10 +00001635 edge.setUseKind(useKind);
1636 }
1637
mhahnenberg@apple.comf37746e2014-03-10 22:21:44 +00001638 void insertStoreBarrier(unsigned indexInBlock, Edge child1)
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001639 {
mhahnenberg@apple.comf37746e2014-03-10 22:21:44 +00001640 Node* barrierNode = m_graph.addNode(SpecNone, StoreBarrier, m_currentNode->origin, child1);
fpizlo@apple.com239e2682014-02-25 17:47:29 +00001641 m_insertionSet.insert(indexInBlock, barrierNode);
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001642 }
1643
msaboff@apple.com95894332014-01-29 19:18:54 +00001644 void fixIntEdge(Edge& edge)
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00001645 {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001646 Node* node = edge.node();
fpizlo@apple.com027ed672014-01-08 00:27:06 +00001647 if (node->shouldSpeculateInt32()) {
1648 fixEdge<Int32Use>(edge);
msaboff@apple.com95894332014-01-29 19:18:54 +00001649 return;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001650 }
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00001651
fpizlo@apple.com027ed672014-01-08 00:27:06 +00001652 UseKind useKind;
1653 if (node->shouldSpeculateMachineInt())
1654 useKind = MachineIntUse;
1655 else if (node->shouldSpeculateNumber())
1656 useKind = NumberUse;
1657 else if (node->shouldSpeculateBoolean())
1658 useKind = BooleanUse;
1659 else
1660 useKind = NotCellUse;
1661 Node* newNode = m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001662 m_indexInBlock, SpecInt32, ValueToInt32, m_currentNode->origin,
fpizlo@apple.com027ed672014-01-08 00:27:06 +00001663 Edge(node, useKind));
1664 observeUseKindOnNode(node, useKind);
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00001665
fpizlo@apple.com027ed672014-01-08 00:27:06 +00001666 edge = Edge(newNode, KnownInt32Use);
msaboff@apple.com95894332014-01-29 19:18:54 +00001667 m_requiredPhantoms.append(node);
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00001668 }
1669
fpizlo@apple.com9df7fef2013-12-29 21:50:55 +00001670 void injectInt32ToDoubleNode(Edge& edge, UseKind useKind = NumberUse)
msaboff@apple.com268bb442013-01-18 21:45:06 +00001671 {
msaboff@apple.com95894332014-01-29 19:18:54 +00001672 m_requiredPhantoms.append(edge.node());
1673
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001674 Node* result = m_insertionSet.insertNode(
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001675 m_indexInBlock, SpecInt52AsDouble, Int32ToDouble,
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001676 m_currentNode->origin, Edge(edge.node(), NumberUse));
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +00001677
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001678 edge = Edge(result, useKind);
1679 }
1680
1681 void truncateConstantToInt32(Edge& edge)
1682 {
1683 Node* oldNode = edge.node();
1684
1685 ASSERT(oldNode->hasConstant());
1686 JSValue value = m_graph.valueOfJSConstant(oldNode);
1687 if (value.isInt32())
1688 return;
1689
1690 value = jsNumber(JSC::toInt32(value.asNumber()));
1691 ASSERT(value.isInt32());
mhahnenberg@apple.com941ab382013-08-16 03:28:39 +00001692 unsigned constantRegister;
1693 if (!codeBlock()->findConstant(value, constantRegister)) {
mhahnenberg@apple.com25e78932013-08-20 19:39:54 +00001694 constantRegister = codeBlock()->addConstantLazily();
mhahnenberg@apple.comfd433bf2013-08-18 03:08:52 +00001695 initializeLazyWriteBarrierForConstant(
mhahnenberg@apple.com941ab382013-08-16 03:28:39 +00001696 m_graph.m_plan.writeBarriers,
mhahnenberg@apple.com25e78932013-08-20 19:39:54 +00001697 codeBlock()->constants()[constantRegister],
1698 codeBlock(),
1699 constantRegister,
mhahnenberg@apple.com941ab382013-08-16 03:28:39 +00001700 codeBlock()->ownerExecutable(),
1701 value);
1702 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001703 edge.setNode(m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001704 m_indexInBlock, SpecInt32, JSConstant, m_currentNode->origin,
mhahnenberg@apple.com941ab382013-08-16 03:28:39 +00001705 OpInfo(constantRegister)));
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001706 }
1707
1708 void truncateConstantsIfNecessary(Node* node, AddSpeculationMode mode)
1709 {
fpizlo@apple.comefacb612013-09-10 22:16:00 +00001710 if (mode != SpeculateInt32AndTruncateConstants)
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001711 return;
1712
1713 ASSERT(node->child1()->hasConstant() || node->child2()->hasConstant());
1714 if (node->child1()->hasConstant())
1715 truncateConstantToInt32(node->child1());
1716 else
1717 truncateConstantToInt32(node->child2());
1718 }
1719
1720 bool attemptToMakeIntegerAdd(Node* node)
1721 {
1722 AddSpeculationMode mode = m_graph.addSpeculationMode(node);
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001723 if (mode != DontSpeculateInt32) {
1724 truncateConstantsIfNecessary(node, mode);
1725 fixEdge<Int32Use>(node->child1());
1726 fixEdge<Int32Use>(node->child2());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +00001727 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
1728 node->setArithMode(Arith::Unchecked);
1729 else
1730 node->setArithMode(Arith::CheckOverflow);
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001731 return true;
1732 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001733
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001734 if (m_graph.addShouldSpeculateMachineInt(node)) {
1735 fixEdge<MachineIntUse>(node->child1());
1736 fixEdge<MachineIntUse>(node->child2());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +00001737 node->setArithMode(Arith::CheckOverflow);
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001738 return true;
1739 }
1740
1741 return false;
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +00001742 }
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00001743
1744 bool attemptToMakeGetArrayLength(Node* node)
1745 {
1746 if (!isInt32Speculation(node->prediction()))
1747 return false;
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001748 CodeBlock* profiledBlock = m_graph.baselineCodeBlockFor(node->origin.semantic);
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00001749 ArrayProfile* arrayProfile =
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001750 profiledBlock->getArrayProfile(node->origin.semantic.bytecodeIndex);
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00001751 ArrayMode arrayMode = ArrayMode(Array::SelectUsingPredictions);
1752 if (arrayProfile) {
1753 ConcurrentJITLocker locker(profiledBlock->m_lock);
1754 arrayProfile->computeUpdatedPrediction(locker, profiledBlock);
1755 arrayMode = ArrayMode::fromObserved(locker, arrayProfile, Array::Read, false);
1756 if (arrayMode.type() == Array::Unprofiled) {
1757 // For normal array operations, it makes sense to treat Unprofiled
1758 // accesses as ForceExit and get more data rather than using
1759 // predictions and then possibly ending up with a Generic. But here,
1760 // we treat anything that is Unprofiled as Generic and keep the
1761 // GetById. I.e. ForceExit = Generic. So, there is no harm - and only
1762 // profit - from treating the Unprofiled case as
1763 // SelectUsingPredictions.
1764 arrayMode = ArrayMode(Array::SelectUsingPredictions);
1765 }
1766 }
1767
msaboff@apple.com95894332014-01-29 19:18:54 +00001768 arrayMode = arrayMode.refine(
fpizlo@apple.come079bb52014-03-05 07:41:03 +00001769 m_graph, node, node->child1()->prediction(), node->prediction());
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00001770
1771 if (arrayMode.type() == Array::Generic) {
1772 // Check if the input is something that we can't get array length for, but for which we
1773 // could insert some conversions in order to transform it into something that we can do it
1774 // for.
1775 if (node->child1()->shouldSpeculateStringObject())
1776 attemptToForceStringArrayModeByToStringConversion<StringObjectUse>(arrayMode, node);
1777 else if (node->child1()->shouldSpeculateStringOrStringObject())
1778 attemptToForceStringArrayModeByToStringConversion<StringOrStringObjectUse>(arrayMode, node);
1779 }
1780
1781 if (!arrayMode.supportsLength())
1782 return false;
1783
1784 convertToGetArrayLength(node, arrayMode);
1785 return true;
1786 }
1787
fpizlo@apple.com537a4772013-08-19 23:16:01 +00001788 bool attemptToMakeGetTypedArrayByteLength(Node* node)
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00001789 {
1790 if (!isInt32Speculation(node->prediction()))
1791 return false;
1792
1793 TypedArrayType type = typedArrayTypeFromSpeculation(node->child1()->prediction());
1794 if (!isTypedView(type))
1795 return false;
1796
1797 if (elementSize(type) == 1) {
1798 convertToGetArrayLength(node, ArrayMode(toArrayType(type)));
1799 return true;
1800 }
1801
1802 Node* length = prependGetArrayLength(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001803 node->origin, node->child1().node(), ArrayMode(toArrayType(type)));
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00001804
1805 Node* shiftAmount = m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001806 m_indexInBlock, SpecInt32, JSConstant, node->origin,
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00001807 OpInfo(m_graph.constantRegisterForConstant(jsNumber(logElementSize(type)))));
1808
1809 // We can use a BitLShift here because typed arrays will never have a byteLength
1810 // that overflows int32.
1811 node->setOp(BitLShift);
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00001812 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
1813 observeUseKindOnNode(length, Int32Use);
1814 observeUseKindOnNode(shiftAmount, Int32Use);
1815 node->child1() = Edge(length, Int32Use);
1816 node->child2() = Edge(shiftAmount, Int32Use);
1817 return true;
1818 }
1819
1820 void convertToGetArrayLength(Node* node, ArrayMode arrayMode)
1821 {
1822 node->setOp(GetArrayLength);
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00001823 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001824 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00001825 node->setArrayMode(arrayMode);
1826
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001827 Node* storage = checkArray(arrayMode, node->origin, node->child1().node(), 0, lengthNeedsStorage);
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00001828 if (!storage)
1829 return;
1830
1831 node->child2() = Edge(storage);
1832 }
1833
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001834 Node* prependGetArrayLength(NodeOrigin origin, Node* child, ArrayMode arrayMode)
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00001835 {
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001836 Node* storage = checkArray(arrayMode, origin, child, 0, lengthNeedsStorage);
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00001837 return m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001838 m_indexInBlock, SpecInt32, GetArrayLength, origin,
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00001839 OpInfo(arrayMode.asWord()), Edge(child, KnownCellUse), Edge(storage));
1840 }
fpizlo@apple.com537a4772013-08-19 23:16:01 +00001841
1842 bool attemptToMakeGetTypedArrayByteOffset(Node* node)
1843 {
1844 if (!isInt32Speculation(node->prediction()))
1845 return false;
1846
1847 TypedArrayType type = typedArrayTypeFromSpeculation(node->child1()->prediction());
1848 if (!isTypedView(type))
1849 return false;
1850
1851 checkArray(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001852 ArrayMode(toArrayType(type)), node->origin, node->child1().node(),
fpizlo@apple.com537a4772013-08-19 23:16:01 +00001853 0, neverNeedsStorage);
1854
1855 node->setOp(GetTypedArrayByteOffset);
1856 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001857 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.com537a4772013-08-19 23:16:01 +00001858 return true;
1859 }
msaboff@apple.com95894332014-01-29 19:18:54 +00001860
1861 void addPhantomsIfNecessary()
1862 {
1863 if (m_requiredPhantoms.isEmpty())
1864 return;
1865
1866 for (unsigned i = m_requiredPhantoms.size(); i--;) {
1867 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001868 m_indexInBlock + 1, SpecNone, Phantom, m_currentNode->origin,
msaboff@apple.com95894332014-01-29 19:18:54 +00001869 Edge(m_requiredPhantoms[i], UntypedUse));
1870 }
1871
1872 m_requiredPhantoms.resize(0);
1873 }
fpizlo@apple.comf10d0722012-12-03 09:21:22 +00001874
1875 BasicBlock* m_block;
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +00001876 unsigned m_indexInBlock;
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001877 Node* m_currentNode;
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +00001878 InsertionSet m_insertionSet;
fpizlo@apple.combbaf6192013-02-27 01:45:28 +00001879 bool m_profitabilityChanged;
msaboff@apple.com95894332014-01-29 19:18:54 +00001880 Vector<Node*, 3> m_requiredPhantoms;
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00001881};
1882
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +00001883bool performFixup(Graph& graph)
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00001884{
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +00001885 SamplingRegion samplingRegion("DFG Fixup Phase");
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +00001886 return runPhase<FixupPhase>(graph);
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00001887}
1888
1889} } // namespace JSC::DFG
1890
1891#endif // ENABLE(DFG_JIT)
1892