blob: 89e583dbcd92ed9964886cb23352d323fe8f0c50 [file] [log] [blame]
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00001/*
mark.lam@apple.com03916fe2017-02-28 01:20:54 +00002 * Copyright (C) 2012-2017 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: {
commit-queue@webkit.org95f28be2016-09-06 21:54:11 +0000129 if (node->child1()->shouldSpeculateNotCell()) {
130 fixIntConvertingEdge(node->child1());
131 node->clearFlags(NodeMustGenerate);
132 } else
133 fixEdge<UntypedUse>(node->child1());
benjamin@webkit.orge324d432015-04-26 19:55:18 +0000134 break;
135 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000136
137 case UInt32ToNumber: {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000138 fixIntConvertingEdge(node->child1());
fpizlo@apple.com9089acb2013-12-14 06:33:42 +0000139 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
140 node->convertToIdentity();
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000141 else if (node->canSpeculateInt32(FixupPass))
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000142 node->setArithMode(Arith::CheckOverflow);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000143 else {
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000144 node->setArithMode(Arith::DoOverflow);
commit-queue@webkit.orgb6d27652016-04-07 04:33:32 +0000145 node->clearFlags(NodeMustGenerate);
commit-queue@webkit.orge086f372016-04-08 18:07:25 +0000146 node->setResult(enableInt52() ? NodeResultInt52 : NodeResultDouble);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000147 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000148 break;
149 }
150
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000151 case ValueAdd: {
fpizlo@apple.com97756552014-01-02 20:15:25 +0000152 if (attemptToMakeIntegerAdd(node)) {
153 node->setOp(ArithAdd);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000154 break;
fpizlo@apple.com97756552014-01-02 20:15:25 +0000155 }
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000156 if (Node::shouldSpeculateNumberOrBooleanExpectingDefined(node->child1().node(), node->child2().node())) {
157 fixDoubleOrBooleanEdge(node->child1());
158 fixDoubleOrBooleanEdge(node->child2());
fpizlo@apple.com97756552014-01-02 20:15:25 +0000159 node->setOp(ArithAdd);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000160 node->setResult(NodeResultDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000161 break;
162 }
fpizlo@apple.com8d225912013-03-19 00:44:57 +0000163
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +0000164 if (attemptToMakeFastStringAdd(node))
fpizlo@apple.com8d225912013-03-19 00:44:57 +0000165 break;
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +0000166
utatane.tea@gmail.com2dd82cf2017-04-18 18:06:37 +0000167 Edge& child1 = node->child1();
168 Edge& child2 = node->child2();
169 if (child1->shouldSpeculateString() || child2->shouldSpeculateString()) {
170 if (child1->shouldSpeculateInt32() || child2->shouldSpeculateInt32()) {
171 auto convertString = [&](Node* node, Edge& edge) {
172 if (edge->shouldSpeculateInt32())
173 convertStringAddUse<Int32Use>(node, edge);
174 else {
175 ASSERT(edge->shouldSpeculateString());
176 convertStringAddUse<StringUse>(node, edge);
177 }
178 };
179 convertString(node, child1);
180 convertString(node, child2);
181 convertToMakeRope(node);
182 break;
183 }
184 }
185
186 fixEdge<UntypedUse>(child1);
187 fixEdge<UntypedUse>(child2);
mark.lam@apple.com102cbf22015-11-17 21:55:33 +0000188 node->setResult(NodeResultJS);
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +0000189 break;
190 }
191
192 case StrCat: {
fpizlo@apple.com2b150e782015-08-27 23:59:57 +0000193 if (attemptToMakeFastStringAdd(node))
194 break;
195
196 // FIXME: Remove empty string arguments and possibly turn this into a ToString operation. That
197 // would require a form of ToString that takes a KnownPrimitiveUse. This is necessary because
198 // the implementation of StrCat doesn't dynamically optimize for empty strings.
199 // https://bugs.webkit.org/show_bug.cgi?id=148540
200 m_graph.doToChildren(
201 node,
202 [&] (Edge& edge) {
203 fixEdge<KnownPrimitiveUse>(edge);
204 });
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000205 break;
206 }
207
fpizlo@apple.com4463e442013-03-20 20:29:37 +0000208 case MakeRope: {
209 fixupMakeRope(node);
210 break;
211 }
212
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000213 case ArithAdd:
214 case ArithSub: {
mark.lam@apple.com75249092015-10-16 23:26:14 +0000215 if (op == ArithSub
fpizlo@apple.comacdb63e2016-05-10 02:01:28 +0000216 && Node::shouldSpeculateUntypedForArithmetic(node->child1().node(), node->child2().node())) {
mark.lam@apple.com75249092015-10-16 23:26:14 +0000217 fixEdge<UntypedUse>(node->child1());
218 fixEdge<UntypedUse>(node->child2());
219 node->setResult(NodeResultJS);
220 break;
221 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000222 if (attemptToMakeIntegerAdd(node))
223 break;
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000224 fixDoubleOrBooleanEdge(node->child1());
225 fixDoubleOrBooleanEdge(node->child2());
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000226 node->setResult(NodeResultDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000227 break;
228 }
229
230 case ArithNegate: {
commit-queue@webkit.orgf59f0ed2016-10-15 02:19:16 +0000231 if (node->child1()->shouldSpeculateInt32OrBoolean() && node->canSpeculateInt32(FixupPass)) {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000232 fixIntOrBooleanEdge(node->child1());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000233 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
234 node->setArithMode(Arith::Unchecked);
235 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
236 node->setArithMode(Arith::CheckOverflow);
237 else
238 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
commit-queue@webkit.orgf59f0ed2016-10-15 02:19:16 +0000239 node->setResult(NodeResultInt32);
240 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000241 break;
242 }
mark.lam@apple.com39e9c982016-04-25 17:48:46 +0000243 if (m_graph.unaryArithShouldSpeculateAnyInt(node, FixupPass)) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000244 fixEdge<Int52RepUse>(node->child1());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000245 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
246 node->setArithMode(Arith::CheckOverflow);
247 else
248 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000249 node->setResult(NodeResultInt52);
commit-queue@webkit.orgf59f0ed2016-10-15 02:19:16 +0000250 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000251 break;
252 }
commit-queue@webkit.orgf59f0ed2016-10-15 02:19:16 +0000253 if (node->child1()->shouldSpeculateNotCell()) {
254 fixDoubleOrBooleanEdge(node->child1());
255 node->setResult(NodeResultDouble);
256 node->clearFlags(NodeMustGenerate);
257 } else
258 fixEdge<UntypedUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000259 break;
260 }
261
262 case ArithMul: {
mark.lam@apple.com1d936142015-12-03 05:42:56 +0000263 Edge& leftChild = node->child1();
264 Edge& rightChild = node->child2();
fpizlo@apple.comacdb63e2016-05-10 02:01:28 +0000265 if (Node::shouldSpeculateUntypedForArithmetic(leftChild.node(), rightChild.node())) {
mark.lam@apple.com1d936142015-12-03 05:42:56 +0000266 fixEdge<UntypedUse>(leftChild);
267 fixEdge<UntypedUse>(rightChild);
268 node->setResult(NodeResultJS);
269 break;
270 }
mark.lam@apple.comfb6b2162016-01-13 22:21:40 +0000271 if (m_graph.binaryArithShouldSpeculateInt32(node, FixupPass)) {
mark.lam@apple.com1d936142015-12-03 05:42:56 +0000272 fixIntOrBooleanEdge(leftChild);
273 fixIntOrBooleanEdge(rightChild);
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000274 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
275 node->setArithMode(Arith::Unchecked);
commit-queue@webkit.orgee8d7db2016-04-22 19:27:57 +0000276 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())
277 || leftChild.node() == rightChild.node())
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000278 node->setArithMode(Arith::CheckOverflow);
279 else
280 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000281 break;
282 }
mark.lam@apple.com39e9c982016-04-25 17:48:46 +0000283 if (m_graph.binaryArithShouldSpeculateAnyInt(node, FixupPass)) {
mark.lam@apple.com1d936142015-12-03 05:42:56 +0000284 fixEdge<Int52RepUse>(leftChild);
285 fixEdge<Int52RepUse>(rightChild);
commit-queue@webkit.orgee8d7db2016-04-22 19:27:57 +0000286 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())
287 || leftChild.node() == rightChild.node())
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000288 node->setArithMode(Arith::CheckOverflow);
289 else
290 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000291 node->setResult(NodeResultInt52);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000292 break;
293 }
mark.lam@apple.com1d936142015-12-03 05:42:56 +0000294 fixDoubleOrBooleanEdge(leftChild);
295 fixDoubleOrBooleanEdge(rightChild);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000296 node->setResult(NodeResultDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000297 break;
298 }
299
oliver@apple.comf4443a72013-07-25 04:01:11 +0000300 case ArithDiv:
301 case ArithMod: {
mark.lam@apple.com224ce4d2015-12-08 21:44:12 +0000302 Edge& leftChild = node->child1();
303 Edge& rightChild = node->child2();
304 if (op == ArithDiv
mark.lam@apple.com46e290b2015-12-14 19:39:45 +0000305 && Node::shouldSpeculateUntypedForArithmetic(leftChild.node(), rightChild.node())
306 && m_graph.hasExitSite(node->origin.semantic, BadType)) {
mark.lam@apple.com224ce4d2015-12-08 21:44:12 +0000307 fixEdge<UntypedUse>(leftChild);
308 fixEdge<UntypedUse>(rightChild);
309 node->setResult(NodeResultJS);
310 break;
311 }
mark.lam@apple.comfb6b2162016-01-13 22:21:40 +0000312 if (m_graph.binaryArithShouldSpeculateInt32(node, FixupPass)) {
ossy@webkit.orgd3a3de92015-03-16 18:44:46 +0000313 if (optimizeForX86() || optimizeForARM64() || optimizeForARMv7IDIVSupported()) {
mark.lam@apple.com224ce4d2015-12-08 21:44:12 +0000314 fixIntOrBooleanEdge(leftChild);
315 fixIntOrBooleanEdge(rightChild);
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000316 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
317 node->setArithMode(Arith::Unchecked);
318 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
319 node->setArithMode(Arith::CheckOverflow);
320 else
321 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000322 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000323 }
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000324
325 // This will cause conversion nodes to be inserted later.
mark.lam@apple.com224ce4d2015-12-08 21:44:12 +0000326 fixDoubleOrBooleanEdge(leftChild);
327 fixDoubleOrBooleanEdge(rightChild);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000328
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000329 // We don't need to do ref'ing on the children because we're stealing them from
330 // the original division.
331 Node* newDivision = m_insertionSet.insertNode(
fpizlo@apple.com85bde1f2014-04-17 04:57:29 +0000332 m_indexInBlock, SpecBytecodeDouble, *node);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000333 newDivision->setResult(NodeResultDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000334
335 node->setOp(DoubleAsInt32);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000336 node->children.initialize(Edge(newDivision, DoubleRepUse), Edge(), Edge());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000337 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
338 node->setArithMode(Arith::CheckOverflow);
339 else
340 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000341 break;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000342 }
mark.lam@apple.com224ce4d2015-12-08 21:44:12 +0000343 fixDoubleOrBooleanEdge(leftChild);
344 fixDoubleOrBooleanEdge(rightChild);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000345 node->setResult(NodeResultDouble);
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000346 break;
347 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000348
349 case ArithMin:
oliver@apple.comf4443a72013-07-25 04:01:11 +0000350 case ArithMax: {
mark.lam@apple.comfb6b2162016-01-13 22:21:40 +0000351 if (m_graph.binaryArithShouldSpeculateInt32(node, FixupPass)) {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000352 fixIntOrBooleanEdge(node->child1());
353 fixIntOrBooleanEdge(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000354 break;
355 }
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000356 fixDoubleOrBooleanEdge(node->child1());
357 fixDoubleOrBooleanEdge(node->child2());
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000358 node->setResult(NodeResultDouble);
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000359 break;
360 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000361
362 case ArithAbs: {
commit-queue@webkit.org0ec71072016-08-29 07:21:04 +0000363 if (node->child1()->shouldSpeculateInt32OrBoolean()
364 && node->canSpeculateInt32(FixupPass)) {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000365 fixIntOrBooleanEdge(node->child1());
commit-queue@webkit.orgf4256ed2016-02-17 23:35:11 +0000366 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
367 node->setArithMode(Arith::Unchecked);
368 else
369 node->setArithMode(Arith::CheckOverflow);
commit-queue@webkit.org0ec71072016-08-29 07:21:04 +0000370 node->clearFlags(NodeMustGenerate);
371 node->setResult(NodeResultInt32);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000372 break;
373 }
commit-queue@webkit.org0ec71072016-08-29 07:21:04 +0000374
commit-queue@webkit.org62da93d2016-08-31 01:48:22 +0000375 if (node->child1()->shouldSpeculateNotCell()) {
commit-queue@webkit.org0ec71072016-08-29 07:21:04 +0000376 fixDoubleOrBooleanEdge(node->child1());
377 node->clearFlags(NodeMustGenerate);
378 } else
379 fixEdge<UntypedUse>(node->child1());
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000380 node->setResult(NodeResultDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000381 break;
382 }
benjamin@webkit.org903025b2015-02-14 04:20:21 +0000383
384 case ArithPow: {
benjamin@webkit.org903025b2015-02-14 04:20:21 +0000385 if (node->child2()->shouldSpeculateInt32OrBooleanForArithmetic()) {
386 fixDoubleOrBooleanEdge(node->child1());
387 fixIntOrBooleanEdge(node->child2());
388 break;
389 }
390
391 fixDoubleOrBooleanEdge(node->child1());
392 fixDoubleOrBooleanEdge(node->child2());
393 break;
394 }
benjamin@webkit.orgcb584082015-05-08 00:23:32 +0000395
utatane.tea@gmail.comd2fca0a2015-12-15 03:51:42 +0000396 case ArithRandom: {
397 node->setResult(NodeResultDouble);
398 break;
399 }
400
utatane.tea@gmail.com9971c632016-03-01 02:30:46 +0000401 case ArithRound:
402 case ArithFloor:
utatane.tea@gmail.com9b9f43e2016-04-03 08:37:26 +0000403 case ArithCeil:
404 case ArithTrunc: {
commit-queue@webkit.org2e9df642016-09-20 00:48:39 +0000405 if (node->child1()->shouldSpeculateInt32OrBoolean() && m_graph.roundShouldSpeculateInt32(node, FixupPass)) {
benjamin@webkit.orgcb584082015-05-08 00:23:32 +0000406 fixIntOrBooleanEdge(node->child1());
fpizlo@apple.com0ef43952016-12-08 22:14:50 +0000407 insertCheck<Int32Use>(node->child1().node());
benjamin@webkit.orgcb584082015-05-08 00:23:32 +0000408 node->convertToIdentity();
409 break;
410 }
commit-queue@webkit.org2e9df642016-09-20 00:48:39 +0000411 if (node->child1()->shouldSpeculateNotCell()) {
412 fixDoubleOrBooleanEdge(node->child1());
benjamin@webkit.orgcb584082015-05-08 00:23:32 +0000413
commit-queue@webkit.org2e9df642016-09-20 00:48:39 +0000414 if (isInt32OrBooleanSpeculation(node->getHeapPrediction()) && m_graph.roundShouldSpeculateInt32(node, FixupPass)) {
415 node->setResult(NodeResultInt32);
416 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
417 node->setArithRoundingMode(Arith::RoundingMode::Int32);
418 else
419 node->setArithRoundingMode(Arith::RoundingMode::Int32WithNegativeZeroCheck);
420 } else {
421 node->setResult(NodeResultDouble);
422 node->setArithRoundingMode(Arith::RoundingMode::Double);
423 }
424 node->clearFlags(NodeMustGenerate);
425 } else
426 fixEdge<UntypedUse>(node->child1());
benjamin@webkit.orgcb584082015-05-08 00:23:32 +0000427 break;
428 }
commit-queue@webkit.orgee8d5482016-08-23 19:09:50 +0000429
benjamin@webkit.org87238e92016-08-25 01:21:43 +0000430 case ArithFRound:
utatane.tea@gmail.com9917d6a2016-09-12 22:01:13 +0000431 case ArithSqrt:
utatane.tea@gmail.comccb74992017-05-04 11:40:46 +0000432 case ArithUnary: {
commit-queue@webkit.org91b902c2016-08-20 02:00:44 +0000433 Edge& child1 = node->child1();
commit-queue@webkit.org62da93d2016-08-31 01:48:22 +0000434 if (child1->shouldSpeculateNotCell()) {
commit-queue@webkit.org91b902c2016-08-20 02:00:44 +0000435 fixDoubleOrBooleanEdge(child1);
commit-queue@webkit.org0ec71072016-08-29 07:21:04 +0000436 node->clearFlags(NodeMustGenerate);
437 } else
commit-queue@webkit.org91b902c2016-08-20 02:00:44 +0000438 fixEdge<UntypedUse>(child1);
439 break;
440 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000441
442 case LogicalNot: {
fpizlo@apple.com7289af32015-08-21 03:59:33 +0000443 if (node->child1()->shouldSpeculateBoolean()) {
444 if (node->child1()->result() == NodeResultBoolean) {
445 // This is necessary in case we have a bytecode instruction implemented by:
446 //
447 // a: CompareEq(...)
448 // b: LogicalNot(@a)
449 //
450 // In that case, CompareEq might have a side-effect. Then, we need to make
451 // sure that we know that Branch does not exit.
452 fixEdge<KnownBooleanUse>(node->child1());
453 } else
454 fixEdge<BooleanUse>(node->child1());
455 } else if (node->child1()->shouldSpeculateObjectOrOther())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000456 fixEdge<ObjectOrOtherUse>(node->child1());
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000457 else if (node->child1()->shouldSpeculateInt32OrBoolean())
458 fixIntOrBooleanEdge(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000459 else if (node->child1()->shouldSpeculateNumber())
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000460 fixEdge<DoubleRepUse>(node->child1());
commit-queue@webkit.org008e8dc2013-10-12 02:21:45 +0000461 else if (node->child1()->shouldSpeculateString())
462 fixEdge<StringUse>(node->child1());
fpizlo@apple.com91331742016-03-07 02:07:28 +0000463 else if (node->child1()->shouldSpeculateStringOrOther())
464 fixEdge<StringOrOtherUse>(node->child1());
sbarati@apple.com1c12d212016-09-08 23:19:38 +0000465 else {
466 WatchpointSet* masqueradesAsUndefinedWatchpoint = m_graph.globalObjectFor(node->origin.semantic)->masqueradesAsUndefinedWatchpoint();
467 if (masqueradesAsUndefinedWatchpoint->isStillValid())
468 m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
469 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000470 break;
471 }
fpizlo@apple.comee10e452013-04-09 00:10:16 +0000472
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000473 case CompareEq:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000474 case CompareLess:
475 case CompareLessEq:
476 case CompareGreater:
477 case CompareGreaterEq: {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000478 if (node->op() == CompareEq
479 && Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
480 fixEdge<BooleanUse>(node->child1());
481 fixEdge<BooleanUse>(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000482 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000483 break;
484 }
485 if (Node::shouldSpeculateInt32OrBoolean(node->child1().node(), node->child2().node())) {
486 fixIntOrBooleanEdge(node->child1());
487 fixIntOrBooleanEdge(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000488 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000489 break;
490 }
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000491 if (enableInt52()
mark.lam@apple.com39e9c982016-04-25 17:48:46 +0000492 && Node::shouldSpeculateAnyInt(node->child1().node(), node->child2().node())) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000493 fixEdge<Int52RepUse>(node->child1());
494 fixEdge<Int52RepUse>(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000495 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000496 break;
497 }
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000498 if (Node::shouldSpeculateNumberOrBoolean(node->child1().node(), node->child2().node())) {
499 fixDoubleOrBooleanEdge(node->child1());
500 fixDoubleOrBooleanEdge(node->child2());
commit-queue@webkit.orgfab33f42016-04-17 04:55:02 +0000501 }
502 if (node->op() != CompareEq
503 && node->child1()->shouldSpeculateNotCell()
504 && node->child2()->shouldSpeculateNotCell()) {
505 if (node->child1()->shouldSpeculateNumberOrBoolean())
506 fixDoubleOrBooleanEdge(node->child1());
507 else
508 fixEdge<DoubleRepUse>(node->child1());
509 if (node->child2()->shouldSpeculateNumberOrBoolean())
510 fixDoubleOrBooleanEdge(node->child2());
511 else
512 fixEdge<DoubleRepUse>(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000513 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000514 break;
515 }
oliver@apple.combd15be82013-07-25 04:03:42 +0000516 if (node->child1()->shouldSpeculateStringIdent() && node->child2()->shouldSpeculateStringIdent()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000517 fixEdge<StringIdentUse>(node->child1());
518 fixEdge<StringIdentUse>(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000519 node->clearFlags(NodeMustGenerate);
oliver@apple.combd15be82013-07-25 04:03:42 +0000520 break;
521 }
fpizlo@apple.comee10e452013-04-09 00:10:16 +0000522 if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && GPRInfo::numberOfRegisters >= 7) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000523 fixEdge<StringUse>(node->child1());
524 fixEdge<StringUse>(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000525 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000526 break;
fpizlo@apple.comee10e452013-04-09 00:10:16 +0000527 }
commit-queue@webkit.org36c52882016-04-22 05:08:28 +0000528
529 if (node->op() != CompareEq)
530 break;
531 if (Node::shouldSpeculateSymbol(node->child1().node(), node->child2().node())) {
532 fixEdge<SymbolUse>(node->child1());
533 fixEdge<SymbolUse>(node->child2());
534 node->clearFlags(NodeMustGenerate);
535 break;
536 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000537 if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000538 fixEdge<ObjectUse>(node->child1());
539 fixEdge<ObjectUse>(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000540 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000541 break;
542 }
benjamin@webkit.org32b8d0a2015-08-19 04:09:12 +0000543
544 // If either child can be proved to be Null or Undefined, comparing them is greatly simplified.
545 bool oneArgumentIsUsedAsSpecOther = false;
546 if (node->child1()->isUndefinedOrNullConstant()) {
547 fixEdge<OtherUse>(node->child1());
548 oneArgumentIsUsedAsSpecOther = true;
549 } else if (node->child1()->shouldSpeculateOther()) {
550 m_insertionSet.insertNode(m_indexInBlock, SpecNone, Check, node->origin,
551 Edge(node->child1().node(), OtherUse));
552 fixEdge<OtherUse>(node->child1());
553 oneArgumentIsUsedAsSpecOther = true;
554 }
555 if (node->child2()->isUndefinedOrNullConstant()) {
556 fixEdge<OtherUse>(node->child2());
557 oneArgumentIsUsedAsSpecOther = true;
558 } else if (node->child2()->shouldSpeculateOther()) {
559 m_insertionSet.insertNode(m_indexInBlock, SpecNone, Check, node->origin,
560 Edge(node->child2().node(), OtherUse));
561 fixEdge<OtherUse>(node->child2());
562 oneArgumentIsUsedAsSpecOther = true;
563 }
564 if (oneArgumentIsUsedAsSpecOther) {
565 node->clearFlags(NodeMustGenerate);
566 break;
567 }
568
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000569 if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObjectOrOther()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000570 fixEdge<ObjectUse>(node->child1());
571 fixEdge<ObjectOrOtherUse>(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000572 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000573 break;
574 }
575 if (node->child1()->shouldSpeculateObjectOrOther() && node->child2()->shouldSpeculateObject()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000576 fixEdge<ObjectOrOtherUse>(node->child1());
577 fixEdge<ObjectUse>(node->child2());
fpizlo@apple.comcad67682015-02-09 19:57:41 +0000578 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000579 break;
580 }
benjamin@webkit.org32b8d0a2015-08-19 04:09:12 +0000581
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000582 break;
583 }
584
fpizlo@apple.comee10e452013-04-09 00:10:16 +0000585 case CompareStrictEq: {
ggaren@apple.com0f001eb2013-04-24 15:48:55 +0000586 if (Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000587 fixEdge<BooleanUse>(node->child1());
588 fixEdge<BooleanUse>(node->child2());
ggaren@apple.com0f001eb2013-04-24 15:48:55 +0000589 break;
590 }
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000591 if (Node::shouldSpeculateInt32(node->child1().node(), node->child2().node())) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000592 fixEdge<Int32Use>(node->child1());
593 fixEdge<Int32Use>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000594 break;
595 }
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000596 if (enableInt52()
mark.lam@apple.com39e9c982016-04-25 17:48:46 +0000597 && Node::shouldSpeculateAnyInt(node->child1().node(), node->child2().node())) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000598 fixEdge<Int52RepUse>(node->child1());
599 fixEdge<Int52RepUse>(node->child2());
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000600 break;
601 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000602 if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000603 fixEdge<DoubleRepUse>(node->child1());
604 fixEdge<DoubleRepUse>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000605 break;
606 }
utatane.tea@gmail.com382ef652015-10-01 17:20:44 +0000607 if (Node::shouldSpeculateSymbol(node->child1().node(), node->child2().node())) {
608 fixEdge<SymbolUse>(node->child1());
609 fixEdge<SymbolUse>(node->child2());
610 break;
611 }
oliver@apple.combd15be82013-07-25 04:03:42 +0000612 if (node->child1()->shouldSpeculateStringIdent() && node->child2()->shouldSpeculateStringIdent()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000613 fixEdge<StringIdentUse>(node->child1());
614 fixEdge<StringIdentUse>(node->child2());
oliver@apple.combd15be82013-07-25 04:03:42 +0000615 break;
616 }
bfulgham@apple.com58de7782014-10-08 16:18:03 +0000617 if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 7) || isFTL(m_graph.m_plan.mode))) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000618 fixEdge<StringUse>(node->child1());
619 fixEdge<StringUse>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000620 break;
fpizlo@apple.comee10e452013-04-09 00:10:16 +0000621 }
commit-queue@webkit.org902685c2015-06-24 19:13:54 +0000622 WatchpointSet* masqueradesAsUndefinedWatchpoint = m_graph.globalObjectFor(node->origin.semantic)->masqueradesAsUndefinedWatchpoint();
623 if (masqueradesAsUndefinedWatchpoint->isStillValid()) {
624
625 if (node->child1()->shouldSpeculateObject()) {
626 m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
627 fixEdge<ObjectUse>(node->child1());
628 break;
629 }
630 if (node->child2()->shouldSpeculateObject()) {
631 m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
632 fixEdge<ObjectUse>(node->child2());
633 break;
634 }
635
636 } else if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000637 fixEdge<ObjectUse>(node->child1());
638 fixEdge<ObjectUse>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000639 break;
640 }
fpizlo@apple.comcef76b22016-07-21 06:23:10 +0000641 if (node->child1()->shouldSpeculateSymbol()) {
642 fixEdge<SymbolUse>(node->child1());
643 break;
644 }
645 if (node->child2()->shouldSpeculateSymbol()) {
646 fixEdge<SymbolUse>(node->child2());
647 break;
648 }
fpizlo@apple.com312efcd2014-03-10 22:11:35 +0000649 if (node->child1()->shouldSpeculateMisc()) {
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000650 fixEdge<MiscUse>(node->child1());
fpizlo@apple.com312efcd2014-03-10 22:11:35 +0000651 break;
652 }
653 if (node->child2()->shouldSpeculateMisc()) {
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000654 fixEdge<MiscUse>(node->child2());
655 break;
656 }
fpizlo@apple.com385a33a2014-03-18 20:53:07 +0000657 if (node->child1()->shouldSpeculateStringIdent()
658 && node->child2()->shouldSpeculateNotStringVar()) {
659 fixEdge<StringIdentUse>(node->child1());
660 fixEdge<NotStringVarUse>(node->child2());
661 break;
662 }
663 if (node->child2()->shouldSpeculateStringIdent()
664 && node->child1()->shouldSpeculateNotStringVar()) {
665 fixEdge<StringIdentUse>(node->child2());
666 fixEdge<NotStringVarUse>(node->child1());
667 break;
668 }
bfulgham@apple.com58de7782014-10-08 16:18:03 +0000669 if (node->child1()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 8) || isFTL(m_graph.m_plan.mode))) {
fpizlo@apple.com385a33a2014-03-18 20:53:07 +0000670 fixEdge<StringUse>(node->child1());
671 break;
672 }
bfulgham@apple.com58de7782014-10-08 16:18:03 +0000673 if (node->child2()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 8) || isFTL(m_graph.m_plan.mode))) {
fpizlo@apple.com385a33a2014-03-18 20:53:07 +0000674 fixEdge<StringUse>(node->child2());
675 break;
676 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000677 break;
678 }
fpizlo@apple.com4077f612016-07-18 19:12:57 +0000679
mark.lam@apple.com03a3e382016-01-08 18:44:36 +0000680 case StringFromCharCode:
fpizlo@apple.com47c16d72016-02-16 19:12:36 +0000681 if (node->child1()->shouldSpeculateInt32())
682 fixEdge<Int32Use>(node->child1());
683 else
mark.lam@apple.com151fe102016-01-13 23:28:38 +0000684 fixEdge<UntypedUse>(node->child1());
commit-queue@webkit.orgaa31a5e2013-04-09 06:45:16 +0000685 break;
686
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000687 case StringCharAt:
688 case StringCharCodeAt: {
689 // Currently we have no good way of refining these.
690 ASSERT(node->arrayMode() == ArrayMode(Array::String));
691 blessArrayOperation(node->child1(), node->child2(), node->child3());
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000692 fixEdge<KnownCellUse>(node->child1());
693 fixEdge<Int32Use>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000694 break;
695 }
696
fpizlo@apple.coma387b6a2012-11-01 07:41:43 +0000697 case GetByVal: {
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +0000698 if (!node->prediction()) {
699 m_insertionSet.insertNode(
700 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
701 }
702
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000703 node->setArrayMode(
704 node->arrayMode().refine(
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000705 m_graph, node,
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000706 node->child1()->prediction(),
707 node->child2()->prediction(),
benjamin@webkit.org9f46ddc2015-04-30 04:40:55 +0000708 SpecNone));
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000709
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000710 blessArrayOperation(node->child1(), node->child2(), node->child3());
fpizlo@apple.com94e84e92012-11-11 02:56:12 +0000711
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000712 ArrayMode arrayMode = node->arrayMode();
oliver@apple.com211b3be2013-07-25 04:03:39 +0000713 switch (arrayMode.type()) {
fpizlo@apple.com661530a2015-05-09 00:18:43 +0000714 case Array::Contiguous:
oliver@apple.com211b3be2013-07-25 04:03:39 +0000715 case Array::Double:
716 if (arrayMode.arrayClass() == Array::OriginalArray
fpizlo@apple.com141cdcc2015-05-06 23:14:14 +0000717 && arrayMode.speculation() == Array::InBounds) {
718 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
fpizlo@apple.com661530a2015-05-09 00:18:43 +0000719 if (globalObject->arrayPrototypeChainIsSane()) {
720 // Check if SaneChain will work on a per-type basis. Note that:
721 //
722 // 1) We don't want double arrays to sometimes return undefined, since
723 // that would require a change to the return type and it would pessimise
724 // things a lot. So, we'd only want to do that if we actually had
725 // evidence that we could read from a hole. That's pretty annoying.
726 // Likely the best way to handle that case is with an equivalent of
727 // SaneChain for OutOfBounds. For now we just detect when Undefined and
728 // NaN are indistinguishable according to backwards propagation, and just
729 // use SaneChain in that case. This happens to catch a lot of cases.
730 //
731 // 2) We don't want int32 array loads to have to do a hole check just to
732 // coerce to Undefined, since that would mean twice the checks.
733 //
734 // This has two implications. First, we have to do more checks than we'd
735 // like. It's unfortunate that we have to do the hole check. Second,
736 // some accesses that hit a hole will now need to take the full-blown
737 // out-of-bounds slow path. We can fix that with:
738 // https://bugs.webkit.org/show_bug.cgi?id=144668
739
740 bool canDoSaneChain = false;
741 switch (arrayMode.type()) {
742 case Array::Contiguous:
743 // This is happens to be entirely natural. We already would have
744 // returned any JSValue, and now we'll return Undefined. We still do
745 // the check but it doesn't require taking any kind of slow path.
746 canDoSaneChain = true;
747 break;
748
749 case Array::Double:
750 if (!(node->flags() & NodeBytecodeUsesAsOther)) {
751 // Holes look like NaN already, so if the user doesn't care
752 // about the difference between Undefined and NaN then we can
753 // do this.
754 canDoSaneChain = true;
755 }
756 break;
757
758 default:
759 break;
760 }
761
762 if (canDoSaneChain) {
763 m_graph.watchpoints().addLazily(
764 globalObject->arrayPrototype()->structure()->transitionWatchpointSet());
765 m_graph.watchpoints().addLazily(
766 globalObject->objectPrototype()->structure()->transitionWatchpointSet());
fpizlo@apple.comc2b8c092016-04-24 17:05:51 +0000767 if (globalObject->arrayPrototypeChainIsSane())
768 node->setArrayMode(arrayMode.withSpeculation(Array::SaneChain));
fpizlo@apple.com661530a2015-05-09 00:18:43 +0000769 }
fpizlo@apple.com141cdcc2015-05-06 23:14:14 +0000770 }
771 }
oliver@apple.com211b3be2013-07-25 04:03:39 +0000772 break;
773
774 case Array::String:
775 if ((node->prediction() & ~SpecString)
fpizlo@apple.com6793a322014-02-12 05:42:32 +0000776 || m_graph.hasExitSite(node->origin.semantic, OutOfBounds))
oliver@apple.com211b3be2013-07-25 04:03:39 +0000777 node->setArrayMode(arrayMode.withSpeculation(Array::OutOfBounds));
778 break;
779
780 default:
781 break;
782 }
fpizlo@apple.com94e84e92012-11-11 02:56:12 +0000783
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000784 arrayMode = node->arrayMode();
785 switch (arrayMode.type()) {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000786 case Array::SelectUsingPredictions:
787 case Array::Unprofiled:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000788 RELEASE_ASSERT_NOT_REACHED();
789 break;
790 case Array::Generic:
791#if USE(JSVALUE32_64)
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000792 fixEdge<CellUse>(node->child1()); // Speculating cell due to register pressure on 32-bit.
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000793#endif
794 break;
795 case Array::ForceExit:
796 break;
797 default:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000798 fixEdge<KnownCellUse>(node->child1());
799 fixEdge<Int32Use>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000800 break;
801 }
802
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000803 switch (arrayMode.type()) {
804 case Array::Double:
805 if (!arrayMode.isOutOfBounds())
806 node->setResult(NodeResultDouble);
807 break;
808
809 case Array::Float32Array:
810 case Array::Float64Array:
811 node->setResult(NodeResultDouble);
812 break;
813
814 case Array::Uint32Array:
815 if (node->shouldSpeculateInt32())
816 break;
mark.lam@apple.com39e9c982016-04-25 17:48:46 +0000817 if (node->shouldSpeculateAnyInt() && enableInt52())
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000818 node->setResult(NodeResultInt52);
819 else
820 node->setResult(NodeResultDouble);
821 break;
822
823 default:
824 break;
825 }
826
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000827 break;
828 }
oliver@apple.come050d642013-10-19 00:09:28 +0000829
830 case PutByValDirect:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000831 case PutByVal:
832 case PutByValAlias: {
833 Edge& child1 = m_graph.varArgChild(node, 0);
834 Edge& child2 = m_graph.varArgChild(node, 1);
835 Edge& child3 = m_graph.varArgChild(node, 2);
836
837 node->setArrayMode(
838 node->arrayMode().refine(
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000839 m_graph, node,
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000840 child1->prediction(),
841 child2->prediction(),
842 child3->prediction()));
843
844 blessArrayOperation(child1, child2, m_graph.varArgChild(node, 3));
845
846 switch (node->arrayMode().modeForPut().type()) {
847 case Array::SelectUsingPredictions:
benjamin@webkit.org5c3fb3a2015-08-14 03:54:32 +0000848 case Array::SelectUsingArguments:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000849 case Array::Unprofiled:
850 case Array::Undecided:
851 RELEASE_ASSERT_NOT_REACHED();
852 break;
853 case Array::ForceExit:
854 case Array::Generic:
855#if USE(JSVALUE32_64)
856 // Due to register pressure on 32-bit, we speculate cell and
857 // ignore the base-is-not-cell case entirely by letting the
858 // baseline JIT handle it.
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000859 fixEdge<CellUse>(child1);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000860#endif
861 break;
862 case Array::Int32:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000863 fixEdge<KnownCellUse>(child1);
864 fixEdge<Int32Use>(child2);
865 fixEdge<Int32Use>(child3);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000866 break;
867 case Array::Double:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000868 fixEdge<KnownCellUse>(child1);
869 fixEdge<Int32Use>(child2);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000870 fixEdge<DoubleRepRealUse>(child3);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000871 break;
872 case Array::Int8Array:
873 case Array::Int16Array:
874 case Array::Int32Array:
875 case Array::Uint8Array:
876 case Array::Uint8ClampedArray:
877 case Array::Uint16Array:
878 case Array::Uint32Array:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000879 fixEdge<KnownCellUse>(child1);
880 fixEdge<Int32Use>(child2);
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000881 if (child3->shouldSpeculateInt32())
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000882 fixIntOrBooleanEdge(child3);
mark.lam@apple.com39e9c982016-04-25 17:48:46 +0000883 else if (child3->shouldSpeculateAnyInt())
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000884 fixEdge<Int52RepUse>(child3);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000885 else
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000886 fixDoubleOrBooleanEdge(child3);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000887 break;
888 case Array::Float32Array:
889 case Array::Float64Array:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000890 fixEdge<KnownCellUse>(child1);
891 fixEdge<Int32Use>(child2);
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000892 fixDoubleOrBooleanEdge(child3);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000893 break;
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000894 case Array::Contiguous:
895 case Array::ArrayStorage:
896 case Array::SlowPutArrayStorage:
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000897 fixEdge<KnownCellUse>(child1);
898 fixEdge<Int32Use>(child2);
fpizlo@apple.com49b1d722015-05-18 03:39:28 +0000899 speculateForBarrier(child3);
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000900 break;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000901 default:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000902 fixEdge<KnownCellUse>(child1);
903 fixEdge<Int32Use>(child2);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000904 break;
905 }
fpizlo@apple.coma387b6a2012-11-01 07:41:43 +0000906 break;
907 }
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +0000908
fpizlo@apple.com2fca8772017-04-20 17:55:44 +0000909 case AtomicsAdd:
910 case AtomicsAnd:
911 case AtomicsCompareExchange:
912 case AtomicsExchange:
913 case AtomicsLoad:
914 case AtomicsOr:
915 case AtomicsStore:
916 case AtomicsSub:
917 case AtomicsXor: {
918 Edge& base = m_graph.child(node, 0);
919 Edge& index = m_graph.child(node, 1);
920
921 bool badNews = false;
922 for (unsigned i = numExtraAtomicsArgs(node->op()); i--;) {
923 Edge& child = m_graph.child(node, 2 + i);
924 // NOTE: DFG is not smart enough to handle double->int conversions in atomics. So, we
925 // just call the function when that happens. But the FTL is totally cool with those
926 // conversions.
927 if (!child->shouldSpeculateInt32()
928 && !child->shouldSpeculateAnyInt()
929 && !(child->shouldSpeculateNumberOrBoolean() && isFTL(m_graph.m_plan.mode)))
930 badNews = true;
931 }
932
933 if (badNews) {
934 node->setArrayMode(ArrayMode(Array::Generic));
935 break;
936 }
937
938 node->setArrayMode(
939 node->arrayMode().refine(
940 m_graph, node, base->prediction(), index->prediction()));
941
942 if (node->arrayMode().type() == Array::Generic)
943 break;
944
945 for (unsigned i = numExtraAtomicsArgs(node->op()); i--;) {
946 Edge& child = m_graph.child(node, 2 + i);
947 if (child->shouldSpeculateInt32())
948 fixIntOrBooleanEdge(child);
949 else if (child->shouldSpeculateAnyInt())
950 fixEdge<Int52RepUse>(child);
951 else {
952 RELEASE_ASSERT(child->shouldSpeculateNumberOrBoolean() && isFTL(m_graph.m_plan.mode));
953 fixDoubleOrBooleanEdge(child);
954 }
955 }
956
957 blessArrayOperation(base, index, m_graph.child(node, 2 + numExtraAtomicsArgs(node->op())));
958 fixEdge<CellUse>(base);
959 fixEdge<Int32Use>(index);
960
961 if (node->arrayMode().type() == Array::Uint32Array) {
962 // NOTE: This means basically always doing Int52.
963 if (node->shouldSpeculateAnyInt() && enableInt52())
964 node->setResult(NodeResultInt52);
965 else
966 node->setResult(NodeResultDouble);
967 }
968 break;
969 }
970
971 case AtomicsIsLockFree:
972 if (node->child1()->shouldSpeculateInt32())
973 fixIntOrBooleanEdge(node->child1());
974 break;
975
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000976 case ArrayPush: {
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000977 // May need to refine the array mode in case the value prediction contravenes
978 // the array prediction. For example, we may have evidence showing that the
979 // array is in Int32 mode, but the value we're storing is likely to be a double.
980 // Then we should turn this into a conversion to Double array followed by the
981 // push. On the other hand, we absolutely don't want to refine based on the
982 // base prediction. If it has non-cell garbage in it, then we want that to be
983 // ignored. That's because ArrayPush can't handle any array modes that aren't
984 // array-related - so if refine() turned this into a "Generic" ArrayPush then
985 // that would break things.
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000986 node->setArrayMode(
987 node->arrayMode().refine(
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000988 m_graph, node,
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000989 node->child1()->prediction() & SpecCell,
mark.lam@apple.com39e9c982016-04-25 17:48:46 +0000990 SpecInt32Only,
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000991 node->child2()->prediction()));
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000992 blessArrayOperation(node->child1(), Edge(), node->child3());
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000993 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000994
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000995 switch (node->arrayMode().type()) {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000996 case Array::Int32:
fpizlo@apple.com1c560f52013-09-12 04:48:13 +0000997 fixEdge<Int32Use>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000998 break;
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000999 case Array::Double:
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001000 fixEdge<DoubleRepRealUse>(node->child2());
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001001 break;
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001002 case Array::Contiguous:
1003 case Array::ArrayStorage:
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00001004 speculateForBarrier(node->child2());
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001005 break;
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001006 default:
1007 break;
1008 }
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001009 break;
1010 }
1011
1012 case ArrayPop: {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001013 blessArrayOperation(node->child1(), Edge(), node->child2());
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001014 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.com8fd79212012-10-16 21:59:35 +00001015 break;
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001016 }
sbarati@apple.comfd407a52017-01-13 04:03:47 +00001017
1018 case ArraySlice: {
1019 fixEdge<KnownCellUse>(m_graph.varArgChild(node, 0));
1020 fixEdge<Int32Use>(m_graph.varArgChild(node, 1));
1021 if (node->numChildren() == 4)
1022 fixEdge<Int32Use>(m_graph.varArgChild(node, 2));
1023 break;
1024 }
utatane.tea@gmail.com8dae6082017-06-12 03:58:23 +00001025
1026 case ArrayIndexOf: {
1027 Edge& array = m_graph.varArgChild(node, 0);
1028 Edge& storage = m_graph.varArgChild(node, node->numChildren() == 3 ? 2 : 3);
1029 blessArrayOperation(array, Edge(), storage);
1030 ASSERT_WITH_MESSAGE(storage.node(), "blessArrayOperation for ArrayIndexOf must set Butterfly for storage edge.");
1031
1032 fixEdge<KnownCellUse>(array);
1033 if (node->numChildren() == 4)
1034 fixEdge<Int32Use>(m_graph.varArgChild(node, 2));
1035
1036 Edge& searchElement = m_graph.varArgChild(node, 1);
1037 // FIXME: We have a chance to constant-fold this node to -1 by
1038 // emitting non number edge filters.
1039 // https://bugs.webkit.org/show_bug.cgi?id=173176
1040 switch (node->arrayMode().type()) {
1041 case Array::Double: {
1042 if (searchElement->shouldSpeculateNumber())
1043 fixEdge<DoubleRepUse>(searchElement);
1044 break;
1045 }
1046 case Array::Int32: {
1047 if (searchElement->shouldSpeculateInt32())
1048 fixEdge<Int32Use>(searchElement);
1049 break;
1050 }
1051 case Array::Contiguous: {
1052 if (searchElement->shouldSpeculateString())
1053 fixEdge<StringUse>(searchElement);
1054 else if (searchElement->shouldSpeculateObject())
1055 fixEdge<ObjectUse>(searchElement);
1056 break;
1057 }
1058 default:
1059 RELEASE_ASSERT_NOT_REACHED();
1060 break;
1061 }
1062 break;
1063 }
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001064
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001065 case RegExpExec:
1066 case RegExpTest: {
fpizlo@apple.com7518ba22016-03-06 20:11:09 +00001067 fixEdge<KnownCellUse>(node->child1());
1068
1069 if (node->child2()->shouldSpeculateRegExpObject()) {
1070 fixEdge<RegExpObjectUse>(node->child2());
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +00001071
fpizlo@apple.com7518ba22016-03-06 20:11:09 +00001072 if (node->child3()->shouldSpeculateString())
1073 fixEdge<StringUse>(node->child3());
fpizlo@apple.com239b0782016-03-03 05:58:59 +00001074 }
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +00001075 break;
1076 }
fpizlo@apple.come799b862016-03-01 21:18:42 +00001077
msaboff@apple.com69940442016-04-27 01:28:03 +00001078 case StringReplace:
1079 case StringReplaceRegExp: {
1080 if (node->child2()->shouldSpeculateString()) {
1081 m_insertionSet.insertNode(
1082 m_indexInBlock, SpecNone, Check, node->origin,
1083 Edge(node->child2().node(), StringUse));
1084 fixEdge<StringUse>(node->child2());
1085 } else if (op == StringReplace) {
1086 if (node->child2()->shouldSpeculateRegExpObject())
1087 addStringReplacePrimordialChecks(node->child2().node());
1088 else
1089 m_insertionSet.insertNode(
1090 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
1091 }
1092
fpizlo@apple.come799b862016-03-01 21:18:42 +00001093 if (node->child1()->shouldSpeculateString()
1094 && node->child2()->shouldSpeculateRegExpObject()
1095 && node->child3()->shouldSpeculateString()) {
msaboff@apple.com69940442016-04-27 01:28:03 +00001096
fpizlo@apple.come799b862016-03-01 21:18:42 +00001097 fixEdge<StringUse>(node->child1());
1098 fixEdge<RegExpObjectUse>(node->child2());
1099 fixEdge<StringUse>(node->child3());
1100 break;
1101 }
1102 break;
1103 }
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +00001104
1105 case Branch: {
fpizlo@apple.com7289af32015-08-21 03:59:33 +00001106 if (node->child1()->shouldSpeculateBoolean()) {
1107 if (node->child1()->result() == NodeResultBoolean) {
1108 // This is necessary in case we have a bytecode instruction implemented by:
1109 //
1110 // a: CompareEq(...)
1111 // b: Branch(@a)
1112 //
1113 // In that case, CompareEq might have a side-effect. Then, we need to make
1114 // sure that we know that Branch does not exit.
1115 fixEdge<KnownBooleanUse>(node->child1());
1116 } else
1117 fixEdge<BooleanUse>(node->child1());
1118 } else if (node->child1()->shouldSpeculateObjectOrOther())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001119 fixEdge<ObjectOrOtherUse>(node->child1());
fpizlo@apple.comd8846b12015-05-18 20:41:54 +00001120 else if (node->child1()->shouldSpeculateInt32OrBoolean())
1121 fixIntOrBooleanEdge(node->child1());
fpizlo@apple.com2537f952014-07-28 20:41:09 +00001122 else if (node->child1()->shouldSpeculateNumber())
1123 fixEdge<DoubleRepUse>(node->child1());
akling@apple.comd8786332015-04-28 18:54:12 +00001124 else if (node->child1()->shouldSpeculateString())
1125 fixEdge<StringUse>(node->child1());
fpizlo@apple.com91331742016-03-07 02:07:28 +00001126 else if (node->child1()->shouldSpeculateStringOrOther())
1127 fixEdge<StringOrOtherUse>(node->child1());
sbarati@apple.com1c12d212016-09-08 23:19:38 +00001128 else {
1129 WatchpointSet* masqueradesAsUndefinedWatchpoint = m_graph.globalObjectFor(node->origin.semantic)->masqueradesAsUndefinedWatchpoint();
1130 if (masqueradesAsUndefinedWatchpoint->isStillValid())
1131 m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
1132 }
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +00001133 break;
1134 }
1135
oliver@apple.com9b7647b2013-07-25 04:03:00 +00001136 case Switch: {
1137 SwitchData* data = node->switchData();
1138 switch (data->kind) {
1139 case SwitchImm:
fpizlo@apple.comefacb612013-09-10 22:16:00 +00001140 if (node->child1()->shouldSpeculateInt32())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001141 fixEdge<Int32Use>(node->child1());
oliver@apple.com9b7647b2013-07-25 04:03:00 +00001142 break;
oliver@apple.com9e1c8092013-07-25 04:03:16 +00001143 case SwitchChar:
1144 if (node->child1()->shouldSpeculateString())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001145 fixEdge<StringUse>(node->child1());
oliver@apple.com9e1c8092013-07-25 04:03:16 +00001146 break;
oliver@apple.com5c826c02013-07-25 04:03:51 +00001147 case SwitchString:
1148 if (node->child1()->shouldSpeculateStringIdent())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001149 fixEdge<StringIdentUse>(node->child1());
oliver@apple.com5c826c02013-07-25 04:03:51 +00001150 else if (node->child1()->shouldSpeculateString())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001151 fixEdge<StringUse>(node->child1());
oliver@apple.com5c826c02013-07-25 04:03:51 +00001152 break;
fpizlo@apple.com29abafe2014-08-28 19:09:48 +00001153 case SwitchCell:
1154 if (node->child1()->shouldSpeculateCell())
1155 fixEdge<CellUse>(node->child1());
1156 // else it's fine for this to have UntypedUse; we will handle this by just making
1157 // non-cells take the default case.
1158 break;
oliver@apple.com9b7647b2013-07-25 04:03:00 +00001159 }
1160 break;
1161 }
1162
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001163 case ToPrimitive: {
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00001164 fixupToPrimitive(node);
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +00001165 break;
1166 }
utatane.tea@gmail.comdb32c542016-06-30 15:26:47 +00001167
1168 case ToNumber: {
1169 fixupToNumber(node);
1170 break;
1171 }
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +00001172
utatane.tea@gmail.com153559e2015-04-06 19:07:12 +00001173 case ToString:
1174 case CallStringConstructor: {
1175 fixupToStringOrCallStringConstructor(node);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001176 break;
1177 }
1178
1179 case NewStringObject: {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001180 fixEdge<KnownStringUse>(node->child1());
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001181 break;
1182 }
sbarati@apple.com99ed4792016-11-12 02:58:11 +00001183
1184 case NewArrayWithSpread: {
1185 watchHavingABadTime(node);
1186
1187 BitVector* bitVector = node->bitVector();
1188 for (unsigned i = node->numChildren(); i--;) {
1189 if (bitVector->get(i))
1190 fixEdge<KnownCellUse>(m_graph.m_varArgChildren[node->firstChild() + i]);
1191 else
1192 fixEdge<UntypedUse>(m_graph.m_varArgChildren[node->firstChild() + i]);
1193 }
1194
1195 break;
1196 }
1197
1198 case Spread: {
1199 // Note: We care about performing the protocol on our child's global object, not necessarily ours.
1200
1201 watchHavingABadTime(node->child1().node());
1202
1203 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->child1()->origin.semantic);
1204 // When we go down the fast path, we don't consult the prototype chain, so we must prove
1205 // that it doesn't contain any indexed properties, and that any holes will result in
1206 // jsUndefined().
1207 InlineWatchpointSet& objectPrototypeTransition = globalObject->objectPrototype()->structure()->transitionWatchpointSet();
1208 InlineWatchpointSet& arrayPrototypeTransition = globalObject->arrayPrototype()->structure()->transitionWatchpointSet();
1209 if (node->child1()->shouldSpeculateArray()
1210 && arrayPrototypeTransition.isStillValid()
1211 && objectPrototypeTransition.isStillValid()
1212 && globalObject->arrayPrototypeChainIsSane()
1213 && m_graph.isWatchingArrayIteratorProtocolWatchpoint(node->child1().node())
1214 && m_graph.isWatchingHavingABadTimeWatchpoint(node->child1().node())) {
1215 m_graph.watchpoints().addLazily(objectPrototypeTransition);
1216 m_graph.watchpoints().addLazily(arrayPrototypeTransition);
1217 fixEdge<ArrayUse>(node->child1());
1218 } else
1219 fixEdge<CellUse>(node->child1());
1220 break;
1221 }
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001222
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001223 case NewArray: {
fpizlo@apple.com35398ea2015-12-04 22:25:26 +00001224 watchHavingABadTime(node);
1225
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001226 for (unsigned i = m_graph.varArgNumChildren(node); i--;) {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001227 node->setIndexingType(
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001228 leastUpperBoundOfIndexingTypeAndType(
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001229 node->indexingType(), m_graph.varArgChild(node, i)->prediction()));
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001230 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001231 switch (node->indexingType()) {
1232 case ALL_BLANK_INDEXING_TYPES:
1233 CRASH();
1234 break;
1235 case ALL_UNDECIDED_INDEXING_TYPES:
1236 if (node->numChildren()) {
1237 // This will only happen if the children have no type predictions. We
1238 // would have already exited by now, but insert a forced exit just to
1239 // be safe.
1240 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001241 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001242 }
1243 break;
1244 case ALL_INT32_INDEXING_TYPES:
1245 for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001246 fixEdge<Int32Use>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001247 break;
1248 case ALL_DOUBLE_INDEXING_TYPES:
1249 for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001250 fixEdge<DoubleRepRealUse>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001251 break;
1252 case ALL_CONTIGUOUS_INDEXING_TYPES:
1253 case ALL_ARRAY_STORAGE_INDEXING_TYPES:
1254 break;
1255 default:
1256 CRASH();
1257 break;
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001258 }
1259 break;
1260 }
1261
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001262 case NewTypedArray: {
fpizlo@apple.com35398ea2015-12-04 22:25:26 +00001263 watchHavingABadTime(node);
1264
fpizlo@apple.comefacb612013-09-10 22:16:00 +00001265 if (node->child1()->shouldSpeculateInt32()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001266 fixEdge<Int32Use>(node->child1());
fpizlo@apple.comcad67682015-02-09 19:57:41 +00001267 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001268 break;
1269 }
1270 break;
1271 }
1272
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001273 case NewArrayWithSize: {
fpizlo@apple.com35398ea2015-12-04 22:25:26 +00001274 watchHavingABadTime(node);
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001275 fixEdge<Int32Use>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001276 break;
1277 }
keith_miller@apple.com5bed6f62016-06-16 06:01:47 +00001278
mark.lam@apple.com38c32f22016-09-13 22:16:25 +00001279 case NewArrayBuffer: {
1280 watchHavingABadTime(node);
1281 break;
1282 }
1283
keith_miller@apple.com5bed6f62016-06-16 06:01:47 +00001284 case CallObjectConstructor: {
1285 if (node->child1()->shouldSpeculateObject()) {
1286 fixEdge<ObjectUse>(node->child1());
1287 node->convertToIdentity();
1288 break;
1289 }
1290
1291 fixEdge<UntypedUse>(node->child1());
1292 break;
1293 }
1294
oliver@apple.come2fe4ce2013-07-25 03:59:41 +00001295 case ToThis: {
utatane.tea@gmail.com44616d02016-01-31 23:05:10 +00001296 fixupToThis(node);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001297 break;
1298 }
1299
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001300 case PutStructure: {
1301 fixEdge<KnownCellUse>(node->child1());
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001302 break;
1303 }
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001304
1305 case GetClosureVar:
1306 case GetFromArguments: {
fpizlo@apple.com90640ab2015-03-04 05:26:54 +00001307 fixEdge<KnownCellUse>(node->child1());
1308 break;
1309 }
1310
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001311 case PutClosureVar:
1312 case PutToArguments: {
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001313 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00001314 speculateForBarrier(node->child2());
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001315 break;
1316 }
commit-queue@webkit.orga4201b02015-08-17 22:24:20 +00001317
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001318 case SkipScope:
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +00001319 case GetScope:
1320 case GetGetter:
fpizlo@apple.com7518ba22016-03-06 20:11:09 +00001321 case GetSetter:
1322 case GetGlobalObject: {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001323 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001324 break;
1325 }
1326
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001327 case AllocatePropertyStorage:
1328 case ReallocatePropertyStorage: {
1329 fixEdge<KnownCellUse>(node->child1());
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001330 break;
1331 }
fpizlo@apple.comb0e7f3d2016-12-10 01:22:15 +00001332
1333 case NukeStructureAndSetButterfly: {
1334 fixEdge<KnownCellUse>(node->child1());
1335 break;
1336 }
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001337
keith_miller@apple.com7deaba82016-04-10 03:38:44 +00001338 case TryGetById: {
1339 if (node->child1()->shouldSpeculateCell())
1340 fixEdge<CellUse>(node->child1());
1341 break;
1342 }
1343
fpizlo@apple.com151e9af2013-08-16 02:30:37 +00001344 case GetById:
1345 case GetByIdFlush: {
fpizlo@apple.com409f5be2016-03-04 02:43:53 +00001346 // FIXME: This should be done in the ByteCodeParser based on reading the
1347 // PolymorphicAccess, which will surely tell us that this is a AccessCase::ArrayLength.
1348 // https://bugs.webkit.org/show_bug.cgi?id=154990
1349 if (node->child1()->shouldSpeculateCellOrOther()
1350 && !m_graph.hasExitSite(node->origin.semantic, BadType)
1351 && !m_graph.hasExitSite(node->origin.semantic, BadCache)
fpizlo@apple.com5116ee72015-02-26 22:44:45 +00001352 && !m_graph.hasExitSite(node->origin.semantic, BadIndexingType)
1353 && !m_graph.hasExitSite(node->origin.semantic, ExoticObjectMode)) {
fpizlo@apple.comef515142016-03-04 06:36:24 +00001354
utatane.tea@gmail.com8268d392015-05-23 18:41:53 +00001355 auto uid = m_graph.identifiers()[node->identifierNumber()];
fpizlo@apple.comef515142016-03-04 06:36:24 +00001356
utatane.tea@gmail.com8268d392015-05-23 18:41:53 +00001357 if (uid == vm().propertyNames->length.impl()) {
fpizlo@apple.com5116ee72015-02-26 22:44:45 +00001358 attemptToMakeGetArrayLength(node);
1359 break;
1360 }
fpizlo@apple.comef515142016-03-04 06:36:24 +00001361
1362 if (uid == vm().propertyNames->lastIndex.impl()
1363 && node->child1()->shouldSpeculateRegExpObject()) {
1364 node->setOp(GetRegExpObjectLastIndex);
1365 node->clearFlags(NodeMustGenerate);
1366 fixEdge<RegExpObjectUse>(node->child1());
1367 break;
1368 }
fpizlo@apple.comcbc41132013-03-19 20:23:01 +00001369 }
fpizlo@apple.com409f5be2016-03-04 02:43:53 +00001370
1371 if (node->child1()->shouldSpeculateCell())
1372 fixEdge<CellUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001373 break;
1374 }
commit-queue@webkit.org99d8c452017-03-06 22:03:56 +00001375
1376 case GetByIdWithThis: {
1377 if (node->child1()->shouldSpeculateCell() && node->child2()->shouldSpeculateCell()) {
1378 fixEdge<CellUse>(node->child1());
1379 fixEdge<CellUse>(node->child2());
1380 }
1381 break;
1382 }
sbarati@apple.com23315d62016-05-09 20:17:23 +00001383
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001384 case PutById:
oliver@apple.com11ce5ff2014-03-06 21:27:13 +00001385 case PutByIdFlush:
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001386 case PutByIdDirect: {
fpizlo@apple.comef515142016-03-04 06:36:24 +00001387 if (node->child1()->shouldSpeculateCellOrOther()
1388 && !m_graph.hasExitSite(node->origin.semantic, BadType)
1389 && !m_graph.hasExitSite(node->origin.semantic, BadCache)
1390 && !m_graph.hasExitSite(node->origin.semantic, BadIndexingType)
1391 && !m_graph.hasExitSite(node->origin.semantic, ExoticObjectMode)) {
1392
1393 auto uid = m_graph.identifiers()[node->identifierNumber()];
1394
1395 if (uid == vm().propertyNames->lastIndex.impl()
1396 && node->child1()->shouldSpeculateRegExpObject()) {
1397 node->setOp(SetRegExpObjectLastIndex);
1398 fixEdge<RegExpObjectUse>(node->child1());
1399 speculateForBarrier(node->child2());
1400 break;
1401 }
1402 }
1403
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001404 fixEdge<CellUse>(node->child1());
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001405 break;
1406 }
1407
utatane.tea@gmail.com287d64c2015-10-27 07:00:57 +00001408 case PutGetterById:
1409 case PutSetterById: {
1410 fixEdge<KnownCellUse>(node->child1());
1411 fixEdge<KnownCellUse>(node->child2());
1412 break;
1413 }
1414
1415 case PutGetterSetterById: {
1416 fixEdge<KnownCellUse>(node->child1());
1417 break;
1418 }
1419
1420 case PutGetterByVal:
1421 case PutSetterByVal: {
1422 fixEdge<KnownCellUse>(node->child1());
1423 fixEdge<KnownCellUse>(node->child3());
1424 break;
1425 }
1426
fpizlo@apple.com29abafe2014-08-28 19:09:48 +00001427 case GetExecutable: {
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001428 fixEdge<FunctionUse>(node->child1());
1429 break;
1430 }
keith_miller@apple.comcb11fe42015-12-18 00:37:35 +00001431
keith_miller@apple.com56806b32016-02-26 21:43:09 +00001432 case OverridesHasInstance:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001433 case CheckStructure:
fpizlo@apple.com29abafe2014-08-28 19:09:48 +00001434 case CheckCell:
oliver@apple.come17632e2013-07-25 04:05:31 +00001435 case CreateThis:
fpizlo@apple.com95ef6492016-03-15 15:26:36 +00001436 case GetButterfly: {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001437 fixEdge<CellUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001438 break;
1439 }
utatane.tea@gmail.comfccd1362015-08-11 22:02:09 +00001440
utatane.tea@gmail.com7f364f22016-07-29 07:15:01 +00001441 case CheckStringIdent: {
1442 fixEdge<StringIdentUse>(node->child1());
utatane.tea@gmail.comfccd1362015-08-11 22:02:09 +00001443 break;
1444 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001445
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001446 case Arrayify:
1447 case ArrayifyToStructure: {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001448 fixEdge<CellUse>(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001449 if (node->child2())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001450 fixEdge<Int32Use>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001451 break;
1452 }
1453
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +00001454 case GetByOffset:
1455 case GetGetterSetterByOffset: {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001456 if (!node->child1()->hasStorageResult())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001457 fixEdge<KnownCellUse>(node->child1());
1458 fixEdge<KnownCellUse>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001459 break;
1460 }
1461
fpizlo@apple.com51614cc2014-02-17 06:35:32 +00001462 case MultiGetByOffset: {
1463 fixEdge<CellUse>(node->child1());
1464 break;
1465 }
1466
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001467 case PutByOffset: {
1468 if (!node->child1()->hasStorageResult())
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001469 fixEdge<KnownCellUse>(node->child1());
1470 fixEdge<KnownCellUse>(node->child2());
fpizlo@apple.com0ef43952016-12-08 22:14:50 +00001471 unsigned index = indexForChecks();
fpizlo@apple.com12835772015-09-21 20:49:04 +00001472 insertInferredTypeCheck(
fpizlo@apple.com0ef43952016-12-08 22:14:50 +00001473 m_insertionSet, index, originForCheck(index), node->child3().node(),
fpizlo@apple.com12835772015-09-21 20:49:04 +00001474 node->storageAccessData().inferredType);
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00001475 speculateForBarrier(node->child3());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001476 break;
1477 }
1478
fpizlo@apple.com43219522014-02-25 02:02:50 +00001479 case MultiPutByOffset: {
1480 fixEdge<CellUse>(node->child1());
fpizlo@apple.com43219522014-02-25 02:02:50 +00001481 break;
1482 }
1483
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001484 case InstanceOf: {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001485 if (!(node->child1()->prediction() & ~SpecCell))
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00001486 fixEdge<CellUse>(node->child1());
1487 fixEdge<CellUse>(node->child2());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001488 break;
1489 }
keith_miller@apple.comcb11fe42015-12-18 00:37:35 +00001490
1491 case InstanceOfCustom:
1492 fixEdge<CellUse>(node->child2());
1493 break;
1494
oliver@apple.comb3e5acb2013-07-25 04:02:53 +00001495 case In: {
keith_miller@apple.com6fc2fb72017-02-09 00:02:20 +00001496 if (node->child2()->shouldSpeculateInt32()) {
1497 convertToHasIndexedProperty(node);
1498 break;
1499 }
1500
1501 fixEdge<CellUse>(node->child1());
oliver@apple.comb3e5acb2013-07-25 04:02:53 +00001502 break;
1503 }
fpizlo@apple.com46955912013-04-26 01:18:18 +00001504
sbarati@apple.coma3db4652016-09-20 01:05:50 +00001505 case HasOwnProperty: {
1506 fixEdge<ObjectUse>(node->child1());
commit-queue@webkit.org1dc38632017-04-06 15:23:53 +00001507#if (CPU(X86) || CPU(MIPS)) && USE(JSVALUE32_64)
1508 // We don't have enough registers to do anything interesting on x86 and mips.
sbarati@apple.coma3db4652016-09-20 01:05:50 +00001509 fixEdge<UntypedUse>(node->child2());
1510#else
1511 if (node->child2()->shouldSpeculateString())
1512 fixEdge<StringUse>(node->child2());
1513 else if (node->child2()->shouldSpeculateSymbol())
1514 fixEdge<SymbolUse>(node->child2());
1515 else
1516 fixEdge<UntypedUse>(node->child2());
1517#endif
1518 break;
1519 }
1520
fpizlo@apple.com9df7fef2013-12-29 21:50:55 +00001521 case Check: {
fpizlo@apple.combb89cd52015-05-22 06:32:30 +00001522 m_graph.doToChildren(
1523 node,
1524 [&] (Edge& edge) {
1525 switch (edge.useKind()) {
1526 case NumberUse:
1527 if (edge->shouldSpeculateInt32ForArithmetic())
1528 edge.setUseKind(Int32Use);
1529 break;
1530 default:
1531 break;
1532 }
1533 observeUseKindOnEdge(edge);
1534 });
fpizlo@apple.com46955912013-04-26 01:18:18 +00001535 break;
1536 }
1537
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001538 case Phantom:
1539 // Phantoms are meaningless past Fixup. We recreate them on-demand in the backend.
1540 node->remove();
1541 break;
1542
fpizlo@apple.comf2999932014-07-15 00:41:39 +00001543 case FiatInt52: {
1544 RELEASE_ASSERT(enableInt52());
1545 node->convertToIdentity();
1546 fixEdge<Int52RepUse>(node->child1());
1547 node->setResult(NodeResultInt52);
1548 break;
1549 }
1550
keith_miller@apple.com59bba5d2015-10-16 22:18:42 +00001551 case GetArrayLength: {
1552 fixEdge<KnownCellUse>(node->child1());
1553 break;
1554 }
1555
1556 case GetTypedArrayByteOffset: {
1557 fixEdge<KnownCellUse>(node->child1());
1558 break;
1559 }
1560
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001561 case Phi:
oliver@apple.com827d2cf2013-07-25 04:04:45 +00001562 case Upsilon:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001563 case GetIndexedPropertyStorage:
1564 case LastNodeType:
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001565 case CheckTierUpInLoop:
1566 case CheckTierUpAtReturn:
1567 case CheckTierUpAndOSREnter:
fpizlo@apple.comd84425d2013-10-30 19:58:08 +00001568 case InvalidationPoint:
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00001569 case CheckArray:
fpizlo@apple.com8624c4b2013-12-10 03:24:31 +00001570 case CheckInBounds:
fpizlo@apple.com9ca951e2013-12-09 01:08:53 +00001571 case ConstantStoragePointer:
fpizlo@apple.com027ed672014-01-08 00:27:06 +00001572 case DoubleAsInt32:
fpizlo@apple.com027ed672014-01-08 00:27:06 +00001573 case ValueToInt32:
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001574 case DoubleRep:
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001575 case ValueRep:
fpizlo@apple.comf2999932014-07-15 00:41:39 +00001576 case Int52Rep:
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00001577 case Int52Constant:
1578 case Identity: // This should have been cleaned up.
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001579 case BooleanToNumber:
fpizlo@apple.comfc70ba62014-09-26 03:59:33 +00001580 case PhantomNewObject:
commit-queue@webkit.org88ab4e72015-04-24 02:23:36 +00001581 case PhantomNewFunction:
utatane.tea@gmail.com9d9fd322015-12-17 10:33:08 +00001582 case PhantomNewGeneratorFunction:
caitp@igalia.com8bc562d2016-11-14 21:14:15 +00001583 case PhantomNewAsyncFunction:
basile_clement@apple.com2ca1f7b2015-05-05 16:34:21 +00001584 case PhantomCreateActivation:
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001585 case PhantomDirectArguments:
sbarati@apple.com7a74ce72016-11-01 20:03:03 +00001586 case PhantomCreateRest:
sbarati@apple.come20444a2016-11-30 06:24:44 +00001587 case PhantomSpread:
1588 case PhantomNewArrayWithSpread:
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001589 case PhantomClonedArguments:
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001590 case GetMyArgumentByVal:
fpizlo@apple.comc2b8c092016-04-24 17:05:51 +00001591 case GetMyArgumentByValOutOfBounds:
utatane.tea@gmail.com95eee7b2017-05-22 06:24:44 +00001592 case GetVectorLength:
fpizlo@apple.com8ff74712015-03-17 15:50:44 +00001593 case PutHint:
fpizlo@apple.comfc70ba62014-09-26 03:59:33 +00001594 case CheckStructureImmediate:
fpizlo@apple.comfc70ba62014-09-26 03:59:33 +00001595 case MaterializeNewObject:
basile_clement@apple.com2ca1f7b2015-05-05 16:34:21 +00001596 case MaterializeCreateActivation:
fpizlo@apple.combcfd8eb2015-02-26 19:51:52 +00001597 case PutStack:
1598 case KillStack:
1599 case GetStack:
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00001600 case StoreBarrier:
fpizlo@apple.com9a175952016-09-28 21:55:53 +00001601 case FencedStoreBarrier:
fpizlo@apple.comef515142016-03-04 06:36:24 +00001602 case GetRegExpObjectLastIndex:
1603 case SetRegExpObjectLastIndex:
fpizlo@apple.com280ef002016-04-05 22:13:16 +00001604 case RecordRegExpCachedResult:
fpizlo@apple.com9ca951e2013-12-09 01:08:53 +00001605 // These are just nodes that we don't currently expect to see during fixup.
1606 // If we ever wanted to insert them prior to fixup, then we just have to create
1607 // fixup rules for them.
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00001608 DFG_CRASH(m_graph, node, "Unexpected node during fixup");
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001609 break;
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001610
saambarati1@gmail.com060e7512015-09-03 19:45:44 +00001611 case PutGlobalVariable: {
fpizlo@apple.com33ea5ee2015-05-15 03:51:52 +00001612 fixEdge<CellUse>(node->child1());
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00001613 speculateForBarrier(node->child2());
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00001614 break;
1615 }
1616
utatane.tea@gmail.com0bfb74c2015-02-24 23:01:58 +00001617 case IsObject:
1618 if (node->child1()->shouldSpeculateObject()) {
1619 m_insertionSet.insertNode(
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001620 m_indexInBlock, SpecNone, Check, node->origin,
utatane.tea@gmail.com0bfb74c2015-02-24 23:01:58 +00001621 Edge(node->child1().node(), ObjectUse));
1622 m_graph.convertToConstant(node, jsBoolean(true));
1623 observeUseKindOnNode<ObjectUse>(node);
1624 }
1625 break;
1626
utatane.tea@gmail.com4a748b12016-09-17 06:32:50 +00001627 case IsCellWithType: {
1628 fixupIsCellWithType(node);
utatane.tea@gmail.com0350d7d2016-09-16 21:17:33 +00001629 break;
utatane.tea@gmail.com4a748b12016-09-17 06:32:50 +00001630 }
utatane.tea@gmail.com0350d7d2016-09-16 21:17:33 +00001631
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001632 case GetEnumerableLength: {
1633 fixEdge<CellUse>(node->child1());
1634 break;
1635 }
1636 case HasGenericProperty: {
msaboff@apple.comb644c252015-03-24 10:05:21 +00001637 fixEdge<CellUse>(node->child2());
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001638 break;
1639 }
1640 case HasStructureProperty: {
1641 fixEdge<StringUse>(node->child2());
1642 fixEdge<KnownCellUse>(node->child3());
1643 break;
1644 }
1645 case HasIndexedProperty: {
1646 node->setArrayMode(
1647 node->arrayMode().refine(
1648 m_graph, node,
1649 node->child1()->prediction(),
1650 node->child2()->prediction(),
benjamin@webkit.org9f46ddc2015-04-30 04:40:55 +00001651 SpecNone));
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001652
1653 blessArrayOperation(node->child1(), node->child2(), node->child3());
1654 fixEdge<CellUse>(node->child1());
1655 fixEdge<KnownInt32Use>(node->child2());
1656 break;
1657 }
1658 case GetDirectPname: {
1659 Edge& base = m_graph.varArgChild(node, 0);
1660 Edge& property = m_graph.varArgChild(node, 1);
1661 Edge& index = m_graph.varArgChild(node, 2);
1662 Edge& enumerator = m_graph.varArgChild(node, 3);
1663 fixEdge<CellUse>(base);
1664 fixEdge<KnownCellUse>(property);
1665 fixEdge<KnownInt32Use>(index);
1666 fixEdge<KnownCellUse>(enumerator);
1667 break;
1668 }
msaboff@apple.comb644c252015-03-24 10:05:21 +00001669 case GetPropertyEnumerator: {
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001670 fixEdge<CellUse>(node->child1());
msaboff@apple.comb644c252015-03-24 10:05:21 +00001671 break;
1672 }
1673 case GetEnumeratorStructurePname: {
1674 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001675 fixEdge<KnownInt32Use>(node->child2());
1676 break;
1677 }
msaboff@apple.comb644c252015-03-24 10:05:21 +00001678 case GetEnumeratorGenericPname: {
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001679 fixEdge<KnownCellUse>(node->child1());
1680 fixEdge<KnownInt32Use>(node->child2());
1681 break;
1682 }
1683 case ToIndexString: {
1684 fixEdge<KnownInt32Use>(node->child1());
1685 break;
1686 }
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001687 case ProfileType: {
1688 // We want to insert type checks based on the instructionTypeSet of the TypeLocation, not the globalTypeSet.
1689 // Because the instructionTypeSet is contained in globalTypeSet, if we produce a type check for
1690 // type T for the instructionTypeSet, the global type set must also have information for type T.
1691 // So if it the type check succeeds for type T in the instructionTypeSet, a type check for type T
1692 // in the globalTypeSet would've also succeeded.
1693 // (The other direction does not hold in general).
1694
1695 RefPtr<TypeSet> typeSet = node->typeLocation()->m_instructionTypeSet;
saambarati1@gmail.comf9b86632015-03-28 17:28:11 +00001696 RuntimeTypeMask seenTypes = typeSet->seenTypes();
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00001697 if (typeSet->doesTypeConformTo(TypeAnyInt)) {
utatane.tea@gmail.comdc10dce2016-08-22 03:47:49 +00001698 if (node->child1()->shouldSpeculateInt32()) {
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001699 fixEdge<Int32Use>(node->child1());
utatane.tea@gmail.comdc10dce2016-08-22 03:47:49 +00001700 node->remove();
1701 break;
1702 }
1703
1704 if (enableInt52()) {
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00001705 fixEdge<AnyIntUse>(node->child1());
utatane.tea@gmail.comdc10dce2016-08-22 03:47:49 +00001706 node->remove();
1707 break;
1708 }
1709
1710 // Must not perform fixEdge<NumberUse> here since the type set only includes TypeAnyInt. Double values should be logged.
1711 }
1712
1713 if (typeSet->doesTypeConformTo(TypeNumber | TypeAnyInt)) {
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001714 fixEdge<NumberUse>(node->child1());
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001715 node->remove();
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001716 } else if (typeSet->doesTypeConformTo(TypeString)) {
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001717 fixEdge<StringUse>(node->child1());
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001718 node->remove();
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001719 } else if (typeSet->doesTypeConformTo(TypeBoolean)) {
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001720 fixEdge<BooleanUse>(node->child1());
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001721 node->remove();
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001722 } else if (typeSet->doesTypeConformTo(TypeUndefined | TypeNull) && (seenTypes & TypeUndefined) && (seenTypes & TypeNull)) {
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001723 fixEdge<OtherUse>(node->child1());
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001724 node->remove();
saambarati1@gmail.comd372c702014-10-16 19:55:14 +00001725 } else if (typeSet->doesTypeConformTo(TypeObject)) {
sbarati@apple.comf54044c2016-06-23 03:24:18 +00001726 StructureSet set;
1727 {
fpizlo@apple.com171d06f2016-11-15 23:21:50 +00001728 ConcurrentJSLocker locker(typeSet->m_lock);
sbarati@apple.comf54044c2016-06-23 03:24:18 +00001729 set = typeSet->structureSet(locker);
1730 }
saambarati1@gmail.comd372c702014-10-16 19:55:14 +00001731 if (!set.isEmpty()) {
saambarati1@gmail.comd372c702014-10-16 19:55:14 +00001732 fixEdge<CellUse>(node->child1());
fpizlo@apple.com163291d2015-04-28 19:27:23 +00001733 node->convertToCheckStructure(m_graph.addStructureSet(set));
saambarati1@gmail.comd372c702014-10-16 19:55:14 +00001734 }
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001735 }
1736
1737 break;
1738 }
msaboff@apple.comcc305da2014-12-11 16:41:33 +00001739
mark.lam@apple.comd3506e62016-11-04 06:18:01 +00001740 case CreateClonedArguments: {
1741 watchHavingABadTime(node);
1742 break;
1743 }
1744
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001745 case CreateScopedArguments:
msaboff@apple.comcc305da2014-12-11 16:41:33 +00001746 case CreateActivation:
utatane.tea@gmail.com9d9fd322015-12-17 10:33:08 +00001747 case NewFunction:
caitp@igalia.com8bc562d2016-11-14 21:14:15 +00001748 case NewGeneratorFunction:
1749 case NewAsyncFunction: {
msaboff@apple.comea77cd02014-11-14 01:07:48 +00001750 fixEdge<CellUse>(node->child1());
1751 break;
1752 }
commit-queue@webkit.orga4201b02015-08-17 22:24:20 +00001753
mark.lam@apple.com47c2f142016-03-16 18:16:32 +00001754 case SetFunctionName: {
1755 // The first child is guaranteed to be a cell because op_set_function_name is only used
1756 // on a newly instantiated function object (the first child).
1757 fixEdge<KnownCellUse>(node->child1());
1758 fixEdge<UntypedUse>(node->child2());
1759 break;
1760 }
1761
sbarati@apple.com6cfefd82016-08-13 02:14:42 +00001762 case CreateRest: {
1763 watchHavingABadTime(node);
1764 fixEdge<KnownInt32Use>(node->child1());
sbarati@apple.comc0722da2015-11-20 02:37:47 +00001765 break;
1766 }
1767
gskachkov@gmail.com077d7d52017-04-30 08:06:23 +00001768 case ResolveScopeForHoistingFuncDeclInEval: {
1769 fixEdge<KnownCellUse>(node->child1());
1770 break;
1771 }
sbarati@apple.come67fd782016-04-19 01:38:30 +00001772 case ResolveScope:
1773 case GetDynamicVar:
1774 case PutDynamicVar: {
1775 fixEdge<KnownCellUse>(node->child1());
1776 break;
1777 }
1778
sbarati@apple.comce5b05e2016-05-16 23:31:39 +00001779 case LogShadowChickenPrologue: {
1780 fixEdge<KnownCellUse>(node->child1());
1781 break;
1782 }
1783 case LogShadowChickenTail: {
1784 fixEdge<UntypedUse>(node->child1());
1785 fixEdge<KnownCellUse>(node->child2());
1786 break;
1787 }
1788
sbarati@apple.com21fc86e2016-09-06 23:22:01 +00001789 case GetMapBucket:
1790 if (node->child1().useKind() == MapObjectUse)
1791 fixEdge<MapObjectUse>(node->child1());
1792 else if (node->child1().useKind() == SetObjectUse)
1793 fixEdge<SetObjectUse>(node->child1());
1794 else
1795 RELEASE_ASSERT_NOT_REACHED();
sbarati@apple.com0868a692016-10-04 00:35:52 +00001796
sbarati@apple.com7ea4e912016-10-04 09:19:48 +00001797#if USE(JSVALUE64)
sbarati@apple.com0868a692016-10-04 00:35:52 +00001798 if (node->child2()->shouldSpeculateBoolean())
1799 fixEdge<BooleanUse>(node->child2());
1800 else if (node->child2()->shouldSpeculateInt32())
1801 fixEdge<Int32Use>(node->child2());
1802 else if (node->child2()->shouldSpeculateSymbol())
1803 fixEdge<SymbolUse>(node->child2());
1804 else if (node->child2()->shouldSpeculateObject())
1805 fixEdge<ObjectUse>(node->child2());
1806 else if (node->child2()->shouldSpeculateString())
1807 fixEdge<StringUse>(node->child2());
1808 else if (node->child2()->shouldSpeculateCell())
1809 fixEdge<CellUse>(node->child2());
1810 else
1811 fixEdge<UntypedUse>(node->child2());
sbarati@apple.com7ea4e912016-10-04 09:19:48 +00001812#else
1813 fixEdge<UntypedUse>(node->child2());
1814#endif // USE(JSVALUE64)
sbarati@apple.com0868a692016-10-04 00:35:52 +00001815
sbarati@apple.com21fc86e2016-09-06 23:22:01 +00001816 fixEdge<Int32Use>(node->child3());
1817 break;
1818
1819 case LoadFromJSMapBucket:
1820 fixEdge<KnownCellUse>(node->child1());
1821 break;
1822
1823 case IsNonEmptyMapBucket:
1824 fixEdge<KnownCellUse>(node->child1());
1825 break;
1826
sbarati@apple.comeda65b82016-10-03 20:49:34 +00001827 case MapHash: {
sbarati@apple.com7ea4e912016-10-04 09:19:48 +00001828#if USE(JSVALUE64)
sbarati@apple.comeda65b82016-10-03 20:49:34 +00001829 if (node->child1()->shouldSpeculateBoolean()) {
1830 fixEdge<BooleanUse>(node->child1());
1831 break;
1832 }
1833
1834 if (node->child1()->shouldSpeculateInt32()) {
1835 fixEdge<Int32Use>(node->child1());
1836 break;
1837 }
1838
1839 if (node->child1()->shouldSpeculateSymbol()) {
1840 fixEdge<SymbolUse>(node->child1());
1841 break;
1842 }
1843
1844 if (node->child1()->shouldSpeculateObject()) {
1845 fixEdge<ObjectUse>(node->child1());
1846 break;
1847 }
1848
1849 if (node->child1()->shouldSpeculateString()) {
1850 fixEdge<StringUse>(node->child1());
1851 break;
1852 }
1853
1854 if (node->child1()->shouldSpeculateCell()) {
1855 fixEdge<CellUse>(node->child1());
1856 break;
1857 }
1858
sbarati@apple.com21fc86e2016-09-06 23:22:01 +00001859 fixEdge<UntypedUse>(node->child1());
sbarati@apple.com7ea4e912016-10-04 09:19:48 +00001860#else
1861 fixEdge<UntypedUse>(node->child1());
1862#endif // USE(JSVALUE64)
sbarati@apple.com21fc86e2016-09-06 23:22:01 +00001863 break;
sbarati@apple.comeda65b82016-10-03 20:49:34 +00001864 }
sbarati@apple.com21fc86e2016-09-06 23:22:01 +00001865
utatane.tea@gmail.comf7db5592016-10-04 19:31:24 +00001866 case DefineDataProperty: {
1867 fixEdge<CellUse>(m_graph.varArgChild(node, 0));
1868 Edge& propertyEdge = m_graph.varArgChild(node, 1);
1869 if (propertyEdge->shouldSpeculateSymbol())
1870 fixEdge<SymbolUse>(propertyEdge);
1871 else if (propertyEdge->shouldSpeculateStringIdent())
1872 fixEdge<StringIdentUse>(propertyEdge);
1873 else if (propertyEdge->shouldSpeculateString())
1874 fixEdge<StringUse>(propertyEdge);
1875 else
1876 fixEdge<UntypedUse>(propertyEdge);
1877 fixEdge<UntypedUse>(m_graph.varArgChild(node, 2));
1878 fixEdge<KnownInt32Use>(m_graph.varArgChild(node, 3));
1879 break;
1880 }
1881
sbarati@apple.com527ebc22016-10-05 06:16:15 +00001882 case ToLowerCase: {
1883 // We currently only support StringUse since that will ensure that
1884 // ToLowerCase is a pure operation. If we decide to update this with
1885 // more types in the future, we need to ensure that the clobberize rules
1886 // are correct.
1887 fixEdge<StringUse>(node->child1());
1888 break;
1889 }
1890
utatane.tea@gmail.comfe5e95d2017-03-21 11:31:43 +00001891 case NumberToStringWithRadix: {
1892 if (node->child1()->shouldSpeculateInt32())
1893 fixEdge<Int32Use>(node->child1());
1894 else if (enableInt52() && node->child1()->shouldSpeculateAnyInt())
1895 fixEdge<Int52RepUse>(node->child1());
1896 else
1897 fixEdge<DoubleRepUse>(node->child1());
1898 fixEdge<Int32Use>(node->child2());
1899 break;
1900 }
1901
utatane.tea@gmail.comf7db5592016-10-04 19:31:24 +00001902 case DefineAccessorProperty: {
1903 fixEdge<CellUse>(m_graph.varArgChild(node, 0));
1904 Edge& propertyEdge = m_graph.varArgChild(node, 1);
1905 if (propertyEdge->shouldSpeculateSymbol())
1906 fixEdge<SymbolUse>(propertyEdge);
1907 else if (propertyEdge->shouldSpeculateStringIdent())
1908 fixEdge<StringIdentUse>(propertyEdge);
1909 else if (propertyEdge->shouldSpeculateString())
1910 fixEdge<StringUse>(propertyEdge);
1911 else
1912 fixEdge<UntypedUse>(propertyEdge);
1913 fixEdge<CellUse>(m_graph.varArgChild(node, 2));
1914 fixEdge<CellUse>(m_graph.varArgChild(node, 3));
1915 fixEdge<KnownInt32Use>(m_graph.varArgChild(node, 4));
1916 break;
1917 }
1918
utatane.tea@gmail.coma5544f12017-05-19 09:23:20 +00001919 case CheckSubClass: {
1920 fixupCheckSubClass(node);
utatane.tea@gmail.com23a42472016-10-06 05:20:10 +00001921 break;
utatane.tea@gmail.com0d74c7c2016-11-03 03:20:53 +00001922 }
utatane.tea@gmail.com23a42472016-10-06 05:20:10 +00001923
utatane.tea@gmail.comc9d8f862016-10-28 22:57:10 +00001924 case CallDOMGetter: {
utatane.tea@gmail.comaf9b93f2017-05-27 19:03:41 +00001925 DOMJIT::CallDOMGetterSnippet* snippet = node->callDOMGetterData()->snippet;
utatane.tea@gmail.com90399a22016-10-24 23:34:32 +00001926 fixEdge<CellUse>(node->child1()); // DOM.
utatane.tea@gmail.comaf9b93f2017-05-27 19:03:41 +00001927 if (snippet->requireGlobalObject)
utatane.tea@gmail.com90399a22016-10-24 23:34:32 +00001928 fixEdge<KnownCellUse>(node->child2()); // GlobalObject.
utatane.tea@gmail.com23a42472016-10-06 05:20:10 +00001929 break;
utatane.tea@gmail.com48b9cac2016-10-12 20:47:51 +00001930 }
utatane.tea@gmail.com23a42472016-10-06 05:20:10 +00001931
utatane.tea@gmail.com0d74c7c2016-11-03 03:20:53 +00001932 case CallDOM: {
1933 fixupCallDOM(node);
1934 break;
1935 }
1936
1937 case Call: {
1938 attemptToMakeCallDOM(node);
1939 break;
1940 }
1941
sbarati@apple.com0c3eb932017-02-24 04:07:30 +00001942 case ParseInt: {
1943 if (node->child1()->shouldSpeculateInt32() && !node->child2()) {
1944 fixEdge<Int32Use>(node->child1());
1945 node->convertToIdentity();
1946 break;
1947 }
1948
1949 if (node->child1()->shouldSpeculateString()) {
1950 fixEdge<StringUse>(node->child1());
1951 node->clearFlags(NodeMustGenerate);
1952 }
1953
1954 if (node->child2())
1955 fixEdge<Int32Use>(node->child2());
1956
1957 break;
1958 }
1959
commit-queue@webkit.org2faae0e2013-10-07 22:08:53 +00001960#if !ASSERT_DISABLED
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001961 // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
1962 case SetArgument:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001963 case JSConstant:
fpizlo@apple.com024424c2016-03-09 05:16:47 +00001964 case LazyJSConstant:
benjamin@webkit.org54d94f52015-02-28 03:21:37 +00001965 case DoubleConstant:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001966 case GetLocal:
1967 case GetCallee:
keith_miller@apple.com85aeabb2016-06-03 23:06:39 +00001968 case GetArgumentCountIncludingThis:
sbarati@apple.com855d5602015-11-30 20:36:54 +00001969 case GetRestLength:
utatane.tea@gmail.combebf7852016-11-10 06:34:05 +00001970 case GetArgument:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001971 case Flush:
1972 case PhantomLocal:
1973 case GetLocalUnlinked:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001974 case GetGlobalVar:
saambarati1@gmail.com060e7512015-09-03 19:45:44 +00001975 case GetGlobalLexicalVariable:
fpizlo@apple.com86468342013-11-27 02:47:43 +00001976 case NotifyWrite:
fpizlo@apple.comf0b30cb2016-10-18 18:30:05 +00001977 case DirectCall:
keith_miller@apple.comcb11fe42015-12-18 00:37:35 +00001978 case CheckTypeInfoFlags:
msaboff@apple.coma3dc7532015-09-24 21:42:59 +00001979 case TailCallInlinedCaller:
fpizlo@apple.comf0b30cb2016-10-18 18:30:05 +00001980 case DirectTailCallInlinedCaller:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001981 case Construct:
fpizlo@apple.comf0b30cb2016-10-18 18:30:05 +00001982 case DirectConstruct:
fpizlo@apple.com8fefdd32015-02-18 19:55:47 +00001983 case CallVarargs:
fpizlo@apple.com48bf58d2016-07-18 19:32:34 +00001984 case CallEval:
msaboff@apple.coma3dc7532015-09-24 21:42:59 +00001985 case TailCallVarargsInlinedCaller:
fpizlo@apple.com8fefdd32015-02-18 19:55:47 +00001986 case ConstructVarargs:
1987 case CallForwardVarargs:
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001988 case ConstructForwardVarargs:
msaboff@apple.coma3dc7532015-09-24 21:42:59 +00001989 case TailCallForwardVarargs:
1990 case TailCallForwardVarargsInlinedCaller:
fpizlo@apple.com8fefdd32015-02-18 19:55:47 +00001991 case LoadVarargs:
keith_miller@apple.come497e202016-06-13 21:05:36 +00001992 case ForwardVarargs:
saambarati1@gmail.comb4f28a52014-12-05 05:58:07 +00001993 case ProfileControlFlow:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001994 case NewObject:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001995 case NewRegexp:
keith_miller@apple.com485f5392016-04-18 20:02:24 +00001996 case DeleteById:
keith_miller@apple.com806e80d2016-05-05 17:30:02 +00001997 case DeleteByVal:
keith_miller@apple.com6919bc12016-06-23 01:39:01 +00001998 case IsTypedArrayView:
gskachkov@gmail.com086f8f62016-04-26 18:40:41 +00001999 case IsEmpty:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002000 case IsUndefined:
2001 case IsBoolean:
2002 case IsNumber:
utatane.tea@gmail.com0bfb74c2015-02-24 23:01:58 +00002003 case IsObjectOrNull:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002004 case IsFunction:
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00002005 case CreateDirectArguments:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002006 case Jump:
2007 case Return:
msaboff@apple.coma3dc7532015-09-24 21:42:59 +00002008 case TailCall:
fpizlo@apple.comf0b30cb2016-10-18 18:30:05 +00002009 case DirectTailCall:
msaboff@apple.coma3dc7532015-09-24 21:42:59 +00002010 case TailCallVarargs:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002011 case Throw:
utatane.tea@gmail.com0eb0f832016-10-06 07:44:23 +00002012 case ThrowStaticError:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002013 case CountExecution:
2014 case ForceOSRExit:
fpizlo@apple.com29abafe2014-08-28 19:09:48 +00002015 case CheckBadCell:
rniwa@webkit.orgeb7ac192015-03-13 01:11:15 +00002016 case CheckNotEmpty:
mark.lam@apple.com03916fe2017-02-28 01:20:54 +00002017 case CheckTraps:
oliver@apple.com1fc04182013-08-19 19:40:13 +00002018 case Unreachable:
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002019 case ExtractOSREntryLocal:
2020 case LoopHint:
fpizlo@apple.com9df7fef2013-12-29 21:50:55 +00002021 case MovHint:
2022 case ZombieHint:
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002023 case ExitOK:
fpizlo@apple.com29abafe2014-08-28 19:09:48 +00002024 case BottomValue:
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00002025 case TypeOf:
sbarati@apple.com23315d62016-05-09 20:17:23 +00002026 case PutByIdWithThis:
2027 case PutByValWithThis:
2028 case GetByValWithThis:
fpizlo@apple.com4077f612016-07-18 19:12:57 +00002029 case CompareEqPtr:
sbarati@apple.com23315d62016-05-09 20:17:23 +00002030 break;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002031#else
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00002032 default:
2033 break;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002034#endif
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00002035 }
fpizlo@apple.comaa1cc982013-09-12 05:46:49 +00002036 }
fpizlo@apple.com35398ea2015-12-04 22:25:26 +00002037
2038 void watchHavingABadTime(Node* node)
2039 {
2040 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
2041
2042 // If this global object is not having a bad time, watch it. We go down this path anytime the code
2043 // does an array allocation. The types of array allocations may change if we start to have a bad
2044 // time. It's easier to reason about this if we know that whenever the types change after we start
2045 // optimizing, the code just gets thrown out. Doing this at FixupPhase is just early enough, since
2046 // prior to this point nobody should have been doing optimizations based on the indexing type of
2047 // the allocation.
sbarati@apple.com99ed4792016-11-12 02:58:11 +00002048 if (!globalObject->isHavingABadTime()) {
fpizlo@apple.com35398ea2015-12-04 22:25:26 +00002049 m_graph.watchpoints().addLazily(globalObject->havingABadTimeWatchpoint());
sbarati@apple.com99ed4792016-11-12 02:58:11 +00002050 m_graph.freeze(globalObject);
2051 }
fpizlo@apple.com35398ea2015-12-04 22:25:26 +00002052 }
fpizlo@apple.comaa1cc982013-09-12 05:46:49 +00002053
fpizlo@apple.com8d225912013-03-19 00:44:57 +00002054 template<UseKind useKind>
fpizlo@apple.com4463e442013-03-20 20:29:37 +00002055 void createToString(Node* node, Edge& edge)
fpizlo@apple.comcbc41132013-03-19 20:23:01 +00002056 {
utatane.tea@gmail.com2dd82cf2017-04-18 18:06:37 +00002057 Node* toString = m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002058 m_indexInBlock, SpecString, ToString, node->origin,
utatane.tea@gmail.com2dd82cf2017-04-18 18:06:37 +00002059 Edge(edge.node(), useKind));
2060 switch (useKind) {
2061 case Int32Use:
2062 case Int52RepUse:
2063 case DoubleRepUse:
2064 case NotCellUse:
2065 toString->clearFlags(NodeMustGenerate);
2066 break;
2067 default:
2068 break;
2069 }
2070 edge.setNode(toString);
fpizlo@apple.comcbc41132013-03-19 20:23:01 +00002071 }
2072
2073 template<UseKind useKind>
2074 void attemptToForceStringArrayModeByToStringConversion(ArrayMode& arrayMode, Node* node)
2075 {
2076 ASSERT(arrayMode == ArrayMode(Array::Generic));
2077
keith_miller@apple.com8b5e9cd2015-11-04 21:46:10 +00002078 if (!m_graph.canOptimizeStringObjectAccess(node->origin.semantic))
fpizlo@apple.comcbc41132013-03-19 20:23:01 +00002079 return;
2080
fpizlo@apple.com4463e442013-03-20 20:29:37 +00002081 createToString<useKind>(node, node->child1());
fpizlo@apple.comcbc41132013-03-19 20:23:01 +00002082 arrayMode = ArrayMode(Array::String);
2083 }
2084
2085 template<UseKind useKind>
fpizlo@apple.com8d225912013-03-19 00:44:57 +00002086 bool isStringObjectUse()
2087 {
2088 switch (useKind) {
2089 case StringObjectUse:
2090 case StringOrStringObjectUse:
2091 return true;
2092 default:
2093 return false;
2094 }
2095 }
2096
2097 template<UseKind useKind>
2098 void convertStringAddUse(Node* node, Edge& edge)
2099 {
2100 if (useKind == StringUse) {
fpizlo@apple.com8d225912013-03-19 00:44:57 +00002101 observeUseKindOnNode<StringUse>(edge.node());
2102 m_insertionSet.insertNode(
fpizlo@apple.com163291d2015-04-28 19:27:23 +00002103 m_indexInBlock, SpecNone, Check, node->origin,
fpizlo@apple.com8d225912013-03-19 00:44:57 +00002104 Edge(edge.node(), StringUse));
2105 edge.setUseKind(KnownStringUse);
2106 return;
2107 }
2108
fpizlo@apple.com8d225912013-03-19 00:44:57 +00002109 observeUseKindOnNode<useKind>(edge.node());
fpizlo@apple.com4463e442013-03-20 20:29:37 +00002110 createToString<useKind>(node, edge);
2111 }
2112
2113 void convertToMakeRope(Node* node)
2114 {
2115 node->setOpAndDefaultFlags(MakeRope);
2116 fixupMakeRope(node);
2117 }
2118
2119 void fixupMakeRope(Node* node)
2120 {
2121 for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
2122 Edge& edge = node->children.child(i);
2123 if (!edge)
2124 break;
2125 edge.setUseKind(KnownStringUse);
keith_miller@apple.com45da7602017-01-27 01:47:52 +00002126 JSString* string = edge->dynamicCastConstant<JSString*>(vm());
fpizlo@apple.comb41e6822014-07-25 20:55:17 +00002127 if (!string)
fpizlo@apple.com4463e442013-03-20 20:29:37 +00002128 continue;
fpizlo@apple.com4463e442013-03-20 20:29:37 +00002129 if (string->length())
2130 continue;
fpizlo@apple.com4bb938e2013-07-16 21:41:06 +00002131
2132 // Don't allow the MakeRope to have zero children.
2133 if (!i && !node->child2())
2134 break;
2135
fpizlo@apple.com4463e442013-03-20 20:29:37 +00002136 node->children.removeEdge(i--);
2137 }
2138
2139 if (!node->child2()) {
2140 ASSERT(!node->child3());
2141 node->convertToIdentity();
2142 }
fpizlo@apple.com8d225912013-03-19 00:44:57 +00002143 }
utatane.tea@gmail.com44616d02016-01-31 23:05:10 +00002144
utatane.tea@gmail.com4a748b12016-09-17 06:32:50 +00002145 void fixupIsCellWithType(Node* node)
2146 {
2147 switch (node->speculatedTypeForQuery()) {
utatane.tea@gmail.com3634afe2016-09-19 17:00:25 +00002148 case SpecString:
2149 if (node->child1()->shouldSpeculateString()) {
2150 m_insertionSet.insertNode(
2151 m_indexInBlock, SpecNone, Check, node->origin,
2152 Edge(node->child1().node(), StringUse));
2153 m_graph.convertToConstant(node, jsBoolean(true));
2154 observeUseKindOnNode<StringUse>(node);
2155 return;
2156 }
2157 break;
2158
utatane.tea@gmail.com4a748b12016-09-17 06:32:50 +00002159 case SpecProxyObject:
2160 if (node->child1()->shouldSpeculateProxyObject()) {
2161 m_insertionSet.insertNode(
2162 m_indexInBlock, SpecNone, Check, node->origin,
2163 Edge(node->child1().node(), ProxyObjectUse));
2164 m_graph.convertToConstant(node, jsBoolean(true));
2165 observeUseKindOnNode<ProxyObjectUse>(node);
2166 return;
2167 }
2168 break;
2169
2170 case SpecRegExpObject:
2171 if (node->child1()->shouldSpeculateRegExpObject()) {
2172 m_insertionSet.insertNode(
2173 m_indexInBlock, SpecNone, Check, node->origin,
2174 Edge(node->child1().node(), RegExpObjectUse));
2175 m_graph.convertToConstant(node, jsBoolean(true));
2176 observeUseKindOnNode<RegExpObjectUse>(node);
2177 return;
2178 }
2179 break;
2180
2181 case SpecArray:
2182 if (node->child1()->shouldSpeculateArray()) {
2183 m_insertionSet.insertNode(
2184 m_indexInBlock, SpecNone, Check, node->origin,
2185 Edge(node->child1().node(), ArrayUse));
2186 m_graph.convertToConstant(node, jsBoolean(true));
2187 observeUseKindOnNode<ArrayUse>(node);
2188 return;
2189 }
2190 break;
2191
2192 case SpecDerivedArray:
2193 if (node->child1()->shouldSpeculateDerivedArray()) {
2194 m_insertionSet.insertNode(
2195 m_indexInBlock, SpecNone, Check, node->origin,
2196 Edge(node->child1().node(), DerivedArrayUse));
2197 m_graph.convertToConstant(node, jsBoolean(true));
2198 observeUseKindOnNode<DerivedArrayUse>(node);
2199 return;
2200 }
2201 break;
2202 }
2203
2204 if (node->child1()->shouldSpeculateCell()) {
2205 fixEdge<CellUse>(node->child1());
2206 return;
2207 }
2208
2209 if (node->child1()->shouldSpeculateNotCell()) {
2210 m_insertionSet.insertNode(
2211 m_indexInBlock, SpecNone, Check, node->origin,
2212 Edge(node->child1().node(), NotCellUse));
2213 m_graph.convertToConstant(node, jsBoolean(false));
2214 observeUseKindOnNode<NotCellUse>(node);
2215 return;
2216 }
2217 }
2218
utatane.tea@gmail.com44616d02016-01-31 23:05:10 +00002219 void fixupToThis(Node* node)
2220 {
2221 ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->isStrictMode() ? StrictMode : NotStrictMode;
2222
2223 if (ecmaMode == StrictMode) {
2224 if (node->child1()->shouldSpeculateBoolean()) {
2225 fixEdge<BooleanUse>(node->child1());
2226 node->convertToIdentity();
2227 return;
2228 }
2229
2230 if (node->child1()->shouldSpeculateInt32()) {
2231 fixEdge<Int32Use>(node->child1());
2232 node->convertToIdentity();
2233 return;
2234 }
2235
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002236 if (enableInt52() && node->child1()->shouldSpeculateAnyInt()) {
utatane.tea@gmail.com44616d02016-01-31 23:05:10 +00002237 fixEdge<Int52RepUse>(node->child1());
2238 node->convertToIdentity();
2239 node->setResult(NodeResultInt52);
2240 return;
2241 }
2242
2243 if (node->child1()->shouldSpeculateNumber()) {
2244 fixEdge<DoubleRepUse>(node->child1());
2245 node->convertToIdentity();
2246 node->setResult(NodeResultDouble);
2247 return;
2248 }
2249
2250 if (node->child1()->shouldSpeculateSymbol()) {
2251 fixEdge<SymbolUse>(node->child1());
2252 node->convertToIdentity();
2253 return;
2254 }
2255
2256 if (node->child1()->shouldSpeculateStringIdent()) {
2257 fixEdge<StringIdentUse>(node->child1());
2258 node->convertToIdentity();
2259 return;
2260 }
2261
2262 if (node->child1()->shouldSpeculateString()) {
2263 fixEdge<StringUse>(node->child1());
2264 node->convertToIdentity();
2265 return;
2266 }
2267 }
2268
2269 if (node->child1()->shouldSpeculateOther()) {
2270 if (ecmaMode == StrictMode) {
2271 fixEdge<OtherUse>(node->child1());
2272 node->convertToIdentity();
2273 return;
2274 }
2275
2276 m_insertionSet.insertNode(
2277 m_indexInBlock, SpecNone, Check, node->origin,
2278 Edge(node->child1().node(), OtherUse));
2279 observeUseKindOnNode<OtherUse>(node->child1().node());
2280 m_graph.convertToConstant(
2281 node, m_graph.globalThisObjectFor(node->origin.semantic));
2282 return;
2283 }
2284
keith_miller@apple.comd1a5d2f2016-05-02 17:38:15 +00002285 // FIXME: This should cover other use cases but we don't have use kinds for them. It's not critical,
2286 // however, since we cover all the missing cases in constant folding.
2287 // https://bugs.webkit.org/show_bug.cgi?id=157213
utatane.tea@gmail.com44616d02016-01-31 23:05:10 +00002288 if (node->child1()->shouldSpeculateStringObject()) {
2289 fixEdge<StringObjectUse>(node->child1());
2290 node->convertToIdentity();
2291 return;
2292 }
2293
2294 if (isFinalObjectSpeculation(node->child1()->prediction())) {
2295 fixEdge<FinalObjectUse>(node->child1());
2296 node->convertToIdentity();
2297 return;
2298 }
2299 }
fpizlo@apple.com8d225912013-03-19 00:44:57 +00002300
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00002301 void fixupToPrimitive(Node* node)
2302 {
fpizlo@apple.comefacb612013-09-10 22:16:00 +00002303 if (node->child1()->shouldSpeculateInt32()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00002304 fixEdge<Int32Use>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00002305 node->convertToIdentity();
2306 return;
2307 }
2308
2309 if (node->child1()->shouldSpeculateString()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00002310 fixEdge<StringUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00002311 node->convertToIdentity();
2312 return;
2313 }
2314
2315 if (node->child1()->shouldSpeculateStringObject()
keith_miller@apple.com8b5e9cd2015-11-04 21:46:10 +00002316 && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00002317 fixEdge<StringObjectUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00002318 node->convertToToString();
2319 return;
2320 }
2321
2322 if (node->child1()->shouldSpeculateStringOrStringObject()
keith_miller@apple.com8b5e9cd2015-11-04 21:46:10 +00002323 && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00002324 fixEdge<StringOrStringObjectUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00002325 node->convertToToString();
2326 return;
2327 }
2328 }
utatane.tea@gmail.comdb32c542016-06-30 15:26:47 +00002329
2330 void fixupToNumber(Node* node)
2331 {
2332 // If the prediction of the child is Number, we attempt to convert ToNumber to Identity.
2333 if (node->child1()->shouldSpeculateNumber()) {
2334 if (isInt32Speculation(node->getHeapPrediction())) {
2335 // If the both predictions of this node and the child is Int32, we just convert ToNumber to Identity, that's simple.
2336 if (node->child1()->shouldSpeculateInt32()) {
2337 fixEdge<Int32Use>(node->child1());
2338 node->convertToIdentity();
2339 return;
2340 }
2341
2342 // The another case is that the predicted type of the child is Int32, but the heap prediction tell the users that this will produce non Int32 values.
2343 // In that case, let's receive the child value as a Double value and convert it to Int32. This case happens in misc-bugs-847389-jpeg2000.
2344 fixEdge<DoubleRepUse>(node->child1());
2345 node->setOp(DoubleAsInt32);
2346 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
2347 node->setArithMode(Arith::CheckOverflow);
2348 else
2349 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
2350 return;
2351 }
2352
2353 fixEdge<DoubleRepUse>(node->child1());
2354 node->convertToIdentity();
2355 node->setResult(NodeResultDouble);
2356 return;
2357 }
2358
2359 fixEdge<UntypedUse>(node->child1());
2360 node->setResult(NodeResultJS);
2361 }
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00002362
utatane.tea@gmail.com153559e2015-04-06 19:07:12 +00002363 void fixupToStringOrCallStringConstructor(Node* node)
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00002364 {
2365 if (node->child1()->shouldSpeculateString()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00002366 fixEdge<StringUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00002367 node->convertToIdentity();
2368 return;
2369 }
2370
2371 if (node->child1()->shouldSpeculateStringObject()
keith_miller@apple.com8b5e9cd2015-11-04 21:46:10 +00002372 && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00002373 fixEdge<StringObjectUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00002374 return;
2375 }
2376
2377 if (node->child1()->shouldSpeculateStringOrStringObject()
keith_miller@apple.com8b5e9cd2015-11-04 21:46:10 +00002378 && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00002379 fixEdge<StringOrStringObjectUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00002380 return;
2381 }
2382
2383 if (node->child1()->shouldSpeculateCell()) {
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00002384 fixEdge<CellUse>(node->child1());
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00002385 return;
2386 }
utatane.tea@gmail.com4ea3bc02017-03-16 04:49:47 +00002387
utatane.tea@gmail.comfe5e95d2017-03-21 11:31:43 +00002388 if (node->child1()->shouldSpeculateInt32()) {
2389 fixEdge<Int32Use>(node->child1());
2390 node->clearFlags(NodeMustGenerate);
2391 return;
2392 }
2393
2394 if (enableInt52() && node->child1()->shouldSpeculateAnyInt()) {
2395 fixEdge<Int52RepUse>(node->child1());
2396 node->clearFlags(NodeMustGenerate);
2397 return;
2398 }
2399
2400 if (node->child1()->shouldSpeculateNumber()) {
2401 fixEdge<DoubleRepUse>(node->child1());
2402 node->clearFlags(NodeMustGenerate);
2403 return;
2404 }
2405
utatane.tea@gmail.com4ea3bc02017-03-16 04:49:47 +00002406 // ToString(Symbol) throws an error. So if the child1 can include Symbols,
2407 // we need to care about it in the clobberize. In the following case,
2408 // since NotCellUse edge filter is used and this edge filters Symbols,
2409 // we can say that ToString never throws an error!
2410 if (node->child1()->shouldSpeculateNotCell()) {
2411 fixEdge<NotCellUse>(node->child1());
2412 node->clearFlags(NodeMustGenerate);
2413 return;
2414 }
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00002415 }
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00002416
2417 bool attemptToMakeFastStringAdd(Node* node)
fpizlo@apple.com8d225912013-03-19 00:44:57 +00002418 {
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00002419 bool goodToGo = true;
2420 m_graph.doToChildren(
2421 node,
2422 [&] (Edge& edge) {
2423 if (edge->shouldSpeculateString())
2424 return;
keith_miller@apple.com8b5e9cd2015-11-04 21:46:10 +00002425 if (m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00002426 if (edge->shouldSpeculateStringObject())
2427 return;
2428 if (edge->shouldSpeculateStringOrStringObject())
2429 return;
2430 }
2431 goodToGo = false;
2432 });
2433 if (!goodToGo)
fpizlo@apple.com8d225912013-03-19 00:44:57 +00002434 return false;
utatane.tea@gmail.comea361c12015-06-18 23:45:06 +00002435
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00002436 m_graph.doToChildren(
2437 node,
2438 [&] (Edge& edge) {
2439 if (edge->shouldSpeculateString()) {
2440 convertStringAddUse<StringUse>(node, edge);
2441 return;
2442 }
keith_miller@apple.com8b5e9cd2015-11-04 21:46:10 +00002443 ASSERT(m_graph.canOptimizeStringObjectAccess(node->origin.semantic));
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00002444 if (edge->shouldSpeculateStringObject()) {
2445 convertStringAddUse<StringObjectUse>(node, edge);
2446 return;
2447 }
2448 if (edge->shouldSpeculateStringOrStringObject()) {
2449 convertStringAddUse<StringOrStringObjectUse>(node, edge);
2450 return;
2451 }
2452 RELEASE_ASSERT_NOT_REACHED();
2453 });
fpizlo@apple.com8d225912013-03-19 00:44:57 +00002454
fpizlo@apple.com7e5ed6e2013-03-20 22:37:09 +00002455 convertToMakeRope(node);
2456 return true;
fpizlo@apple.com8d225912013-03-19 00:44:57 +00002457 }
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00002458
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00002459 void fixupGetAndSetLocalsInBlock(BasicBlock* block)
fpizlo@apple.combbaf6192013-02-27 01:45:28 +00002460 {
2461 if (!block)
2462 return;
2463 ASSERT(block->isReachable);
2464 m_block = block;
2465 for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
2466 Node* node = m_currentNode = block->at(m_indexInBlock);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00002467 if (node->op() != SetLocal && node->op() != GetLocal)
fpizlo@apple.combbaf6192013-02-27 01:45:28 +00002468 continue;
fpizlo@apple.combbaf6192013-02-27 01:45:28 +00002469
2470 VariableAccessData* variable = node->variableAccessData();
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00002471 switch (node->op()) {
2472 case GetLocal:
2473 switch (variable->flushFormat()) {
2474 case FlushedDouble:
2475 node->setResult(NodeResultDouble);
2476 break;
2477 case FlushedInt52:
2478 node->setResult(NodeResultInt52);
2479 break;
2480 default:
2481 break;
2482 }
fpizlo@apple.com571d3b22013-09-11 21:24:34 +00002483 break;
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00002484
2485 case SetLocal:
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00002486 // NOTE: Any type checks we put here may get hoisted by fixupChecksInBlock(). So, if we
2487 // add new type checking use kind for SetLocals, we need to modify that code as well.
2488
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00002489 switch (variable->flushFormat()) {
2490 case FlushedJSValue:
2491 break;
2492 case FlushedDouble:
2493 fixEdge<DoubleRepUse>(node->child1());
2494 break;
2495 case FlushedInt32:
2496 fixEdge<Int32Use>(node->child1());
2497 break;
2498 case FlushedInt52:
2499 fixEdge<Int52RepUse>(node->child1());
2500 break;
2501 case FlushedCell:
2502 fixEdge<CellUse>(node->child1());
2503 break;
2504 case FlushedBoolean:
2505 fixEdge<BooleanUse>(node->child1());
2506 break;
2507 default:
2508 RELEASE_ASSERT_NOT_REACHED();
2509 break;
2510 }
fpizlo@apple.com571d3b22013-09-11 21:24:34 +00002511 break;
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00002512
fpizlo@apple.com571d3b22013-09-11 21:24:34 +00002513 default:
2514 RELEASE_ASSERT_NOT_REACHED();
2515 break;
2516 }
fpizlo@apple.com6921b292013-09-18 17:14:02 +00002517 }
2518 m_insertionSet.execute(block);
2519 }
2520
msaboff@apple.com69940442016-04-27 01:28:03 +00002521 void addStringReplacePrimordialChecks(Node* searchRegExp)
2522 {
2523 Node* node = m_currentNode;
2524
2525 // Check that structure of searchRegExp is RegExp object
2526 m_insertionSet.insertNode(
2527 m_indexInBlock, SpecNone, Check, node->origin,
2528 Edge(searchRegExp, RegExpObjectUse));
2529
2530 auto emitPrimordialCheckFor = [&] (JSValue primordialProperty, UniquedStringImpl* propertyUID) {
2531 unsigned index = m_graph.identifiers().ensure(propertyUID);
2532
2533 Node* actualProperty = m_insertionSet.insertNode(
2534 m_indexInBlock, SpecNone, TryGetById, node->origin,
2535 OpInfo(index), OpInfo(SpecFunction), Edge(searchRegExp, CellUse));
2536
2537 m_insertionSet.insertNode(
2538 m_indexInBlock, SpecNone, CheckCell, node->origin,
2539 OpInfo(m_graph.freeze(primordialProperty)), Edge(actualProperty, CellUse));
2540 };
2541
2542 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
2543
2544 // Check that searchRegExp.exec is the primordial RegExp.prototype.exec
2545 emitPrimordialCheckFor(globalObject->regExpProtoExecFunction(), vm().propertyNames->exec.impl());
2546 // Check that searchRegExp.global is the primordial RegExp.prototype.global
2547 emitPrimordialCheckFor(globalObject->regExpProtoGlobalGetter(), vm().propertyNames->global.impl());
2548 // Check that searchRegExp.unicode is the primordial RegExp.prototype.unicode
2549 emitPrimordialCheckFor(globalObject->regExpProtoUnicodeGetter(), vm().propertyNames->unicode.impl());
2550 // Check that searchRegExp[Symbol.match] is the primordial RegExp.prototype[Symbol.replace]
2551 emitPrimordialCheckFor(globalObject->regExpProtoSymbolReplaceFunction(), vm().propertyNames->replaceSymbol.impl());
2552 }
2553
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002554 Node* checkArray(ArrayMode arrayMode, const NodeOrigin& origin, Node* array, Node* index, bool (*storageCheck)(const ArrayMode&) = canCSEStorage)
fpizlo@apple.com04c19742012-08-26 22:35:26 +00002555 {
fpizlo@apple.com34d1f082012-10-28 06:13:23 +00002556 ASSERT(arrayMode.isSpecific());
fpizlo@apple.com04c19742012-08-26 22:35:26 +00002557
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00002558 if (arrayMode.type() == Array::String) {
2559 m_insertionSet.insertNode(
fpizlo@apple.com163291d2015-04-28 19:27:23 +00002560 m_indexInBlock, SpecNone, Check, origin, Edge(array, StringUse));
fpizlo@apple.com99f37622012-10-29 04:02:08 +00002561 } else {
fpizlo@apple.com141cdcc2015-05-06 23:14:14 +00002562 // Note that we only need to be using a structure check if we opt for SaneChain, since
2563 // that needs to protect against JSArray's __proto__ being changed.
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002564 Structure* structure = arrayMode.originalArrayStructure(m_graph, origin.semantic);
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00002565
2566 Edge indexEdge = index ? Edge(index, Int32Use) : Edge();
fpizlo@apple.com141cdcc2015-05-06 23:14:14 +00002567
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00002568 if (arrayMode.doesConversion()) {
2569 if (structure) {
2570 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002571 m_indexInBlock, SpecNone, ArrayifyToStructure, origin,
sbarati@apple.com239d20b2017-01-26 23:50:58 +00002572 OpInfo(m_graph.registerStructure(structure)), OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00002573 } else {
2574 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002575 m_indexInBlock, SpecNone, Arrayify, origin,
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00002576 OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
2577 }
fpizlo@apple.com3f1a01b2012-11-10 05:54:11 +00002578 } else {
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00002579 if (structure) {
2580 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002581 m_indexInBlock, SpecNone, CheckStructure, origin,
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00002582 OpInfo(m_graph.addStructureSet(structure)), Edge(array, CellUse));
2583 } else {
2584 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002585 m_indexInBlock, SpecNone, CheckArray, origin,
fpizlo@apple.com97ef5782013-11-05 05:39:03 +00002586 OpInfo(arrayMode.asWord()), Edge(array, CellUse));
2587 }
fpizlo@apple.com3f1a01b2012-11-10 05:54:11 +00002588 }
fpizlo@apple.com497c7512012-09-19 01:20:52 +00002589 }
2590
fpizlo@apple.com04c19742012-08-26 22:35:26 +00002591 if (!storageCheck(arrayMode))
commit-queue@webkit.orgb4bf63e2016-09-12 22:13:37 +00002592 return nullptr;
fpizlo@apple.com04c19742012-08-26 22:35:26 +00002593
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +00002594 if (arrayMode.usesButterfly()) {
2595 return m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002596 m_indexInBlock, SpecNone, GetButterfly, origin, Edge(array, CellUse));
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +00002597 }
fpizlo@apple.com04c19742012-08-26 22:35:26 +00002598
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +00002599 return m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002600 m_indexInBlock, SpecNone, GetIndexedPropertyStorage, origin,
fpizlo@apple.com06f82b52013-03-06 02:27:16 +00002601 OpInfo(arrayMode.asWord()), Edge(array, KnownCellUse));
fpizlo@apple.com04c19742012-08-26 22:35:26 +00002602 }
2603
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002604 void blessArrayOperation(Edge base, Edge index, Edge& storageChild)
fpizlo@apple.com04c19742012-08-26 22:35:26 +00002605 {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00002606 Node* node = m_currentNode;
2607
2608 switch (node->arrayMode().type()) {
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00002609 case Array::ForceExit: {
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +00002610 m_insertionSet.insertNode(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002611 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
fpizlo@apple.com04c19742012-08-26 22:35:26 +00002612 return;
2613 }
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00002614
fpizlo@apple.coma0ec0592012-10-22 23:52:15 +00002615 case Array::SelectUsingPredictions:
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00002616 case Array::Unprofiled:
oliver@apple.com5598c182013-01-23 22:25:07 +00002617 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.com04c19742012-08-26 22:35:26 +00002618 return;
2619
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00002620 case Array::Generic:
fpizlo@apple.com04c19742012-08-26 22:35:26 +00002621 return;
2622
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00002623 default: {
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002624 Node* storage = checkArray(node->arrayMode(), node->origin, base.node(), index.node());
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00002625 if (!storage)
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00002626 return;
2627
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002628 storageChild = Edge(storage);
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00002629 return;
2630 } }
fpizlo@apple.com04c19742012-08-26 22:35:26 +00002631 }
2632
fpizlo@apple.combbaf6192013-02-27 01:45:28 +00002633 bool alwaysUnboxSimplePrimitives()
2634 {
2635#if USE(JSVALUE64)
2636 return false;
2637#else
2638 // Any boolean, int, or cell value is profitable to unbox on 32-bit because it
2639 // reduces traffic.
2640 return true;
2641#endif
2642 }
fpizlo@apple.com46955912013-04-26 01:18:18 +00002643
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00002644 template<UseKind useKind>
2645 void observeUseKindOnNode(Node* node)
2646 {
fpizlo@apple.comaa1cc982013-09-12 05:46:49 +00002647 if (useKind == UntypedUse)
2648 return;
fpizlo@apple.com46955912013-04-26 01:18:18 +00002649 observeUseKindOnNode(node, useKind);
2650 }
2651
2652 void observeUseKindOnEdge(Edge edge)
2653 {
2654 observeUseKindOnNode(edge.node(), edge.useKind());
2655 }
2656
2657 void observeUseKindOnNode(Node* node, UseKind useKind)
2658 {
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00002659 if (node->op() != GetLocal)
2660 return;
2661
fpizlo@apple.com6921b292013-09-18 17:14:02 +00002662 // FIXME: The way this uses alwaysUnboxSimplePrimitives() is suspicious.
2663 // https://bugs.webkit.org/show_bug.cgi?id=121518
2664
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00002665 VariableAccessData* variable = node->variableAccessData();
2666 switch (useKind) {
2667 case Int32Use:
fpizlo@apple.com7289af32015-08-21 03:59:33 +00002668 case KnownInt32Use:
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00002669 if (alwaysUnboxSimplePrimitives()
2670 || isInt32Speculation(variable->prediction()))
2671 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
2672 break;
2673 case NumberUse:
fpizlo@apple.com318af072015-06-05 04:59:28 +00002674 case RealNumberUse:
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00002675 case DoubleRepUse:
2676 case DoubleRepRealUse:
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00002677 if (variable->doubleFormatState() == UsingDoubleFormat)
2678 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
2679 break;
2680 case BooleanUse:
fpizlo@apple.com7289af32015-08-21 03:59:33 +00002681 case KnownBooleanUse:
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00002682 if (alwaysUnboxSimplePrimitives()
2683 || isBooleanSpeculation(variable->prediction()))
2684 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
2685 break;
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00002686 case Int52RepUse:
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002687 if (isAnyIntSpeculation(variable->prediction()))
fpizlo@apple.com6921b292013-09-18 17:14:02 +00002688 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
2689 break;
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00002690 case CellUse:
oliver@apple.com176a3472013-07-25 04:00:19 +00002691 case KnownCellUse:
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00002692 case ObjectUse:
fpizlo@apple.coma398a562014-08-06 21:32:55 +00002693 case FunctionUse:
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00002694 case StringUse:
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00002695 case KnownStringUse:
utatane.tea@gmail.comfccd1362015-08-11 22:02:09 +00002696 case SymbolUse:
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00002697 case StringObjectUse:
2698 case StringOrStringObjectUse:
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00002699 if (alwaysUnboxSimplePrimitives()
2700 || isCellSpeculation(variable->prediction()))
2701 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
2702 break;
2703 default:
2704 break;
2705 }
2706 }
2707
fpizlo@apple.com35701872013-02-23 01:03:10 +00002708 template<UseKind useKind>
fpizlo@apple.comc6bb4a92013-09-30 20:38:46 +00002709 void fixEdge(Edge& edge)
fpizlo@apple.com35701872013-02-23 01:03:10 +00002710 {
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +00002711 observeUseKindOnNode<useKind>(edge.node());
fpizlo@apple.com35701872013-02-23 01:03:10 +00002712 edge.setUseKind(useKind);
2713 }
2714
fpizlo@apple.com0ef43952016-12-08 22:14:50 +00002715 unsigned indexForChecks()
2716 {
2717 unsigned index = m_indexInBlock;
2718 while (!m_block->at(index)->origin.exitOK)
2719 index--;
2720 return index;
2721 }
2722
2723 NodeOrigin originForCheck(unsigned index)
2724 {
2725 return m_block->at(index)->origin.withSemantic(m_currentNode->origin.semantic);
2726 }
2727
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00002728 void speculateForBarrier(Edge value)
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00002729 {
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00002730 // Currently, the DFG won't take advantage of this speculation. But, we want to do it in
2731 // the DFG anyway because if such a speculation would be wrong, we want to know before
2732 // we do an expensive compile.
2733
2734 if (value->shouldSpeculateInt32()) {
fpizlo@apple.com0ef43952016-12-08 22:14:50 +00002735 insertCheck<Int32Use>(value.node());
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00002736 return;
fpizlo@apple.com593cd922015-05-15 21:11:39 +00002737 }
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00002738
2739 if (value->shouldSpeculateBoolean()) {
fpizlo@apple.com0ef43952016-12-08 22:14:50 +00002740 insertCheck<BooleanUse>(value.node());
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00002741 return;
2742 }
2743
2744 if (value->shouldSpeculateOther()) {
fpizlo@apple.com0ef43952016-12-08 22:14:50 +00002745 insertCheck<OtherUse>(value.node());
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00002746 return;
2747 }
2748
2749 if (value->shouldSpeculateNumber()) {
fpizlo@apple.com0ef43952016-12-08 22:14:50 +00002750 insertCheck<NumberUse>(value.node());
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00002751 return;
2752 }
2753
2754 if (value->shouldSpeculateNotCell()) {
fpizlo@apple.com0ef43952016-12-08 22:14:50 +00002755 insertCheck<NotCellUse>(value.node());
fpizlo@apple.com49b1d722015-05-18 03:39:28 +00002756 return;
2757 }
fpizlo@apple.com9ab60fa2014-09-26 22:53:20 +00002758 }
2759
2760 template<UseKind useKind>
fpizlo@apple.com0ef43952016-12-08 22:14:50 +00002761 void insertCheck(Node* node)
fpizlo@apple.com9ab60fa2014-09-26 22:53:20 +00002762 {
2763 observeUseKindOnNode<useKind>(node);
fpizlo@apple.com0ef43952016-12-08 22:14:50 +00002764 unsigned index = indexForChecks();
2765 m_insertionSet.insertNode(index, SpecNone, Check, originForCheck(index), Edge(node, useKind));
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00002766 }
2767
fpizlo@apple.com96509b72014-05-26 17:43:41 +00002768 void fixIntConvertingEdge(Edge& edge)
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00002769 {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00002770 Node* node = edge.node();
fpizlo@apple.com96509b72014-05-26 17:43:41 +00002771 if (node->shouldSpeculateInt32OrBoolean()) {
2772 fixIntOrBooleanEdge(edge);
msaboff@apple.com95894332014-01-29 19:18:54 +00002773 return;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002774 }
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00002775
fpizlo@apple.com027ed672014-01-08 00:27:06 +00002776 UseKind useKind;
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002777 if (node->shouldSpeculateAnyInt())
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00002778 useKind = Int52RepUse;
fpizlo@apple.com027ed672014-01-08 00:27:06 +00002779 else if (node->shouldSpeculateNumber())
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00002780 useKind = DoubleRepUse;
fpizlo@apple.com027ed672014-01-08 00:27:06 +00002781 else
2782 useKind = NotCellUse;
2783 Node* newNode = m_insertionSet.insertNode(
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002784 m_indexInBlock, SpecInt32Only, ValueToInt32, m_currentNode->origin,
fpizlo@apple.com027ed672014-01-08 00:27:06 +00002785 Edge(node, useKind));
2786 observeUseKindOnNode(node, useKind);
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00002787
fpizlo@apple.com027ed672014-01-08 00:27:06 +00002788 edge = Edge(newNode, KnownInt32Use);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002789 }
2790
fpizlo@apple.com96509b72014-05-26 17:43:41 +00002791 void fixIntOrBooleanEdge(Edge& edge)
2792 {
2793 Node* node = edge.node();
2794 if (!node->sawBooleans()) {
2795 fixEdge<Int32Use>(edge);
2796 return;
2797 }
2798
2799 UseKind useKind;
2800 if (node->shouldSpeculateBoolean())
2801 useKind = BooleanUse;
2802 else
2803 useKind = UntypedUse;
2804 Node* newNode = m_insertionSet.insertNode(
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002805 m_indexInBlock, SpecInt32Only, BooleanToNumber, m_currentNode->origin,
fpizlo@apple.com96509b72014-05-26 17:43:41 +00002806 Edge(node, useKind));
2807 observeUseKindOnNode(node, useKind);
2808
2809 edge = Edge(newNode, Int32Use);
fpizlo@apple.com96509b72014-05-26 17:43:41 +00002810 }
2811
2812 void fixDoubleOrBooleanEdge(Edge& edge)
2813 {
2814 Node* node = edge.node();
2815 if (!node->sawBooleans()) {
2816 fixEdge<DoubleRepUse>(edge);
2817 return;
2818 }
2819
2820 UseKind useKind;
2821 if (node->shouldSpeculateBoolean())
2822 useKind = BooleanUse;
2823 else
2824 useKind = UntypedUse;
2825 Node* newNode = m_insertionSet.insertNode(
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002826 m_indexInBlock, SpecInt32Only, BooleanToNumber, m_currentNode->origin,
fpizlo@apple.com96509b72014-05-26 17:43:41 +00002827 Edge(node, useKind));
2828 observeUseKindOnNode(node, useKind);
2829
2830 edge = Edge(newNode, DoubleRepUse);
fpizlo@apple.com96509b72014-05-26 17:43:41 +00002831 }
2832
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002833 void truncateConstantToInt32(Edge& edge)
2834 {
2835 Node* oldNode = edge.node();
2836
fpizlo@apple.comb41e6822014-07-25 20:55:17 +00002837 JSValue value = oldNode->asJSValue();
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002838 if (value.isInt32())
2839 return;
2840
2841 value = jsNumber(JSC::toInt32(value.asNumber()));
2842 ASSERT(value.isInt32());
2843 edge.setNode(m_insertionSet.insertNode(
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002844 m_indexInBlock, SpecInt32Only, JSConstant, m_currentNode->origin,
fpizlo@apple.comb41e6822014-07-25 20:55:17 +00002845 OpInfo(m_graph.freeze(value))));
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002846 }
2847
2848 void truncateConstantsIfNecessary(Node* node, AddSpeculationMode mode)
2849 {
fpizlo@apple.comefacb612013-09-10 22:16:00 +00002850 if (mode != SpeculateInt32AndTruncateConstants)
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002851 return;
2852
2853 ASSERT(node->child1()->hasConstant() || node->child2()->hasConstant());
2854 if (node->child1()->hasConstant())
2855 truncateConstantToInt32(node->child1());
2856 else
2857 truncateConstantToInt32(node->child2());
2858 }
keith_miller@apple.com6fc2fb72017-02-09 00:02:20 +00002859
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002860 bool attemptToMakeIntegerAdd(Node* node)
2861 {
fpizlo@apple.com96509b72014-05-26 17:43:41 +00002862 AddSpeculationMode mode = m_graph.addSpeculationMode(node, FixupPass);
fpizlo@apple.com6921b292013-09-18 17:14:02 +00002863 if (mode != DontSpeculateInt32) {
2864 truncateConstantsIfNecessary(node, mode);
fpizlo@apple.com96509b72014-05-26 17:43:41 +00002865 fixIntOrBooleanEdge(node->child1());
2866 fixIntOrBooleanEdge(node->child2());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +00002867 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
2868 node->setArithMode(Arith::Unchecked);
2869 else
2870 node->setArithMode(Arith::CheckOverflow);
fpizlo@apple.com6921b292013-09-18 17:14:02 +00002871 return true;
2872 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002873
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002874 if (m_graph.addShouldSpeculateAnyInt(node)) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00002875 fixEdge<Int52RepUse>(node->child1());
2876 fixEdge<Int52RepUse>(node->child2());
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +00002877 node->setArithMode(Arith::CheckOverflow);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +00002878 node->setResult(NodeResultInt52);
fpizlo@apple.com6921b292013-09-18 17:14:02 +00002879 return true;
2880 }
2881
2882 return false;
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +00002883 }
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002884
2885 bool attemptToMakeGetArrayLength(Node* node)
2886 {
2887 if (!isInt32Speculation(node->prediction()))
2888 return false;
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002889 CodeBlock* profiledBlock = m_graph.baselineCodeBlockFor(node->origin.semantic);
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002890 ArrayProfile* arrayProfile =
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002891 profiledBlock->getArrayProfile(node->origin.semantic.bytecodeIndex);
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002892 ArrayMode arrayMode = ArrayMode(Array::SelectUsingPredictions);
2893 if (arrayProfile) {
fpizlo@apple.com171d06f2016-11-15 23:21:50 +00002894 ConcurrentJSLocker locker(profiledBlock->m_lock);
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002895 arrayProfile->computeUpdatedPrediction(locker, profiledBlock);
2896 arrayMode = ArrayMode::fromObserved(locker, arrayProfile, Array::Read, false);
2897 if (arrayMode.type() == Array::Unprofiled) {
2898 // For normal array operations, it makes sense to treat Unprofiled
2899 // accesses as ForceExit and get more data rather than using
2900 // predictions and then possibly ending up with a Generic. But here,
2901 // we treat anything that is Unprofiled as Generic and keep the
2902 // GetById. I.e. ForceExit = Generic. So, there is no harm - and only
2903 // profit - from treating the Unprofiled case as
2904 // SelectUsingPredictions.
2905 arrayMode = ArrayMode(Array::SelectUsingPredictions);
2906 }
2907 }
2908
msaboff@apple.com95894332014-01-29 19:18:54 +00002909 arrayMode = arrayMode.refine(
fpizlo@apple.come079bb52014-03-05 07:41:03 +00002910 m_graph, node, node->child1()->prediction(), node->prediction());
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002911
2912 if (arrayMode.type() == Array::Generic) {
2913 // Check if the input is something that we can't get array length for, but for which we
2914 // could insert some conversions in order to transform it into something that we can do it
2915 // for.
2916 if (node->child1()->shouldSpeculateStringObject())
2917 attemptToForceStringArrayModeByToStringConversion<StringObjectUse>(arrayMode, node);
2918 else if (node->child1()->shouldSpeculateStringOrStringObject())
2919 attemptToForceStringArrayModeByToStringConversion<StringOrStringObjectUse>(arrayMode, node);
2920 }
2921
keith_miller@apple.com032f6722016-04-08 00:10:20 +00002922 if (!arrayMode.supportsSelfLength())
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002923 return false;
2924
2925 convertToGetArrayLength(node, arrayMode);
2926 return true;
2927 }
keith_miller@apple.com59bba5d2015-10-16 22:18:42 +00002928
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002929 void convertToGetArrayLength(Node* node, ArrayMode arrayMode)
2930 {
2931 node->setOp(GetArrayLength);
fpizlo@apple.comcad67682015-02-09 19:57:41 +00002932 node->clearFlags(NodeMustGenerate);
fpizlo@apple.com1c560f52013-09-12 04:48:13 +00002933 fixEdge<KnownCellUse>(node->child1());
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002934 node->setArrayMode(arrayMode);
2935
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002936 Node* storage = checkArray(arrayMode, node->origin, node->child1().node(), 0, lengthNeedsStorage);
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002937 if (!storage)
2938 return;
2939
2940 node->child2() = Edge(storage);
2941 }
2942
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002943 Node* prependGetArrayLength(NodeOrigin origin, Node* child, ArrayMode arrayMode)
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002944 {
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002945 Node* storage = checkArray(arrayMode, origin, child, 0, lengthNeedsStorage);
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002946 return m_insertionSet.insertNode(
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00002947 m_indexInBlock, SpecInt32Only, GetArrayLength, origin,
fpizlo@apple.comc09dc632013-08-17 05:50:48 +00002948 OpInfo(arrayMode.asWord()), Edge(child, KnownCellUse), Edge(storage));
2949 }
keith_miller@apple.com6fc2fb72017-02-09 00:02:20 +00002950
2951 void convertToHasIndexedProperty(Node* node)
2952 {
2953 node->setOp(HasIndexedProperty);
2954 node->clearFlags(NodeMustGenerate);
2955 node->setArrayMode(
2956 node->arrayMode().refine(
2957 m_graph, node,
2958 node->child1()->prediction(),
2959 node->child2()->prediction(),
2960 SpecNone));
2961 node->setInternalMethodType(PropertySlot::InternalMethodType::HasProperty);
2962
2963 blessArrayOperation(node->child1(), node->child2(), node->child3());
2964
2965 fixEdge<CellUse>(node->child1());
2966 fixEdge<Int32Use>(node->child2());
2967 }
2968
utatane.tea@gmail.com0d74c7c2016-11-03 03:20:53 +00002969 bool attemptToMakeCallDOM(Node* node)
2970 {
2971 if (m_graph.hasExitSite(node->origin.semantic, BadType))
2972 return false;
2973
2974 const DOMJIT::Signature* signature = node->signature();
2975 if (!signature)
2976 return false;
2977
2978 {
2979 unsigned index = 0;
2980 bool shouldConvertToCallDOM = true;
2981 m_graph.doToChildren(node, [&](Edge& edge) {
2982 // Callee. Ignore this. DFGByteCodeParser already emit appropriate checks.
2983 if (!index)
2984 return;
2985
2986 if (index == 1) {
2987 // DOM node case.
2988 if (edge->shouldSpeculateNotCell())
2989 shouldConvertToCallDOM = false;
2990 } else {
2991 switch (signature->arguments[index - 2]) {
2992 case SpecString:
2993 if (edge->shouldSpeculateNotString())
2994 shouldConvertToCallDOM = false;
2995 break;
2996 case SpecInt32Only:
2997 if (edge->shouldSpeculateNotInt32())
2998 shouldConvertToCallDOM = false;
2999 break;
3000 case SpecBoolean:
3001 if (edge->shouldSpeculateNotBoolean())
3002 shouldConvertToCallDOM = false;
3003 break;
3004 default:
3005 RELEASE_ASSERT_NOT_REACHED();
3006 break;
3007 }
3008 }
3009 ++index;
3010 });
3011 if (!shouldConvertToCallDOM)
3012 return false;
3013 }
3014
3015 Node* thisNode = m_graph.varArgChild(node, 1).node();
utatane.tea@gmail.coma5544f12017-05-19 09:23:20 +00003016 Node* checkSubClass = m_insertionSet.insertNode(m_indexInBlock, SpecNone, CheckSubClass, node->origin, OpInfo(signature->classInfo), Edge(thisNode));
utatane.tea@gmail.com0d74c7c2016-11-03 03:20:53 +00003017 node->convertToCallDOM(m_graph);
utatane.tea@gmail.coma5544f12017-05-19 09:23:20 +00003018 fixupCheckSubClass(checkSubClass);
utatane.tea@gmail.com0d74c7c2016-11-03 03:20:53 +00003019 fixupCallDOM(node);
3020 return true;
3021 }
3022
utatane.tea@gmail.coma5544f12017-05-19 09:23:20 +00003023 void fixupCheckSubClass(Node* node)
utatane.tea@gmail.com0d74c7c2016-11-03 03:20:53 +00003024 {
3025 fixEdge<CellUse>(node->child1());
3026 }
3027
3028 void fixupCallDOM(Node* node)
3029 {
3030 const DOMJIT::Signature* signature = node->signature();
3031 auto fixup = [&](Edge& edge, unsigned argumentIndex) {
3032 if (!edge)
3033 return;
3034 switch (signature->arguments[argumentIndex]) {
3035 case SpecString:
3036 fixEdge<StringUse>(edge);
3037 break;
3038 case SpecInt32Only:
3039 fixEdge<Int32Use>(edge);
3040 break;
3041 case SpecBoolean:
3042 fixEdge<BooleanUse>(edge);
3043 break;
3044 default:
3045 RELEASE_ASSERT_NOT_REACHED();
3046 break;
3047 }
3048 };
3049 fixEdge<CellUse>(node->child1()); // DOM.
3050 fixup(node->child2(), 0);
3051 fixup(node->child3(), 1);
3052 }
3053
fpizlo@apple.com10107332015-08-24 21:44:39 +00003054 void fixupChecksInBlock(BasicBlock* block)
fpizlo@apple.comd4a77bb2014-04-12 18:22:27 +00003055 {
3056 if (!block)
3057 return;
3058 ASSERT(block->isReachable);
3059 m_block = block;
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00003060 unsigned indexForChecks = UINT_MAX;
3061 NodeOrigin originForChecks;
3062 for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
3063 Node* node = block->at(indexInBlock);
3064
3065 // If this is a node at which we could exit, then save its index. If nodes after this one
3066 // cannot exit, then we will hoist checks to here.
3067 if (node->origin.exitOK) {
3068 indexForChecks = indexInBlock;
3069 originForChecks = node->origin;
3070 }
3071
3072 originForChecks = originForChecks.withSemantic(node->origin.semantic);
fpizlo@apple.com0ef43952016-12-08 22:14:50 +00003073
fpizlo@apple.com10107332015-08-24 21:44:39 +00003074 // First, try to relax the representational demands of each node, in order to have
3075 // fewer conversions.
3076 switch (node->op()) {
3077 case MovHint:
3078 case Check:
3079 m_graph.doToChildren(
3080 node,
3081 [&] (Edge& edge) {
3082 switch (edge.useKind()) {
3083 case DoubleRepUse:
3084 case DoubleRepRealUse:
3085 if (edge->hasDoubleResult())
3086 break;
3087
3088 if (edge->hasInt52Result())
3089 edge.setUseKind(Int52RepUse);
3090 else if (edge.useKind() == DoubleRepUse)
3091 edge.setUseKind(NumberUse);
3092 break;
3093
3094 case Int52RepUse:
3095 // Nothing we can really do.
3096 break;
3097
3098 case UntypedUse:
3099 case NumberUse:
3100 if (edge->hasDoubleResult())
3101 edge.setUseKind(DoubleRepUse);
3102 else if (edge->hasInt52Result())
3103 edge.setUseKind(Int52RepUse);
3104 break;
3105
3106 case RealNumberUse:
3107 if (edge->hasDoubleResult())
3108 edge.setUseKind(DoubleRepRealUse);
3109 else if (edge->hasInt52Result())
3110 edge.setUseKind(Int52RepUse);
3111 break;
3112
3113 default:
3114 break;
3115 }
3116 });
3117 break;
3118
3119 case ValueToInt32:
3120 if (node->child1().useKind() == DoubleRepUse
3121 && !node->child1()->hasDoubleResult()) {
3122 node->child1().setUseKind(NumberUse);
3123 break;
3124 }
3125 break;
3126
3127 default:
3128 break;
3129 }
3130
3131 // Now, insert type conversions if necessary.
3132 m_graph.doToChildren(
3133 node,
3134 [&] (Edge& edge) {
3135 Node* result = nullptr;
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00003136
fpizlo@apple.com10107332015-08-24 21:44:39 +00003137 switch (edge.useKind()) {
3138 case DoubleRepUse:
3139 case DoubleRepRealUse:
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00003140 case DoubleRepAnyIntUse: {
fpizlo@apple.com10107332015-08-24 21:44:39 +00003141 if (edge->hasDoubleResult())
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00003142 break;
fpizlo@apple.com10107332015-08-24 21:44:39 +00003143
3144 if (edge->isNumberConstant()) {
3145 result = m_insertionSet.insertNode(
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00003146 indexForChecks, SpecBytecodeDouble, DoubleConstant, originForChecks,
fpizlo@apple.com10107332015-08-24 21:44:39 +00003147 OpInfo(m_graph.freeze(jsDoubleNumber(edge->asNumber()))));
3148 } else if (edge->hasInt52Result()) {
3149 result = m_insertionSet.insertNode(
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00003150 indexForChecks, SpecAnyIntAsDouble, DoubleRep, originForChecks,
fpizlo@apple.com10107332015-08-24 21:44:39 +00003151 Edge(edge.node(), Int52RepUse));
3152 } else {
3153 UseKind useKind;
3154 if (edge->shouldSpeculateDoubleReal())
3155 useKind = RealNumberUse;
3156 else if (edge->shouldSpeculateNumber())
3157 useKind = NumberUse;
3158 else
3159 useKind = NotCellUse;
3160
3161 result = m_insertionSet.insertNode(
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00003162 indexForChecks, SpecBytecodeDouble, DoubleRep, originForChecks,
fpizlo@apple.com10107332015-08-24 21:44:39 +00003163 Edge(edge.node(), useKind));
3164 }
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00003165
3166 edge.setNode(result);
fpizlo@apple.com10107332015-08-24 21:44:39 +00003167 break;
3168 }
3169
3170 case Int52RepUse: {
3171 if (edge->hasInt52Result())
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00003172 break;
fpizlo@apple.com10107332015-08-24 21:44:39 +00003173
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00003174 if (edge->isAnyIntConstant()) {
fpizlo@apple.com10107332015-08-24 21:44:39 +00003175 result = m_insertionSet.insertNode(
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00003176 indexForChecks, SpecAnyInt, Int52Constant, originForChecks,
fpizlo@apple.com10107332015-08-24 21:44:39 +00003177 OpInfo(edge->constant()));
3178 } else if (edge->hasDoubleResult()) {
3179 result = m_insertionSet.insertNode(
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00003180 indexForChecks, SpecAnyInt, Int52Rep, originForChecks,
3181 Edge(edge.node(), DoubleRepAnyIntUse));
fpizlo@apple.com10107332015-08-24 21:44:39 +00003182 } else if (edge->shouldSpeculateInt32ForArithmetic()) {
3183 result = m_insertionSet.insertNode(
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00003184 indexForChecks, SpecInt32Only, Int52Rep, originForChecks,
fpizlo@apple.com10107332015-08-24 21:44:39 +00003185 Edge(edge.node(), Int32Use));
3186 } else {
3187 result = m_insertionSet.insertNode(
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00003188 indexForChecks, SpecAnyInt, Int52Rep, originForChecks,
3189 Edge(edge.node(), AnyIntUse));
fpizlo@apple.com10107332015-08-24 21:44:39 +00003190 }
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00003191
3192 edge.setNode(result);
fpizlo@apple.com10107332015-08-24 21:44:39 +00003193 break;
3194 }
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00003195
fpizlo@apple.com10107332015-08-24 21:44:39 +00003196 default: {
3197 if (!edge->hasDoubleResult() && !edge->hasInt52Result())
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00003198 break;
fpizlo@apple.com10107332015-08-24 21:44:39 +00003199
3200 if (edge->hasDoubleResult()) {
3201 result = m_insertionSet.insertNode(
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00003202 indexForChecks, SpecBytecodeDouble, ValueRep, originForChecks,
fpizlo@apple.com10107332015-08-24 21:44:39 +00003203 Edge(edge.node(), DoubleRepUse));
3204 } else {
3205 result = m_insertionSet.insertNode(
mark.lam@apple.com39e9c982016-04-25 17:48:46 +00003206 indexForChecks, SpecInt32Only | SpecAnyIntAsDouble, ValueRep,
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00003207 originForChecks, Edge(edge.node(), Int52RepUse));
fpizlo@apple.com10107332015-08-24 21:44:39 +00003208 }
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00003209
3210 edge.setNode(result);
fpizlo@apple.com10107332015-08-24 21:44:39 +00003211 break;
3212 } }
fpizlo@apple.comf29186e2015-08-26 19:24:41 +00003213
3214 // It's remotely possible that this node cannot do type checks, but we now have a
3215 // type check on this node. We don't have to handle the general form of this
3216 // problem. It only arises when ByteCodeParser emits an immediate SetLocal, rather
3217 // than a delayed one. So, we only worry about those checks that we may have put on
3218 // a SetLocal. Note that "indexForChecks != indexInBlock" is just another way of
3219 // saying "!node->origin.exitOK".
3220 if (indexForChecks != indexInBlock && mayHaveTypeCheck(edge.useKind())) {
3221 UseKind knownUseKind;
3222
3223 switch (edge.useKind()) {
3224 case Int32Use:
3225 knownUseKind = KnownInt32Use;
3226 break;
3227 case CellUse:
3228 knownUseKind = KnownCellUse;
3229 break;
3230 case BooleanUse:
3231 knownUseKind = KnownBooleanUse;
3232 break;
3233 default:
3234 // This can only arise if we have a Check node, and in that case, we can
3235 // just remove the original check.
3236 DFG_ASSERT(m_graph, node, node->op() == Check);
3237 knownUseKind = UntypedUse;
3238 break;
3239 }
3240
3241 m_insertionSet.insertNode(
3242 indexForChecks, SpecNone, Check, originForChecks, edge);
3243
3244 edge.setUseKind(knownUseKind);
3245 }
fpizlo@apple.com10107332015-08-24 21:44:39 +00003246 });
fpizlo@apple.comd4a77bb2014-04-12 18:22:27 +00003247 }
fpizlo@apple.com10107332015-08-24 21:44:39 +00003248
fpizlo@apple.comd4a77bb2014-04-12 18:22:27 +00003249 m_insertionSet.execute(block);
3250 }
3251
fpizlo@apple.comf10d0722012-12-03 09:21:22 +00003252 BasicBlock* m_block;
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +00003253 unsigned m_indexInBlock;
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00003254 Node* m_currentNode;
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +00003255 InsertionSet m_insertionSet;
fpizlo@apple.combbaf6192013-02-27 01:45:28 +00003256 bool m_profitabilityChanged;
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00003257};
3258
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +00003259bool performFixup(Graph& graph)
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00003260{
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +00003261 return runPhase<FixupPhase>(graph);
fpizlo@apple.coma73f21d2012-03-24 03:23:02 +00003262}
3263
3264} } // namespace JSC::DFG
3265
3266#endif // ENABLE(DFG_JIT)
3267