blob: d5e9c3d7f49edfacb29366982c754bf441857b23 [file] [log] [blame]
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00001/*
fpizlo@apple.comcad67682015-02-09 19:57:41 +00002 * Copyright (C) 2012-2015 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.com141cdcc2015-05-06 23:14:14 +000031#include "ArrayPrototype.h"
fpizlo@apple.com0bef2a12014-02-10 19:26:29 +000032#include "DFGGraph.h"
fpizlo@apple.com12835772015-09-21 20:49:04 +000033#include "DFGInferredTypeCheck.h"
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +000034#include "DFGInsertionSet.h"
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000035#include "DFGPhase.h"
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +000036#include "DFGPredictionPropagationPhase.h"
fpizlo@apple.com0bef2a12014-02-10 19:26:29 +000037#include "DFGVariableAccessDataDump.h"
fpizlo@apple.comfb7eff22014-02-11 01:45:50 +000038#include "JSCInlines.h"
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +000039#include "TypeLocation.h"
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000040
41namespace JSC { namespace DFG {
42
43class FixupPhase : public Phase {
44public:
45 FixupPhase(Graph& graph)
46 : Phase(graph, "fixup")
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +000047 , m_insertionSet(graph)
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000048 {
49 }
50
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +000051 bool run()
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000052 {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +000053 ASSERT(m_graph.m_fixpointState == BeforeFixpoint);
54 ASSERT(m_graph.m_form == ThreadedCPS);
55
fpizlo@apple.combbaf6192013-02-27 01:45:28 +000056 m_profitabilityChanged = false;
oliver@apple.com426f5b02013-07-25 04:04:27 +000057 for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
58 fixupBlock(m_graph.block(blockIndex));
fpizlo@apple.combbaf6192013-02-27 01:45:28 +000059
60 while (m_profitabilityChanged) {
61 m_profitabilityChanged = false;
62
63 for (unsigned i = m_graph.m_argumentPositions.size(); i--;)
64 m_graph.m_argumentPositions[i].mergeArgumentUnboxingAwareness();
65
oliver@apple.com426f5b02013-07-25 04:04:27 +000066 for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +000067 fixupGetAndSetLocalsInBlock(m_graph.block(blockIndex));
fpizlo@apple.combbaf6192013-02-27 01:45:28 +000068 }
69
fpizlo@apple.com6921b292013-09-18 17:14:02 +000070 for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
fpizlo@apple.com10107332015-08-24 21:44:39 +000071 fixupChecksInBlock(m_graph.block(blockIndex));
benjamin@webkit.org54d94f52015-02-28 03:21:37 +000072
73 m_graph.m_planStage = PlanStage::AfterFixup;
74
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +000075 return true;
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000076 }
77
78private:
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +000079 void fixupBlock(BasicBlock* block)
80 {
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +000081 if (!block)
82 return;
83 ASSERT(block->isReachable);
fpizlo@apple.comf10d0722012-12-03 09:21:22 +000084 m_block = block;
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +000085 for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +000086 m_currentNode = block->at(m_indexInBlock);
87 fixupNode(m_currentNode);
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +000088 }
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +000089 m_insertionSet.execute(block);
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +000090 }
91
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +000092 void fixupNode(Node* node)
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000093 {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +000094 NodeType op = node->op();
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000095
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +000096 switch (op) {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +000097 case SetLocal: {
msaboff@apple.com54129b62015-04-11 00:00:38 +000098 // This gets handled by fixupGetAndSetLocalsInBlock().
fpizlo@apple.com6921b292013-09-18 17:14:02 +000099 return;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000100 }
101
102 case BitAnd:
fpizlo@apple.com027ed672014-01-08 00:27:06 +0000103 case BitOr:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000104 case BitXor:
105 case BitRShift:
106 case BitLShift:
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000107 case BitURShift: {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000108 fixIntConvertingEdge(node->child1());
109 fixIntConvertingEdge(node->child2());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000110 break;
111 }
fpizlo@apple.com027ed672014-01-08 00:27:06 +0000112
oliver@apple.com64367322013-04-26 00:41:38 +0000113 case ArithIMul: {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000114 fixIntConvertingEdge(node->child1());
115 fixIntConvertingEdge(node->child2());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000116 node->setOp(ArithMul);
117 node->setArithMode(Arith::Unchecked);
118 node->child1().setUseKind(Int32Use);
119 node->child2().setUseKind(Int32Use);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000120 break;
121 }
benjamin@webkit.orge324d432015-04-26 19:55:18 +0000122
123 case ArithClz32: {
124 fixIntConvertingEdge(node->child1());
125 node->setArithMode(Arith::Unchecked);
126 break;
127 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000128
129 case UInt32ToNumber: {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000130 fixIntConvertingEdge(node->child1());
fpizlo@apple.com9089acb2013-12-14 06:33:42 +0000131 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
132 node->convertToIdentity();
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000133 else if (node->canSpeculateInt32(FixupPass))
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000134 node->setArithMode(Arith::CheckOverflow);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000135 else {
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000136 node->setArithMode(Arith::DoOverflow);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000137 node->setResult(NodeResultDouble);
138 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000139 break;
140 }
141
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000142 case ValueAdd: {
fpizlo@apple.com97756552014-01-02 20:15:25 +0000143 if (attemptToMakeIntegerAdd(node)) {
144 node->setOp(ArithAdd);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000145 break;
fpizlo@apple.com97756552014-01-02 20:15:25 +0000146 }
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000147 if (Node::shouldSpeculateNumberOrBooleanExpectingDefined(node->child1().node(), node->child2().node())) {
148 fixDoubleOrBooleanEdge(node->child1());
149 fixDoubleOrBooleanEdge(node->child2());
fpizlo@apple.com97756552014-01-02 20:15:25 +0000150 node->setOp(ArithAdd);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000151 node->setResult(NodeResultDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000152 break;
153 }
fpizlo@apple.com8d225912013-03-19 00:44:57 +0000154
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +0000155 if (attemptToMakeFastStringAdd(node))
fpizlo@apple.com8d225912013-03-19 00:44:57 +0000156 break;
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +0000157
158 // We could attempt to turn this into a StrCat here. But for now, that wouldn't
159 // significantly reduce the number of branches required.
160 break;
161 }
162
163 case StrCat: {
fpizlo@apple.com2b150e782015-08-27 23:59:57 +0000164 if (attemptToMakeFastStringAdd(node))
165 break;
166
167 // FIXME: Remove empty string arguments and possibly turn this into a ToString operation. That
168 // would require a form of ToString that takes a KnownPrimitiveUse. This is necessary because
169 // the implementation of StrCat doesn't dynamically optimize for empty strings.
170 // https://bugs.webkit.org/show_bug.cgi?id=148540
171 m_graph.doToChildren(
172 node,
173 [&] (Edge& edge) {
174 fixEdge<KnownPrimitiveUse>(edge);
175 });
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000176 break;
177 }
178
fpizlo@apple.com4463e442013-03-20 20:29:37 +0000179 case MakeRope: {
180 fixupMakeRope(node);
181 break;
182 }
183
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000184 case ArithAdd:
185 case ArithSub: {
186 if (attemptToMakeIntegerAdd(node))
187 break;
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000188 fixDoubleOrBooleanEdge(node->child1());
189 fixDoubleOrBooleanEdge(node->child2());
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000190 node->setResult(NodeResultDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000191 break;
192 }
193
194 case ArithNegate: {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000195 if (m_graph.negateShouldSpeculateInt32(node, FixupPass)) {
196 fixIntOrBooleanEdge(node->child1());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000197 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
198 node->setArithMode(Arith::Unchecked);
199 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
200 node->setArithMode(Arith::CheckOverflow);
201 else
202 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000203 break;
204 }
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000205 if (m_graph.negateShouldSpeculateMachineInt(node, FixupPass)) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000206 fixEdge<Int52RepUse>(node->child1());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000207 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
208 node->setArithMode(Arith::CheckOverflow);
209 else
210 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000211 node->setResult(NodeResultInt52);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000212 break;
213 }
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000214 fixDoubleOrBooleanEdge(node->child1());
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000215 node->setResult(NodeResultDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000216 break;
217 }
218
219 case ArithMul: {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000220 if (m_graph.mulShouldSpeculateInt32(node, FixupPass)) {
221 fixIntOrBooleanEdge(node->child1());
222 fixIntOrBooleanEdge(node->child2());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000223 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
224 node->setArithMode(Arith::Unchecked);
225 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
226 node->setArithMode(Arith::CheckOverflow);
227 else
228 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000229 break;
230 }
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000231 if (m_graph.mulShouldSpeculateMachineInt(node, FixupPass)) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000232 fixEdge<Int52RepUse>(node->child1());
233 fixEdge<Int52RepUse>(node->child2());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000234 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
235 node->setArithMode(Arith::CheckOverflow);
236 else
237 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000238 node->setResult(NodeResultInt52);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000239 break;
240 }
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000241 fixDoubleOrBooleanEdge(node->child1());
242 fixDoubleOrBooleanEdge(node->child2());
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000243 node->setResult(NodeResultDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000244 break;
245 }
246
oliver@apple.comf4443a72013-07-25 04:01:11 +0000247 case ArithDiv:
248 case ArithMod: {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000249 if (Node::shouldSpeculateInt32OrBooleanForArithmetic(node->child1().node(), node->child2().node())
250 && node->canSpeculateInt32(FixupPass)) {
ossy@webkit.orgd3a3de92015-03-16 18:44:46 +0000251 if (optimizeForX86() || optimizeForARM64() || optimizeForARMv7IDIVSupported()) {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000252 fixIntOrBooleanEdge(node->child1());
253 fixIntOrBooleanEdge(node->child2());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000254 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
255 node->setArithMode(Arith::Unchecked);
256 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
257 node->setArithMode(Arith::CheckOverflow);
258 else
259 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000260 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000261 }
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000262
263 // This will cause conversion nodes to be inserted later.
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000264 fixDoubleOrBooleanEdge(node->child1());
265 fixDoubleOrBooleanEdge(node->child2());
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000266
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000267 // We don't need to do ref'ing on the children because we're stealing them from
268 // the original division.
269 Node* newDivision = m_insertionSet.insertNode(
fpizlo@apple.com85bde1f2014-04-17 04:57:29 +0000270 m_indexInBlock, SpecBytecodeDouble, *node);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000271 newDivision->setResult(NodeResultDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000272
273 node->setOp(DoubleAsInt32);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000274 node->children.initialize(Edge(newDivision, DoubleRepUse), Edge(), Edge());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000275 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
276 node->setArithMode(Arith::CheckOverflow);
277 else
278 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000279 break;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000280 }
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000281 fixDoubleOrBooleanEdge(node->child1());
282 fixDoubleOrBooleanEdge(node->child2());
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000283 node->setResult(NodeResultDouble);
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000284 break;
285 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000286
287 case ArithMin:
oliver@apple.comf4443a72013-07-25 04:01:11 +0000288 case ArithMax: {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000289 if (Node::shouldSpeculateInt32OrBooleanForArithmetic(node->child1().node(), node->child2().node())
290 && node->canSpeculateInt32(FixupPass)) {
291 fixIntOrBooleanEdge(node->child1());
292 fixIntOrBooleanEdge(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000293 break;
294 }
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000295 fixDoubleOrBooleanEdge(node->child1());
296 fixDoubleOrBooleanEdge(node->child2());
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000297 node->setResult(NodeResultDouble);
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000298 break;
299 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000300
301 case ArithAbs: {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000302 if (node->child1()->shouldSpeculateInt32OrBooleanForArithmetic()
303 && node->canSpeculateInt32(FixupPass)) {
304 fixIntOrBooleanEdge(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000305 break;
306 }
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000307 fixDoubleOrBooleanEdge(node->child1());
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000308 node->setResult(NodeResultDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000309 break;
310 }
benjamin@webkit.org903025b2015-02-14 04:20:21 +0000311
312 case ArithPow: {
313 node->setResult(NodeResultDouble);
314 if (node->child2()->shouldSpeculateInt32OrBooleanForArithmetic()) {
315 fixDoubleOrBooleanEdge(node->child1());
316 fixIntOrBooleanEdge(node->child2());
317 break;
318 }
319
320 fixDoubleOrBooleanEdge(node->child1());
321 fixDoubleOrBooleanEdge(node->child2());
322 break;
323 }
benjamin@webkit.orgcb584082015-05-08 00:23:32 +0000324
325 case ArithRound: {
326 if (node->child1()->shouldSpeculateInt32OrBooleanForArithmetic() && node->canSpeculateInt32(FixupPass)) {
327 fixIntOrBooleanEdge(node->child1());
328 insertCheck<Int32Use>(m_indexInBlock, node->child1().node());
329 node->convertToIdentity();
330 break;
331 }
332 fixDoubleOrBooleanEdge(node->child1());
333
334 if (isInt32OrBooleanSpeculation(node->getHeapPrediction()) && m_graph.roundShouldSpeculateInt32(node, FixupPass)) {
335 node->setResult(NodeResultInt32);
336 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
337 node->setArithRoundingMode(Arith::RoundingMode::Int32);
338 else
339 node->setArithRoundingMode(Arith::RoundingMode::Int32WithNegativeZeroCheck);
340 } else {
341 node->setResult(NodeResultDouble);
342 node->setArithRoundingMode(Arith::RoundingMode::Double);
343 }
344 break;
345 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000346
fpizlo@apple.comb3336c72013-10-31 19:19:15 +0000347 case ArithSqrt:
fpizlo@apple.comc5919412014-04-12 23:01:33 +0000348 case ArithFRound:
fpizlo@apple.comb3336c72013-10-31 19:19:15 +0000349 case ArithSin:
benjamin@webkit.org2b5682d2015-03-04 22:39:28 +0000350 case ArithCos:
351 case ArithLog: {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000352 fixDoubleOrBooleanEdge(node->child1());
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000353 node->setResult(NodeResultDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000354 break;
355 }
356
357 case LogicalNot: {
fpizlo@apple.com7289af32015-08-21 03:59:33 +0000358 if (node->child1()->shouldSpeculateBoolean()) {
359 if (node->child1()->result() == NodeResultBoolean) {
360 // This is necessary in case we have a bytecode instruction implemented by:
361 //
362 // a: CompareEq(...)
363 // b: LogicalNot(@a)
364 //
365 // In that case, CompareEq might have a side-effect. Then, we need to make
366 // sure that we know that Branch does not exit.
367 fixEdge<KnownBooleanUse>(node->child1());
368 } else
369 fixEdge<BooleanUse>(node->child1());
370 } else if (node->child1()->shouldSpeculateObjectOrOther())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000371 fixEdge<ObjectOrOtherUse>(node->child1());
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000372 else if (node->child1()->shouldSpeculateInt32OrBoolean())
373 fixIntOrBooleanEdge(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000374 else if (node->child1()->shouldSpeculateNumber())
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000375 fixEdge<DoubleRepUse>(node->child1());
commit-queue@webkit.org008e8dc2013-10-12 02:21:45 +0000376 else if (node->child1()->shouldSpeculateString())
377 fixEdge<StringUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000378 break;
379 }
fpizlo@apple.comee10e452013-04-09 00:10:16 +0000380
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000381 case CompareEq:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000382 case CompareLess:
383 case CompareLessEq:
384 case CompareGreater:
385 case CompareGreaterEq: {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000386 if (node->op() == CompareEq
387 && Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
388 fixEdge<BooleanUse>(node->child1());
389 fixEdge<BooleanUse>(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000390 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000391 break;
392 }
393 if (Node::shouldSpeculateInt32OrBoolean(node->child1().node(), node->child2().node())) {
394 fixIntOrBooleanEdge(node->child1());
395 fixIntOrBooleanEdge(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000396 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000397 break;
398 }
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000399 if (enableInt52()
400 && Node::shouldSpeculateMachineInt(node->child1().node(), node->child2().node())) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000401 fixEdge<Int52RepUse>(node->child1());
402 fixEdge<Int52RepUse>(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000403 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000404 break;
405 }
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000406 if (Node::shouldSpeculateNumberOrBoolean(node->child1().node(), node->child2().node())) {
407 fixDoubleOrBooleanEdge(node->child1());
408 fixDoubleOrBooleanEdge(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000409 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000410 break;
411 }
412 if (node->op() != CompareEq)
413 break;
oliver@apple.combd15be82013-07-25 04:03:42 +0000414 if (node->child1()->shouldSpeculateStringIdent() && node->child2()->shouldSpeculateStringIdent()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000415 fixEdge<StringIdentUse>(node->child1());
416 fixEdge<StringIdentUse>(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000417 node->clearFlags(NodeMustGenerate);
oliver@apple.combd15be82013-07-25 04:03:42 +0000418 break;
419 }
fpizlo@apple.comee10e452013-04-09 00:10:16 +0000420 if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && GPRInfo::numberOfRegisters >= 7) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000421 fixEdge<StringUse>(node->child1());
422 fixEdge<StringUse>(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000423 node->clearFlags(NodeMustGenerate);
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.comcad67682015-02-09 19:57:41 +0000429 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000430 break;
431 }
benjamin@webkit.org32b8d0a2015-08-19 04:09:12 +0000432
433 // If either child can be proved to be Null or Undefined, comparing them is greatly simplified.
434 bool oneArgumentIsUsedAsSpecOther = false;
435 if (node->child1()->isUndefinedOrNullConstant()) {
436 fixEdge<OtherUse>(node->child1());
437 oneArgumentIsUsedAsSpecOther = true;
438 } else if (node->child1()->shouldSpeculateOther()) {
439 m_insertionSet.insertNode(m_indexInBlock, SpecNone, Check, node->origin,
440 Edge(node->child1().node(), OtherUse));
441 fixEdge<OtherUse>(node->child1());
442 oneArgumentIsUsedAsSpecOther = true;
443 }
444 if (node->child2()->isUndefinedOrNullConstant()) {
445 fixEdge<OtherUse>(node->child2());
446 oneArgumentIsUsedAsSpecOther = true;
447 } else if (node->child2()->shouldSpeculateOther()) {
448 m_insertionSet.insertNode(m_indexInBlock, SpecNone, Check, node->origin,
449 Edge(node->child2().node(), OtherUse));
450 fixEdge<OtherUse>(node->child2());
451 oneArgumentIsUsedAsSpecOther = true;
452 }
453 if (oneArgumentIsUsedAsSpecOther) {
454 node->clearFlags(NodeMustGenerate);
455 break;
456 }
457
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000458 if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObjectOrOther()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000459 fixEdge<ObjectUse>(node->child1());
460 fixEdge<ObjectOrOtherUse>(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000461 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000462 break;
463 }
464 if (node->child1()->shouldSpeculateObjectOrOther() && node->child2()->shouldSpeculateObject()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000465 fixEdge<ObjectOrOtherUse>(node->child1());
466 fixEdge<ObjectUse>(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000467 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000468 break;
469 }
benjamin@webkit.org32b8d0a2015-08-19 04:09:12 +0000470
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000471 break;
472 }
473
fpizlo@apple.comee10e452013-04-09 00:10:16 +0000474 case CompareStrictEq: {
ggaren@apple.com0f001eb2013-04-24 15:48:55 +0000475 if (Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000476 fixEdge<BooleanUse>(node->child1());
477 fixEdge<BooleanUse>(node->child2());
ggaren@apple.com0f001eb2013-04-24 15:48:55 +0000478 break;
479 }
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000480 if (Node::shouldSpeculateInt32(node->child1().node(), node->child2().node())) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000481 fixEdge<Int32Use>(node->child1());
482 fixEdge<Int32Use>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000483 break;
484 }
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000485 if (enableInt52()
486 && Node::shouldSpeculateMachineInt(node->child1().node(), node->child2().node())) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000487 fixEdge<Int52RepUse>(node->child1());
488 fixEdge<Int52RepUse>(node->child2());
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000489 break;
490 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000491 if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000492 fixEdge<DoubleRepUse>(node->child1());
493 fixEdge<DoubleRepUse>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000494 break;
495 }
oliver@apple.combd15be82013-07-25 04:03:42 +0000496 if (node->child1()->shouldSpeculateStringIdent() && node->child2()->shouldSpeculateStringIdent()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000497 fixEdge<StringIdentUse>(node->child1());
498 fixEdge<StringIdentUse>(node->child2());
oliver@apple.combd15be82013-07-25 04:03:42 +0000499 break;
500 }
bfulgham@apple.com58de7782014-10-08 16:18:03 +0000501 if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 7) || isFTL(m_graph.m_plan.mode))) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000502 fixEdge<StringUse>(node->child1());
503 fixEdge<StringUse>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000504 break;
fpizlo@apple.comee10e452013-04-09 00:10:16 +0000505 }
commit-queue@webkit.org902685c2015-06-24 19:13:54 +0000506 WatchpointSet* masqueradesAsUndefinedWatchpoint = m_graph.globalObjectFor(node->origin.semantic)->masqueradesAsUndefinedWatchpoint();
507 if (masqueradesAsUndefinedWatchpoint->isStillValid()) {
508
509 if (node->child1()->shouldSpeculateObject()) {
510 m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
511 fixEdge<ObjectUse>(node->child1());
512 break;
513 }
514 if (node->child2()->shouldSpeculateObject()) {
515 m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
516 fixEdge<ObjectUse>(node->child2());
517 break;
518 }
519
520 } else if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000521 fixEdge<ObjectUse>(node->child1());
522 fixEdge<ObjectUse>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000523 break;
524 }
fpizlo@apple.com312efcd2014-03-10 22:11:35 +0000525 if (node->child1()->shouldSpeculateMisc()) {
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000526 fixEdge<MiscUse>(node->child1());
fpizlo@apple.com312efcd2014-03-10 22:11:35 +0000527 break;
528 }
529 if (node->child2()->shouldSpeculateMisc()) {
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000530 fixEdge<MiscUse>(node->child2());
531 break;
532 }
fpizlo@apple.com385a33a2014-03-18 20:53:07 +0000533 if (node->child1()->shouldSpeculateStringIdent()
534 && node->child2()->shouldSpeculateNotStringVar()) {
535 fixEdge<StringIdentUse>(node->child1());
536 fixEdge<NotStringVarUse>(node->child2());
537 break;
538 }
539 if (node->child2()->shouldSpeculateStringIdent()
540 && node->child1()->shouldSpeculateNotStringVar()) {
541 fixEdge<StringIdentUse>(node->child2());
542 fixEdge<NotStringVarUse>(node->child1());
543 break;
544 }
bfulgham@apple.com58de7782014-10-08 16:18:03 +0000545 if (node->child1()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 8) || isFTL(m_graph.m_plan.mode))) {
fpizlo@apple.com385a33a2014-03-18 20:53:07 +0000546 fixEdge<StringUse>(node->child1());
547 break;
548 }
bfulgham@apple.com58de7782014-10-08 16:18:03 +0000549 if (node->child2()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 8) || isFTL(m_graph.m_plan.mode))) {
fpizlo@apple.com385a33a2014-03-18 20:53:07 +0000550 fixEdge<StringUse>(node->child2());
551 break;
552 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000553 break;
554 }
555
commit-queue@webkit.orgaa31a5e2013-04-09 06:45:16 +0000556 case StringFromCharCode:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000557 fixEdge<Int32Use>(node->child1());
commit-queue@webkit.orgaa31a5e2013-04-09 06:45:16 +0000558 break;
559
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000560 case StringCharAt:
561 case StringCharCodeAt: {
562 // Currently we have no good way of refining these.
563 ASSERT(node->arrayMode() == ArrayMode(Array::String));
564 blessArrayOperation(node->child1(), node->child2(), node->child3());
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000565 fixEdge<KnownCellUse>(node->child1());
566 fixEdge<Int32Use>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000567 break;
568 }
569
fpizlo@apple.coma387b6a2012-11-01 07:41:43 +0000570 case GetByVal: {
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +0000571 if (!node->prediction()) {
572 m_insertionSet.insertNode(
573 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
574 }
575
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000576 node->setArrayMode(
577 node->arrayMode().refine(
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000578 m_graph, node,
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000579 node->child1()->prediction(),
580 node->child2()->prediction(),
benjamin@webkit.org9f46ddc2015-04-30 04:40:55 +0000581 SpecNone));
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000582
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000583 blessArrayOperation(node->child1(), node->child2(), node->child3());
fpizlo@apple.com94e84e92012-11-11 02:56:12 +0000584
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000585 ArrayMode arrayMode = node->arrayMode();
oliver@apple.com211b3be2013-07-25 04:03:39 +0000586 switch (arrayMode.type()) {
fpizlo@apple.com661530a2015-05-09 00:18:43 +0000587 case Array::Contiguous:
oliver@apple.com211b3be2013-07-25 04:03:39 +0000588 case Array::Double:
589 if (arrayMode.arrayClass() == Array::OriginalArray
fpizlo@apple.com141cdcc2015-05-06 23:14:14 +0000590 && arrayMode.speculation() == Array::InBounds) {
591 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
fpizlo@apple.com661530a2015-05-09 00:18:43 +0000592 if (globalObject->arrayPrototypeChainIsSane()) {
593 // Check if SaneChain will work on a per-type basis. Note that:
594 //
595 // 1) We don't want double arrays to sometimes return undefined, since
596 // that would require a change to the return type and it would pessimise
597 // things a lot. So, we'd only want to do that if we actually had
598 // evidence that we could read from a hole. That's pretty annoying.
599 // Likely the best way to handle that case is with an equivalent of
600 // SaneChain for OutOfBounds. For now we just detect when Undefined and
601 // NaN are indistinguishable according to backwards propagation, and just
602 // use SaneChain in that case. This happens to catch a lot of cases.
603 //
604 // 2) We don't want int32 array loads to have to do a hole check just to
605 // coerce to Undefined, since that would mean twice the checks.
606 //
607 // This has two implications. First, we have to do more checks than we'd
608 // like. It's unfortunate that we have to do the hole check. Second,
609 // some accesses that hit a hole will now need to take the full-blown
610 // out-of-bounds slow path. We can fix that with:
611 // https://bugs.webkit.org/show_bug.cgi?id=144668
612
613 bool canDoSaneChain = false;
614 switch (arrayMode.type()) {
615 case Array::Contiguous:
616 // This is happens to be entirely natural. We already would have
617 // returned any JSValue, and now we'll return Undefined. We still do
618 // the check but it doesn't require taking any kind of slow path.
619 canDoSaneChain = true;
620 break;
621
622 case Array::Double:
623 if (!(node->flags() & NodeBytecodeUsesAsOther)) {
624 // Holes look like NaN already, so if the user doesn't care
625 // about the difference between Undefined and NaN then we can
626 // do this.
627 canDoSaneChain = true;
628 }
629 break;
630
631 default:
632 break;
633 }
634
635 if (canDoSaneChain) {
636 m_graph.watchpoints().addLazily(
637 globalObject->arrayPrototype()->structure()->transitionWatchpointSet());
638 m_graph.watchpoints().addLazily(
639 globalObject->objectPrototype()->structure()->transitionWatchpointSet());
640 node->setArrayMode(arrayMode.withSpeculation(Array::SaneChain));
641 }
fpizlo@apple.com141cdcc2015-05-06 23:14:14 +0000642 }
643 }
oliver@apple.com211b3be2013-07-25 04:03:39 +0000644 break;
645
646 case Array::String:
647 if ((node->prediction() & ~SpecString)
fpizlo@apple.com6793a322014-02-12 05:42:32 +0000648 || m_graph.hasExitSite(node->origin.semantic, OutOfBounds))
oliver@apple.com211b3be2013-07-25 04:03:39 +0000649 node->setArrayMode(arrayMode.withSpeculation(Array::OutOfBounds));
650 break;
651
652 default:
653 break;
654 }
fpizlo@apple.com94e84e92012-11-11 02:56:12 +0000655
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000656 arrayMode = node->arrayMode();
657 switch (arrayMode.type()) {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000658 case Array::SelectUsingPredictions:
659 case Array::Unprofiled:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000660 RELEASE_ASSERT_NOT_REACHED();
661 break;
662 case Array::Generic:
663#if USE(JSVALUE32_64)
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000664 fixEdge<CellUse>(node->child1()); // Speculating cell due to register pressure on 32-bit.
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000665#endif
666 break;
667 case Array::ForceExit:
668 break;
669 default:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000670 fixEdge<KnownCellUse>(node->child1());
671 fixEdge<Int32Use>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000672 break;
673 }
674
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000675 switch (arrayMode.type()) {
676 case Array::Double:
677 if (!arrayMode.isOutOfBounds())
678 node->setResult(NodeResultDouble);
679 break;
680
681 case Array::Float32Array:
682 case Array::Float64Array:
683 node->setResult(NodeResultDouble);
684 break;
685
686 case Array::Uint32Array:
687 if (node->shouldSpeculateInt32())
688 break;
689 if (node->shouldSpeculateMachineInt() && enableInt52())
690 node->setResult(NodeResultInt52);
691 else
692 node->setResult(NodeResultDouble);
693 break;
694
695 default:
696 break;
697 }
698
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000699 break;
700 }
oliver@apple.come050d642013-10-19 00:09:28 +0000701
702 case PutByValDirect:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000703 case PutByVal:
704 case PutByValAlias: {
705 Edge& child1 = m_graph.varArgChild(node, 0);
706 Edge& child2 = m_graph.varArgChild(node, 1);
707 Edge& child3 = m_graph.varArgChild(node, 2);
708
709 node->setArrayMode(
710 node->arrayMode().refine(
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000711 m_graph, node,
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000712 child1->prediction(),
713 child2->prediction(),
714 child3->prediction()));
715
716 blessArrayOperation(child1, child2, m_graph.varArgChild(node, 3));
717
718 switch (node->arrayMode().modeForPut().type()) {
719 case Array::SelectUsingPredictions:
benjamin@webkit.org5c3fb3a2015-08-14 03:54:32 +0000720 case Array::SelectUsingArguments:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000721 case Array::Unprofiled:
722 case Array::Undecided:
723 RELEASE_ASSERT_NOT_REACHED();
724 break;
725 case Array::ForceExit:
726 case Array::Generic:
727#if USE(JSVALUE32_64)
728 // Due to register pressure on 32-bit, we speculate cell and
729 // ignore the base-is-not-cell case entirely by letting the
730 // baseline JIT handle it.
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000731 fixEdge<CellUse>(child1);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000732#endif
733 break;
734 case Array::Int32:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000735 fixEdge<KnownCellUse>(child1);
736 fixEdge<Int32Use>(child2);
737 fixEdge<Int32Use>(child3);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000738 break;
739 case Array::Double:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000740 fixEdge<KnownCellUse>(child1);
741 fixEdge<Int32Use>(child2);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000742 fixEdge<DoubleRepRealUse>(child3);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000743 break;
744 case Array::Int8Array:
745 case Array::Int16Array:
746 case Array::Int32Array:
747 case Array::Uint8Array:
748 case Array::Uint8ClampedArray:
749 case Array::Uint16Array:
750 case Array::Uint32Array:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000751 fixEdge<KnownCellUse>(child1);
752 fixEdge<Int32Use>(child2);
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000753 if (child3->shouldSpeculateInt32())
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000754 fixIntOrBooleanEdge(child3);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000755 else if (child3->shouldSpeculateMachineInt())
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000756 fixEdge<Int52RepUse>(child3);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000757 else
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000758 fixDoubleOrBooleanEdge(child3);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000759 break;
760 case Array::Float32Array:
761 case Array::Float64Array:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000762 fixEdge<KnownCellUse>(child1);
763 fixEdge<Int32Use>(child2);
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000764 fixDoubleOrBooleanEdge(child3);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000765 break;
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000766 case Array::Contiguous:
767 case Array::ArrayStorage:
768 case Array::SlowPutArrayStorage:
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000769 fixEdge<KnownCellUse>(child1);
770 fixEdge<Int32Use>(child2);
fpizlo@apple.com49b1d722015-05-18 03:39:28 +0000771 speculateForBarrier(child3);
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000772 break;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000773 default:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000774 fixEdge<KnownCellUse>(child1);
775 fixEdge<Int32Use>(child2);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000776 break;
777 }
fpizlo@apple.coma387b6a2012-11-01 07:41:43 +0000778 break;
779 }
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000780
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000781 case ArrayPush: {
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000782 // May need to refine the array mode in case the value prediction contravenes
783 // the array prediction. For example, we may have evidence showing that the
784 // array is in Int32 mode, but the value we're storing is likely to be a double.
785 // Then we should turn this into a conversion to Double array followed by the
786 // push. On the other hand, we absolutely don't want to refine based on the
787 // base prediction. If it has non-cell garbage in it, then we want that to be
788 // ignored. That's because ArrayPush can't handle any array modes that aren't
789 // array-related - so if refine() turned this into a "Generic" ArrayPush then
790 // that would break things.
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000791 node->setArrayMode(
792 node->arrayMode().refine(
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000793 m_graph, node,
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000794 node->child1()->prediction() & SpecCell,
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000795 SpecInt32,
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000796 node->child2()->prediction()));
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000797 blessArrayOperation(node->child1(), Edge(), node->child3());
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000798 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000799
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000800 switch (node->arrayMode().type()) {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000801 case Array::Int32:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000802 fixEdge<Int32Use>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000803 break;
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000804 case Array::Double:
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000805 fixEdge<DoubleRepRealUse>(node->child2());
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000806 break;
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000807 case Array::Contiguous:
808 case Array::ArrayStorage:
fpizlo@apple.com49b1d722015-05-18 03:39:28 +0000809 speculateForBarrier(node->child2());
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000810 break;
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000811 default:
812 break;
813 }
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000814 break;
815 }
816
817 case ArrayPop: {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000818 blessArrayOperation(node->child1(), Edge(), node->child2());
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000819 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.com8fd79212012-10-16 21:59:35 +0000820 break;
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000821 }
822
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000823 case RegExpExec:
824 case RegExpTest: {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000825 fixEdge<CellUse>(node->child1());
826 fixEdge<CellUse>(node->child2());
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000827 break;
828 }
829
830 case Branch: {
fpizlo@apple.com7289af32015-08-21 03:59:33 +0000831 if (node->child1()->shouldSpeculateBoolean()) {
832 if (node->child1()->result() == NodeResultBoolean) {
833 // This is necessary in case we have a bytecode instruction implemented by:
834 //
835 // a: CompareEq(...)
836 // b: Branch(@a)
837 //
838 // In that case, CompareEq might have a side-effect. Then, we need to make
839 // sure that we know that Branch does not exit.
840 fixEdge<KnownBooleanUse>(node->child1());
841 } else
842 fixEdge<BooleanUse>(node->child1());
843 } else if (node->child1()->shouldSpeculateObjectOrOther())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000844 fixEdge<ObjectOrOtherUse>(node->child1());
fpizlo@apple.comd8846b12015-05-18 20:41:54 +0000845 else if (node->child1()->shouldSpeculateInt32OrBoolean())
846 fixIntOrBooleanEdge(node->child1());
fpizlo@apple.com2537f952014-07-28 20:41:09 +0000847 else if (node->child1()->shouldSpeculateNumber())
848 fixEdge<DoubleRepUse>(node->child1());
akling@apple.comd8786332015-04-28 18:54:12 +0000849 else if (node->child1()->shouldSpeculateString())
850 fixEdge<StringUse>(node->child1());
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000851 break;
852 }
853
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000854 case Switch: {
855 SwitchData* data = node->switchData();
856 switch (data->kind) {
857 case SwitchImm:
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000858 if (node->child1()->shouldSpeculateInt32())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000859 fixEdge<Int32Use>(node->child1());
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000860 break;
oliver@apple.com9e1c8092013-07-25 04:03:16 +0000861 case SwitchChar:
862 if (node->child1()->shouldSpeculateString())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000863 fixEdge<StringUse>(node->child1());
oliver@apple.com9e1c8092013-07-25 04:03:16 +0000864 break;
oliver@apple.com5c826c02013-07-25 04:03:51 +0000865 case SwitchString:
866 if (node->child1()->shouldSpeculateStringIdent())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000867 fixEdge<StringIdentUse>(node->child1());
oliver@apple.com5c826c02013-07-25 04:03:51 +0000868 else if (node->child1()->shouldSpeculateString())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000869 fixEdge<StringUse>(node->child1());
oliver@apple.com5c826c02013-07-25 04:03:51 +0000870 break;
fpizlo@apple.com29abafe2014-08-28 19:09:48 +0000871 case SwitchCell:
872 if (node->child1()->shouldSpeculateCell())
873 fixEdge<CellUse>(node->child1());
874 // else it's fine for this to have UntypedUse; we will handle this by just making
875 // non-cells take the default case.
876 break;
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000877 }
878 break;
879 }
880
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000881 case ToPrimitive: {
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +0000882 fixupToPrimitive(node);
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000883 break;
884 }
885
utatane.tea@gmail.com153559e2015-04-06 19:07:12 +0000886 case ToString:
887 case CallStringConstructor: {
888 fixupToStringOrCallStringConstructor(node);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +0000889 break;
890 }
891
892 case NewStringObject: {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000893 fixEdge<KnownStringUse>(node->child1());
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +0000894 break;
895 }
896
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000897 case NewArray: {
898 for (unsigned i = m_graph.varArgNumChildren(node); i--;) {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000899 node->setIndexingType(
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000900 leastUpperBoundOfIndexingTypeAndType(
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000901 node->indexingType(), m_graph.varArgChild(node, i)->prediction()));
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000902 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000903 switch (node->indexingType()) {
904 case ALL_BLANK_INDEXING_TYPES:
905 CRASH();
906 break;
907 case ALL_UNDECIDED_INDEXING_TYPES:
908 if (node->numChildren()) {
909 // This will only happen if the children have no type predictions. We
910 // would have already exited by now, but insert a forced exit just to
911 // be safe.
912 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +0000913 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000914 }
915 break;
916 case ALL_INT32_INDEXING_TYPES:
917 for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000918 fixEdge<Int32Use>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000919 break;
920 case ALL_DOUBLE_INDEXING_TYPES:
921 for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000922 fixEdge<DoubleRepRealUse>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000923 break;
924 case ALL_CONTIGUOUS_INDEXING_TYPES:
925 case ALL_ARRAY_STORAGE_INDEXING_TYPES:
926 break;
927 default:
928 CRASH();
929 break;
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000930 }
931 break;
932 }
933
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000934 case NewTypedArray: {
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000935 if (node->child1()->shouldSpeculateInt32()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000936 fixEdge<Int32Use>(node->child1());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000937 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000938 break;
939 }
940 break;
941 }
942
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000943 case NewArrayWithSize: {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000944 fixEdge<Int32Use>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000945 break;
946 }
947
oliver@apple.come2fe4ce2013-07-25 03:59:41 +0000948 case ToThis: {
fpizlo@apple.com6793a322014-02-12 05:42:32 +0000949 ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->isStrictMode() ? StrictMode : NotStrictMode;
oliver@apple.come2fe4ce2013-07-25 03:59:41 +0000950
fpizlo@apple.com312efcd2014-03-10 22:11:35 +0000951 if (node->child1()->shouldSpeculateOther()) {
oliver@apple.come2fe4ce2013-07-25 03:59:41 +0000952 if (ecmaMode == StrictMode) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000953 fixEdge<OtherUse>(node->child1());
oliver@apple.come2fe4ce2013-07-25 03:59:41 +0000954 node->convertToIdentity();
955 break;
956 }
957
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +0000958 m_insertionSet.insertNode(
fpizlo@apple.com163291d2015-04-28 19:27:23 +0000959 m_indexInBlock, SpecNone, Check, node->origin,
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +0000960 Edge(node->child1().node(), OtherUse));
961 observeUseKindOnNode<OtherUse>(node->child1().node());
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000962 m_graph.convertToConstant(
963 node, m_graph.globalThisObjectFor(node->origin.semantic));
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +0000964 break;
965 }
966
oliver@apple.come2fe4ce2013-07-25 03:59:41 +0000967 if (isFinalObjectSpeculation(node->child1()->prediction())) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000968 fixEdge<FinalObjectUse>(node->child1());
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +0000969 node->convertToIdentity();
970 break;
971 }
972
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000973 break;
974 }
975
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000976 case PutStructure: {
977 fixEdge<KnownCellUse>(node->child1());
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000978 break;
979 }
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000980
981 case GetClosureVar:
982 case GetFromArguments: {
fpizlo@apple.com90640ab2015-03-04 05:26:54 +0000983 fixEdge<KnownCellUse>(node->child1());
984 break;
985 }
986
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000987 case PutClosureVar:
988 case PutToArguments: {
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000989 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.com49b1d722015-05-18 03:39:28 +0000990 speculateForBarrier(node->child2());
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000991 break;
992 }
commit-queue@webkit.orga4201b02015-08-17 22:24:20 +0000993
994 case LoadArrowFunctionThis: {
995 fixEdge<KnownCellUse>(node->child1());
996 break;
997 }
998
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000999 case SkipScope:
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +00001000 case GetScope:
1001 case GetGetter:
1002 case GetSetter: {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001003 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001004 break;
1005 }
1006
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001007 case AllocatePropertyStorage:
1008 case ReallocatePropertyStorage: {
1009 fixEdge<KnownCellUse>(node->child1());
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001010 break;
1011 }
1012
fpizlo@apple.com151e9af2013-08-16 02:30:37 +00001013 case GetById:
1014 case GetByIdFlush: {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001015 if (!node->child1()->shouldSpeculateCell())
1016 break;
fpizlo@apple.com5116ee72015-02-26 22:44:45 +00001017
1018 // If we hadn't exited because of BadCache, BadIndexingType, or ExoticObjectMode, then
1019 // leave this as a GetById.
1020 if (!m_graph.hasExitSite(node->origin.semantic, BadCache)
1021 && !m_graph.hasExitSite(node->origin.semantic, BadIndexingType)
1022 && !m_graph.hasExitSite(node->origin.semantic, ExoticObjectMode)) {
utatane.tea@gmail.com8268d392015-05-23 18:41:53 +00001023 auto uid = m_graph.identifiers()[node->identifierNumber()];
1024 if (uid == vm().propertyNames->length.impl()) {
fpizlo@apple.com5116ee72015-02-26 22:44:45 +00001025 attemptToMakeGetArrayLength(node);
1026 break;
1027 }
utatane.tea@gmail.com8268d392015-05-23 18:41:53 +00001028 if (uid == vm().propertyNames->byteLength.impl()) {
fpizlo@apple.com5116ee72015-02-26 22:44:45 +00001029 attemptToMakeGetTypedArrayByteLength(node);
1030 break;
1031 }
utatane.tea@gmail.com8268d392015-05-23 18:41:53 +00001032 if (uid == vm().propertyNames->byteOffset.impl()) {
fpizlo@apple.com5116ee72015-02-26 22:44:45 +00001033 attemptToMakeGetTypedArrayByteOffset(node);
1034 break;
1035 }
fpizlo@apple.comcbc41132013-03-19 20:23:01 +00001036 }
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001037 fixEdge<CellUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001038 break;
1039 }
1040
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001041 case PutById:
oliver@apple.com11ce5ff2014-03-06 21:27:13 +00001042 case PutByIdFlush:
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001043 case PutByIdDirect: {
1044 fixEdge<CellUse>(node->child1());
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001045 break;
1046 }
1047
fpizlo@apple.com29abafe2014-08-28 19:09:48 +00001048 case GetExecutable: {
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001049 fixEdge<FunctionUse>(node->child1());
1050 break;
1051 }
1052
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001053 case CheckStructure:
fpizlo@apple.com29abafe2014-08-28 19:09:48 +00001054 case CheckCell:
oliver@apple.come17632e2013-07-25 04:05:31 +00001055 case CheckHasInstance:
1056 case CreateThis:
1057 case GetButterfly: {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001058 fixEdge<CellUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001059 break;
1060 }
utatane.tea@gmail.comfccd1362015-08-11 22:02:09 +00001061
1062 case CheckIdent: {
1063 UniquedStringImpl* uid = node->uidOperand();
1064 if (uid->isSymbol())
1065 fixEdge<SymbolUse>(node->child1());
1066 else
1067 fixEdge<StringIdentUse>(node->child1());
1068 break;
1069 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001070
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001071 case Arrayify:
1072 case ArrayifyToStructure: {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001073 fixEdge<CellUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001074 if (node->child2())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001075 fixEdge<Int32Use>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001076 break;
1077 }
1078
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +00001079 case GetByOffset:
1080 case GetGetterSetterByOffset: {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001081 if (!node->child1()->hasStorageResult())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001082 fixEdge<KnownCellUse>(node->child1());
1083 fixEdge<KnownCellUse>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001084 break;
1085 }
1086
fpizlo@apple.com51614cc2014-02-17 06:35:32 +00001087 case MultiGetByOffset: {
1088 fixEdge<CellUse>(node->child1());
1089 break;
1090 }
1091
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001092 case PutByOffset: {
1093 if (!node->child1()->hasStorageResult())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001094 fixEdge<KnownCellUse>(node->child1());
1095 fixEdge<KnownCellUse>(node->child2());
fpizlo@apple.com12835772015-09-21 20:49:04 +00001096 insertInferredTypeCheck(
1097 m_insertionSet, m_indexInBlock, node->origin, node->child3().node(),
1098 node->storageAccessData().inferredType);
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00001099 speculateForBarrier(node->child3());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001100 break;
1101 }
1102
fpizlo@apple.com43219522014-02-25 02:02:50 +00001103 case MultiPutByOffset: {
1104 fixEdge<CellUse>(node->child1());
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00001105 speculateForBarrier(node->child2());
fpizlo@apple.com43219522014-02-25 02:02:50 +00001106 break;
1107 }
1108
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001109 case InstanceOf: {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001110 if (!(node->child1()->prediction() & ~SpecCell))
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001111 fixEdge<CellUse>(node->child1());
1112 fixEdge<CellUse>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001113 break;
1114 }
oliver@apple.comb3e5acb2013-07-25 04:02:53 +00001115
1116 case In: {
1117 // FIXME: We should at some point have array profiling on op_in, in which
1118 // case we would be able to turn this into a kind of GetByVal.
1119
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001120 fixEdge<CellUse>(node->child2());
oliver@apple.comb3e5acb2013-07-25 04:02:53 +00001121 break;
1122 }
fpizlo@apple.com46955912013-04-26 01:18:18 +00001123
fpizlo@apple.com9df7fef2013-12-29 21:50:55 +00001124 case Check: {
fpizlo@apple.combb89cd52015-05-22 06:32:30 +00001125 m_graph.doToChildren(
1126 node,
1127 [&] (Edge& edge) {
1128 switch (edge.useKind()) {
1129 case NumberUse:
1130 if (edge->shouldSpeculateInt32ForArithmetic())
1131 edge.setUseKind(Int32Use);
1132 break;
1133 default:
1134 break;
1135 }
1136 observeUseKindOnEdge(edge);
1137 });
fpizlo@apple.com46955912013-04-26 01:18:18 +00001138 break;
1139 }
1140
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001141 case Phantom:
1142 // Phantoms are meaningless past Fixup. We recreate them on-demand in the backend.
1143 node->remove();
1144 break;
1145
fpizlo@apple.comf2999932014-07-15 00:41:39 +00001146 case FiatInt52: {
1147 RELEASE_ASSERT(enableInt52());
1148 node->convertToIdentity();
1149 fixEdge<Int52RepUse>(node->child1());
1150 node->setResult(NodeResultInt52);
1151 break;
1152 }
1153
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001154 case GetArrayLength:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001155 case Phi:
oliver@apple.com827d2cf2013-07-25 04:04:45 +00001156 case Upsilon:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001157 case GetIndexedPropertyStorage:
fpizlo@apple.com537a4772013-08-19 23:16:01 +00001158 case GetTypedArrayByteOffset:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001159 case LastNodeType:
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001160 case CheckTierUpInLoop:
1161 case CheckTierUpAtReturn:
1162 case CheckTierUpAndOSREnter:
benjamin@webkit.org8f625992015-05-18 20:45:34 +00001163 case CheckTierUpWithNestedTriggerAndOSREnter:
fpizlo@apple.comd84425d2013-10-30 19:58:08 +00001164 case InvalidationPoint:
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00001165 case CheckArray:
fpizlo@apple.com8624c4b2013-12-10 03:24:31 +00001166 case CheckInBounds:
fpizlo@apple.com9ca951e2013-12-09 01:08:53 +00001167 case ConstantStoragePointer:
fpizlo@apple.com027ed672014-01-08 00:27:06 +00001168 case DoubleAsInt32:
fpizlo@apple.com027ed672014-01-08 00:27:06 +00001169 case ValueToInt32:
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001170 case DoubleRep:
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001171 case ValueRep:
fpizlo@apple.comf2999932014-07-15 00:41:39 +00001172 case Int52Rep:
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001173 case Int52Constant:
1174 case Identity: // This should have been cleaned up.
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001175 case BooleanToNumber:
fpizlo@apple.comfc70ba62014-09-26 03:59:33 +00001176 case PhantomNewObject:
commit-queue@webkit.org88ab4e72015-04-24 02:23:36 +00001177 case PhantomNewFunction:
basile_clement@apple.com2ca1f7b2015-05-05 16:34:21 +00001178 case PhantomCreateActivation:
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001179 case PhantomDirectArguments:
1180 case PhantomClonedArguments:
1181 case ForwardVarargs:
1182 case GetMyArgumentByVal:
fpizlo@apple.com8ff74712015-03-17 15:50:44 +00001183 case PutHint:
fpizlo@apple.comfc70ba62014-09-26 03:59:33 +00001184 case CheckStructureImmediate:
fpizlo@apple.comfc70ba62014-09-26 03:59:33 +00001185 case MaterializeNewObject:
basile_clement@apple.com2ca1f7b2015-05-05 16:34:21 +00001186 case MaterializeCreateActivation:
fpizlo@apple.combcfd8eb2015-02-26 19:51:52 +00001187 case PutStack:
1188 case KillStack:
1189 case GetStack:
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00001190 case StoreBarrier:
fpizlo@apple.com9ca951e2013-12-09 01:08:53 +00001191 // These are just nodes that we don't currently expect to see during fixup.
1192 // If we ever wanted to insert them prior to fixup, then we just have to create
1193 // fixup rules for them.
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00001194 DFG_CRASH(m_graph, node, "Unexpected node during fixup");
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001195 break;
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001196
saambarati1@gmail.com060e7512015-09-03 19:45:44 +00001197 case PutGlobalVariable: {
fpizlo@apple.com33ea5ee2015-05-15 03:51:52 +00001198 fixEdge<CellUse>(node->child1());
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00001199 speculateForBarrier(node->child2());
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001200 break;
1201 }
1202
commit-queue@webkit.org2faae0e2013-10-07 22:08:53 +00001203 case IsString:
1204 if (node->child1()->shouldSpeculateString()) {
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001205 m_insertionSet.insertNode(
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001206 m_indexInBlock, SpecNone, Check, node->origin,
commit-queue@webkit.org2faae0e2013-10-07 22:08:53 +00001207 Edge(node->child1().node(), StringUse));
1208 m_graph.convertToConstant(node, jsBoolean(true));
1209 observeUseKindOnNode<StringUse>(node);
1210 }
1211 break;
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001212
utatane.tea@gmail.com0bfb74c2015-02-24 23:01:58 +00001213 case IsObject:
1214 if (node->child1()->shouldSpeculateObject()) {
1215 m_insertionSet.insertNode(
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001216 m_indexInBlock, SpecNone, Check, node->origin,
utatane.tea@gmail.com0bfb74c2015-02-24 23:01:58 +00001217 Edge(node->child1().node(), ObjectUse));
1218 m_graph.convertToConstant(node, jsBoolean(true));
1219 observeUseKindOnNode<ObjectUse>(node);
1220 }
1221 break;
1222
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001223 case GetEnumerableLength: {
1224 fixEdge<CellUse>(node->child1());
1225 break;
1226 }
1227 case HasGenericProperty: {
msaboff@apple.comb644c252015-03-24 10:05:21 +00001228 fixEdge<CellUse>(node->child2());
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001229 break;
1230 }
1231 case HasStructureProperty: {
1232 fixEdge<StringUse>(node->child2());
1233 fixEdge<KnownCellUse>(node->child3());
1234 break;
1235 }
1236 case HasIndexedProperty: {
1237 node->setArrayMode(
1238 node->arrayMode().refine(
1239 m_graph, node,
1240 node->child1()->prediction(),
1241 node->child2()->prediction(),
benjamin@webkit.org9f46ddc2015-04-30 04:40:55 +00001242 SpecNone));
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001243
1244 blessArrayOperation(node->child1(), node->child2(), node->child3());
1245 fixEdge<CellUse>(node->child1());
1246 fixEdge<KnownInt32Use>(node->child2());
1247 break;
1248 }
1249 case GetDirectPname: {
1250 Edge& base = m_graph.varArgChild(node, 0);
1251 Edge& property = m_graph.varArgChild(node, 1);
1252 Edge& index = m_graph.varArgChild(node, 2);
1253 Edge& enumerator = m_graph.varArgChild(node, 3);
1254 fixEdge<CellUse>(base);
1255 fixEdge<KnownCellUse>(property);
1256 fixEdge<KnownInt32Use>(index);
1257 fixEdge<KnownCellUse>(enumerator);
1258 break;
1259 }
msaboff@apple.comb644c252015-03-24 10:05:21 +00001260 case GetPropertyEnumerator: {
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001261 fixEdge<CellUse>(node->child1());
msaboff@apple.comb644c252015-03-24 10:05:21 +00001262 break;
1263 }
1264 case GetEnumeratorStructurePname: {
1265 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001266 fixEdge<KnownInt32Use>(node->child2());
1267 break;
1268 }
msaboff@apple.comb644c252015-03-24 10:05:21 +00001269 case GetEnumeratorGenericPname: {
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001270 fixEdge<KnownCellUse>(node->child1());
1271 fixEdge<KnownInt32Use>(node->child2());
1272 break;
1273 }
1274 case ToIndexString: {
1275 fixEdge<KnownInt32Use>(node->child1());
1276 break;
1277 }
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001278 case ProfileType: {
1279 // We want to insert type checks based on the instructionTypeSet of the TypeLocation, not the globalTypeSet.
1280 // Because the instructionTypeSet is contained in globalTypeSet, if we produce a type check for
1281 // type T for the instructionTypeSet, the global type set must also have information for type T.
1282 // So if it the type check succeeds for type T in the instructionTypeSet, a type check for type T
1283 // in the globalTypeSet would've also succeeded.
1284 // (The other direction does not hold in general).
1285
1286 RefPtr<TypeSet> typeSet = node->typeLocation()->m_instructionTypeSet;
saambarati1@gmail.comf9b86632015-03-28 17:28:11 +00001287 RuntimeTypeMask seenTypes = typeSet->seenTypes();
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001288 if (typeSet->doesTypeConformTo(TypeMachineInt)) {
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001289 if (node->child1()->shouldSpeculateInt32())
1290 fixEdge<Int32Use>(node->child1());
1291 else
1292 fixEdge<MachineIntUse>(node->child1());
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001293 node->remove();
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001294 } else if (typeSet->doesTypeConformTo(TypeNumber | TypeMachineInt)) {
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001295 fixEdge<NumberUse>(node->child1());
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001296 node->remove();
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001297 } else if (typeSet->doesTypeConformTo(TypeString)) {
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001298 fixEdge<StringUse>(node->child1());
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001299 node->remove();
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001300 } else if (typeSet->doesTypeConformTo(TypeBoolean)) {
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001301 fixEdge<BooleanUse>(node->child1());
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001302 node->remove();
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001303 } else if (typeSet->doesTypeConformTo(TypeUndefined | TypeNull) && (seenTypes & TypeUndefined) && (seenTypes & TypeNull)) {
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001304 fixEdge<OtherUse>(node->child1());
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001305 node->remove();
saambarati1@gmail.comd372c702014-10-16 19:55:14 +00001306 } else if (typeSet->doesTypeConformTo(TypeObject)) {
1307 StructureSet set = typeSet->structureSet();
1308 if (!set.isEmpty()) {
saambarati1@gmail.comd372c702014-10-16 19:55:14 +00001309 fixEdge<CellUse>(node->child1());
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001310 node->convertToCheckStructure(m_graph.addStructureSet(set));
saambarati1@gmail.comd372c702014-10-16 19:55:14 +00001311 }
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001312 }
1313
1314 break;
1315 }
msaboff@apple.comcc305da2014-12-11 16:41:33 +00001316
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001317 case CreateScopedArguments:
msaboff@apple.comcc305da2014-12-11 16:41:33 +00001318 case CreateActivation:
msaboff@apple.comea77cd02014-11-14 01:07:48 +00001319 case NewFunction: {
msaboff@apple.comea77cd02014-11-14 01:07:48 +00001320 fixEdge<CellUse>(node->child1());
1321 break;
1322 }
commit-queue@webkit.orga4201b02015-08-17 22:24:20 +00001323
1324 case NewArrowFunction: {
1325 fixEdge<CellUse>(node->child1());
1326 fixEdge<CellUse>(node->child2());
1327 break;
1328 }
1329
commit-queue@webkit.org2faae0e2013-10-07 22:08:53 +00001330#if !ASSERT_DISABLED
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001331 // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
1332 case SetArgument:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001333 case JSConstant:
benjamin@webkit.org54d94f52015-02-28 03:21:37 +00001334 case DoubleConstant:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001335 case GetLocal:
1336 case GetCallee:
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001337 case GetArgumentCount:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001338 case Flush:
1339 case PhantomLocal:
1340 case GetLocalUnlinked:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001341 case GetGlobalVar:
saambarati1@gmail.com060e7512015-09-03 19:45:44 +00001342 case GetGlobalLexicalVariable:
fpizlo@apple.com86468342013-11-27 02:47:43 +00001343 case NotifyWrite:
oliver@apple.com58c86752013-07-25 04:02:40 +00001344 case VarInjectionWatchpoint:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001345 case Call:
msaboff@apple.coma3dc7532015-09-24 21:42:59 +00001346 case TailCallInlinedCaller:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001347 case Construct:
fpizlo@apple.com8fefdd32015-02-18 19:55:47 +00001348 case CallVarargs:
msaboff@apple.coma3dc7532015-09-24 21:42:59 +00001349 case TailCallVarargsInlinedCaller:
fpizlo@apple.com8fefdd32015-02-18 19:55:47 +00001350 case ConstructVarargs:
1351 case CallForwardVarargs:
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001352 case ConstructForwardVarargs:
msaboff@apple.coma3dc7532015-09-24 21:42:59 +00001353 case TailCallForwardVarargs:
1354 case TailCallForwardVarargsInlinedCaller:
fpizlo@apple.com8fefdd32015-02-18 19:55:47 +00001355 case LoadVarargs:
saambarati1@gmail.comb4f28a52014-12-05 05:58:07 +00001356 case ProfileControlFlow:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001357 case NewObject:
1358 case NewArrayBuffer:
1359 case NewRegexp:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001360 case Breakpoint:
mark.lam@apple.comeb19fea2014-01-23 23:13:23 +00001361 case ProfileWillCall:
1362 case ProfileDidCall:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001363 case IsUndefined:
1364 case IsBoolean:
1365 case IsNumber:
utatane.tea@gmail.com0bfb74c2015-02-24 23:01:58 +00001366 case IsObjectOrNull:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001367 case IsFunction:
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001368 case CreateDirectArguments:
1369 case CreateClonedArguments:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001370 case Jump:
1371 case Return:
msaboff@apple.coma3dc7532015-09-24 21:42:59 +00001372 case TailCall:
1373 case TailCallVarargs:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001374 case Throw:
1375 case ThrowReferenceError:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001376 case CountExecution:
1377 case ForceOSRExit:
fpizlo@apple.com29abafe2014-08-28 19:09:48 +00001378 case CheckBadCell:
rniwa@webkit.orgeb7ac192015-03-13 01:11:15 +00001379 case CheckNotEmpty:
mark.lam@apple.com10d23a12013-04-25 02:59:51 +00001380 case CheckWatchdogTimer:
oliver@apple.com1fc04182013-08-19 19:40:13 +00001381 case Unreachable:
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001382 case ExtractOSREntryLocal:
1383 case LoopHint:
fpizlo@apple.com9df7fef2013-12-29 21:50:55 +00001384 case MovHint:
1385 case ZombieHint:
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00001386 case ExitOK:
fpizlo@apple.com29abafe2014-08-28 19:09:48 +00001387 case BottomValue:
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001388 case TypeOf:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001389 break;
1390#else
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00001391 default:
1392 break;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001393#endif
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00001394 }
fpizlo@apple.comaa1cc982013-09-12 05:46:49 +00001395 }
1396
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001397 template<UseKind useKind>
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001398 void createToString(Node* node, Edge& edge)
fpizlo@apple.comcbc41132013-03-19 20:23:01 +00001399 {
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001400 edge.setNode(m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001401 m_indexInBlock, SpecString, ToString, node->origin,
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001402 Edge(edge.node(), useKind)));
fpizlo@apple.comcbc41132013-03-19 20:23:01 +00001403 }
1404
1405 template<UseKind useKind>
1406 void attemptToForceStringArrayModeByToStringConversion(ArrayMode& arrayMode, Node* node)
1407 {
1408 ASSERT(arrayMode == ArrayMode(Array::Generic));
1409
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001410 if (!canOptimizeStringObjectAccess(node->origin.semantic))
fpizlo@apple.comcbc41132013-03-19 20:23:01 +00001411 return;
1412
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001413 createToString<useKind>(node, node->child1());
fpizlo@apple.comcbc41132013-03-19 20:23:01 +00001414 arrayMode = ArrayMode(Array::String);
1415 }
1416
1417 template<UseKind useKind>
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001418 bool isStringObjectUse()
1419 {
1420 switch (useKind) {
1421 case StringObjectUse:
1422 case StringOrStringObjectUse:
1423 return true;
1424 default:
1425 return false;
1426 }
1427 }
1428
1429 template<UseKind useKind>
1430 void convertStringAddUse(Node* node, Edge& edge)
1431 {
1432 if (useKind == StringUse) {
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001433 observeUseKindOnNode<StringUse>(edge.node());
1434 m_insertionSet.insertNode(
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001435 m_indexInBlock, SpecNone, Check, node->origin,
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001436 Edge(edge.node(), StringUse));
1437 edge.setUseKind(KnownStringUse);
1438 return;
1439 }
1440
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001441 observeUseKindOnNode<useKind>(edge.node());
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001442 createToString<useKind>(node, edge);
1443 }
1444
1445 void convertToMakeRope(Node* node)
1446 {
1447 node->setOpAndDefaultFlags(MakeRope);
1448 fixupMakeRope(node);
1449 }
1450
1451 void fixupMakeRope(Node* node)
1452 {
1453 for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
1454 Edge& edge = node->children.child(i);
1455 if (!edge)
1456 break;
1457 edge.setUseKind(KnownStringUse);
fpizlo@apple.comb41e6822014-07-25 20:55:17 +00001458 JSString* string = edge->dynamicCastConstant<JSString*>();
1459 if (!string)
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001460 continue;
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001461 if (string->length())
1462 continue;
fpizlo@apple.com4bb938e2013-07-16 21:41:06 +00001463
1464 // Don't allow the MakeRope to have zero children.
1465 if (!i && !node->child2())
1466 break;
1467
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001468 node->children.removeEdge(i--);
1469 }
1470
1471 if (!node->child2()) {
1472 ASSERT(!node->child3());
1473 node->convertToIdentity();
1474 }
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001475 }
1476
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001477 void fixupToPrimitive(Node* node)
1478 {
fpizlo@apple.comefacb612013-09-10 22:16:00 +00001479 if (node->child1()->shouldSpeculateInt32()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001480 fixEdge<Int32Use>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001481 node->convertToIdentity();
1482 return;
1483 }
1484
1485 if (node->child1()->shouldSpeculateString()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001486 fixEdge<StringUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001487 node->convertToIdentity();
1488 return;
1489 }
1490
1491 if (node->child1()->shouldSpeculateStringObject()
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001492 && canOptimizeStringObjectAccess(node->origin.semantic)) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001493 fixEdge<StringObjectUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001494 node->convertToToString();
1495 return;
1496 }
1497
1498 if (node->child1()->shouldSpeculateStringOrStringObject()
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001499 && canOptimizeStringObjectAccess(node->origin.semantic)) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001500 fixEdge<StringOrStringObjectUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001501 node->convertToToString();
1502 return;
1503 }
1504 }
1505
utatane.tea@gmail.com153559e2015-04-06 19:07:12 +00001506 void fixupToStringOrCallStringConstructor(Node* node)
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001507 {
1508 if (node->child1()->shouldSpeculateString()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001509 fixEdge<StringUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001510 node->convertToIdentity();
1511 return;
1512 }
1513
1514 if (node->child1()->shouldSpeculateStringObject()
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001515 && canOptimizeStringObjectAccess(node->origin.semantic)) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001516 fixEdge<StringObjectUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001517 return;
1518 }
1519
1520 if (node->child1()->shouldSpeculateStringOrStringObject()
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001521 && canOptimizeStringObjectAccess(node->origin.semantic)) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001522 fixEdge<StringOrStringObjectUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001523 return;
1524 }
1525
1526 if (node->child1()->shouldSpeculateCell()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001527 fixEdge<CellUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001528 return;
1529 }
1530 }
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001531
1532 bool attemptToMakeFastStringAdd(Node* node)
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001533 {
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001534 bool goodToGo = true;
1535 m_graph.doToChildren(
1536 node,
1537 [&] (Edge& edge) {
1538 if (edge->shouldSpeculateString())
1539 return;
1540 if (canOptimizeStringObjectAccess(node->origin.semantic)) {
1541 if (edge->shouldSpeculateStringObject())
1542 return;
1543 if (edge->shouldSpeculateStringOrStringObject())
1544 return;
1545 }
1546 goodToGo = false;
1547 });
1548 if (!goodToGo)
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001549 return false;
utatane.tea@gmail.comea361c12015-06-18 23:45:06 +00001550
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001551 m_graph.doToChildren(
1552 node,
1553 [&] (Edge& edge) {
1554 if (edge->shouldSpeculateString()) {
1555 convertStringAddUse<StringUse>(node, edge);
1556 return;
1557 }
1558 ASSERT(canOptimizeStringObjectAccess(node->origin.semantic));
1559 if (edge->shouldSpeculateStringObject()) {
1560 convertStringAddUse<StringObjectUse>(node, edge);
1561 return;
1562 }
1563 if (edge->shouldSpeculateStringOrStringObject()) {
1564 convertStringAddUse<StringOrStringObjectUse>(node, edge);
1565 return;
1566 }
1567 RELEASE_ASSERT_NOT_REACHED();
1568 });
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001569
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001570 convertToMakeRope(node);
1571 return true;
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001572 }
1573
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001574 bool isStringPrototypeMethodSane(
utatane.tea@gmail.com8268d392015-05-23 18:41:53 +00001575 JSObject* stringPrototype, Structure* stringPrototypeStructure, UniquedStringImpl* uid)
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001576 {
1577 unsigned attributesUnused;
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001578 PropertyOffset offset =
fpizlo@apple.com15ec1b22014-09-21 19:18:40 +00001579 stringPrototypeStructure->getConcurrently(uid, attributesUnused);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001580 if (!isValidOffset(offset))
1581 return false;
1582
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001583 JSValue value = m_graph.tryGetConstantProperty(
1584 stringPrototype, stringPrototypeStructure, offset);
1585 if (!value)
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001586 return false;
1587
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001588 JSFunction* function = jsDynamicCast<JSFunction*>(value);
1589 if (!function)
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001590 return false;
1591
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001592 if (function->executable()->intrinsicFor(CodeForCall) != StringPrototypeValueOfIntrinsic)
1593 return false;
1594
1595 return true;
1596 }
1597
1598 bool canOptimizeStringObjectAccess(const CodeOrigin& codeOrigin)
1599 {
1600 if (m_graph.hasExitSite(codeOrigin, NotStringObject))
1601 return false;
1602
1603 Structure* stringObjectStructure = m_graph.globalObjectFor(codeOrigin)->stringObjectStructure();
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001604 m_graph.registerStructure(stringObjectStructure);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001605 ASSERT(stringObjectStructure->storedPrototype().isObject());
fpizlo@apple.com10ae2d02013-08-14 02:41:47 +00001606 ASSERT(stringObjectStructure->storedPrototype().asCell()->classInfo() == StringPrototype::info());
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001607
1608 FrozenValue* stringPrototypeObjectValue =
1609 m_graph.freeze(stringObjectStructure->storedPrototype());
1610 StringPrototype* stringPrototypeObject =
1611 stringPrototypeObjectValue->dynamicCast<StringPrototype*>();
1612 Structure* stringPrototypeStructure = stringPrototypeObjectValue->structure();
fpizlo@apple.com920c1672014-08-19 00:55:31 +00001613 if (m_graph.registerStructure(stringPrototypeStructure) != StructureRegisteredAndWatched)
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001614 return false;
1615
1616 if (stringPrototypeStructure->isDictionary())
1617 return false;
1618
1619 // We're being conservative here. We want DFG's ToString on StringObject to be
1620 // used in both numeric contexts (that would call valueOf()) and string contexts
1621 // (that would call toString()). We don't want the DFG to have to distinguish
1622 // between the two, just because that seems like it would get confusing. So we
1623 // just require both methods to be sane.
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001624 if (!isStringPrototypeMethodSane(stringPrototypeObject, stringPrototypeStructure, vm().propertyNames->valueOf.impl()))
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001625 return false;
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001626 if (!isStringPrototypeMethodSane(stringPrototypeObject, stringPrototypeStructure, vm().propertyNames->toString.impl()))
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001627 return false;
1628
1629 return true;
1630 }
1631
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001632 void fixupGetAndSetLocalsInBlock(BasicBlock* block)
fpizlo@apple.combbaf6192013-02-27 01:45:28 +00001633 {
1634 if (!block)
1635 return;
1636 ASSERT(block->isReachable);
1637 m_block = block;
1638 for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
1639 Node* node = m_currentNode = block->at(m_indexInBlock);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001640 if (node->op() != SetLocal && node->op() != GetLocal)
fpizlo@apple.combbaf6192013-02-27 01:45:28 +00001641 continue;
fpizlo@apple.combbaf6192013-02-27 01:45:28 +00001642
1643 VariableAccessData* variable = node->variableAccessData();
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001644 switch (node->op()) {
1645 case GetLocal:
1646 switch (variable->flushFormat()) {
1647 case FlushedDouble:
1648 node->setResult(NodeResultDouble);
1649 break;
1650 case FlushedInt52:
1651 node->setResult(NodeResultInt52);
1652 break;
1653 default:
1654 break;
1655 }
fpizlo@apple.com571d3b22013-09-11 21:24:34 +00001656 break;
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001657
1658 case SetLocal:
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00001659 // NOTE: Any type checks we put here may get hoisted by fixupChecksInBlock(). So, if we
1660 // add new type checking use kind for SetLocals, we need to modify that code as well.
1661
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001662 switch (variable->flushFormat()) {
1663 case FlushedJSValue:
1664 break;
1665 case FlushedDouble:
1666 fixEdge<DoubleRepUse>(node->child1());
1667 break;
1668 case FlushedInt32:
1669 fixEdge<Int32Use>(node->child1());
1670 break;
1671 case FlushedInt52:
1672 fixEdge<Int52RepUse>(node->child1());
1673 break;
1674 case FlushedCell:
1675 fixEdge<CellUse>(node->child1());
1676 break;
1677 case FlushedBoolean:
1678 fixEdge<BooleanUse>(node->child1());
1679 break;
1680 default:
1681 RELEASE_ASSERT_NOT_REACHED();
1682 break;
1683 }
fpizlo@apple.com571d3b22013-09-11 21:24:34 +00001684 break;
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001685
fpizlo@apple.com571d3b22013-09-11 21:24:34 +00001686 default:
1687 RELEASE_ASSERT_NOT_REACHED();
1688 break;
1689 }
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001690 }
1691 m_insertionSet.execute(block);
1692 }
1693
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001694 Node* checkArray(ArrayMode arrayMode, const NodeOrigin& origin, Node* array, Node* index, bool (*storageCheck)(const ArrayMode&) = canCSEStorage)
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001695 {
fpizlo@apple.com34d1f082012-10-28 06:13:23 +00001696 ASSERT(arrayMode.isSpecific());
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001697
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00001698 if (arrayMode.type() == Array::String) {
1699 m_insertionSet.insertNode(
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001700 m_indexInBlock, SpecNone, Check, origin, Edge(array, StringUse));
fpizlo@apple.com99f37622012-10-29 04:02:08 +00001701 } else {
fpizlo@apple.com141cdcc2015-05-06 23:14:14 +00001702 // Note that we only need to be using a structure check if we opt for SaneChain, since
1703 // that needs to protect against JSArray's __proto__ being changed.
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001704 Structure* structure = arrayMode.originalArrayStructure(m_graph, origin.semantic);
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00001705
1706 Edge indexEdge = index ? Edge(index, Int32Use) : Edge();
fpizlo@apple.com141cdcc2015-05-06 23:14:14 +00001707
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00001708 if (arrayMode.doesConversion()) {
1709 if (structure) {
1710 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001711 m_indexInBlock, SpecNone, ArrayifyToStructure, origin,
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00001712 OpInfo(structure), OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
1713 } else {
1714 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001715 m_indexInBlock, SpecNone, Arrayify, origin,
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00001716 OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
1717 }
fpizlo@apple.com3f1a01b2012-11-10 05:54:11 +00001718 } else {
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00001719 if (structure) {
1720 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001721 m_indexInBlock, SpecNone, CheckStructure, origin,
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00001722 OpInfo(m_graph.addStructureSet(structure)), Edge(array, CellUse));
1723 } else {
1724 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001725 m_indexInBlock, SpecNone, CheckArray, origin,
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00001726 OpInfo(arrayMode.asWord()), Edge(array, CellUse));
1727 }
fpizlo@apple.com3f1a01b2012-11-10 05:54:11 +00001728 }
fpizlo@apple.com497c7512012-09-19 01:20:52 +00001729 }
1730
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001731 if (!storageCheck(arrayMode))
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001732 return 0;
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001733
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +00001734 if (arrayMode.usesButterfly()) {
1735 return m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001736 m_indexInBlock, SpecNone, GetButterfly, origin, Edge(array, CellUse));
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +00001737 }
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001738
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +00001739 return m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001740 m_indexInBlock, SpecNone, GetIndexedPropertyStorage, origin,
fpizlo@apple.com06f82b52013-03-06 02:27:16 +00001741 OpInfo(arrayMode.asWord()), Edge(array, KnownCellUse));
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001742 }
1743
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001744 void blessArrayOperation(Edge base, Edge index, Edge& storageChild)
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001745 {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001746 Node* node = m_currentNode;
1747
1748 switch (node->arrayMode().type()) {
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001749 case Array::ForceExit: {
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +00001750 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001751 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001752 return;
1753 }
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001754
fpizlo@apple.coma0ec0592012-10-22 23:52:15 +00001755 case Array::SelectUsingPredictions:
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001756 case Array::Unprofiled:
oliver@apple.com5598c182013-01-23 22:25:07 +00001757 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001758 return;
1759
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001760 case Array::Generic:
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001761 return;
1762
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001763 default: {
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001764 Node* storage = checkArray(node->arrayMode(), node->origin, base.node(), index.node());
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001765 if (!storage)
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001766 return;
1767
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001768 storageChild = Edge(storage);
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001769 return;
1770 } }
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001771 }
1772
fpizlo@apple.combbaf6192013-02-27 01:45:28 +00001773 bool alwaysUnboxSimplePrimitives()
1774 {
1775#if USE(JSVALUE64)
1776 return false;
1777#else
1778 // Any boolean, int, or cell value is profitable to unbox on 32-bit because it
1779 // reduces traffic.
1780 return true;
1781#endif
1782 }
fpizlo@apple.com46955912013-04-26 01:18:18 +00001783
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00001784 template<UseKind useKind>
1785 void observeUseKindOnNode(Node* node)
1786 {
fpizlo@apple.comaa1cc982013-09-12 05:46:49 +00001787 if (useKind == UntypedUse)
1788 return;
fpizlo@apple.com46955912013-04-26 01:18:18 +00001789 observeUseKindOnNode(node, useKind);
1790 }
1791
1792 void observeUseKindOnEdge(Edge edge)
1793 {
1794 observeUseKindOnNode(edge.node(), edge.useKind());
1795 }
1796
1797 void observeUseKindOnNode(Node* node, UseKind useKind)
1798 {
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00001799 if (node->op() != GetLocal)
1800 return;
1801
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001802 // FIXME: The way this uses alwaysUnboxSimplePrimitives() is suspicious.
1803 // https://bugs.webkit.org/show_bug.cgi?id=121518
1804
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00001805 VariableAccessData* variable = node->variableAccessData();
1806 switch (useKind) {
1807 case Int32Use:
fpizlo@apple.com7289af32015-08-21 03:59:33 +00001808 case KnownInt32Use:
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00001809 if (alwaysUnboxSimplePrimitives()
1810 || isInt32Speculation(variable->prediction()))
1811 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1812 break;
1813 case NumberUse:
fpizlo@apple.com318af072015-06-05 04:59:28 +00001814 case RealNumberUse:
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001815 case DoubleRepUse:
1816 case DoubleRepRealUse:
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00001817 if (variable->doubleFormatState() == UsingDoubleFormat)
1818 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1819 break;
1820 case BooleanUse:
fpizlo@apple.com7289af32015-08-21 03:59:33 +00001821 case KnownBooleanUse:
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00001822 if (alwaysUnboxSimplePrimitives()
1823 || isBooleanSpeculation(variable->prediction()))
1824 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1825 break;
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001826 case Int52RepUse:
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001827 if (isMachineIntSpeculation(variable->prediction()))
1828 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1829 break;
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00001830 case CellUse:
oliver@apple.com176a3472013-07-25 04:00:19 +00001831 case KnownCellUse:
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00001832 case ObjectUse:
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001833 case FunctionUse:
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00001834 case StringUse:
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001835 case KnownStringUse:
utatane.tea@gmail.comfccd1362015-08-11 22:02:09 +00001836 case SymbolUse:
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001837 case StringObjectUse:
1838 case StringOrStringObjectUse:
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00001839 if (alwaysUnboxSimplePrimitives()
1840 || isCellSpeculation(variable->prediction()))
1841 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1842 break;
1843 default:
1844 break;
1845 }
1846 }
1847
fpizlo@apple.com35701872013-02-23 01:03:10 +00001848 template<UseKind useKind>
fpizlo@apple.comc6bb4a92013-09-30 20:38:46 +00001849 void fixEdge(Edge& edge)
fpizlo@apple.com35701872013-02-23 01:03:10 +00001850 {
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00001851 observeUseKindOnNode<useKind>(edge.node());
fpizlo@apple.com35701872013-02-23 01:03:10 +00001852 edge.setUseKind(useKind);
1853 }
1854
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00001855 void speculateForBarrier(Edge value)
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001856 {
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00001857 // Currently, the DFG won't take advantage of this speculation. But, we want to do it in
1858 // the DFG anyway because if such a speculation would be wrong, we want to know before
1859 // we do an expensive compile.
1860
1861 if (value->shouldSpeculateInt32()) {
1862 insertCheck<Int32Use>(m_indexInBlock, value.node());
1863 return;
fpizlo@apple.com593cd922015-05-15 21:11:39 +00001864 }
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00001865
1866 if (value->shouldSpeculateBoolean()) {
1867 insertCheck<BooleanUse>(m_indexInBlock, value.node());
1868 return;
1869 }
1870
1871 if (value->shouldSpeculateOther()) {
1872 insertCheck<OtherUse>(m_indexInBlock, value.node());
1873 return;
1874 }
1875
1876 if (value->shouldSpeculateNumber()) {
1877 insertCheck<NumberUse>(m_indexInBlock, value.node());
1878 return;
1879 }
1880
1881 if (value->shouldSpeculateNotCell()) {
1882 insertCheck<NotCellUse>(m_indexInBlock, value.node());
1883 return;
1884 }
fpizlo@apple.com9ab60fa2014-09-26 22:53:20 +00001885 }
1886
1887 template<UseKind useKind>
1888 void insertCheck(unsigned indexInBlock, Node* node)
1889 {
1890 observeUseKindOnNode<useKind>(node);
fpizlo@apple.com3beeb7f2015-03-20 23:26:26 +00001891 m_insertionSet.insertNode(
fpizlo@apple.com9ab60fa2014-09-26 22:53:20 +00001892 indexInBlock, SpecNone, Check, m_currentNode->origin, Edge(node, useKind));
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001893 }
1894
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001895 void fixIntConvertingEdge(Edge& edge)
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00001896 {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001897 Node* node = edge.node();
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001898 if (node->shouldSpeculateInt32OrBoolean()) {
1899 fixIntOrBooleanEdge(edge);
msaboff@apple.com95894332014-01-29 19:18:54 +00001900 return;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001901 }
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00001902
fpizlo@apple.com027ed672014-01-08 00:27:06 +00001903 UseKind useKind;
1904 if (node->shouldSpeculateMachineInt())
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001905 useKind = Int52RepUse;
fpizlo@apple.com027ed672014-01-08 00:27:06 +00001906 else if (node->shouldSpeculateNumber())
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001907 useKind = DoubleRepUse;
fpizlo@apple.com027ed672014-01-08 00:27:06 +00001908 else
1909 useKind = NotCellUse;
1910 Node* newNode = m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001911 m_indexInBlock, SpecInt32, ValueToInt32, m_currentNode->origin,
fpizlo@apple.com027ed672014-01-08 00:27:06 +00001912 Edge(node, useKind));
1913 observeUseKindOnNode(node, useKind);
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00001914
fpizlo@apple.com027ed672014-01-08 00:27:06 +00001915 edge = Edge(newNode, KnownInt32Use);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001916 }
1917
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001918 void fixIntOrBooleanEdge(Edge& edge)
1919 {
1920 Node* node = edge.node();
1921 if (!node->sawBooleans()) {
1922 fixEdge<Int32Use>(edge);
1923 return;
1924 }
1925
1926 UseKind useKind;
1927 if (node->shouldSpeculateBoolean())
1928 useKind = BooleanUse;
1929 else
1930 useKind = UntypedUse;
1931 Node* newNode = m_insertionSet.insertNode(
1932 m_indexInBlock, SpecInt32, BooleanToNumber, m_currentNode->origin,
1933 Edge(node, useKind));
1934 observeUseKindOnNode(node, useKind);
1935
1936 edge = Edge(newNode, Int32Use);
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001937 }
1938
1939 void fixDoubleOrBooleanEdge(Edge& edge)
1940 {
1941 Node* node = edge.node();
1942 if (!node->sawBooleans()) {
1943 fixEdge<DoubleRepUse>(edge);
1944 return;
1945 }
1946
1947 UseKind useKind;
1948 if (node->shouldSpeculateBoolean())
1949 useKind = BooleanUse;
1950 else
1951 useKind = UntypedUse;
1952 Node* newNode = m_insertionSet.insertNode(
1953 m_indexInBlock, SpecInt32, BooleanToNumber, m_currentNode->origin,
1954 Edge(node, useKind));
1955 observeUseKindOnNode(node, useKind);
1956
1957 edge = Edge(newNode, DoubleRepUse);
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001958 }
1959
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001960 void truncateConstantToInt32(Edge& edge)
1961 {
1962 Node* oldNode = edge.node();
1963
fpizlo@apple.comb41e6822014-07-25 20:55:17 +00001964 JSValue value = oldNode->asJSValue();
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001965 if (value.isInt32())
1966 return;
1967
1968 value = jsNumber(JSC::toInt32(value.asNumber()));
1969 ASSERT(value.isInt32());
1970 edge.setNode(m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001971 m_indexInBlock, SpecInt32, JSConstant, m_currentNode->origin,
fpizlo@apple.comb41e6822014-07-25 20:55:17 +00001972 OpInfo(m_graph.freeze(value))));
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001973 }
1974
1975 void truncateConstantsIfNecessary(Node* node, AddSpeculationMode mode)
1976 {
fpizlo@apple.comefacb612013-09-10 22:16:00 +00001977 if (mode != SpeculateInt32AndTruncateConstants)
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001978 return;
1979
1980 ASSERT(node->child1()->hasConstant() || node->child2()->hasConstant());
1981 if (node->child1()->hasConstant())
1982 truncateConstantToInt32(node->child1());
1983 else
1984 truncateConstantToInt32(node->child2());
1985 }
1986
1987 bool attemptToMakeIntegerAdd(Node* node)
1988 {
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001989 AddSpeculationMode mode = m_graph.addSpeculationMode(node, FixupPass);
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001990 if (mode != DontSpeculateInt32) {
1991 truncateConstantsIfNecessary(node, mode);
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001992 fixIntOrBooleanEdge(node->child1());
1993 fixIntOrBooleanEdge(node->child2());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +00001994 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
1995 node->setArithMode(Arith::Unchecked);
1996 else
1997 node->setArithMode(Arith::CheckOverflow);
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001998 return true;
1999 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002000
fpizlo@apple.com6921b292013-09-18 17:14:02 +00002001 if (m_graph.addShouldSpeculateMachineInt(node)) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00002002 fixEdge<Int52RepUse>(node->child1());
2003 fixEdge<Int52RepUse>(node->child2());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +00002004 node->setArithMode(Arith::CheckOverflow);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00002005 node->setResult(NodeResultInt52);
fpizlo@apple.com6921b292013-09-18 17:14:02 +00002006 return true;
2007 }
2008
2009 return false;
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +00002010 }
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002011
2012 bool attemptToMakeGetArrayLength(Node* node)
2013 {
2014 if (!isInt32Speculation(node->prediction()))
2015 return false;
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002016 CodeBlock* profiledBlock = m_graph.baselineCodeBlockFor(node->origin.semantic);
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002017 ArrayProfile* arrayProfile =
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002018 profiledBlock->getArrayProfile(node->origin.semantic.bytecodeIndex);
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002019 ArrayMode arrayMode = ArrayMode(Array::SelectUsingPredictions);
2020 if (arrayProfile) {
2021 ConcurrentJITLocker locker(profiledBlock->m_lock);
2022 arrayProfile->computeUpdatedPrediction(locker, profiledBlock);
2023 arrayMode = ArrayMode::fromObserved(locker, arrayProfile, Array::Read, false);
2024 if (arrayMode.type() == Array::Unprofiled) {
2025 // For normal array operations, it makes sense to treat Unprofiled
2026 // accesses as ForceExit and get more data rather than using
2027 // predictions and then possibly ending up with a Generic. But here,
2028 // we treat anything that is Unprofiled as Generic and keep the
2029 // GetById. I.e. ForceExit = Generic. So, there is no harm - and only
2030 // profit - from treating the Unprofiled case as
2031 // SelectUsingPredictions.
2032 arrayMode = ArrayMode(Array::SelectUsingPredictions);
2033 }
2034 }
2035
msaboff@apple.com95894332014-01-29 19:18:54 +00002036 arrayMode = arrayMode.refine(
fpizlo@apple.come079bb52014-03-05 07:41:03 +00002037 m_graph, node, node->child1()->prediction(), node->prediction());
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002038
2039 if (arrayMode.type() == Array::Generic) {
2040 // Check if the input is something that we can't get array length for, but for which we
2041 // could insert some conversions in order to transform it into something that we can do it
2042 // for.
2043 if (node->child1()->shouldSpeculateStringObject())
2044 attemptToForceStringArrayModeByToStringConversion<StringObjectUse>(arrayMode, node);
2045 else if (node->child1()->shouldSpeculateStringOrStringObject())
2046 attemptToForceStringArrayModeByToStringConversion<StringOrStringObjectUse>(arrayMode, node);
2047 }
2048
2049 if (!arrayMode.supportsLength())
2050 return false;
2051
2052 convertToGetArrayLength(node, arrayMode);
2053 return true;
2054 }
2055
fpizlo@apple.com537a4772013-08-19 23:16:01 +00002056 bool attemptToMakeGetTypedArrayByteLength(Node* node)
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002057 {
2058 if (!isInt32Speculation(node->prediction()))
2059 return false;
2060
2061 TypedArrayType type = typedArrayTypeFromSpeculation(node->child1()->prediction());
2062 if (!isTypedView(type))
2063 return false;
2064
2065 if (elementSize(type) == 1) {
2066 convertToGetArrayLength(node, ArrayMode(toArrayType(type)));
2067 return true;
2068 }
2069
2070 Node* length = prependGetArrayLength(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002071 node->origin, node->child1().node(), ArrayMode(toArrayType(type)));
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002072
2073 Node* shiftAmount = m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002074 m_indexInBlock, SpecInt32, JSConstant, node->origin,
fpizlo@apple.comb41e6822014-07-25 20:55:17 +00002075 OpInfo(m_graph.freeze(jsNumber(logElementSize(type)))));
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002076
2077 // We can use a BitLShift here because typed arrays will never have a byteLength
2078 // that overflows int32.
2079 node->setOp(BitLShift);
fpizlo@apple.comcad67682015-02-09 19:57:41 +00002080 node->clearFlags(NodeMustGenerate);
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002081 observeUseKindOnNode(length, Int32Use);
2082 observeUseKindOnNode(shiftAmount, Int32Use);
2083 node->child1() = Edge(length, Int32Use);
2084 node->child2() = Edge(shiftAmount, Int32Use);
2085 return true;
2086 }
2087
2088 void convertToGetArrayLength(Node* node, ArrayMode arrayMode)
2089 {
2090 node->setOp(GetArrayLength);
fpizlo@apple.comcad67682015-02-09 19:57:41 +00002091 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00002092 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002093 node->setArrayMode(arrayMode);
2094
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002095 Node* storage = checkArray(arrayMode, node->origin, node->child1().node(), 0, lengthNeedsStorage);
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002096 if (!storage)
2097 return;
2098
2099 node->child2() = Edge(storage);
2100 }
2101
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002102 Node* prependGetArrayLength(NodeOrigin origin, Node* child, ArrayMode arrayMode)
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002103 {
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002104 Node* storage = checkArray(arrayMode, origin, child, 0, lengthNeedsStorage);
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002105 return m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002106 m_indexInBlock, SpecInt32, GetArrayLength, origin,
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002107 OpInfo(arrayMode.asWord()), Edge(child, KnownCellUse), Edge(storage));
2108 }
fpizlo@apple.com537a4772013-08-19 23:16:01 +00002109
2110 bool attemptToMakeGetTypedArrayByteOffset(Node* node)
2111 {
2112 if (!isInt32Speculation(node->prediction()))
2113 return false;
2114
2115 TypedArrayType type = typedArrayTypeFromSpeculation(node->child1()->prediction());
2116 if (!isTypedView(type))
2117 return false;
2118
2119 checkArray(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002120 ArrayMode(toArrayType(type)), node->origin, node->child1().node(),
fpizlo@apple.com537a4772013-08-19 23:16:01 +00002121 0, neverNeedsStorage);
2122
2123 node->setOp(GetTypedArrayByteOffset);
fpizlo@apple.comcad67682015-02-09 19:57:41 +00002124 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00002125 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.com537a4772013-08-19 23:16:01 +00002126 return true;
2127 }
msaboff@apple.com95894332014-01-29 19:18:54 +00002128
fpizlo@apple.com10107332015-08-24 21:44:39 +00002129 void fixupChecksInBlock(BasicBlock* block)
fpizlo@apple.comd4a77bb2014-04-12 18:22:27 +00002130 {
2131 if (!block)
2132 return;
2133 ASSERT(block->isReachable);
2134 m_block = block;
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002135 unsigned indexForChecks = UINT_MAX;
2136 NodeOrigin originForChecks;
2137 for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
2138 Node* node = block->at(indexInBlock);
2139
2140 // If this is a node at which we could exit, then save its index. If nodes after this one
2141 // cannot exit, then we will hoist checks to here.
2142 if (node->origin.exitOK) {
2143 indexForChecks = indexInBlock;
2144 originForChecks = node->origin;
2145 }
2146
2147 originForChecks = originForChecks.withSemantic(node->origin.semantic);
fpizlo@apple.com10107332015-08-24 21:44:39 +00002148
2149 // First, try to relax the representational demands of each node, in order to have
2150 // fewer conversions.
2151 switch (node->op()) {
2152 case MovHint:
2153 case Check:
2154 m_graph.doToChildren(
2155 node,
2156 [&] (Edge& edge) {
2157 switch (edge.useKind()) {
2158 case DoubleRepUse:
2159 case DoubleRepRealUse:
2160 if (edge->hasDoubleResult())
2161 break;
2162
2163 if (edge->hasInt52Result())
2164 edge.setUseKind(Int52RepUse);
2165 else if (edge.useKind() == DoubleRepUse)
2166 edge.setUseKind(NumberUse);
2167 break;
2168
2169 case Int52RepUse:
2170 // Nothing we can really do.
2171 break;
2172
2173 case UntypedUse:
2174 case NumberUse:
2175 if (edge->hasDoubleResult())
2176 edge.setUseKind(DoubleRepUse);
2177 else if (edge->hasInt52Result())
2178 edge.setUseKind(Int52RepUse);
2179 break;
2180
2181 case RealNumberUse:
2182 if (edge->hasDoubleResult())
2183 edge.setUseKind(DoubleRepRealUse);
2184 else if (edge->hasInt52Result())
2185 edge.setUseKind(Int52RepUse);
2186 break;
2187
2188 default:
2189 break;
2190 }
2191 });
2192 break;
2193
2194 case ValueToInt32:
2195 if (node->child1().useKind() == DoubleRepUse
2196 && !node->child1()->hasDoubleResult()) {
2197 node->child1().setUseKind(NumberUse);
2198 break;
2199 }
2200 break;
2201
2202 default:
2203 break;
2204 }
2205
2206 // Now, insert type conversions if necessary.
2207 m_graph.doToChildren(
2208 node,
2209 [&] (Edge& edge) {
2210 Node* result = nullptr;
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002211
fpizlo@apple.com10107332015-08-24 21:44:39 +00002212 switch (edge.useKind()) {
2213 case DoubleRepUse:
2214 case DoubleRepRealUse:
2215 case DoubleRepMachineIntUse: {
2216 if (edge->hasDoubleResult())
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002217 break;
fpizlo@apple.com10107332015-08-24 21:44:39 +00002218
2219 if (edge->isNumberConstant()) {
2220 result = m_insertionSet.insertNode(
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002221 indexForChecks, SpecBytecodeDouble, DoubleConstant, originForChecks,
fpizlo@apple.com10107332015-08-24 21:44:39 +00002222 OpInfo(m_graph.freeze(jsDoubleNumber(edge->asNumber()))));
2223 } else if (edge->hasInt52Result()) {
2224 result = m_insertionSet.insertNode(
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002225 indexForChecks, SpecInt52AsDouble, DoubleRep, originForChecks,
fpizlo@apple.com10107332015-08-24 21:44:39 +00002226 Edge(edge.node(), Int52RepUse));
2227 } else {
2228 UseKind useKind;
2229 if (edge->shouldSpeculateDoubleReal())
2230 useKind = RealNumberUse;
2231 else if (edge->shouldSpeculateNumber())
2232 useKind = NumberUse;
2233 else
2234 useKind = NotCellUse;
2235
2236 result = m_insertionSet.insertNode(
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002237 indexForChecks, SpecBytecodeDouble, DoubleRep, originForChecks,
fpizlo@apple.com10107332015-08-24 21:44:39 +00002238 Edge(edge.node(), useKind));
2239 }
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002240
2241 edge.setNode(result);
fpizlo@apple.com10107332015-08-24 21:44:39 +00002242 break;
2243 }
2244
2245 case Int52RepUse: {
2246 if (edge->hasInt52Result())
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002247 break;
fpizlo@apple.com10107332015-08-24 21:44:39 +00002248
2249 if (edge->isMachineIntConstant()) {
2250 result = m_insertionSet.insertNode(
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002251 indexForChecks, SpecMachineInt, Int52Constant, originForChecks,
fpizlo@apple.com10107332015-08-24 21:44:39 +00002252 OpInfo(edge->constant()));
2253 } else if (edge->hasDoubleResult()) {
2254 result = m_insertionSet.insertNode(
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002255 indexForChecks, SpecMachineInt, Int52Rep, originForChecks,
fpizlo@apple.com10107332015-08-24 21:44:39 +00002256 Edge(edge.node(), DoubleRepMachineIntUse));
2257 } else if (edge->shouldSpeculateInt32ForArithmetic()) {
2258 result = m_insertionSet.insertNode(
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002259 indexForChecks, SpecInt32, Int52Rep, originForChecks,
fpizlo@apple.com10107332015-08-24 21:44:39 +00002260 Edge(edge.node(), Int32Use));
2261 } else {
2262 result = m_insertionSet.insertNode(
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002263 indexForChecks, SpecMachineInt, Int52Rep, originForChecks,
fpizlo@apple.com10107332015-08-24 21:44:39 +00002264 Edge(edge.node(), MachineIntUse));
2265 }
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002266
2267 edge.setNode(result);
fpizlo@apple.com10107332015-08-24 21:44:39 +00002268 break;
2269 }
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002270
fpizlo@apple.com10107332015-08-24 21:44:39 +00002271 default: {
2272 if (!edge->hasDoubleResult() && !edge->hasInt52Result())
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002273 break;
fpizlo@apple.com10107332015-08-24 21:44:39 +00002274
2275 if (edge->hasDoubleResult()) {
2276 result = m_insertionSet.insertNode(
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002277 indexForChecks, SpecBytecodeDouble, ValueRep, originForChecks,
fpizlo@apple.com10107332015-08-24 21:44:39 +00002278 Edge(edge.node(), DoubleRepUse));
2279 } else {
2280 result = m_insertionSet.insertNode(
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002281 indexForChecks, SpecInt32 | SpecInt52AsDouble, ValueRep,
2282 originForChecks, Edge(edge.node(), Int52RepUse));
fpizlo@apple.com10107332015-08-24 21:44:39 +00002283 }
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002284
2285 edge.setNode(result);
fpizlo@apple.com10107332015-08-24 21:44:39 +00002286 break;
2287 } }
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002288
2289 // It's remotely possible that this node cannot do type checks, but we now have a
2290 // type check on this node. We don't have to handle the general form of this
2291 // problem. It only arises when ByteCodeParser emits an immediate SetLocal, rather
2292 // than a delayed one. So, we only worry about those checks that we may have put on
2293 // a SetLocal. Note that "indexForChecks != indexInBlock" is just another way of
2294 // saying "!node->origin.exitOK".
2295 if (indexForChecks != indexInBlock && mayHaveTypeCheck(edge.useKind())) {
2296 UseKind knownUseKind;
2297
2298 switch (edge.useKind()) {
2299 case Int32Use:
2300 knownUseKind = KnownInt32Use;
2301 break;
2302 case CellUse:
2303 knownUseKind = KnownCellUse;
2304 break;
2305 case BooleanUse:
2306 knownUseKind = KnownBooleanUse;
2307 break;
2308 default:
2309 // This can only arise if we have a Check node, and in that case, we can
2310 // just remove the original check.
2311 DFG_ASSERT(m_graph, node, node->op() == Check);
2312 knownUseKind = UntypedUse;
2313 break;
2314 }
2315
2316 m_insertionSet.insertNode(
2317 indexForChecks, SpecNone, Check, originForChecks, edge);
2318
2319 edge.setUseKind(knownUseKind);
2320 }
fpizlo@apple.com10107332015-08-24 21:44:39 +00002321 });
fpizlo@apple.comd4a77bb2014-04-12 18:22:27 +00002322 }
fpizlo@apple.com10107332015-08-24 21:44:39 +00002323
fpizlo@apple.comd4a77bb2014-04-12 18:22:27 +00002324 m_insertionSet.execute(block);
2325 }
2326
fpizlo@apple.comf10d0722012-12-03 09:21:22 +00002327 BasicBlock* m_block;
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +00002328 unsigned m_indexInBlock;
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00002329 Node* m_currentNode;
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +00002330 InsertionSet m_insertionSet;
fpizlo@apple.combbaf6192013-02-27 01:45:28 +00002331 bool m_profitabilityChanged;
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00002332};
2333
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +00002334bool performFixup(Graph& graph)
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00002335{
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +00002336 SamplingRegion samplingRegion("DFG Fixup Phase");
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +00002337 return runPhase<FixupPhase>(graph);
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00002338}
2339
2340} } // namespace JSC::DFG
2341
2342#endif // ENABLE(DFG_JIT)
2343