blob: 997accab8a4f4c8357c999e557c1539f92e9a956 [file] [log] [blame]
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00001/*
fpizlo@apple.come799b862016-03-01 21:18:42 +00002 * Copyright (C) 2012-2016 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.comac4848f2016-05-16 19:41:01 +0000108 if (Node::shouldSpeculateUntypedForBitOps(node->child1().node(), node->child2().node())) {
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000109 fixEdge<UntypedUse>(node->child1());
110 fixEdge<UntypedUse>(node->child2());
111 break;
112 }
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000113 fixIntConvertingEdge(node->child1());
114 fixIntConvertingEdge(node->child2());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000115 break;
116 }
fpizlo@apple.com027ed672014-01-08 00:27:06 +0000117
oliver@apple.com64367322013-04-26 00:41:38 +0000118 case ArithIMul: {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000119 fixIntConvertingEdge(node->child1());
120 fixIntConvertingEdge(node->child2());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000121 node->setOp(ArithMul);
122 node->setArithMode(Arith::Unchecked);
123 node->child1().setUseKind(Int32Use);
124 node->child2().setUseKind(Int32Use);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000125 break;
126 }
benjamin@webkit.orge324d432015-04-26 19:55:18 +0000127
128 case ArithClz32: {
129 fixIntConvertingEdge(node->child1());
130 node->setArithMode(Arith::Unchecked);
131 break;
132 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000133
134 case UInt32ToNumber: {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000135 fixIntConvertingEdge(node->child1());
fpizlo@apple.com9089acb2013-12-14 06:33:42 +0000136 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
137 node->convertToIdentity();
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000138 else if (node->canSpeculateInt32(FixupPass))
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000139 node->setArithMode(Arith::CheckOverflow);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000140 else {
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000141 node->setArithMode(Arith::DoOverflow);
commit-queue@webkit.orgb6d27652016-04-07 04:33:32 +0000142 node->clearFlags(NodeMustGenerate);
commit-queue@webkit.orge086f372016-04-08 18:07:25 +0000143 node->setResult(enableInt52() ? NodeResultInt52 : NodeResultDouble);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000144 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000145 break;
146 }
147
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000148 case ValueAdd: {
fpizlo@apple.com97756552014-01-02 20:15:25 +0000149 if (attemptToMakeIntegerAdd(node)) {
150 node->setOp(ArithAdd);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000151 break;
fpizlo@apple.com97756552014-01-02 20:15:25 +0000152 }
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000153 if (Node::shouldSpeculateNumberOrBooleanExpectingDefined(node->child1().node(), node->child2().node())) {
154 fixDoubleOrBooleanEdge(node->child1());
155 fixDoubleOrBooleanEdge(node->child2());
fpizlo@apple.com97756552014-01-02 20:15:25 +0000156 node->setOp(ArithAdd);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000157 node->setResult(NodeResultDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000158 break;
159 }
fpizlo@apple.com8d225912013-03-19 00:44:57 +0000160
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +0000161 if (attemptToMakeFastStringAdd(node))
fpizlo@apple.com8d225912013-03-19 00:44:57 +0000162 break;
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +0000163
mark.lam@apple.com102cbf22015-11-17 21:55:33 +0000164 fixEdge<UntypedUse>(node->child1());
165 fixEdge<UntypedUse>(node->child2());
166 node->setResult(NodeResultJS);
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +0000167 break;
168 }
169
170 case StrCat: {
fpizlo@apple.com2b150e782015-08-27 23:59:57 +0000171 if (attemptToMakeFastStringAdd(node))
172 break;
173
174 // FIXME: Remove empty string arguments and possibly turn this into a ToString operation. That
175 // would require a form of ToString that takes a KnownPrimitiveUse. This is necessary because
176 // the implementation of StrCat doesn't dynamically optimize for empty strings.
177 // https://bugs.webkit.org/show_bug.cgi?id=148540
178 m_graph.doToChildren(
179 node,
180 [&] (Edge& edge) {
181 fixEdge<KnownPrimitiveUse>(edge);
182 });
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000183 break;
184 }
185
fpizlo@apple.com4463e442013-03-20 20:29:37 +0000186 case MakeRope: {
187 fixupMakeRope(node);
188 break;
189 }
190
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000191 case ArithAdd:
192 case ArithSub: {
mark.lam@apple.com75249092015-10-16 23:26:14 +0000193 if (op == ArithSub
fpizlo@apple.comacdb63e2016-05-10 02:01:28 +0000194 && Node::shouldSpeculateUntypedForArithmetic(node->child1().node(), node->child2().node())) {
mark.lam@apple.com75249092015-10-16 23:26:14 +0000195 fixEdge<UntypedUse>(node->child1());
196 fixEdge<UntypedUse>(node->child2());
197 node->setResult(NodeResultJS);
198 break;
199 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000200 if (attemptToMakeIntegerAdd(node))
201 break;
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000202 fixDoubleOrBooleanEdge(node->child1());
203 fixDoubleOrBooleanEdge(node->child2());
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000204 node->setResult(NodeResultDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000205 break;
206 }
207
208 case ArithNegate: {
mark.lam@apple.comfb6b2162016-01-13 22:21:40 +0000209 if (m_graph.unaryArithShouldSpeculateInt32(node, FixupPass)) {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000210 fixIntOrBooleanEdge(node->child1());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000211 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
212 node->setArithMode(Arith::Unchecked);
213 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
214 node->setArithMode(Arith::CheckOverflow);
215 else
216 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000217 break;
218 }
mark.lam@apple.com39e9c982016-04-25 17:48:46 +0000219 if (m_graph.unaryArithShouldSpeculateAnyInt(node, FixupPass)) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000220 fixEdge<Int52RepUse>(node->child1());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000221 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
222 node->setArithMode(Arith::CheckOverflow);
223 else
224 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000225 node->setResult(NodeResultInt52);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000226 break;
227 }
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000228 fixDoubleOrBooleanEdge(node->child1());
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000229 node->setResult(NodeResultDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000230 break;
231 }
232
233 case ArithMul: {
mark.lam@apple.com1d936142015-12-03 05:42:56 +0000234 Edge& leftChild = node->child1();
235 Edge& rightChild = node->child2();
fpizlo@apple.comacdb63e2016-05-10 02:01:28 +0000236 if (Node::shouldSpeculateUntypedForArithmetic(leftChild.node(), rightChild.node())) {
mark.lam@apple.com1d936142015-12-03 05:42:56 +0000237 fixEdge<UntypedUse>(leftChild);
238 fixEdge<UntypedUse>(rightChild);
239 node->setResult(NodeResultJS);
240 break;
241 }
mark.lam@apple.comfb6b2162016-01-13 22:21:40 +0000242 if (m_graph.binaryArithShouldSpeculateInt32(node, FixupPass)) {
mark.lam@apple.com1d936142015-12-03 05:42:56 +0000243 fixIntOrBooleanEdge(leftChild);
244 fixIntOrBooleanEdge(rightChild);
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000245 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
246 node->setArithMode(Arith::Unchecked);
commit-queue@webkit.orgee8d7db2016-04-22 19:27:57 +0000247 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())
248 || leftChild.node() == rightChild.node())
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000249 node->setArithMode(Arith::CheckOverflow);
250 else
251 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000252 break;
253 }
mark.lam@apple.com39e9c982016-04-25 17:48:46 +0000254 if (m_graph.binaryArithShouldSpeculateAnyInt(node, FixupPass)) {
mark.lam@apple.com1d936142015-12-03 05:42:56 +0000255 fixEdge<Int52RepUse>(leftChild);
256 fixEdge<Int52RepUse>(rightChild);
commit-queue@webkit.orgee8d7db2016-04-22 19:27:57 +0000257 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())
258 || leftChild.node() == rightChild.node())
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000259 node->setArithMode(Arith::CheckOverflow);
260 else
261 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000262 node->setResult(NodeResultInt52);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000263 break;
264 }
mark.lam@apple.com1d936142015-12-03 05:42:56 +0000265 fixDoubleOrBooleanEdge(leftChild);
266 fixDoubleOrBooleanEdge(rightChild);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000267 node->setResult(NodeResultDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000268 break;
269 }
270
oliver@apple.comf4443a72013-07-25 04:01:11 +0000271 case ArithDiv:
272 case ArithMod: {
mark.lam@apple.com224ce4d2015-12-08 21:44:12 +0000273 Edge& leftChild = node->child1();
274 Edge& rightChild = node->child2();
275 if (op == ArithDiv
mark.lam@apple.com46e290b2015-12-14 19:39:45 +0000276 && Node::shouldSpeculateUntypedForArithmetic(leftChild.node(), rightChild.node())
277 && m_graph.hasExitSite(node->origin.semantic, BadType)) {
mark.lam@apple.com224ce4d2015-12-08 21:44:12 +0000278 fixEdge<UntypedUse>(leftChild);
279 fixEdge<UntypedUse>(rightChild);
280 node->setResult(NodeResultJS);
281 break;
282 }
mark.lam@apple.comfb6b2162016-01-13 22:21:40 +0000283 if (m_graph.binaryArithShouldSpeculateInt32(node, FixupPass)) {
ossy@webkit.orgd3a3de92015-03-16 18:44:46 +0000284 if (optimizeForX86() || optimizeForARM64() || optimizeForARMv7IDIVSupported()) {
mark.lam@apple.com224ce4d2015-12-08 21:44:12 +0000285 fixIntOrBooleanEdge(leftChild);
286 fixIntOrBooleanEdge(rightChild);
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000287 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
288 node->setArithMode(Arith::Unchecked);
289 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
290 node->setArithMode(Arith::CheckOverflow);
291 else
292 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000293 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000294 }
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000295
296 // This will cause conversion nodes to be inserted later.
mark.lam@apple.com224ce4d2015-12-08 21:44:12 +0000297 fixDoubleOrBooleanEdge(leftChild);
298 fixDoubleOrBooleanEdge(rightChild);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000299
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000300 // We don't need to do ref'ing on the children because we're stealing them from
301 // the original division.
302 Node* newDivision = m_insertionSet.insertNode(
fpizlo@apple.com85bde1f2014-04-17 04:57:29 +0000303 m_indexInBlock, SpecBytecodeDouble, *node);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000304 newDivision->setResult(NodeResultDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000305
306 node->setOp(DoubleAsInt32);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000307 node->children.initialize(Edge(newDivision, DoubleRepUse), Edge(), Edge());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000308 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
309 node->setArithMode(Arith::CheckOverflow);
310 else
311 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000312 break;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000313 }
mark.lam@apple.com224ce4d2015-12-08 21:44:12 +0000314 fixDoubleOrBooleanEdge(leftChild);
315 fixDoubleOrBooleanEdge(rightChild);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000316 node->setResult(NodeResultDouble);
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000317 break;
318 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000319
320 case ArithMin:
oliver@apple.comf4443a72013-07-25 04:01:11 +0000321 case ArithMax: {
mark.lam@apple.comfb6b2162016-01-13 22:21:40 +0000322 if (m_graph.binaryArithShouldSpeculateInt32(node, FixupPass)) {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000323 fixIntOrBooleanEdge(node->child1());
324 fixIntOrBooleanEdge(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000325 break;
326 }
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000327 fixDoubleOrBooleanEdge(node->child1());
328 fixDoubleOrBooleanEdge(node->child2());
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000329 node->setResult(NodeResultDouble);
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000330 break;
331 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000332
333 case ArithAbs: {
mark.lam@apple.comfb6b2162016-01-13 22:21:40 +0000334 if (m_graph.unaryArithShouldSpeculateInt32(node, FixupPass)) {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000335 fixIntOrBooleanEdge(node->child1());
commit-queue@webkit.orgf4256ed2016-02-17 23:35:11 +0000336 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
337 node->setArithMode(Arith::Unchecked);
338 else
339 node->setArithMode(Arith::CheckOverflow);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000340 break;
341 }
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000342 fixDoubleOrBooleanEdge(node->child1());
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000343 node->setResult(NodeResultDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000344 break;
345 }
benjamin@webkit.org903025b2015-02-14 04:20:21 +0000346
347 case ArithPow: {
benjamin@webkit.org903025b2015-02-14 04:20:21 +0000348 if (node->child2()->shouldSpeculateInt32OrBooleanForArithmetic()) {
349 fixDoubleOrBooleanEdge(node->child1());
350 fixIntOrBooleanEdge(node->child2());
351 break;
352 }
353
354 fixDoubleOrBooleanEdge(node->child1());
355 fixDoubleOrBooleanEdge(node->child2());
356 break;
357 }
benjamin@webkit.orgcb584082015-05-08 00:23:32 +0000358
utatane.tea@gmail.comd2fca0a2015-12-15 03:51:42 +0000359 case ArithRandom: {
360 node->setResult(NodeResultDouble);
361 break;
362 }
363
utatane.tea@gmail.com9971c632016-03-01 02:30:46 +0000364 case ArithRound:
365 case ArithFloor:
utatane.tea@gmail.com9b9f43e2016-04-03 08:37:26 +0000366 case ArithCeil:
367 case ArithTrunc: {
mark.lam@apple.comfb6b2162016-01-13 22:21:40 +0000368 if (m_graph.unaryArithShouldSpeculateInt32(node, FixupPass)) {
benjamin@webkit.orgcb584082015-05-08 00:23:32 +0000369 fixIntOrBooleanEdge(node->child1());
370 insertCheck<Int32Use>(m_indexInBlock, node->child1().node());
371 node->convertToIdentity();
372 break;
373 }
374 fixDoubleOrBooleanEdge(node->child1());
375
376 if (isInt32OrBooleanSpeculation(node->getHeapPrediction()) && m_graph.roundShouldSpeculateInt32(node, FixupPass)) {
377 node->setResult(NodeResultInt32);
378 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
379 node->setArithRoundingMode(Arith::RoundingMode::Int32);
380 else
381 node->setArithRoundingMode(Arith::RoundingMode::Int32WithNegativeZeroCheck);
382 } else {
383 node->setResult(NodeResultDouble);
384 node->setArithRoundingMode(Arith::RoundingMode::Double);
385 }
386 break;
387 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000388
fpizlo@apple.comb3336c72013-10-31 19:19:15 +0000389 case ArithSqrt:
fpizlo@apple.comc5919412014-04-12 23:01:33 +0000390 case ArithFRound:
fpizlo@apple.comb3336c72013-10-31 19:19:15 +0000391 case ArithSin:
benjamin@webkit.org2b5682d2015-03-04 22:39:28 +0000392 case ArithCos:
393 case ArithLog: {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000394 fixDoubleOrBooleanEdge(node->child1());
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000395 node->setResult(NodeResultDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000396 break;
397 }
398
399 case LogicalNot: {
fpizlo@apple.com7289af32015-08-21 03:59:33 +0000400 if (node->child1()->shouldSpeculateBoolean()) {
401 if (node->child1()->result() == NodeResultBoolean) {
402 // This is necessary in case we have a bytecode instruction implemented by:
403 //
404 // a: CompareEq(...)
405 // b: LogicalNot(@a)
406 //
407 // In that case, CompareEq might have a side-effect. Then, we need to make
408 // sure that we know that Branch does not exit.
409 fixEdge<KnownBooleanUse>(node->child1());
410 } else
411 fixEdge<BooleanUse>(node->child1());
412 } else if (node->child1()->shouldSpeculateObjectOrOther())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000413 fixEdge<ObjectOrOtherUse>(node->child1());
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000414 else if (node->child1()->shouldSpeculateInt32OrBoolean())
415 fixIntOrBooleanEdge(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000416 else if (node->child1()->shouldSpeculateNumber())
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000417 fixEdge<DoubleRepUse>(node->child1());
commit-queue@webkit.org008e8dc2013-10-12 02:21:45 +0000418 else if (node->child1()->shouldSpeculateString())
419 fixEdge<StringUse>(node->child1());
fpizlo@apple.com91331742016-03-07 02:07:28 +0000420 else if (node->child1()->shouldSpeculateStringOrOther())
421 fixEdge<StringOrOtherUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000422 break;
423 }
fpizlo@apple.comee10e452013-04-09 00:10:16 +0000424
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000425 case CompareEq:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000426 case CompareLess:
427 case CompareLessEq:
428 case CompareGreater:
429 case CompareGreaterEq: {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000430 if (node->op() == CompareEq
431 && Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
432 fixEdge<BooleanUse>(node->child1());
433 fixEdge<BooleanUse>(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000434 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000435 break;
436 }
437 if (Node::shouldSpeculateInt32OrBoolean(node->child1().node(), node->child2().node())) {
438 fixIntOrBooleanEdge(node->child1());
439 fixIntOrBooleanEdge(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000440 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000441 break;
442 }
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000443 if (enableInt52()
mark.lam@apple.com39e9c982016-04-25 17:48:46 +0000444 && Node::shouldSpeculateAnyInt(node->child1().node(), node->child2().node())) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000445 fixEdge<Int52RepUse>(node->child1());
446 fixEdge<Int52RepUse>(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000447 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000448 break;
449 }
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000450 if (Node::shouldSpeculateNumberOrBoolean(node->child1().node(), node->child2().node())) {
451 fixDoubleOrBooleanEdge(node->child1());
452 fixDoubleOrBooleanEdge(node->child2());
commit-queue@webkit.orgfab33f42016-04-17 04:55:02 +0000453 }
454 if (node->op() != CompareEq
455 && node->child1()->shouldSpeculateNotCell()
456 && node->child2()->shouldSpeculateNotCell()) {
457 if (node->child1()->shouldSpeculateNumberOrBoolean())
458 fixDoubleOrBooleanEdge(node->child1());
459 else
460 fixEdge<DoubleRepUse>(node->child1());
461 if (node->child2()->shouldSpeculateNumberOrBoolean())
462 fixDoubleOrBooleanEdge(node->child2());
463 else
464 fixEdge<DoubleRepUse>(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000465 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000466 break;
467 }
oliver@apple.combd15be82013-07-25 04:03:42 +0000468 if (node->child1()->shouldSpeculateStringIdent() && node->child2()->shouldSpeculateStringIdent()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000469 fixEdge<StringIdentUse>(node->child1());
470 fixEdge<StringIdentUse>(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000471 node->clearFlags(NodeMustGenerate);
oliver@apple.combd15be82013-07-25 04:03:42 +0000472 break;
473 }
fpizlo@apple.comee10e452013-04-09 00:10:16 +0000474 if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && GPRInfo::numberOfRegisters >= 7) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000475 fixEdge<StringUse>(node->child1());
476 fixEdge<StringUse>(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000477 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000478 break;
fpizlo@apple.comee10e452013-04-09 00:10:16 +0000479 }
commit-queue@webkit.org36c52882016-04-22 05:08:28 +0000480
481 if (node->op() != CompareEq)
482 break;
483 if (Node::shouldSpeculateSymbol(node->child1().node(), node->child2().node())) {
484 fixEdge<SymbolUse>(node->child1());
485 fixEdge<SymbolUse>(node->child2());
486 node->clearFlags(NodeMustGenerate);
487 break;
488 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000489 if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000490 fixEdge<ObjectUse>(node->child1());
491 fixEdge<ObjectUse>(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000492 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000493 break;
494 }
benjamin@webkit.org32b8d0a2015-08-19 04:09:12 +0000495
496 // If either child can be proved to be Null or Undefined, comparing them is greatly simplified.
497 bool oneArgumentIsUsedAsSpecOther = false;
498 if (node->child1()->isUndefinedOrNullConstant()) {
499 fixEdge<OtherUse>(node->child1());
500 oneArgumentIsUsedAsSpecOther = true;
501 } else if (node->child1()->shouldSpeculateOther()) {
502 m_insertionSet.insertNode(m_indexInBlock, SpecNone, Check, node->origin,
503 Edge(node->child1().node(), OtherUse));
504 fixEdge<OtherUse>(node->child1());
505 oneArgumentIsUsedAsSpecOther = true;
506 }
507 if (node->child2()->isUndefinedOrNullConstant()) {
508 fixEdge<OtherUse>(node->child2());
509 oneArgumentIsUsedAsSpecOther = true;
510 } else if (node->child2()->shouldSpeculateOther()) {
511 m_insertionSet.insertNode(m_indexInBlock, SpecNone, Check, node->origin,
512 Edge(node->child2().node(), OtherUse));
513 fixEdge<OtherUse>(node->child2());
514 oneArgumentIsUsedAsSpecOther = true;
515 }
516 if (oneArgumentIsUsedAsSpecOther) {
517 node->clearFlags(NodeMustGenerate);
518 break;
519 }
520
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000521 if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObjectOrOther()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000522 fixEdge<ObjectUse>(node->child1());
523 fixEdge<ObjectOrOtherUse>(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000524 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000525 break;
526 }
527 if (node->child1()->shouldSpeculateObjectOrOther() && node->child2()->shouldSpeculateObject()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000528 fixEdge<ObjectOrOtherUse>(node->child1());
529 fixEdge<ObjectUse>(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000530 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000531 break;
532 }
benjamin@webkit.org32b8d0a2015-08-19 04:09:12 +0000533
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000534 break;
535 }
536
fpizlo@apple.comee10e452013-04-09 00:10:16 +0000537 case CompareStrictEq: {
ggaren@apple.com0f001eb2013-04-24 15:48:55 +0000538 if (Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000539 fixEdge<BooleanUse>(node->child1());
540 fixEdge<BooleanUse>(node->child2());
ggaren@apple.com0f001eb2013-04-24 15:48:55 +0000541 break;
542 }
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000543 if (Node::shouldSpeculateInt32(node->child1().node(), node->child2().node())) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000544 fixEdge<Int32Use>(node->child1());
545 fixEdge<Int32Use>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000546 break;
547 }
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000548 if (enableInt52()
mark.lam@apple.com39e9c982016-04-25 17:48:46 +0000549 && Node::shouldSpeculateAnyInt(node->child1().node(), node->child2().node())) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000550 fixEdge<Int52RepUse>(node->child1());
551 fixEdge<Int52RepUse>(node->child2());
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000552 break;
553 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000554 if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000555 fixEdge<DoubleRepUse>(node->child1());
556 fixEdge<DoubleRepUse>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000557 break;
558 }
utatane.tea@gmail.com382ef652015-10-01 17:20:44 +0000559 if (Node::shouldSpeculateSymbol(node->child1().node(), node->child2().node())) {
560 fixEdge<SymbolUse>(node->child1());
561 fixEdge<SymbolUse>(node->child2());
562 break;
563 }
oliver@apple.combd15be82013-07-25 04:03:42 +0000564 if (node->child1()->shouldSpeculateStringIdent() && node->child2()->shouldSpeculateStringIdent()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000565 fixEdge<StringIdentUse>(node->child1());
566 fixEdge<StringIdentUse>(node->child2());
oliver@apple.combd15be82013-07-25 04:03:42 +0000567 break;
568 }
bfulgham@apple.com58de7782014-10-08 16:18:03 +0000569 if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 7) || isFTL(m_graph.m_plan.mode))) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000570 fixEdge<StringUse>(node->child1());
571 fixEdge<StringUse>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000572 break;
fpizlo@apple.comee10e452013-04-09 00:10:16 +0000573 }
commit-queue@webkit.org902685c2015-06-24 19:13:54 +0000574 WatchpointSet* masqueradesAsUndefinedWatchpoint = m_graph.globalObjectFor(node->origin.semantic)->masqueradesAsUndefinedWatchpoint();
575 if (masqueradesAsUndefinedWatchpoint->isStillValid()) {
576
577 if (node->child1()->shouldSpeculateObject()) {
578 m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
579 fixEdge<ObjectUse>(node->child1());
580 break;
581 }
582 if (node->child2()->shouldSpeculateObject()) {
583 m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
584 fixEdge<ObjectUse>(node->child2());
585 break;
586 }
587
588 } else if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000589 fixEdge<ObjectUse>(node->child1());
590 fixEdge<ObjectUse>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000591 break;
592 }
fpizlo@apple.com312efcd2014-03-10 22:11:35 +0000593 if (node->child1()->shouldSpeculateMisc()) {
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000594 fixEdge<MiscUse>(node->child1());
fpizlo@apple.com312efcd2014-03-10 22:11:35 +0000595 break;
596 }
597 if (node->child2()->shouldSpeculateMisc()) {
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000598 fixEdge<MiscUse>(node->child2());
599 break;
600 }
fpizlo@apple.com385a33a2014-03-18 20:53:07 +0000601 if (node->child1()->shouldSpeculateStringIdent()
602 && node->child2()->shouldSpeculateNotStringVar()) {
603 fixEdge<StringIdentUse>(node->child1());
604 fixEdge<NotStringVarUse>(node->child2());
605 break;
606 }
607 if (node->child2()->shouldSpeculateStringIdent()
608 && node->child1()->shouldSpeculateNotStringVar()) {
609 fixEdge<StringIdentUse>(node->child2());
610 fixEdge<NotStringVarUse>(node->child1());
611 break;
612 }
bfulgham@apple.com58de7782014-10-08 16:18:03 +0000613 if (node->child1()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 8) || isFTL(m_graph.m_plan.mode))) {
fpizlo@apple.com385a33a2014-03-18 20:53:07 +0000614 fixEdge<StringUse>(node->child1());
615 break;
616 }
bfulgham@apple.com58de7782014-10-08 16:18:03 +0000617 if (node->child2()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 8) || isFTL(m_graph.m_plan.mode))) {
fpizlo@apple.com385a33a2014-03-18 20:53:07 +0000618 fixEdge<StringUse>(node->child2());
619 break;
620 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000621 break;
622 }
623
mark.lam@apple.com03a3e382016-01-08 18:44:36 +0000624 case StringFromCharCode:
fpizlo@apple.com47c16d72016-02-16 19:12:36 +0000625 if (node->child1()->shouldSpeculateInt32())
626 fixEdge<Int32Use>(node->child1());
627 else
mark.lam@apple.com151fe102016-01-13 23:28:38 +0000628 fixEdge<UntypedUse>(node->child1());
commit-queue@webkit.orgaa31a5e2013-04-09 06:45:16 +0000629 break;
630
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000631 case StringCharAt:
632 case StringCharCodeAt: {
633 // Currently we have no good way of refining these.
634 ASSERT(node->arrayMode() == ArrayMode(Array::String));
635 blessArrayOperation(node->child1(), node->child2(), node->child3());
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000636 fixEdge<KnownCellUse>(node->child1());
637 fixEdge<Int32Use>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000638 break;
639 }
640
fpizlo@apple.coma387b6a2012-11-01 07:41:43 +0000641 case GetByVal: {
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +0000642 if (!node->prediction()) {
643 m_insertionSet.insertNode(
644 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
645 }
646
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000647 node->setArrayMode(
648 node->arrayMode().refine(
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000649 m_graph, node,
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000650 node->child1()->prediction(),
651 node->child2()->prediction(),
benjamin@webkit.org9f46ddc2015-04-30 04:40:55 +0000652 SpecNone));
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000653
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000654 blessArrayOperation(node->child1(), node->child2(), node->child3());
fpizlo@apple.com94e84e92012-11-11 02:56:12 +0000655
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000656 ArrayMode arrayMode = node->arrayMode();
oliver@apple.com211b3be2013-07-25 04:03:39 +0000657 switch (arrayMode.type()) {
fpizlo@apple.com661530a2015-05-09 00:18:43 +0000658 case Array::Contiguous:
oliver@apple.com211b3be2013-07-25 04:03:39 +0000659 case Array::Double:
660 if (arrayMode.arrayClass() == Array::OriginalArray
fpizlo@apple.com141cdcc2015-05-06 23:14:14 +0000661 && arrayMode.speculation() == Array::InBounds) {
662 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
fpizlo@apple.com661530a2015-05-09 00:18:43 +0000663 if (globalObject->arrayPrototypeChainIsSane()) {
664 // Check if SaneChain will work on a per-type basis. Note that:
665 //
666 // 1) We don't want double arrays to sometimes return undefined, since
667 // that would require a change to the return type and it would pessimise
668 // things a lot. So, we'd only want to do that if we actually had
669 // evidence that we could read from a hole. That's pretty annoying.
670 // Likely the best way to handle that case is with an equivalent of
671 // SaneChain for OutOfBounds. For now we just detect when Undefined and
672 // NaN are indistinguishable according to backwards propagation, and just
673 // use SaneChain in that case. This happens to catch a lot of cases.
674 //
675 // 2) We don't want int32 array loads to have to do a hole check just to
676 // coerce to Undefined, since that would mean twice the checks.
677 //
678 // This has two implications. First, we have to do more checks than we'd
679 // like. It's unfortunate that we have to do the hole check. Second,
680 // some accesses that hit a hole will now need to take the full-blown
681 // out-of-bounds slow path. We can fix that with:
682 // https://bugs.webkit.org/show_bug.cgi?id=144668
683
684 bool canDoSaneChain = false;
685 switch (arrayMode.type()) {
686 case Array::Contiguous:
687 // This is happens to be entirely natural. We already would have
688 // returned any JSValue, and now we'll return Undefined. We still do
689 // the check but it doesn't require taking any kind of slow path.
690 canDoSaneChain = true;
691 break;
692
693 case Array::Double:
694 if (!(node->flags() & NodeBytecodeUsesAsOther)) {
695 // Holes look like NaN already, so if the user doesn't care
696 // about the difference between Undefined and NaN then we can
697 // do this.
698 canDoSaneChain = true;
699 }
700 break;
701
702 default:
703 break;
704 }
705
706 if (canDoSaneChain) {
707 m_graph.watchpoints().addLazily(
708 globalObject->arrayPrototype()->structure()->transitionWatchpointSet());
709 m_graph.watchpoints().addLazily(
710 globalObject->objectPrototype()->structure()->transitionWatchpointSet());
fpizlo@apple.comc2b8c092016-04-24 17:05:51 +0000711 if (globalObject->arrayPrototypeChainIsSane())
712 node->setArrayMode(arrayMode.withSpeculation(Array::SaneChain));
fpizlo@apple.com661530a2015-05-09 00:18:43 +0000713 }
fpizlo@apple.com141cdcc2015-05-06 23:14:14 +0000714 }
715 }
oliver@apple.com211b3be2013-07-25 04:03:39 +0000716 break;
717
718 case Array::String:
719 if ((node->prediction() & ~SpecString)
fpizlo@apple.com6793a322014-02-12 05:42:32 +0000720 || m_graph.hasExitSite(node->origin.semantic, OutOfBounds))
oliver@apple.com211b3be2013-07-25 04:03:39 +0000721 node->setArrayMode(arrayMode.withSpeculation(Array::OutOfBounds));
722 break;
723
724 default:
725 break;
726 }
fpizlo@apple.com94e84e92012-11-11 02:56:12 +0000727
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000728 arrayMode = node->arrayMode();
729 switch (arrayMode.type()) {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000730 case Array::SelectUsingPredictions:
731 case Array::Unprofiled:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000732 RELEASE_ASSERT_NOT_REACHED();
733 break;
734 case Array::Generic:
735#if USE(JSVALUE32_64)
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000736 fixEdge<CellUse>(node->child1()); // Speculating cell due to register pressure on 32-bit.
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000737#endif
738 break;
739 case Array::ForceExit:
740 break;
741 default:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000742 fixEdge<KnownCellUse>(node->child1());
743 fixEdge<Int32Use>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000744 break;
745 }
746
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000747 switch (arrayMode.type()) {
748 case Array::Double:
749 if (!arrayMode.isOutOfBounds())
750 node->setResult(NodeResultDouble);
751 break;
752
753 case Array::Float32Array:
754 case Array::Float64Array:
755 node->setResult(NodeResultDouble);
756 break;
757
758 case Array::Uint32Array:
759 if (node->shouldSpeculateInt32())
760 break;
mark.lam@apple.com39e9c982016-04-25 17:48:46 +0000761 if (node->shouldSpeculateAnyInt() && enableInt52())
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000762 node->setResult(NodeResultInt52);
763 else
764 node->setResult(NodeResultDouble);
765 break;
766
767 default:
768 break;
769 }
770
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000771 break;
772 }
oliver@apple.come050d642013-10-19 00:09:28 +0000773
774 case PutByValDirect:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000775 case PutByVal:
776 case PutByValAlias: {
777 Edge& child1 = m_graph.varArgChild(node, 0);
778 Edge& child2 = m_graph.varArgChild(node, 1);
779 Edge& child3 = m_graph.varArgChild(node, 2);
780
781 node->setArrayMode(
782 node->arrayMode().refine(
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000783 m_graph, node,
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000784 child1->prediction(),
785 child2->prediction(),
786 child3->prediction()));
787
788 blessArrayOperation(child1, child2, m_graph.varArgChild(node, 3));
789
790 switch (node->arrayMode().modeForPut().type()) {
791 case Array::SelectUsingPredictions:
benjamin@webkit.org5c3fb3a2015-08-14 03:54:32 +0000792 case Array::SelectUsingArguments:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000793 case Array::Unprofiled:
794 case Array::Undecided:
795 RELEASE_ASSERT_NOT_REACHED();
796 break;
797 case Array::ForceExit:
798 case Array::Generic:
799#if USE(JSVALUE32_64)
800 // Due to register pressure on 32-bit, we speculate cell and
801 // ignore the base-is-not-cell case entirely by letting the
802 // baseline JIT handle it.
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000803 fixEdge<CellUse>(child1);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000804#endif
805 break;
806 case Array::Int32:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000807 fixEdge<KnownCellUse>(child1);
808 fixEdge<Int32Use>(child2);
809 fixEdge<Int32Use>(child3);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000810 break;
811 case Array::Double:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000812 fixEdge<KnownCellUse>(child1);
813 fixEdge<Int32Use>(child2);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000814 fixEdge<DoubleRepRealUse>(child3);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000815 break;
816 case Array::Int8Array:
817 case Array::Int16Array:
818 case Array::Int32Array:
819 case Array::Uint8Array:
820 case Array::Uint8ClampedArray:
821 case Array::Uint16Array:
822 case Array::Uint32Array:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000823 fixEdge<KnownCellUse>(child1);
824 fixEdge<Int32Use>(child2);
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000825 if (child3->shouldSpeculateInt32())
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000826 fixIntOrBooleanEdge(child3);
mark.lam@apple.com39e9c982016-04-25 17:48:46 +0000827 else if (child3->shouldSpeculateAnyInt())
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000828 fixEdge<Int52RepUse>(child3);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000829 else
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000830 fixDoubleOrBooleanEdge(child3);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000831 break;
832 case Array::Float32Array:
833 case Array::Float64Array:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000834 fixEdge<KnownCellUse>(child1);
835 fixEdge<Int32Use>(child2);
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000836 fixDoubleOrBooleanEdge(child3);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000837 break;
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000838 case Array::Contiguous:
839 case Array::ArrayStorage:
840 case Array::SlowPutArrayStorage:
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000841 fixEdge<KnownCellUse>(child1);
842 fixEdge<Int32Use>(child2);
fpizlo@apple.com49b1d722015-05-18 03:39:28 +0000843 speculateForBarrier(child3);
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000844 break;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000845 default:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000846 fixEdge<KnownCellUse>(child1);
847 fixEdge<Int32Use>(child2);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000848 break;
849 }
fpizlo@apple.coma387b6a2012-11-01 07:41:43 +0000850 break;
851 }
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000852
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000853 case ArrayPush: {
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000854 // May need to refine the array mode in case the value prediction contravenes
855 // the array prediction. For example, we may have evidence showing that the
856 // array is in Int32 mode, but the value we're storing is likely to be a double.
857 // Then we should turn this into a conversion to Double array followed by the
858 // push. On the other hand, we absolutely don't want to refine based on the
859 // base prediction. If it has non-cell garbage in it, then we want that to be
860 // ignored. That's because ArrayPush can't handle any array modes that aren't
861 // array-related - so if refine() turned this into a "Generic" ArrayPush then
862 // that would break things.
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000863 node->setArrayMode(
864 node->arrayMode().refine(
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000865 m_graph, node,
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000866 node->child1()->prediction() & SpecCell,
mark.lam@apple.com39e9c982016-04-25 17:48:46 +0000867 SpecInt32Only,
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000868 node->child2()->prediction()));
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000869 blessArrayOperation(node->child1(), Edge(), node->child3());
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000870 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000871
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000872 switch (node->arrayMode().type()) {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000873 case Array::Int32:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000874 fixEdge<Int32Use>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000875 break;
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000876 case Array::Double:
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000877 fixEdge<DoubleRepRealUse>(node->child2());
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000878 break;
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000879 case Array::Contiguous:
880 case Array::ArrayStorage:
fpizlo@apple.com49b1d722015-05-18 03:39:28 +0000881 speculateForBarrier(node->child2());
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000882 break;
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000883 default:
884 break;
885 }
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000886 break;
887 }
888
889 case ArrayPop: {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000890 blessArrayOperation(node->child1(), Edge(), node->child2());
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000891 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.com8fd79212012-10-16 21:59:35 +0000892 break;
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000893 }
894
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000895 case RegExpExec:
896 case RegExpTest: {
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000897 fixEdge<KnownCellUse>(node->child1());
898
899 if (node->child2()->shouldSpeculateRegExpObject()) {
900 fixEdge<RegExpObjectUse>(node->child2());
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +0000901
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000902 if (node->child3()->shouldSpeculateString())
903 fixEdge<StringUse>(node->child3());
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000904 }
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000905 break;
906 }
fpizlo@apple.come799b862016-03-01 21:18:42 +0000907
msaboff@apple.com69940442016-04-27 01:28:03 +0000908 case StringReplace:
909 case StringReplaceRegExp: {
910 if (node->child2()->shouldSpeculateString()) {
911 m_insertionSet.insertNode(
912 m_indexInBlock, SpecNone, Check, node->origin,
913 Edge(node->child2().node(), StringUse));
914 fixEdge<StringUse>(node->child2());
915 } else if (op == StringReplace) {
916 if (node->child2()->shouldSpeculateRegExpObject())
917 addStringReplacePrimordialChecks(node->child2().node());
918 else
919 m_insertionSet.insertNode(
920 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
921 }
922
fpizlo@apple.come799b862016-03-01 21:18:42 +0000923 if (node->child1()->shouldSpeculateString()
924 && node->child2()->shouldSpeculateRegExpObject()
925 && node->child3()->shouldSpeculateString()) {
msaboff@apple.com69940442016-04-27 01:28:03 +0000926
fpizlo@apple.come799b862016-03-01 21:18:42 +0000927 fixEdge<StringUse>(node->child1());
928 fixEdge<RegExpObjectUse>(node->child2());
929 fixEdge<StringUse>(node->child3());
930 break;
931 }
932 break;
933 }
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000934
935 case Branch: {
fpizlo@apple.com7289af32015-08-21 03:59:33 +0000936 if (node->child1()->shouldSpeculateBoolean()) {
937 if (node->child1()->result() == NodeResultBoolean) {
938 // This is necessary in case we have a bytecode instruction implemented by:
939 //
940 // a: CompareEq(...)
941 // b: Branch(@a)
942 //
943 // In that case, CompareEq might have a side-effect. Then, we need to make
944 // sure that we know that Branch does not exit.
945 fixEdge<KnownBooleanUse>(node->child1());
946 } else
947 fixEdge<BooleanUse>(node->child1());
948 } else if (node->child1()->shouldSpeculateObjectOrOther())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000949 fixEdge<ObjectOrOtherUse>(node->child1());
fpizlo@apple.comd8846b12015-05-18 20:41:54 +0000950 else if (node->child1()->shouldSpeculateInt32OrBoolean())
951 fixIntOrBooleanEdge(node->child1());
fpizlo@apple.com2537f952014-07-28 20:41:09 +0000952 else if (node->child1()->shouldSpeculateNumber())
953 fixEdge<DoubleRepUse>(node->child1());
akling@apple.comd8786332015-04-28 18:54:12 +0000954 else if (node->child1()->shouldSpeculateString())
955 fixEdge<StringUse>(node->child1());
fpizlo@apple.com91331742016-03-07 02:07:28 +0000956 else if (node->child1()->shouldSpeculateStringOrOther())
957 fixEdge<StringOrOtherUse>(node->child1());
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000958 break;
959 }
960
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000961 case Switch: {
962 SwitchData* data = node->switchData();
963 switch (data->kind) {
964 case SwitchImm:
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000965 if (node->child1()->shouldSpeculateInt32())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000966 fixEdge<Int32Use>(node->child1());
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000967 break;
oliver@apple.com9e1c8092013-07-25 04:03:16 +0000968 case SwitchChar:
969 if (node->child1()->shouldSpeculateString())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000970 fixEdge<StringUse>(node->child1());
oliver@apple.com9e1c8092013-07-25 04:03:16 +0000971 break;
oliver@apple.com5c826c02013-07-25 04:03:51 +0000972 case SwitchString:
973 if (node->child1()->shouldSpeculateStringIdent())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000974 fixEdge<StringIdentUse>(node->child1());
oliver@apple.com5c826c02013-07-25 04:03:51 +0000975 else if (node->child1()->shouldSpeculateString())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000976 fixEdge<StringUse>(node->child1());
oliver@apple.com5c826c02013-07-25 04:03:51 +0000977 break;
fpizlo@apple.com29abafe2014-08-28 19:09:48 +0000978 case SwitchCell:
979 if (node->child1()->shouldSpeculateCell())
980 fixEdge<CellUse>(node->child1());
981 // else it's fine for this to have UntypedUse; we will handle this by just making
982 // non-cells take the default case.
983 break;
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000984 }
985 break;
986 }
987
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000988 case ToPrimitive: {
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +0000989 fixupToPrimitive(node);
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000990 break;
991 }
utatane.tea@gmail.com2a7c2992016-06-24 03:41:52 +0000992
993 case ToNumber: {
994 fixupToNumber(node);
995 break;
996 }
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000997
utatane.tea@gmail.com153559e2015-04-06 19:07:12 +0000998 case ToString:
999 case CallStringConstructor: {
1000 fixupToStringOrCallStringConstructor(node);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001001 break;
1002 }
1003
1004 case NewStringObject: {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001005 fixEdge<KnownStringUse>(node->child1());
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001006 break;
1007 }
1008
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001009 case NewArray: {
fpizlo@apple.com35398ea2015-12-04 22:25:26 +00001010 watchHavingABadTime(node);
1011
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001012 for (unsigned i = m_graph.varArgNumChildren(node); i--;) {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001013 node->setIndexingType(
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001014 leastUpperBoundOfIndexingTypeAndType(
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001015 node->indexingType(), m_graph.varArgChild(node, i)->prediction()));
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001016 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001017 switch (node->indexingType()) {
1018 case ALL_BLANK_INDEXING_TYPES:
1019 CRASH();
1020 break;
1021 case ALL_UNDECIDED_INDEXING_TYPES:
1022 if (node->numChildren()) {
1023 // This will only happen if the children have no type predictions. We
1024 // would have already exited by now, but insert a forced exit just to
1025 // be safe.
1026 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001027 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001028 }
1029 break;
1030 case ALL_INT32_INDEXING_TYPES:
1031 for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001032 fixEdge<Int32Use>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001033 break;
1034 case ALL_DOUBLE_INDEXING_TYPES:
1035 for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001036 fixEdge<DoubleRepRealUse>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001037 break;
1038 case ALL_CONTIGUOUS_INDEXING_TYPES:
1039 case ALL_ARRAY_STORAGE_INDEXING_TYPES:
1040 break;
1041 default:
1042 CRASH();
1043 break;
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001044 }
1045 break;
1046 }
1047
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001048 case NewTypedArray: {
fpizlo@apple.com35398ea2015-12-04 22:25:26 +00001049 watchHavingABadTime(node);
1050
fpizlo@apple.comefacb612013-09-10 22:16:00 +00001051 if (node->child1()->shouldSpeculateInt32()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001052 fixEdge<Int32Use>(node->child1());
fpizlo@apple.comcad67682015-02-09 19:57:41 +00001053 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001054 break;
1055 }
1056 break;
1057 }
1058
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001059 case NewArrayWithSize: {
fpizlo@apple.com35398ea2015-12-04 22:25:26 +00001060 watchHavingABadTime(node);
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001061 fixEdge<Int32Use>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001062 break;
1063 }
keith_miller@apple.com5bed6f62016-06-16 06:01:47 +00001064
1065 case CallObjectConstructor: {
1066 if (node->child1()->shouldSpeculateObject()) {
1067 fixEdge<ObjectUse>(node->child1());
1068 node->convertToIdentity();
1069 break;
1070 }
1071
1072 fixEdge<UntypedUse>(node->child1());
1073 break;
1074 }
1075
oliver@apple.come2fe4ce2013-07-25 03:59:41 +00001076 case ToThis: {
utatane.tea@gmail.com44616d02016-01-31 23:05:10 +00001077 fixupToThis(node);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001078 break;
1079 }
1080
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001081 case PutStructure: {
1082 fixEdge<KnownCellUse>(node->child1());
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001083 break;
1084 }
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001085
1086 case GetClosureVar:
1087 case GetFromArguments: {
fpizlo@apple.com90640ab2015-03-04 05:26:54 +00001088 fixEdge<KnownCellUse>(node->child1());
1089 break;
1090 }
1091
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001092 case PutClosureVar:
1093 case PutToArguments: {
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001094 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00001095 speculateForBarrier(node->child2());
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001096 break;
1097 }
commit-queue@webkit.orga4201b02015-08-17 22:24:20 +00001098
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001099 case SkipScope:
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +00001100 case GetScope:
1101 case GetGetter:
fpizlo@apple.com7518ba22016-03-06 20:11:09 +00001102 case GetSetter:
1103 case GetGlobalObject: {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001104 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001105 break;
1106 }
1107
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001108 case AllocatePropertyStorage:
1109 case ReallocatePropertyStorage: {
1110 fixEdge<KnownCellUse>(node->child1());
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001111 break;
1112 }
1113
keith_miller@apple.com7deaba82016-04-10 03:38:44 +00001114 case TryGetById: {
1115 if (node->child1()->shouldSpeculateCell())
1116 fixEdge<CellUse>(node->child1());
1117 break;
1118 }
1119
fpizlo@apple.com151e9af2013-08-16 02:30:37 +00001120 case GetById:
1121 case GetByIdFlush: {
fpizlo@apple.com409f5be2016-03-04 02:43:53 +00001122 // FIXME: This should be done in the ByteCodeParser based on reading the
1123 // PolymorphicAccess, which will surely tell us that this is a AccessCase::ArrayLength.
1124 // https://bugs.webkit.org/show_bug.cgi?id=154990
1125 if (node->child1()->shouldSpeculateCellOrOther()
1126 && !m_graph.hasExitSite(node->origin.semantic, BadType)
1127 && !m_graph.hasExitSite(node->origin.semantic, BadCache)
fpizlo@apple.com5116ee72015-02-26 22:44:45 +00001128 && !m_graph.hasExitSite(node->origin.semantic, BadIndexingType)
1129 && !m_graph.hasExitSite(node->origin.semantic, ExoticObjectMode)) {
fpizlo@apple.comef515142016-03-04 06:36:24 +00001130
utatane.tea@gmail.com8268d392015-05-23 18:41:53 +00001131 auto uid = m_graph.identifiers()[node->identifierNumber()];
fpizlo@apple.comef515142016-03-04 06:36:24 +00001132
utatane.tea@gmail.com8268d392015-05-23 18:41:53 +00001133 if (uid == vm().propertyNames->length.impl()) {
fpizlo@apple.com5116ee72015-02-26 22:44:45 +00001134 attemptToMakeGetArrayLength(node);
1135 break;
1136 }
fpizlo@apple.comef515142016-03-04 06:36:24 +00001137
1138 if (uid == vm().propertyNames->lastIndex.impl()
1139 && node->child1()->shouldSpeculateRegExpObject()) {
1140 node->setOp(GetRegExpObjectLastIndex);
1141 node->clearFlags(NodeMustGenerate);
1142 fixEdge<RegExpObjectUse>(node->child1());
1143 break;
1144 }
fpizlo@apple.comcbc41132013-03-19 20:23:01 +00001145 }
fpizlo@apple.com409f5be2016-03-04 02:43:53 +00001146
1147 if (node->child1()->shouldSpeculateCell())
1148 fixEdge<CellUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001149 break;
1150 }
sbarati@apple.com23315d62016-05-09 20:17:23 +00001151
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001152 case PutById:
oliver@apple.com11ce5ff2014-03-06 21:27:13 +00001153 case PutByIdFlush:
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001154 case PutByIdDirect: {
fpizlo@apple.comef515142016-03-04 06:36:24 +00001155 if (node->child1()->shouldSpeculateCellOrOther()
1156 && !m_graph.hasExitSite(node->origin.semantic, BadType)
1157 && !m_graph.hasExitSite(node->origin.semantic, BadCache)
1158 && !m_graph.hasExitSite(node->origin.semantic, BadIndexingType)
1159 && !m_graph.hasExitSite(node->origin.semantic, ExoticObjectMode)) {
1160
1161 auto uid = m_graph.identifiers()[node->identifierNumber()];
1162
1163 if (uid == vm().propertyNames->lastIndex.impl()
1164 && node->child1()->shouldSpeculateRegExpObject()) {
1165 node->setOp(SetRegExpObjectLastIndex);
1166 fixEdge<RegExpObjectUse>(node->child1());
1167 speculateForBarrier(node->child2());
1168 break;
1169 }
1170 }
1171
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001172 fixEdge<CellUse>(node->child1());
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001173 break;
1174 }
1175
utatane.tea@gmail.com287d64c2015-10-27 07:00:57 +00001176 case PutGetterById:
1177 case PutSetterById: {
1178 fixEdge<KnownCellUse>(node->child1());
1179 fixEdge<KnownCellUse>(node->child2());
1180 break;
1181 }
1182
1183 case PutGetterSetterById: {
1184 fixEdge<KnownCellUse>(node->child1());
1185 break;
1186 }
1187
1188 case PutGetterByVal:
1189 case PutSetterByVal: {
1190 fixEdge<KnownCellUse>(node->child1());
1191 fixEdge<KnownCellUse>(node->child3());
1192 break;
1193 }
1194
fpizlo@apple.com29abafe2014-08-28 19:09:48 +00001195 case GetExecutable: {
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001196 fixEdge<FunctionUse>(node->child1());
1197 break;
1198 }
keith_miller@apple.comcb11fe42015-12-18 00:37:35 +00001199
keith_miller@apple.com56806b32016-02-26 21:43:09 +00001200 case OverridesHasInstance:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001201 case CheckStructure:
fpizlo@apple.com29abafe2014-08-28 19:09:48 +00001202 case CheckCell:
oliver@apple.come17632e2013-07-25 04:05:31 +00001203 case CreateThis:
fpizlo@apple.com95ef6492016-03-15 15:26:36 +00001204 case GetButterfly: {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001205 fixEdge<CellUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001206 break;
1207 }
utatane.tea@gmail.comfccd1362015-08-11 22:02:09 +00001208
1209 case CheckIdent: {
1210 UniquedStringImpl* uid = node->uidOperand();
1211 if (uid->isSymbol())
1212 fixEdge<SymbolUse>(node->child1());
1213 else
1214 fixEdge<StringIdentUse>(node->child1());
1215 break;
1216 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001217
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001218 case Arrayify:
1219 case ArrayifyToStructure: {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001220 fixEdge<CellUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001221 if (node->child2())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001222 fixEdge<Int32Use>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001223 break;
1224 }
1225
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +00001226 case GetByOffset:
1227 case GetGetterSetterByOffset: {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001228 if (!node->child1()->hasStorageResult())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001229 fixEdge<KnownCellUse>(node->child1());
1230 fixEdge<KnownCellUse>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001231 break;
1232 }
1233
fpizlo@apple.com51614cc2014-02-17 06:35:32 +00001234 case MultiGetByOffset: {
1235 fixEdge<CellUse>(node->child1());
1236 break;
1237 }
1238
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001239 case PutByOffset: {
1240 if (!node->child1()->hasStorageResult())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001241 fixEdge<KnownCellUse>(node->child1());
1242 fixEdge<KnownCellUse>(node->child2());
fpizlo@apple.com12835772015-09-21 20:49:04 +00001243 insertInferredTypeCheck(
1244 m_insertionSet, m_indexInBlock, node->origin, node->child3().node(),
1245 node->storageAccessData().inferredType);
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00001246 speculateForBarrier(node->child3());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001247 break;
1248 }
1249
fpizlo@apple.com43219522014-02-25 02:02:50 +00001250 case MultiPutByOffset: {
1251 fixEdge<CellUse>(node->child1());
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00001252 speculateForBarrier(node->child2());
fpizlo@apple.com43219522014-02-25 02:02:50 +00001253 break;
1254 }
1255
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001256 case InstanceOf: {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001257 if (!(node->child1()->prediction() & ~SpecCell))
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001258 fixEdge<CellUse>(node->child1());
1259 fixEdge<CellUse>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001260 break;
1261 }
keith_miller@apple.comcb11fe42015-12-18 00:37:35 +00001262
1263 case InstanceOfCustom:
1264 fixEdge<CellUse>(node->child2());
1265 break;
1266
oliver@apple.comb3e5acb2013-07-25 04:02:53 +00001267 case In: {
1268 // FIXME: We should at some point have array profiling on op_in, in which
1269 // case we would be able to turn this into a kind of GetByVal.
1270
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001271 fixEdge<CellUse>(node->child2());
oliver@apple.comb3e5acb2013-07-25 04:02:53 +00001272 break;
1273 }
fpizlo@apple.com46955912013-04-26 01:18:18 +00001274
fpizlo@apple.com9df7fef2013-12-29 21:50:55 +00001275 case Check: {
fpizlo@apple.combb89cd52015-05-22 06:32:30 +00001276 m_graph.doToChildren(
1277 node,
1278 [&] (Edge& edge) {
1279 switch (edge.useKind()) {
1280 case NumberUse:
1281 if (edge->shouldSpeculateInt32ForArithmetic())
1282 edge.setUseKind(Int32Use);
1283 break;
1284 default:
1285 break;
1286 }
1287 observeUseKindOnEdge(edge);
1288 });
fpizlo@apple.com46955912013-04-26 01:18:18 +00001289 break;
1290 }
1291
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001292 case Phantom:
1293 // Phantoms are meaningless past Fixup. We recreate them on-demand in the backend.
1294 node->remove();
1295 break;
1296
fpizlo@apple.comf2999932014-07-15 00:41:39 +00001297 case FiatInt52: {
1298 RELEASE_ASSERT(enableInt52());
1299 node->convertToIdentity();
1300 fixEdge<Int52RepUse>(node->child1());
1301 node->setResult(NodeResultInt52);
1302 break;
1303 }
1304
keith_miller@apple.com59bba5d2015-10-16 22:18:42 +00001305 case GetArrayLength: {
1306 fixEdge<KnownCellUse>(node->child1());
1307 break;
1308 }
1309
1310 case GetTypedArrayByteOffset: {
1311 fixEdge<KnownCellUse>(node->child1());
1312 break;
1313 }
1314
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001315 case Phi:
oliver@apple.com827d2cf2013-07-25 04:04:45 +00001316 case Upsilon:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001317 case GetIndexedPropertyStorage:
1318 case LastNodeType:
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001319 case CheckTierUpInLoop:
1320 case CheckTierUpAtReturn:
1321 case CheckTierUpAndOSREnter:
fpizlo@apple.comd84425d2013-10-30 19:58:08 +00001322 case InvalidationPoint:
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00001323 case CheckArray:
fpizlo@apple.com8624c4b2013-12-10 03:24:31 +00001324 case CheckInBounds:
fpizlo@apple.com9ca951e2013-12-09 01:08:53 +00001325 case ConstantStoragePointer:
fpizlo@apple.com027ed672014-01-08 00:27:06 +00001326 case DoubleAsInt32:
fpizlo@apple.com027ed672014-01-08 00:27:06 +00001327 case ValueToInt32:
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001328 case DoubleRep:
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001329 case ValueRep:
fpizlo@apple.comf2999932014-07-15 00:41:39 +00001330 case Int52Rep:
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001331 case Int52Constant:
1332 case Identity: // This should have been cleaned up.
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001333 case BooleanToNumber:
fpizlo@apple.comfc70ba62014-09-26 03:59:33 +00001334 case PhantomNewObject:
commit-queue@webkit.org88ab4e72015-04-24 02:23:36 +00001335 case PhantomNewFunction:
utatane.tea@gmail.com9d9fd322015-12-17 10:33:08 +00001336 case PhantomNewGeneratorFunction:
basile_clement@apple.com2ca1f7b2015-05-05 16:34:21 +00001337 case PhantomCreateActivation:
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001338 case PhantomDirectArguments:
1339 case PhantomClonedArguments:
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001340 case GetMyArgumentByVal:
fpizlo@apple.comc2b8c092016-04-24 17:05:51 +00001341 case GetMyArgumentByValOutOfBounds:
fpizlo@apple.com8ff74712015-03-17 15:50:44 +00001342 case PutHint:
fpizlo@apple.comfc70ba62014-09-26 03:59:33 +00001343 case CheckStructureImmediate:
fpizlo@apple.comfc70ba62014-09-26 03:59:33 +00001344 case MaterializeNewObject:
basile_clement@apple.com2ca1f7b2015-05-05 16:34:21 +00001345 case MaterializeCreateActivation:
fpizlo@apple.combcfd8eb2015-02-26 19:51:52 +00001346 case PutStack:
1347 case KillStack:
1348 case GetStack:
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00001349 case StoreBarrier:
fpizlo@apple.comef515142016-03-04 06:36:24 +00001350 case GetRegExpObjectLastIndex:
1351 case SetRegExpObjectLastIndex:
fpizlo@apple.com280ef002016-04-05 22:13:16 +00001352 case RecordRegExpCachedResult:
fpizlo@apple.com9ca951e2013-12-09 01:08:53 +00001353 // These are just nodes that we don't currently expect to see during fixup.
1354 // If we ever wanted to insert them prior to fixup, then we just have to create
1355 // fixup rules for them.
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00001356 DFG_CRASH(m_graph, node, "Unexpected node during fixup");
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001357 break;
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001358
saambarati1@gmail.com060e7512015-09-03 19:45:44 +00001359 case PutGlobalVariable: {
fpizlo@apple.com33ea5ee2015-05-15 03:51:52 +00001360 fixEdge<CellUse>(node->child1());
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00001361 speculateForBarrier(node->child2());
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001362 break;
1363 }
1364
commit-queue@webkit.org2faae0e2013-10-07 22:08:53 +00001365 case IsString:
1366 if (node->child1()->shouldSpeculateString()) {
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001367 m_insertionSet.insertNode(
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001368 m_indexInBlock, SpecNone, Check, node->origin,
commit-queue@webkit.org2faae0e2013-10-07 22:08:53 +00001369 Edge(node->child1().node(), StringUse));
1370 m_graph.convertToConstant(node, jsBoolean(true));
1371 observeUseKindOnNode<StringUse>(node);
1372 }
1373 break;
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001374
utatane.tea@gmail.com0bfb74c2015-02-24 23:01:58 +00001375 case IsObject:
1376 if (node->child1()->shouldSpeculateObject()) {
1377 m_insertionSet.insertNode(
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001378 m_indexInBlock, SpecNone, Check, node->origin,
utatane.tea@gmail.com0bfb74c2015-02-24 23:01:58 +00001379 Edge(node->child1().node(), ObjectUse));
1380 m_graph.convertToConstant(node, jsBoolean(true));
1381 observeUseKindOnNode<ObjectUse>(node);
1382 }
1383 break;
1384
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001385 case GetEnumerableLength: {
1386 fixEdge<CellUse>(node->child1());
1387 break;
1388 }
1389 case HasGenericProperty: {
msaboff@apple.comb644c252015-03-24 10:05:21 +00001390 fixEdge<CellUse>(node->child2());
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001391 break;
1392 }
1393 case HasStructureProperty: {
1394 fixEdge<StringUse>(node->child2());
1395 fixEdge<KnownCellUse>(node->child3());
1396 break;
1397 }
1398 case HasIndexedProperty: {
1399 node->setArrayMode(
1400 node->arrayMode().refine(
1401 m_graph, node,
1402 node->child1()->prediction(),
1403 node->child2()->prediction(),
benjamin@webkit.org9f46ddc2015-04-30 04:40:55 +00001404 SpecNone));
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001405
1406 blessArrayOperation(node->child1(), node->child2(), node->child3());
1407 fixEdge<CellUse>(node->child1());
1408 fixEdge<KnownInt32Use>(node->child2());
1409 break;
1410 }
1411 case GetDirectPname: {
1412 Edge& base = m_graph.varArgChild(node, 0);
1413 Edge& property = m_graph.varArgChild(node, 1);
1414 Edge& index = m_graph.varArgChild(node, 2);
1415 Edge& enumerator = m_graph.varArgChild(node, 3);
1416 fixEdge<CellUse>(base);
1417 fixEdge<KnownCellUse>(property);
1418 fixEdge<KnownInt32Use>(index);
1419 fixEdge<KnownCellUse>(enumerator);
1420 break;
1421 }
msaboff@apple.comb644c252015-03-24 10:05:21 +00001422 case GetPropertyEnumerator: {
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001423 fixEdge<CellUse>(node->child1());
msaboff@apple.comb644c252015-03-24 10:05:21 +00001424 break;
1425 }
1426 case GetEnumeratorStructurePname: {
1427 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001428 fixEdge<KnownInt32Use>(node->child2());
1429 break;
1430 }
msaboff@apple.comb644c252015-03-24 10:05:21 +00001431 case GetEnumeratorGenericPname: {
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001432 fixEdge<KnownCellUse>(node->child1());
1433 fixEdge<KnownInt32Use>(node->child2());
1434 break;
1435 }
1436 case ToIndexString: {
1437 fixEdge<KnownInt32Use>(node->child1());
1438 break;
1439 }
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001440 case ProfileType: {
1441 // We want to insert type checks based on the instructionTypeSet of the TypeLocation, not the globalTypeSet.
1442 // Because the instructionTypeSet is contained in globalTypeSet, if we produce a type check for
1443 // type T for the instructionTypeSet, the global type set must also have information for type T.
1444 // So if it the type check succeeds for type T in the instructionTypeSet, a type check for type T
1445 // in the globalTypeSet would've also succeeded.
1446 // (The other direction does not hold in general).
1447
1448 RefPtr<TypeSet> typeSet = node->typeLocation()->m_instructionTypeSet;
saambarati1@gmail.comf9b86632015-03-28 17:28:11 +00001449 RuntimeTypeMask seenTypes = typeSet->seenTypes();
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00001450 if (typeSet->doesTypeConformTo(TypeAnyInt)) {
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001451 if (node->child1()->shouldSpeculateInt32())
1452 fixEdge<Int32Use>(node->child1());
1453 else
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00001454 fixEdge<AnyIntUse>(node->child1());
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001455 node->remove();
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00001456 } else if (typeSet->doesTypeConformTo(TypeNumber | TypeAnyInt)) {
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001457 fixEdge<NumberUse>(node->child1());
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001458 node->remove();
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001459 } else if (typeSet->doesTypeConformTo(TypeString)) {
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001460 fixEdge<StringUse>(node->child1());
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001461 node->remove();
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001462 } else if (typeSet->doesTypeConformTo(TypeBoolean)) {
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001463 fixEdge<BooleanUse>(node->child1());
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001464 node->remove();
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001465 } else if (typeSet->doesTypeConformTo(TypeUndefined | TypeNull) && (seenTypes & TypeUndefined) && (seenTypes & TypeNull)) {
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001466 fixEdge<OtherUse>(node->child1());
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001467 node->remove();
saambarati1@gmail.comd372c702014-10-16 19:55:14 +00001468 } else if (typeSet->doesTypeConformTo(TypeObject)) {
sbarati@apple.comf54044c2016-06-23 03:24:18 +00001469 StructureSet set;
1470 {
1471 ConcurrentJITLocker locker(typeSet->m_lock);
1472 set = typeSet->structureSet(locker);
1473 }
saambarati1@gmail.comd372c702014-10-16 19:55:14 +00001474 if (!set.isEmpty()) {
saambarati1@gmail.comd372c702014-10-16 19:55:14 +00001475 fixEdge<CellUse>(node->child1());
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001476 node->convertToCheckStructure(m_graph.addStructureSet(set));
saambarati1@gmail.comd372c702014-10-16 19:55:14 +00001477 }
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001478 }
1479
1480 break;
1481 }
msaboff@apple.comcc305da2014-12-11 16:41:33 +00001482
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001483 case CreateScopedArguments:
msaboff@apple.comcc305da2014-12-11 16:41:33 +00001484 case CreateActivation:
utatane.tea@gmail.com9d9fd322015-12-17 10:33:08 +00001485 case NewFunction:
1486 case NewGeneratorFunction: {
msaboff@apple.comea77cd02014-11-14 01:07:48 +00001487 fixEdge<CellUse>(node->child1());
1488 break;
1489 }
commit-queue@webkit.orga4201b02015-08-17 22:24:20 +00001490
mark.lam@apple.com47c2f142016-03-16 18:16:32 +00001491 case SetFunctionName: {
1492 // The first child is guaranteed to be a cell because op_set_function_name is only used
1493 // on a newly instantiated function object (the first child).
1494 fixEdge<KnownCellUse>(node->child1());
1495 fixEdge<UntypedUse>(node->child2());
1496 break;
1497 }
1498
sbarati@apple.comc0722da2015-11-20 02:37:47 +00001499 case CopyRest: {
1500 fixEdge<KnownCellUse>(node->child1());
sbarati@apple.com855d5602015-11-30 20:36:54 +00001501 fixEdge<KnownInt32Use>(node->child2());
sbarati@apple.comc0722da2015-11-20 02:37:47 +00001502 break;
1503 }
1504
sbarati@apple.come67fd782016-04-19 01:38:30 +00001505 case ResolveScope:
1506 case GetDynamicVar:
1507 case PutDynamicVar: {
1508 fixEdge<KnownCellUse>(node->child1());
1509 break;
1510 }
1511
sbarati@apple.comce5b05e2016-05-16 23:31:39 +00001512 case LogShadowChickenPrologue: {
1513 fixEdge<KnownCellUse>(node->child1());
1514 break;
1515 }
1516 case LogShadowChickenTail: {
1517 fixEdge<UntypedUse>(node->child1());
1518 fixEdge<KnownCellUse>(node->child2());
1519 break;
1520 }
1521
commit-queue@webkit.org2faae0e2013-10-07 22:08:53 +00001522#if !ASSERT_DISABLED
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001523 // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
1524 case SetArgument:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001525 case JSConstant:
fpizlo@apple.com024424c2016-03-09 05:16:47 +00001526 case LazyJSConstant:
benjamin@webkit.org54d94f52015-02-28 03:21:37 +00001527 case DoubleConstant:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001528 case GetLocal:
1529 case GetCallee:
keith_miller@apple.com85aeabb2016-06-03 23:06:39 +00001530 case GetArgumentCountIncludingThis:
sbarati@apple.com855d5602015-11-30 20:36:54 +00001531 case GetRestLength:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001532 case Flush:
1533 case PhantomLocal:
1534 case GetLocalUnlinked:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001535 case GetGlobalVar:
saambarati1@gmail.com060e7512015-09-03 19:45:44 +00001536 case GetGlobalLexicalVariable:
fpizlo@apple.com86468342013-11-27 02:47:43 +00001537 case NotifyWrite:
oliver@apple.com58c86752013-07-25 04:02:40 +00001538 case VarInjectionWatchpoint:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001539 case Call:
keith_miller@apple.comcb11fe42015-12-18 00:37:35 +00001540 case CheckTypeInfoFlags:
msaboff@apple.coma3dc7532015-09-24 21:42:59 +00001541 case TailCallInlinedCaller:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001542 case Construct:
fpizlo@apple.com8fefdd32015-02-18 19:55:47 +00001543 case CallVarargs:
msaboff@apple.coma3dc7532015-09-24 21:42:59 +00001544 case TailCallVarargsInlinedCaller:
fpizlo@apple.com8fefdd32015-02-18 19:55:47 +00001545 case ConstructVarargs:
1546 case CallForwardVarargs:
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001547 case ConstructForwardVarargs:
msaboff@apple.coma3dc7532015-09-24 21:42:59 +00001548 case TailCallForwardVarargs:
1549 case TailCallForwardVarargsInlinedCaller:
fpizlo@apple.com8fefdd32015-02-18 19:55:47 +00001550 case LoadVarargs:
keith_miller@apple.come497e202016-06-13 21:05:36 +00001551 case ForwardVarargs:
saambarati1@gmail.comb4f28a52014-12-05 05:58:07 +00001552 case ProfileControlFlow:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001553 case NewObject:
1554 case NewArrayBuffer:
1555 case NewRegexp:
keith_miller@apple.com485f5392016-04-18 20:02:24 +00001556 case DeleteById:
keith_miller@apple.com806e80d2016-05-05 17:30:02 +00001557 case DeleteByVal:
keith_miller@apple.com5bed6f62016-06-16 06:01:47 +00001558 case IsJSArray:
keith_miller@apple.com6919bc12016-06-23 01:39:01 +00001559 case IsTypedArrayView:
gskachkov@gmail.com086f8f62016-04-26 18:40:41 +00001560 case IsEmpty:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001561 case IsUndefined:
1562 case IsBoolean:
1563 case IsNumber:
utatane.tea@gmail.com0bfb74c2015-02-24 23:01:58 +00001564 case IsObjectOrNull:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001565 case IsFunction:
mark.lam@apple.com2c87b1a2016-04-20 00:02:07 +00001566 case IsRegExpObject:
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001567 case CreateDirectArguments:
1568 case CreateClonedArguments:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001569 case Jump:
1570 case Return:
msaboff@apple.coma3dc7532015-09-24 21:42:59 +00001571 case TailCall:
1572 case TailCallVarargs:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001573 case Throw:
1574 case ThrowReferenceError:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001575 case CountExecution:
1576 case ForceOSRExit:
fpizlo@apple.com29abafe2014-08-28 19:09:48 +00001577 case CheckBadCell:
rniwa@webkit.orgeb7ac192015-03-13 01:11:15 +00001578 case CheckNotEmpty:
mark.lam@apple.com10d23a12013-04-25 02:59:51 +00001579 case CheckWatchdogTimer:
oliver@apple.com1fc04182013-08-19 19:40:13 +00001580 case Unreachable:
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001581 case ExtractOSREntryLocal:
1582 case LoopHint:
fpizlo@apple.com9df7fef2013-12-29 21:50:55 +00001583 case MovHint:
1584 case ZombieHint:
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00001585 case ExitOK:
fpizlo@apple.com29abafe2014-08-28 19:09:48 +00001586 case BottomValue:
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001587 case TypeOf:
sbarati@apple.com23315d62016-05-09 20:17:23 +00001588 case GetByIdWithThis:
1589 case PutByIdWithThis:
1590 case PutByValWithThis:
1591 case GetByValWithThis:
1592 break;
1593
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001594 break;
1595#else
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00001596 default:
1597 break;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001598#endif
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00001599 }
fpizlo@apple.comaa1cc982013-09-12 05:46:49 +00001600 }
fpizlo@apple.com35398ea2015-12-04 22:25:26 +00001601
1602 void watchHavingABadTime(Node* node)
1603 {
1604 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
1605
1606 // If this global object is not having a bad time, watch it. We go down this path anytime the code
1607 // does an array allocation. The types of array allocations may change if we start to have a bad
1608 // time. It's easier to reason about this if we know that whenever the types change after we start
1609 // optimizing, the code just gets thrown out. Doing this at FixupPhase is just early enough, since
1610 // prior to this point nobody should have been doing optimizations based on the indexing type of
1611 // the allocation.
1612 if (!globalObject->isHavingABadTime())
1613 m_graph.watchpoints().addLazily(globalObject->havingABadTimeWatchpoint());
1614 }
fpizlo@apple.comaa1cc982013-09-12 05:46:49 +00001615
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001616 template<UseKind useKind>
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001617 void createToString(Node* node, Edge& edge)
fpizlo@apple.comcbc41132013-03-19 20:23:01 +00001618 {
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001619 edge.setNode(m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001620 m_indexInBlock, SpecString, ToString, node->origin,
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001621 Edge(edge.node(), useKind)));
fpizlo@apple.comcbc41132013-03-19 20:23:01 +00001622 }
1623
1624 template<UseKind useKind>
1625 void attemptToForceStringArrayModeByToStringConversion(ArrayMode& arrayMode, Node* node)
1626 {
1627 ASSERT(arrayMode == ArrayMode(Array::Generic));
1628
keith_miller@apple.com8b5e9cd2015-11-04 21:46:10 +00001629 if (!m_graph.canOptimizeStringObjectAccess(node->origin.semantic))
fpizlo@apple.comcbc41132013-03-19 20:23:01 +00001630 return;
1631
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001632 createToString<useKind>(node, node->child1());
fpizlo@apple.comcbc41132013-03-19 20:23:01 +00001633 arrayMode = ArrayMode(Array::String);
1634 }
1635
1636 template<UseKind useKind>
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001637 bool isStringObjectUse()
1638 {
1639 switch (useKind) {
1640 case StringObjectUse:
1641 case StringOrStringObjectUse:
1642 return true;
1643 default:
1644 return false;
1645 }
1646 }
1647
1648 template<UseKind useKind>
1649 void convertStringAddUse(Node* node, Edge& edge)
1650 {
1651 if (useKind == StringUse) {
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001652 observeUseKindOnNode<StringUse>(edge.node());
1653 m_insertionSet.insertNode(
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001654 m_indexInBlock, SpecNone, Check, node->origin,
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001655 Edge(edge.node(), StringUse));
1656 edge.setUseKind(KnownStringUse);
1657 return;
1658 }
1659
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001660 observeUseKindOnNode<useKind>(edge.node());
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001661 createToString<useKind>(node, edge);
1662 }
1663
1664 void convertToMakeRope(Node* node)
1665 {
1666 node->setOpAndDefaultFlags(MakeRope);
1667 fixupMakeRope(node);
1668 }
1669
1670 void fixupMakeRope(Node* node)
1671 {
1672 for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
1673 Edge& edge = node->children.child(i);
1674 if (!edge)
1675 break;
1676 edge.setUseKind(KnownStringUse);
fpizlo@apple.comb41e6822014-07-25 20:55:17 +00001677 JSString* string = edge->dynamicCastConstant<JSString*>();
1678 if (!string)
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001679 continue;
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001680 if (string->length())
1681 continue;
fpizlo@apple.com4bb938e2013-07-16 21:41:06 +00001682
1683 // Don't allow the MakeRope to have zero children.
1684 if (!i && !node->child2())
1685 break;
1686
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001687 node->children.removeEdge(i--);
1688 }
1689
1690 if (!node->child2()) {
1691 ASSERT(!node->child3());
1692 node->convertToIdentity();
1693 }
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001694 }
utatane.tea@gmail.com44616d02016-01-31 23:05:10 +00001695
1696 void fixupToThis(Node* node)
1697 {
1698 ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->isStrictMode() ? StrictMode : NotStrictMode;
1699
1700 if (ecmaMode == StrictMode) {
1701 if (node->child1()->shouldSpeculateBoolean()) {
1702 fixEdge<BooleanUse>(node->child1());
1703 node->convertToIdentity();
1704 return;
1705 }
1706
1707 if (node->child1()->shouldSpeculateInt32()) {
1708 fixEdge<Int32Use>(node->child1());
1709 node->convertToIdentity();
1710 return;
1711 }
1712
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00001713 if (enableInt52() && node->child1()->shouldSpeculateAnyInt()) {
utatane.tea@gmail.com44616d02016-01-31 23:05:10 +00001714 fixEdge<Int52RepUse>(node->child1());
1715 node->convertToIdentity();
1716 node->setResult(NodeResultInt52);
1717 return;
1718 }
1719
1720 if (node->child1()->shouldSpeculateNumber()) {
1721 fixEdge<DoubleRepUse>(node->child1());
1722 node->convertToIdentity();
1723 node->setResult(NodeResultDouble);
1724 return;
1725 }
1726
1727 if (node->child1()->shouldSpeculateSymbol()) {
1728 fixEdge<SymbolUse>(node->child1());
1729 node->convertToIdentity();
1730 return;
1731 }
1732
1733 if (node->child1()->shouldSpeculateStringIdent()) {
1734 fixEdge<StringIdentUse>(node->child1());
1735 node->convertToIdentity();
1736 return;
1737 }
1738
1739 if (node->child1()->shouldSpeculateString()) {
1740 fixEdge<StringUse>(node->child1());
1741 node->convertToIdentity();
1742 return;
1743 }
1744 }
1745
1746 if (node->child1()->shouldSpeculateOther()) {
1747 if (ecmaMode == StrictMode) {
1748 fixEdge<OtherUse>(node->child1());
1749 node->convertToIdentity();
1750 return;
1751 }
1752
1753 m_insertionSet.insertNode(
1754 m_indexInBlock, SpecNone, Check, node->origin,
1755 Edge(node->child1().node(), OtherUse));
1756 observeUseKindOnNode<OtherUse>(node->child1().node());
1757 m_graph.convertToConstant(
1758 node, m_graph.globalThisObjectFor(node->origin.semantic));
1759 return;
1760 }
1761
keith_miller@apple.comd1a5d2f2016-05-02 17:38:15 +00001762 // FIXME: This should cover other use cases but we don't have use kinds for them. It's not critical,
1763 // however, since we cover all the missing cases in constant folding.
1764 // https://bugs.webkit.org/show_bug.cgi?id=157213
utatane.tea@gmail.com44616d02016-01-31 23:05:10 +00001765 if (node->child1()->shouldSpeculateStringObject()) {
1766 fixEdge<StringObjectUse>(node->child1());
1767 node->convertToIdentity();
1768 return;
1769 }
1770
1771 if (isFinalObjectSpeculation(node->child1()->prediction())) {
1772 fixEdge<FinalObjectUse>(node->child1());
1773 node->convertToIdentity();
1774 return;
1775 }
1776 }
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001777
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001778 void fixupToPrimitive(Node* node)
1779 {
fpizlo@apple.comefacb612013-09-10 22:16:00 +00001780 if (node->child1()->shouldSpeculateInt32()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001781 fixEdge<Int32Use>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001782 node->convertToIdentity();
1783 return;
1784 }
1785
1786 if (node->child1()->shouldSpeculateString()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001787 fixEdge<StringUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001788 node->convertToIdentity();
1789 return;
1790 }
1791
1792 if (node->child1()->shouldSpeculateStringObject()
keith_miller@apple.com8b5e9cd2015-11-04 21:46:10 +00001793 && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001794 fixEdge<StringObjectUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001795 node->convertToToString();
1796 return;
1797 }
1798
1799 if (node->child1()->shouldSpeculateStringOrStringObject()
keith_miller@apple.com8b5e9cd2015-11-04 21:46:10 +00001800 && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001801 fixEdge<StringOrStringObjectUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001802 node->convertToToString();
1803 return;
1804 }
1805 }
utatane.tea@gmail.com2a7c2992016-06-24 03:41:52 +00001806
1807 void fixupToNumber(Node* node)
1808 {
1809 if (node->child1()->shouldSpeculateInt32()) {
1810 fixEdge<Int32Use>(node->child1());
1811 node->convertToIdentity();
1812 return;
1813 }
1814
1815 if (enableInt52() && node->child1()->shouldSpeculateAnyInt()) {
1816 fixEdge<Int52RepUse>(node->child1());
1817 node->convertToIdentity();
1818 node->setResult(NodeResultInt52);
1819 return;
1820 }
1821
1822 if (node->child1()->shouldSpeculateNumber()) {
1823 fixEdge<DoubleRepUse>(node->child1());
1824 node->convertToIdentity();
1825 node->setResult(NodeResultDouble);
1826 return;
1827 }
1828
1829 fixEdge<UntypedUse>(node->child1());
1830 node->setResult(NodeResultJS);
1831 }
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001832
utatane.tea@gmail.com153559e2015-04-06 19:07:12 +00001833 void fixupToStringOrCallStringConstructor(Node* node)
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001834 {
1835 if (node->child1()->shouldSpeculateString()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001836 fixEdge<StringUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001837 node->convertToIdentity();
1838 return;
1839 }
1840
1841 if (node->child1()->shouldSpeculateStringObject()
keith_miller@apple.com8b5e9cd2015-11-04 21:46:10 +00001842 && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001843 fixEdge<StringObjectUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001844 return;
1845 }
1846
1847 if (node->child1()->shouldSpeculateStringOrStringObject()
keith_miller@apple.com8b5e9cd2015-11-04 21:46:10 +00001848 && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001849 fixEdge<StringOrStringObjectUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001850 return;
1851 }
1852
1853 if (node->child1()->shouldSpeculateCell()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001854 fixEdge<CellUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001855 return;
1856 }
1857 }
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001858
1859 bool attemptToMakeFastStringAdd(Node* node)
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001860 {
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001861 bool goodToGo = true;
1862 m_graph.doToChildren(
1863 node,
1864 [&] (Edge& edge) {
1865 if (edge->shouldSpeculateString())
1866 return;
keith_miller@apple.com8b5e9cd2015-11-04 21:46:10 +00001867 if (m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001868 if (edge->shouldSpeculateStringObject())
1869 return;
1870 if (edge->shouldSpeculateStringOrStringObject())
1871 return;
1872 }
1873 goodToGo = false;
1874 });
1875 if (!goodToGo)
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001876 return false;
utatane.tea@gmail.comea361c12015-06-18 23:45:06 +00001877
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001878 m_graph.doToChildren(
1879 node,
1880 [&] (Edge& edge) {
1881 if (edge->shouldSpeculateString()) {
1882 convertStringAddUse<StringUse>(node, edge);
1883 return;
1884 }
keith_miller@apple.com8b5e9cd2015-11-04 21:46:10 +00001885 ASSERT(m_graph.canOptimizeStringObjectAccess(node->origin.semantic));
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001886 if (edge->shouldSpeculateStringObject()) {
1887 convertStringAddUse<StringObjectUse>(node, edge);
1888 return;
1889 }
1890 if (edge->shouldSpeculateStringOrStringObject()) {
1891 convertStringAddUse<StringOrStringObjectUse>(node, edge);
1892 return;
1893 }
1894 RELEASE_ASSERT_NOT_REACHED();
1895 });
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001896
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001897 convertToMakeRope(node);
1898 return true;
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001899 }
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001900
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001901 void fixupGetAndSetLocalsInBlock(BasicBlock* block)
fpizlo@apple.combbaf6192013-02-27 01:45:28 +00001902 {
1903 if (!block)
1904 return;
1905 ASSERT(block->isReachable);
1906 m_block = block;
1907 for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
1908 Node* node = m_currentNode = block->at(m_indexInBlock);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001909 if (node->op() != SetLocal && node->op() != GetLocal)
fpizlo@apple.combbaf6192013-02-27 01:45:28 +00001910 continue;
fpizlo@apple.combbaf6192013-02-27 01:45:28 +00001911
1912 VariableAccessData* variable = node->variableAccessData();
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001913 switch (node->op()) {
1914 case GetLocal:
1915 switch (variable->flushFormat()) {
1916 case FlushedDouble:
1917 node->setResult(NodeResultDouble);
1918 break;
1919 case FlushedInt52:
1920 node->setResult(NodeResultInt52);
1921 break;
1922 default:
1923 break;
1924 }
fpizlo@apple.com571d3b22013-09-11 21:24:34 +00001925 break;
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001926
1927 case SetLocal:
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00001928 // NOTE: Any type checks we put here may get hoisted by fixupChecksInBlock(). So, if we
1929 // add new type checking use kind for SetLocals, we need to modify that code as well.
1930
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001931 switch (variable->flushFormat()) {
1932 case FlushedJSValue:
1933 break;
1934 case FlushedDouble:
1935 fixEdge<DoubleRepUse>(node->child1());
1936 break;
1937 case FlushedInt32:
1938 fixEdge<Int32Use>(node->child1());
1939 break;
1940 case FlushedInt52:
1941 fixEdge<Int52RepUse>(node->child1());
1942 break;
1943 case FlushedCell:
1944 fixEdge<CellUse>(node->child1());
1945 break;
1946 case FlushedBoolean:
1947 fixEdge<BooleanUse>(node->child1());
1948 break;
1949 default:
1950 RELEASE_ASSERT_NOT_REACHED();
1951 break;
1952 }
fpizlo@apple.com571d3b22013-09-11 21:24:34 +00001953 break;
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001954
fpizlo@apple.com571d3b22013-09-11 21:24:34 +00001955 default:
1956 RELEASE_ASSERT_NOT_REACHED();
1957 break;
1958 }
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001959 }
1960 m_insertionSet.execute(block);
1961 }
1962
msaboff@apple.com69940442016-04-27 01:28:03 +00001963 void addStringReplacePrimordialChecks(Node* searchRegExp)
1964 {
1965 Node* node = m_currentNode;
1966
1967 // Check that structure of searchRegExp is RegExp object
1968 m_insertionSet.insertNode(
1969 m_indexInBlock, SpecNone, Check, node->origin,
1970 Edge(searchRegExp, RegExpObjectUse));
1971
1972 auto emitPrimordialCheckFor = [&] (JSValue primordialProperty, UniquedStringImpl* propertyUID) {
1973 unsigned index = m_graph.identifiers().ensure(propertyUID);
1974
1975 Node* actualProperty = m_insertionSet.insertNode(
1976 m_indexInBlock, SpecNone, TryGetById, node->origin,
1977 OpInfo(index), OpInfo(SpecFunction), Edge(searchRegExp, CellUse));
1978
1979 m_insertionSet.insertNode(
1980 m_indexInBlock, SpecNone, CheckCell, node->origin,
1981 OpInfo(m_graph.freeze(primordialProperty)), Edge(actualProperty, CellUse));
1982 };
1983
1984 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
1985
1986 // Check that searchRegExp.exec is the primordial RegExp.prototype.exec
1987 emitPrimordialCheckFor(globalObject->regExpProtoExecFunction(), vm().propertyNames->exec.impl());
1988 // Check that searchRegExp.global is the primordial RegExp.prototype.global
1989 emitPrimordialCheckFor(globalObject->regExpProtoGlobalGetter(), vm().propertyNames->global.impl());
1990 // Check that searchRegExp.unicode is the primordial RegExp.prototype.unicode
1991 emitPrimordialCheckFor(globalObject->regExpProtoUnicodeGetter(), vm().propertyNames->unicode.impl());
1992 // Check that searchRegExp[Symbol.match] is the primordial RegExp.prototype[Symbol.replace]
1993 emitPrimordialCheckFor(globalObject->regExpProtoSymbolReplaceFunction(), vm().propertyNames->replaceSymbol.impl());
1994 }
1995
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001996 Node* checkArray(ArrayMode arrayMode, const NodeOrigin& origin, Node* array, Node* index, bool (*storageCheck)(const ArrayMode&) = canCSEStorage)
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001997 {
fpizlo@apple.com34d1f082012-10-28 06:13:23 +00001998 ASSERT(arrayMode.isSpecific());
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001999
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00002000 if (arrayMode.type() == Array::String) {
2001 m_insertionSet.insertNode(
fpizlo@apple.com163291d2015-04-28 19:27:23 +00002002 m_indexInBlock, SpecNone, Check, origin, Edge(array, StringUse));
fpizlo@apple.com99f37622012-10-29 04:02:08 +00002003 } else {
fpizlo@apple.com141cdcc2015-05-06 23:14:14 +00002004 // Note that we only need to be using a structure check if we opt for SaneChain, since
2005 // that needs to protect against JSArray's __proto__ being changed.
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002006 Structure* structure = arrayMode.originalArrayStructure(m_graph, origin.semantic);
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00002007
2008 Edge indexEdge = index ? Edge(index, Int32Use) : Edge();
fpizlo@apple.com141cdcc2015-05-06 23:14:14 +00002009
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00002010 if (arrayMode.doesConversion()) {
2011 if (structure) {
2012 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002013 m_indexInBlock, SpecNone, ArrayifyToStructure, origin,
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00002014 OpInfo(structure), OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
2015 } else {
2016 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002017 m_indexInBlock, SpecNone, Arrayify, origin,
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00002018 OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
2019 }
fpizlo@apple.com3f1a01b2012-11-10 05:54:11 +00002020 } else {
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00002021 if (structure) {
2022 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002023 m_indexInBlock, SpecNone, CheckStructure, origin,
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00002024 OpInfo(m_graph.addStructureSet(structure)), Edge(array, CellUse));
2025 } else {
2026 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002027 m_indexInBlock, SpecNone, CheckArray, origin,
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00002028 OpInfo(arrayMode.asWord()), Edge(array, CellUse));
2029 }
fpizlo@apple.com3f1a01b2012-11-10 05:54:11 +00002030 }
fpizlo@apple.com497c7512012-09-19 01:20:52 +00002031 }
2032
fpizlo@apple.com04c19742012-08-26 22:35:26 +00002033 if (!storageCheck(arrayMode))
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00002034 return 0;
fpizlo@apple.com04c19742012-08-26 22:35:26 +00002035
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +00002036 if (arrayMode.usesButterfly()) {
2037 return m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002038 m_indexInBlock, SpecNone, GetButterfly, origin, Edge(array, CellUse));
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +00002039 }
fpizlo@apple.com04c19742012-08-26 22:35:26 +00002040
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +00002041 return m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002042 m_indexInBlock, SpecNone, GetIndexedPropertyStorage, origin,
fpizlo@apple.com06f82b52013-03-06 02:27:16 +00002043 OpInfo(arrayMode.asWord()), Edge(array, KnownCellUse));
fpizlo@apple.com04c19742012-08-26 22:35:26 +00002044 }
2045
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002046 void blessArrayOperation(Edge base, Edge index, Edge& storageChild)
fpizlo@apple.com04c19742012-08-26 22:35:26 +00002047 {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00002048 Node* node = m_currentNode;
2049
2050 switch (node->arrayMode().type()) {
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00002051 case Array::ForceExit: {
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +00002052 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002053 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
fpizlo@apple.com04c19742012-08-26 22:35:26 +00002054 return;
2055 }
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00002056
fpizlo@apple.coma0ec0592012-10-22 23:52:15 +00002057 case Array::SelectUsingPredictions:
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00002058 case Array::Unprofiled:
oliver@apple.com5598c182013-01-23 22:25:07 +00002059 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.com04c19742012-08-26 22:35:26 +00002060 return;
2061
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00002062 case Array::Generic:
fpizlo@apple.com04c19742012-08-26 22:35:26 +00002063 return;
2064
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00002065 default: {
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002066 Node* storage = checkArray(node->arrayMode(), node->origin, base.node(), index.node());
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00002067 if (!storage)
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00002068 return;
2069
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002070 storageChild = Edge(storage);
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00002071 return;
2072 } }
fpizlo@apple.com04c19742012-08-26 22:35:26 +00002073 }
2074
fpizlo@apple.combbaf6192013-02-27 01:45:28 +00002075 bool alwaysUnboxSimplePrimitives()
2076 {
2077#if USE(JSVALUE64)
2078 return false;
2079#else
2080 // Any boolean, int, or cell value is profitable to unbox on 32-bit because it
2081 // reduces traffic.
2082 return true;
2083#endif
2084 }
fpizlo@apple.com46955912013-04-26 01:18:18 +00002085
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00002086 template<UseKind useKind>
2087 void observeUseKindOnNode(Node* node)
2088 {
fpizlo@apple.comaa1cc982013-09-12 05:46:49 +00002089 if (useKind == UntypedUse)
2090 return;
fpizlo@apple.com46955912013-04-26 01:18:18 +00002091 observeUseKindOnNode(node, useKind);
2092 }
2093
2094 void observeUseKindOnEdge(Edge edge)
2095 {
2096 observeUseKindOnNode(edge.node(), edge.useKind());
2097 }
2098
2099 void observeUseKindOnNode(Node* node, UseKind useKind)
2100 {
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00002101 if (node->op() != GetLocal)
2102 return;
2103
fpizlo@apple.com6921b292013-09-18 17:14:02 +00002104 // FIXME: The way this uses alwaysUnboxSimplePrimitives() is suspicious.
2105 // https://bugs.webkit.org/show_bug.cgi?id=121518
2106
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00002107 VariableAccessData* variable = node->variableAccessData();
2108 switch (useKind) {
2109 case Int32Use:
fpizlo@apple.com7289af32015-08-21 03:59:33 +00002110 case KnownInt32Use:
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00002111 if (alwaysUnboxSimplePrimitives()
2112 || isInt32Speculation(variable->prediction()))
2113 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
2114 break;
2115 case NumberUse:
fpizlo@apple.com318af072015-06-05 04:59:28 +00002116 case RealNumberUse:
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00002117 case DoubleRepUse:
2118 case DoubleRepRealUse:
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00002119 if (variable->doubleFormatState() == UsingDoubleFormat)
2120 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
2121 break;
2122 case BooleanUse:
fpizlo@apple.com7289af32015-08-21 03:59:33 +00002123 case KnownBooleanUse:
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00002124 if (alwaysUnboxSimplePrimitives()
2125 || isBooleanSpeculation(variable->prediction()))
2126 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
2127 break;
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00002128 case Int52RepUse:
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002129 if (isAnyIntSpeculation(variable->prediction()))
fpizlo@apple.com6921b292013-09-18 17:14:02 +00002130 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
2131 break;
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00002132 case CellUse:
oliver@apple.com176a3472013-07-25 04:00:19 +00002133 case KnownCellUse:
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00002134 case ObjectUse:
fpizlo@apple.coma398a562014-08-06 21:32:55 +00002135 case FunctionUse:
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00002136 case StringUse:
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00002137 case KnownStringUse:
utatane.tea@gmail.comfccd1362015-08-11 22:02:09 +00002138 case SymbolUse:
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00002139 case StringObjectUse:
2140 case StringOrStringObjectUse:
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00002141 if (alwaysUnboxSimplePrimitives()
2142 || isCellSpeculation(variable->prediction()))
2143 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
2144 break;
2145 default:
2146 break;
2147 }
2148 }
2149
fpizlo@apple.com35701872013-02-23 01:03:10 +00002150 template<UseKind useKind>
fpizlo@apple.comc6bb4a92013-09-30 20:38:46 +00002151 void fixEdge(Edge& edge)
fpizlo@apple.com35701872013-02-23 01:03:10 +00002152 {
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00002153 observeUseKindOnNode<useKind>(edge.node());
fpizlo@apple.com35701872013-02-23 01:03:10 +00002154 edge.setUseKind(useKind);
2155 }
2156
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00002157 void speculateForBarrier(Edge value)
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00002158 {
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00002159 // Currently, the DFG won't take advantage of this speculation. But, we want to do it in
2160 // the DFG anyway because if such a speculation would be wrong, we want to know before
2161 // we do an expensive compile.
2162
2163 if (value->shouldSpeculateInt32()) {
2164 insertCheck<Int32Use>(m_indexInBlock, value.node());
2165 return;
fpizlo@apple.com593cd922015-05-15 21:11:39 +00002166 }
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00002167
2168 if (value->shouldSpeculateBoolean()) {
2169 insertCheck<BooleanUse>(m_indexInBlock, value.node());
2170 return;
2171 }
2172
2173 if (value->shouldSpeculateOther()) {
2174 insertCheck<OtherUse>(m_indexInBlock, value.node());
2175 return;
2176 }
2177
2178 if (value->shouldSpeculateNumber()) {
2179 insertCheck<NumberUse>(m_indexInBlock, value.node());
2180 return;
2181 }
2182
2183 if (value->shouldSpeculateNotCell()) {
2184 insertCheck<NotCellUse>(m_indexInBlock, value.node());
2185 return;
2186 }
fpizlo@apple.com9ab60fa2014-09-26 22:53:20 +00002187 }
2188
2189 template<UseKind useKind>
2190 void insertCheck(unsigned indexInBlock, Node* node)
2191 {
2192 observeUseKindOnNode<useKind>(node);
fpizlo@apple.com3beeb7f2015-03-20 23:26:26 +00002193 m_insertionSet.insertNode(
fpizlo@apple.com9ab60fa2014-09-26 22:53:20 +00002194 indexInBlock, SpecNone, Check, m_currentNode->origin, Edge(node, useKind));
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00002195 }
2196
fpizlo@apple.com96509b72014-05-26 17:43:41 +00002197 void fixIntConvertingEdge(Edge& edge)
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00002198 {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00002199 Node* node = edge.node();
fpizlo@apple.com96509b72014-05-26 17:43:41 +00002200 if (node->shouldSpeculateInt32OrBoolean()) {
2201 fixIntOrBooleanEdge(edge);
msaboff@apple.com95894332014-01-29 19:18:54 +00002202 return;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002203 }
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00002204
fpizlo@apple.com027ed672014-01-08 00:27:06 +00002205 UseKind useKind;
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002206 if (node->shouldSpeculateAnyInt())
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00002207 useKind = Int52RepUse;
fpizlo@apple.com027ed672014-01-08 00:27:06 +00002208 else if (node->shouldSpeculateNumber())
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00002209 useKind = DoubleRepUse;
fpizlo@apple.com027ed672014-01-08 00:27:06 +00002210 else
2211 useKind = NotCellUse;
2212 Node* newNode = m_insertionSet.insertNode(
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002213 m_indexInBlock, SpecInt32Only, ValueToInt32, m_currentNode->origin,
fpizlo@apple.com027ed672014-01-08 00:27:06 +00002214 Edge(node, useKind));
2215 observeUseKindOnNode(node, useKind);
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00002216
fpizlo@apple.com027ed672014-01-08 00:27:06 +00002217 edge = Edge(newNode, KnownInt32Use);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002218 }
2219
fpizlo@apple.com96509b72014-05-26 17:43:41 +00002220 void fixIntOrBooleanEdge(Edge& edge)
2221 {
2222 Node* node = edge.node();
2223 if (!node->sawBooleans()) {
2224 fixEdge<Int32Use>(edge);
2225 return;
2226 }
2227
2228 UseKind useKind;
2229 if (node->shouldSpeculateBoolean())
2230 useKind = BooleanUse;
2231 else
2232 useKind = UntypedUse;
2233 Node* newNode = m_insertionSet.insertNode(
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002234 m_indexInBlock, SpecInt32Only, BooleanToNumber, m_currentNode->origin,
fpizlo@apple.com96509b72014-05-26 17:43:41 +00002235 Edge(node, useKind));
2236 observeUseKindOnNode(node, useKind);
2237
2238 edge = Edge(newNode, Int32Use);
fpizlo@apple.com96509b72014-05-26 17:43:41 +00002239 }
2240
2241 void fixDoubleOrBooleanEdge(Edge& edge)
2242 {
2243 Node* node = edge.node();
2244 if (!node->sawBooleans()) {
2245 fixEdge<DoubleRepUse>(edge);
2246 return;
2247 }
2248
2249 UseKind useKind;
2250 if (node->shouldSpeculateBoolean())
2251 useKind = BooleanUse;
2252 else
2253 useKind = UntypedUse;
2254 Node* newNode = m_insertionSet.insertNode(
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002255 m_indexInBlock, SpecInt32Only, BooleanToNumber, m_currentNode->origin,
fpizlo@apple.com96509b72014-05-26 17:43:41 +00002256 Edge(node, useKind));
2257 observeUseKindOnNode(node, useKind);
2258
2259 edge = Edge(newNode, DoubleRepUse);
fpizlo@apple.com96509b72014-05-26 17:43:41 +00002260 }
2261
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002262 void truncateConstantToInt32(Edge& edge)
2263 {
2264 Node* oldNode = edge.node();
2265
fpizlo@apple.comb41e6822014-07-25 20:55:17 +00002266 JSValue value = oldNode->asJSValue();
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002267 if (value.isInt32())
2268 return;
2269
2270 value = jsNumber(JSC::toInt32(value.asNumber()));
2271 ASSERT(value.isInt32());
2272 edge.setNode(m_insertionSet.insertNode(
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002273 m_indexInBlock, SpecInt32Only, JSConstant, m_currentNode->origin,
fpizlo@apple.comb41e6822014-07-25 20:55:17 +00002274 OpInfo(m_graph.freeze(value))));
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002275 }
2276
2277 void truncateConstantsIfNecessary(Node* node, AddSpeculationMode mode)
2278 {
fpizlo@apple.comefacb612013-09-10 22:16:00 +00002279 if (mode != SpeculateInt32AndTruncateConstants)
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002280 return;
2281
2282 ASSERT(node->child1()->hasConstant() || node->child2()->hasConstant());
2283 if (node->child1()->hasConstant())
2284 truncateConstantToInt32(node->child1());
2285 else
2286 truncateConstantToInt32(node->child2());
2287 }
2288
2289 bool attemptToMakeIntegerAdd(Node* node)
2290 {
fpizlo@apple.com96509b72014-05-26 17:43:41 +00002291 AddSpeculationMode mode = m_graph.addSpeculationMode(node, FixupPass);
fpizlo@apple.com6921b292013-09-18 17:14:02 +00002292 if (mode != DontSpeculateInt32) {
2293 truncateConstantsIfNecessary(node, mode);
fpizlo@apple.com96509b72014-05-26 17:43:41 +00002294 fixIntOrBooleanEdge(node->child1());
2295 fixIntOrBooleanEdge(node->child2());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +00002296 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
2297 node->setArithMode(Arith::Unchecked);
2298 else
2299 node->setArithMode(Arith::CheckOverflow);
fpizlo@apple.com6921b292013-09-18 17:14:02 +00002300 return true;
2301 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002302
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002303 if (m_graph.addShouldSpeculateAnyInt(node)) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00002304 fixEdge<Int52RepUse>(node->child1());
2305 fixEdge<Int52RepUse>(node->child2());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +00002306 node->setArithMode(Arith::CheckOverflow);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00002307 node->setResult(NodeResultInt52);
fpizlo@apple.com6921b292013-09-18 17:14:02 +00002308 return true;
2309 }
2310
2311 return false;
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +00002312 }
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002313
2314 bool attemptToMakeGetArrayLength(Node* node)
2315 {
2316 if (!isInt32Speculation(node->prediction()))
2317 return false;
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002318 CodeBlock* profiledBlock = m_graph.baselineCodeBlockFor(node->origin.semantic);
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002319 ArrayProfile* arrayProfile =
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002320 profiledBlock->getArrayProfile(node->origin.semantic.bytecodeIndex);
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002321 ArrayMode arrayMode = ArrayMode(Array::SelectUsingPredictions);
2322 if (arrayProfile) {
2323 ConcurrentJITLocker locker(profiledBlock->m_lock);
2324 arrayProfile->computeUpdatedPrediction(locker, profiledBlock);
2325 arrayMode = ArrayMode::fromObserved(locker, arrayProfile, Array::Read, false);
2326 if (arrayMode.type() == Array::Unprofiled) {
2327 // For normal array operations, it makes sense to treat Unprofiled
2328 // accesses as ForceExit and get more data rather than using
2329 // predictions and then possibly ending up with a Generic. But here,
2330 // we treat anything that is Unprofiled as Generic and keep the
2331 // GetById. I.e. ForceExit = Generic. So, there is no harm - and only
2332 // profit - from treating the Unprofiled case as
2333 // SelectUsingPredictions.
2334 arrayMode = ArrayMode(Array::SelectUsingPredictions);
2335 }
2336 }
2337
msaboff@apple.com95894332014-01-29 19:18:54 +00002338 arrayMode = arrayMode.refine(
fpizlo@apple.come079bb52014-03-05 07:41:03 +00002339 m_graph, node, node->child1()->prediction(), node->prediction());
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002340
2341 if (arrayMode.type() == Array::Generic) {
2342 // Check if the input is something that we can't get array length for, but for which we
2343 // could insert some conversions in order to transform it into something that we can do it
2344 // for.
2345 if (node->child1()->shouldSpeculateStringObject())
2346 attemptToForceStringArrayModeByToStringConversion<StringObjectUse>(arrayMode, node);
2347 else if (node->child1()->shouldSpeculateStringOrStringObject())
2348 attemptToForceStringArrayModeByToStringConversion<StringOrStringObjectUse>(arrayMode, node);
2349 }
2350
keith_miller@apple.com032f6722016-04-08 00:10:20 +00002351 if (!arrayMode.supportsSelfLength())
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002352 return false;
2353
2354 convertToGetArrayLength(node, arrayMode);
2355 return true;
2356 }
keith_miller@apple.com59bba5d2015-10-16 22:18:42 +00002357
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002358 void convertToGetArrayLength(Node* node, ArrayMode arrayMode)
2359 {
2360 node->setOp(GetArrayLength);
fpizlo@apple.comcad67682015-02-09 19:57:41 +00002361 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00002362 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002363 node->setArrayMode(arrayMode);
2364
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002365 Node* storage = checkArray(arrayMode, node->origin, node->child1().node(), 0, lengthNeedsStorage);
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002366 if (!storage)
2367 return;
2368
2369 node->child2() = Edge(storage);
2370 }
2371
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002372 Node* prependGetArrayLength(NodeOrigin origin, Node* child, ArrayMode arrayMode)
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002373 {
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002374 Node* storage = checkArray(arrayMode, origin, child, 0, lengthNeedsStorage);
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002375 return m_insertionSet.insertNode(
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002376 m_indexInBlock, SpecInt32Only, GetArrayLength, origin,
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002377 OpInfo(arrayMode.asWord()), Edge(child, KnownCellUse), Edge(storage));
2378 }
fpizlo@apple.com537a4772013-08-19 23:16:01 +00002379
fpizlo@apple.com10107332015-08-24 21:44:39 +00002380 void fixupChecksInBlock(BasicBlock* block)
fpizlo@apple.comd4a77bb2014-04-12 18:22:27 +00002381 {
2382 if (!block)
2383 return;
2384 ASSERT(block->isReachable);
2385 m_block = block;
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002386 unsigned indexForChecks = UINT_MAX;
2387 NodeOrigin originForChecks;
2388 for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
2389 Node* node = block->at(indexInBlock);
2390
2391 // If this is a node at which we could exit, then save its index. If nodes after this one
2392 // cannot exit, then we will hoist checks to here.
2393 if (node->origin.exitOK) {
2394 indexForChecks = indexInBlock;
2395 originForChecks = node->origin;
2396 }
2397
2398 originForChecks = originForChecks.withSemantic(node->origin.semantic);
fpizlo@apple.com10107332015-08-24 21:44:39 +00002399
2400 // First, try to relax the representational demands of each node, in order to have
2401 // fewer conversions.
2402 switch (node->op()) {
2403 case MovHint:
2404 case Check:
2405 m_graph.doToChildren(
2406 node,
2407 [&] (Edge& edge) {
2408 switch (edge.useKind()) {
2409 case DoubleRepUse:
2410 case DoubleRepRealUse:
2411 if (edge->hasDoubleResult())
2412 break;
2413
2414 if (edge->hasInt52Result())
2415 edge.setUseKind(Int52RepUse);
2416 else if (edge.useKind() == DoubleRepUse)
2417 edge.setUseKind(NumberUse);
2418 break;
2419
2420 case Int52RepUse:
2421 // Nothing we can really do.
2422 break;
2423
2424 case UntypedUse:
2425 case NumberUse:
2426 if (edge->hasDoubleResult())
2427 edge.setUseKind(DoubleRepUse);
2428 else if (edge->hasInt52Result())
2429 edge.setUseKind(Int52RepUse);
2430 break;
2431
2432 case RealNumberUse:
2433 if (edge->hasDoubleResult())
2434 edge.setUseKind(DoubleRepRealUse);
2435 else if (edge->hasInt52Result())
2436 edge.setUseKind(Int52RepUse);
2437 break;
2438
2439 default:
2440 break;
2441 }
2442 });
2443 break;
2444
2445 case ValueToInt32:
2446 if (node->child1().useKind() == DoubleRepUse
2447 && !node->child1()->hasDoubleResult()) {
2448 node->child1().setUseKind(NumberUse);
2449 break;
2450 }
2451 break;
2452
2453 default:
2454 break;
2455 }
2456
2457 // Now, insert type conversions if necessary.
2458 m_graph.doToChildren(
2459 node,
2460 [&] (Edge& edge) {
2461 Node* result = nullptr;
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002462
fpizlo@apple.com10107332015-08-24 21:44:39 +00002463 switch (edge.useKind()) {
2464 case DoubleRepUse:
2465 case DoubleRepRealUse:
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002466 case DoubleRepAnyIntUse: {
fpizlo@apple.com10107332015-08-24 21:44:39 +00002467 if (edge->hasDoubleResult())
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002468 break;
fpizlo@apple.com10107332015-08-24 21:44:39 +00002469
2470 if (edge->isNumberConstant()) {
2471 result = m_insertionSet.insertNode(
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002472 indexForChecks, SpecBytecodeDouble, DoubleConstant, originForChecks,
fpizlo@apple.com10107332015-08-24 21:44:39 +00002473 OpInfo(m_graph.freeze(jsDoubleNumber(edge->asNumber()))));
2474 } else if (edge->hasInt52Result()) {
2475 result = m_insertionSet.insertNode(
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002476 indexForChecks, SpecAnyIntAsDouble, DoubleRep, originForChecks,
fpizlo@apple.com10107332015-08-24 21:44:39 +00002477 Edge(edge.node(), Int52RepUse));
2478 } else {
2479 UseKind useKind;
2480 if (edge->shouldSpeculateDoubleReal())
2481 useKind = RealNumberUse;
2482 else if (edge->shouldSpeculateNumber())
2483 useKind = NumberUse;
2484 else
2485 useKind = NotCellUse;
2486
2487 result = m_insertionSet.insertNode(
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002488 indexForChecks, SpecBytecodeDouble, DoubleRep, originForChecks,
fpizlo@apple.com10107332015-08-24 21:44:39 +00002489 Edge(edge.node(), useKind));
2490 }
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002491
2492 edge.setNode(result);
fpizlo@apple.com10107332015-08-24 21:44:39 +00002493 break;
2494 }
2495
2496 case Int52RepUse: {
2497 if (edge->hasInt52Result())
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002498 break;
fpizlo@apple.com10107332015-08-24 21:44:39 +00002499
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002500 if (edge->isAnyIntConstant()) {
fpizlo@apple.com10107332015-08-24 21:44:39 +00002501 result = m_insertionSet.insertNode(
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002502 indexForChecks, SpecAnyInt, Int52Constant, originForChecks,
fpizlo@apple.com10107332015-08-24 21:44:39 +00002503 OpInfo(edge->constant()));
2504 } else if (edge->hasDoubleResult()) {
2505 result = m_insertionSet.insertNode(
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002506 indexForChecks, SpecAnyInt, Int52Rep, originForChecks,
2507 Edge(edge.node(), DoubleRepAnyIntUse));
fpizlo@apple.com10107332015-08-24 21:44:39 +00002508 } else if (edge->shouldSpeculateInt32ForArithmetic()) {
2509 result = m_insertionSet.insertNode(
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002510 indexForChecks, SpecInt32Only, Int52Rep, originForChecks,
fpizlo@apple.com10107332015-08-24 21:44:39 +00002511 Edge(edge.node(), Int32Use));
2512 } else {
2513 result = m_insertionSet.insertNode(
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002514 indexForChecks, SpecAnyInt, Int52Rep, originForChecks,
2515 Edge(edge.node(), AnyIntUse));
fpizlo@apple.com10107332015-08-24 21:44:39 +00002516 }
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002517
2518 edge.setNode(result);
fpizlo@apple.com10107332015-08-24 21:44:39 +00002519 break;
2520 }
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002521
fpizlo@apple.com10107332015-08-24 21:44:39 +00002522 default: {
2523 if (!edge->hasDoubleResult() && !edge->hasInt52Result())
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002524 break;
fpizlo@apple.com10107332015-08-24 21:44:39 +00002525
2526 if (edge->hasDoubleResult()) {
2527 result = m_insertionSet.insertNode(
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002528 indexForChecks, SpecBytecodeDouble, ValueRep, originForChecks,
fpizlo@apple.com10107332015-08-24 21:44:39 +00002529 Edge(edge.node(), DoubleRepUse));
2530 } else {
2531 result = m_insertionSet.insertNode(
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002532 indexForChecks, SpecInt32Only | SpecAnyIntAsDouble, ValueRep,
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002533 originForChecks, Edge(edge.node(), Int52RepUse));
fpizlo@apple.com10107332015-08-24 21:44:39 +00002534 }
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002535
2536 edge.setNode(result);
fpizlo@apple.com10107332015-08-24 21:44:39 +00002537 break;
2538 } }
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002539
2540 // It's remotely possible that this node cannot do type checks, but we now have a
2541 // type check on this node. We don't have to handle the general form of this
2542 // problem. It only arises when ByteCodeParser emits an immediate SetLocal, rather
2543 // than a delayed one. So, we only worry about those checks that we may have put on
2544 // a SetLocal. Note that "indexForChecks != indexInBlock" is just another way of
2545 // saying "!node->origin.exitOK".
2546 if (indexForChecks != indexInBlock && mayHaveTypeCheck(edge.useKind())) {
2547 UseKind knownUseKind;
2548
2549 switch (edge.useKind()) {
2550 case Int32Use:
2551 knownUseKind = KnownInt32Use;
2552 break;
2553 case CellUse:
2554 knownUseKind = KnownCellUse;
2555 break;
2556 case BooleanUse:
2557 knownUseKind = KnownBooleanUse;
2558 break;
2559 default:
2560 // This can only arise if we have a Check node, and in that case, we can
2561 // just remove the original check.
2562 DFG_ASSERT(m_graph, node, node->op() == Check);
2563 knownUseKind = UntypedUse;
2564 break;
2565 }
2566
2567 m_insertionSet.insertNode(
2568 indexForChecks, SpecNone, Check, originForChecks, edge);
2569
2570 edge.setUseKind(knownUseKind);
2571 }
fpizlo@apple.com10107332015-08-24 21:44:39 +00002572 });
fpizlo@apple.comd4a77bb2014-04-12 18:22:27 +00002573 }
fpizlo@apple.com10107332015-08-24 21:44:39 +00002574
fpizlo@apple.comd4a77bb2014-04-12 18:22:27 +00002575 m_insertionSet.execute(block);
2576 }
2577
fpizlo@apple.comf10d0722012-12-03 09:21:22 +00002578 BasicBlock* m_block;
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +00002579 unsigned m_indexInBlock;
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00002580 Node* m_currentNode;
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +00002581 InsertionSet m_insertionSet;
fpizlo@apple.combbaf6192013-02-27 01:45:28 +00002582 bool m_profitabilityChanged;
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00002583};
2584
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +00002585bool performFixup(Graph& graph)
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00002586{
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +00002587 return runPhase<FixupPhase>(graph);
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00002588}
2589
2590} } // namespace JSC::DFG
2591
2592#endif // ENABLE(DFG_JIT)
2593