3f1c8915325c24381462838351a740ac69e62bde
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGFixupPhase.cpp
1 /*
2  * Copyright (C) 2012-2019 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "DFGFixupPhase.h"
28
29 #if ENABLE(DFG_JIT)
30
31 #include "ArrayPrototype.h"
32 #include "DFGGraph.h"
33 #include "DFGInsertionSet.h"
34 #include "DFGPhase.h"
35 #include "DFGPredictionPropagationPhase.h"
36 #include "DFGVariableAccessDataDump.h"
37 #include "JSCInlines.h"
38 #include "TypeLocation.h"
39
40 namespace JSC { namespace DFG {
41
42 class FixupPhase : public Phase {
43 public:
44     FixupPhase(Graph& graph)
45         : Phase(graph, "fixup")
46         , m_insertionSet(graph)
47     {
48     }
49     
50     bool run()
51     {
52         ASSERT(m_graph.m_fixpointState == BeforeFixpoint);
53         ASSERT(m_graph.m_form == ThreadedCPS);
54         
55         m_profitabilityChanged = false;
56         for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
57             fixupBlock(m_graph.block(blockIndex));
58         
59         while (m_profitabilityChanged) {
60             m_profitabilityChanged = false;
61             
62             for (unsigned i = m_graph.m_argumentPositions.size(); i--;)
63                 m_graph.m_argumentPositions[i].mergeArgumentUnboxingAwareness();
64             
65             for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
66                 fixupGetAndSetLocalsInBlock(m_graph.block(blockIndex));
67         }
68         
69         for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
70             fixupChecksInBlock(m_graph.block(blockIndex));
71
72         m_graph.m_planStage = PlanStage::AfterFixup;
73
74         return true;
75     }
76
77 private:
78
79     void fixupArithDivInt32(Node* node, Edge& leftChild, Edge& rightChild)
80     {
81         if (optimizeForX86() || optimizeForARM64() || optimizeForARMv7IDIVSupported()) {
82             fixIntOrBooleanEdge(leftChild);
83             fixIntOrBooleanEdge(rightChild);
84             if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
85                 node->setArithMode(Arith::Unchecked);
86             else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
87                 node->setArithMode(Arith::CheckOverflow);
88             else
89                 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
90             return;
91         }
92
93         // This will cause conversion nodes to be inserted later.
94         fixDoubleOrBooleanEdge(leftChild);
95         fixDoubleOrBooleanEdge(rightChild);
96
97         // We don't need to do ref'ing on the children because we're stealing them from
98         // the original division.
99         Node* newDivision = m_insertionSet.insertNode(m_indexInBlock, SpecBytecodeDouble, *node);
100         newDivision->setResult(NodeResultDouble);
101
102         node->setOp(DoubleAsInt32);
103         node->children.initialize(Edge(newDivision, DoubleRepUse), Edge(), Edge());
104         if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
105             node->setArithMode(Arith::CheckOverflow);
106         else
107             node->setArithMode(Arith::CheckOverflowAndNegativeZero);
108
109     }
110
111     void fixupArithPow(Node* node)
112     {
113         if (node->child2()->shouldSpeculateInt32OrBooleanForArithmetic()) {
114             fixDoubleOrBooleanEdge(node->child1());
115             fixIntOrBooleanEdge(node->child2());
116             return;
117         }
118
119         fixDoubleOrBooleanEdge(node->child1());
120         fixDoubleOrBooleanEdge(node->child2());
121     }
122
123     void fixupArithDiv(Node* node, Edge& leftChild, Edge& rightChild)
124     {
125         if (m_graph.binaryArithShouldSpeculateInt32(node, FixupPass)) {
126             fixupArithDivInt32(node, leftChild, rightChild);
127             return;
128         }
129         
130         fixDoubleOrBooleanEdge(leftChild);
131         fixDoubleOrBooleanEdge(rightChild);
132         node->setResult(NodeResultDouble);
133     }
134     
135     void fixupArithMul(Node* node, Edge& leftChild, Edge& rightChild)
136     {
137         if (m_graph.binaryArithShouldSpeculateInt32(node, FixupPass)) {
138             fixIntOrBooleanEdge(leftChild);
139             fixIntOrBooleanEdge(rightChild);
140             if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
141                 node->setArithMode(Arith::Unchecked);
142             else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()) || leftChild.node() == rightChild.node())
143                 node->setArithMode(Arith::CheckOverflow);
144             else
145                 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
146             return;
147         }
148         if (m_graph.binaryArithShouldSpeculateInt52(node, FixupPass)) {
149             fixEdge<Int52RepUse>(leftChild);
150             fixEdge<Int52RepUse>(rightChild);
151             if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()) || leftChild.node() == rightChild.node())
152                 node->setArithMode(Arith::CheckOverflow);
153             else
154                 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
155             node->setResult(NodeResultInt52);
156             return;
157         }
158
159         fixDoubleOrBooleanEdge(leftChild);
160         fixDoubleOrBooleanEdge(rightChild);
161         node->setResult(NodeResultDouble);
162     }
163
164     void fixupBlock(BasicBlock* block)
165     {
166         if (!block)
167             return;
168         ASSERT(block->isReachable);
169         m_block = block;
170         for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
171             m_currentNode = block->at(m_indexInBlock);
172             fixupNode(m_currentNode);
173         }
174         m_insertionSet.execute(block);
175     }
176     
177     void fixupNode(Node* node)
178     {
179         NodeType op = node->op();
180
181         switch (op) {
182         case SetLocal: {
183             // This gets handled by fixupGetAndSetLocalsInBlock().
184             return;
185         }
186
187         case ValueSub: {
188             Edge& child1 = node->child1();
189             Edge& child2 = node->child2();
190
191             if (Node::shouldSpeculateBigInt(child1.node(), child2.node())) {
192                 fixEdge<BigIntUse>(child1);
193                 fixEdge<BigIntUse>(child2);
194                 break; 
195             }
196             
197             if (Node::shouldSpeculateUntypedForArithmetic(node->child1().node(), node->child2().node())) {
198                 fixEdge<UntypedUse>(child1);
199                 fixEdge<UntypedUse>(child2);
200                 break;
201             }
202
203             if (attemptToMakeIntegerAdd(node)) {
204                 // FIXME: Clear ArithSub's NodeMustGenerate when ArithMode is unchecked
205                 // https://bugs.webkit.org/show_bug.cgi?id=190607
206                 node->setOp(ArithSub);
207                 break;
208             }
209
210             fixDoubleOrBooleanEdge(node->child1());
211             fixDoubleOrBooleanEdge(node->child2());
212             node->setOp(ArithSub);
213             node->setResult(NodeResultDouble);
214
215             break;
216         }
217
218         case ValueBitLShift:
219         case ValueBitRShift:
220         case ValueBitXor:
221         case ValueBitOr:
222         case ValueBitAnd: {
223             if (Node::shouldSpeculateBigInt(node->child1().node(), node->child2().node())) {
224                 fixEdge<BigIntUse>(node->child1());
225                 fixEdge<BigIntUse>(node->child2());
226                 node->clearFlags(NodeMustGenerate);
227                 break;
228             }
229
230             if (Node::shouldSpeculateUntypedForBitOps(node->child1().node(), node->child2().node())) {
231                 fixEdge<UntypedUse>(node->child1());
232                 fixEdge<UntypedUse>(node->child2());
233                 break;
234             }
235             
236             switch (op) {
237             case ValueBitXor:
238                 node->setOp(ArithBitXor);
239                 break;
240             case ValueBitOr:
241                 node->setOp(ArithBitOr);
242                 break;
243             case ValueBitAnd:
244                 node->setOp(ArithBitAnd);
245                 break;
246             case ValueBitLShift:
247                 node->setOp(ArithBitLShift);
248                 break;
249             case ValueBitRShift:
250                 node->setOp(ArithBitRShift);
251                 break;
252             default:
253                 DFG_CRASH(m_graph, node, "Unexpected node during ValueBit operation fixup");
254                 break;
255             }
256
257             node->clearFlags(NodeMustGenerate);
258             node->setResult(NodeResultInt32);
259             fixIntConvertingEdge(node->child1());
260             fixIntConvertingEdge(node->child2());
261             break;
262         }
263
264         case ValueBitNot: {
265             Edge& operandEdge = node->child1();
266
267             if (operandEdge.node()->shouldSpeculateBigInt()) {
268                 node->clearFlags(NodeMustGenerate);
269                 fixEdge<BigIntUse>(operandEdge);
270             } else if (operandEdge.node()->shouldSpeculateUntypedForBitOps())
271                 fixEdge<UntypedUse>(operandEdge);
272             else {
273                 node->setOp(ArithBitNot);
274                 node->setResult(NodeResultInt32);
275                 node->clearFlags(NodeMustGenerate);
276                 fixIntConvertingEdge(operandEdge);
277             }
278             break;
279         }
280
281         case ArithBitNot: {
282             Edge& operandEdge = node->child1();
283
284             fixIntConvertingEdge(operandEdge);
285             break;
286         }
287
288         case ArithBitRShift:
289         case ArithBitLShift: 
290         case ArithBitXor:
291         case ArithBitOr:
292         case ArithBitAnd: {
293             fixIntConvertingEdge(node->child1());
294             fixIntConvertingEdge(node->child2());
295             break;
296         }
297
298         case BitURShift: {
299             if (Node::shouldSpeculateUntypedForBitOps(node->child1().node(), node->child2().node())) {
300                 fixEdge<UntypedUse>(node->child1());
301                 fixEdge<UntypedUse>(node->child2());
302                 break;
303             }
304             fixIntConvertingEdge(node->child1());
305             fixIntConvertingEdge(node->child2());
306             break;
307         }
308
309         case ArithIMul: {
310             fixIntConvertingEdge(node->child1());
311             fixIntConvertingEdge(node->child2());
312             node->setOp(ArithMul);
313             node->setArithMode(Arith::Unchecked);
314             node->child1().setUseKind(Int32Use);
315             node->child2().setUseKind(Int32Use);
316             break;
317         }
318
319         case ArithClz32: {
320             if (node->child1()->shouldSpeculateNotCell()) {
321                 fixIntConvertingEdge(node->child1());
322                 node->clearFlags(NodeMustGenerate);
323             } else
324                 fixEdge<UntypedUse>(node->child1());
325             break;
326         }
327             
328         case UInt32ToNumber: {
329             fixIntConvertingEdge(node->child1());
330             if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
331                 node->convertToIdentity();
332             else if (node->canSpeculateInt32(FixupPass))
333                 node->setArithMode(Arith::CheckOverflow);
334             else {
335                 node->setArithMode(Arith::DoOverflow);
336                 node->setResult(enableInt52() ? NodeResultInt52 : NodeResultDouble);
337             }
338             break;
339         }
340
341         case ValueNegate: {
342             if (node->child1()->shouldSpeculateInt32OrBoolean() && node->canSpeculateInt32(FixupPass)) {
343                 node->setOp(ArithNegate);
344                 fixIntOrBooleanEdge(node->child1());
345                 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
346                     node->setArithMode(Arith::Unchecked);
347                 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
348                     node->setArithMode(Arith::CheckOverflow);
349                 else
350                     node->setArithMode(Arith::CheckOverflowAndNegativeZero);
351                 node->setResult(NodeResultInt32);
352                 node->clearFlags(NodeMustGenerate);
353                 break;
354             }
355             
356             if (m_graph.unaryArithShouldSpeculateInt52(node, FixupPass)) {
357                 node->setOp(ArithNegate);
358                 fixEdge<Int52RepUse>(node->child1());
359                 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
360                     node->setArithMode(Arith::CheckOverflow);
361                 else
362                     node->setArithMode(Arith::CheckOverflowAndNegativeZero);
363                 node->setResult(NodeResultInt52);
364                 node->clearFlags(NodeMustGenerate);
365                 break;
366             }
367             if (node->child1()->shouldSpeculateNotCell()) {
368                 node->setOp(ArithNegate);
369                 fixDoubleOrBooleanEdge(node->child1());
370                 node->setResult(NodeResultDouble);
371                 node->clearFlags(NodeMustGenerate);
372             } else {
373                 fixEdge<UntypedUse>(node->child1());
374                 node->setResult(NodeResultJS);
375             }
376             break;
377         }
378
379         case ValueAdd: {
380             if (attemptToMakeIntegerAdd(node)) {
381                 node->setOp(ArithAdd);
382                 break;
383             }
384             if (Node::shouldSpeculateNumberOrBooleanExpectingDefined(node->child1().node(), node->child2().node())) {
385                 fixDoubleOrBooleanEdge(node->child1());
386                 fixDoubleOrBooleanEdge(node->child2());
387                 node->setOp(ArithAdd);
388                 node->setResult(NodeResultDouble);
389                 break;
390             }
391             
392             if (attemptToMakeFastStringAdd(node))
393                 break;
394
395             Edge& child1 = node->child1();
396             Edge& child2 = node->child2();
397             if (child1->shouldSpeculateString() || child2->shouldSpeculateString()) {
398                 if (child1->shouldSpeculateInt32() || child2->shouldSpeculateInt32()) {
399                     auto convertString = [&](Node* node, Edge& edge) {
400                         if (edge->shouldSpeculateInt32())
401                             convertStringAddUse<Int32Use>(node, edge);
402                         else {
403                             ASSERT(edge->shouldSpeculateString());
404                             convertStringAddUse<StringUse>(node, edge);
405                         }
406                     };
407                     convertString(node, child1);
408                     convertString(node, child2);
409                     convertToMakeRope(node);
410                     break;
411                 }
412             }
413
414             if (Node::shouldSpeculateBigInt(child1.node(), child2.node())) {
415                 fixEdge<BigIntUse>(child1);
416                 fixEdge<BigIntUse>(child2);
417             } else {
418                 fixEdge<UntypedUse>(child1);
419                 fixEdge<UntypedUse>(child2);
420             }
421
422             node->setResult(NodeResultJS);
423             break;
424         }
425
426         case StrCat: {
427             if (attemptToMakeFastStringAdd(node))
428                 break;
429
430             // FIXME: Remove empty string arguments and possibly turn this into a ToString operation. That
431             // would require a form of ToString that takes a KnownPrimitiveUse. This is necessary because
432             // the implementation of StrCat doesn't dynamically optimize for empty strings.
433             // https://bugs.webkit.org/show_bug.cgi?id=148540
434             m_graph.doToChildren(
435                 node,
436                 [&] (Edge& edge) {
437                     fixEdge<KnownPrimitiveUse>(edge);
438                     // StrCat automatically coerces the values into strings before concatenating them.
439                     // The ECMA spec says that we're not allowed to automatically coerce a Symbol into
440                     // a string. If a Symbol is encountered, a TypeError will be thrown. As a result,
441                     // our runtime functions for this slow path expect that they will never be passed
442                     // Symbols.
443                     m_insertionSet.insertNode(
444                         m_indexInBlock, SpecNone, Check, node->origin,
445                         Edge(edge.node(), NotSymbolUse));
446                 });
447             break;
448         }
449             
450         case MakeRope: {
451             fixupMakeRope(node);
452             break;
453         }
454             
455         case ArithAdd:
456         case ArithSub: {
457             // FIXME: Clear ArithSub's NodeMustGenerate when ArithMode is unchecked
458             // https://bugs.webkit.org/show_bug.cgi?id=190607
459             if (attemptToMakeIntegerAdd(node))
460                 break;
461             fixDoubleOrBooleanEdge(node->child1());
462             fixDoubleOrBooleanEdge(node->child2());
463             node->setResult(NodeResultDouble);
464             break;
465         }
466             
467         case ArithNegate: {
468             if (node->child1()->shouldSpeculateInt32OrBoolean() && node->canSpeculateInt32(FixupPass)) {
469                 fixIntOrBooleanEdge(node->child1());
470                 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
471                     node->setArithMode(Arith::Unchecked);
472                 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
473                     node->setArithMode(Arith::CheckOverflow);
474                 else
475                     node->setArithMode(Arith::CheckOverflowAndNegativeZero);
476                 node->setResult(NodeResultInt32);
477                 node->clearFlags(NodeMustGenerate);
478                 break;
479             }
480             if (m_graph.unaryArithShouldSpeculateInt52(node, FixupPass)) {
481                 fixEdge<Int52RepUse>(node->child1());
482                 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
483                     node->setArithMode(Arith::CheckOverflow);
484                 else
485                     node->setArithMode(Arith::CheckOverflowAndNegativeZero);
486                 node->setResult(NodeResultInt52);
487                 node->clearFlags(NodeMustGenerate);
488                 break;
489             }
490
491             fixDoubleOrBooleanEdge(node->child1());
492             node->setResult(NodeResultDouble);
493             node->clearFlags(NodeMustGenerate);
494             break;
495         }
496
497         case ValueMul: {
498             Edge& leftChild = node->child1();
499             Edge& rightChild = node->child2();
500
501             if (Node::shouldSpeculateBigInt(leftChild.node(), rightChild.node())) {
502                 fixEdge<BigIntUse>(node->child1());
503                 fixEdge<BigIntUse>(node->child2());
504                 node->clearFlags(NodeMustGenerate);
505                 break;
506             }
507
508             // There are cases where we can have BigInt + Int32 operands reaching ValueMul.
509             // Imagine the scenario where ValueMul was never executed, but we can predict types
510             // reaching the node:
511             //
512             // 63: GetLocal(Check:Untyped:@72, JS|MustGen, NonBoolInt32, ...)  predicting NonBoolInt32
513             // 64: GetLocal(Check:Untyped:@71, JS|MustGen, BigInt, ...)  predicting BigInt
514             // 65: ValueMul(Check:Untyped:@63, Check:Untyped:@64, BigInt|BoolInt32|NonBoolInt32, ...)
515             // 
516             // In such scenario, we need to emit ValueMul(Untyped, Untyped), so the runtime can throw 
517             // an exception whenever it gets excuted.
518             if (Node::shouldSpeculateUntypedForArithmetic(leftChild.node(), rightChild.node())) {
519                 fixEdge<UntypedUse>(leftChild);
520                 fixEdge<UntypedUse>(rightChild);
521                 break;
522             }
523
524             // At this point, all other possible specializations are only handled by ArithMul.
525             node->setOp(ArithMul);
526             node->setResult(NodeResultNumber);
527             fixupArithMul(node, leftChild, rightChild);
528             break;
529         }
530
531         case ArithMul: {
532             Edge& leftChild = node->child1();
533             Edge& rightChild = node->child2();
534
535             fixupArithMul(node, leftChild, rightChild);
536             break;
537         }
538
539         case ValueMod: 
540         case ValueDiv: {
541             Edge& leftChild = node->child1();
542             Edge& rightChild = node->child2();
543
544             if (Node::shouldSpeculateBigInt(leftChild.node(), rightChild.node())) {
545                 fixEdge<BigIntUse>(leftChild);
546                 fixEdge<BigIntUse>(rightChild);
547                 node->clearFlags(NodeMustGenerate);
548                 break; 
549             }
550
551             if (Node::shouldSpeculateUntypedForArithmetic(leftChild.node(), rightChild.node())) {
552                 fixEdge<UntypedUse>(leftChild);
553                 fixEdge<UntypedUse>(rightChild);
554                 break;
555             }
556
557             if (op == ValueDiv)
558                 node->setOp(ArithDiv);
559             else
560                 node->setOp(ArithMod);
561
562             node->setResult(NodeResultNumber);
563             fixupArithDiv(node, leftChild, rightChild);
564             break;
565
566         }
567
568         case ArithDiv:
569         case ArithMod: {
570             Edge& leftChild = node->child1();
571             Edge& rightChild = node->child2();
572
573             fixupArithDiv(node, leftChild, rightChild);
574             break;
575         }
576             
577         case ArithMin:
578         case ArithMax: {
579             if (m_graph.binaryArithShouldSpeculateInt32(node, FixupPass)) {
580                 fixIntOrBooleanEdge(node->child1());
581                 fixIntOrBooleanEdge(node->child2());
582                 break;
583             }
584             fixDoubleOrBooleanEdge(node->child1());
585             fixDoubleOrBooleanEdge(node->child2());
586             node->setResult(NodeResultDouble);
587             break;
588         }
589             
590         case ArithAbs: {
591             if (node->child1()->shouldSpeculateInt32OrBoolean()
592                 && node->canSpeculateInt32(FixupPass)) {
593                 fixIntOrBooleanEdge(node->child1());
594                 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
595                     node->setArithMode(Arith::Unchecked);
596                 else
597                     node->setArithMode(Arith::CheckOverflow);
598                 node->clearFlags(NodeMustGenerate);
599                 node->setResult(NodeResultInt32);
600                 break;
601             }
602
603             if (node->child1()->shouldSpeculateNotCell()) {
604                 fixDoubleOrBooleanEdge(node->child1());
605                 node->clearFlags(NodeMustGenerate);
606             } else
607                 fixEdge<UntypedUse>(node->child1());
608             node->setResult(NodeResultDouble);
609             break;
610         }
611
612         case ValuePow: {
613             if (Node::shouldSpeculateBigInt(node->child1().node(), node->child2().node())) {
614                 fixEdge<BigIntUse>(node->child1());
615                 fixEdge<BigIntUse>(node->child2());
616                 node->clearFlags(NodeMustGenerate);
617                 break;
618             }
619
620             if (Node::shouldSpeculateUntypedForArithmetic(node->child1().node(), node->child2().node())) {
621                 fixEdge<UntypedUse>(node->child1());
622                 fixEdge<UntypedUse>(node->child2());
623                 break;
624             }
625
626             node->setOp(ArithPow);
627             node->clearFlags(NodeMustGenerate);
628             node->setResult(NodeResultDouble);
629
630             fixupArithPow(node);
631             break;
632         }
633
634         case ArithPow: {
635             fixupArithPow(node);
636             break;
637         }
638
639         case ArithRandom: {
640             node->setResult(NodeResultDouble);
641             break;
642         }
643
644         case ArithRound:
645         case ArithFloor:
646         case ArithCeil:
647         case ArithTrunc: {
648             if (node->child1()->shouldSpeculateInt32OrBoolean() && m_graph.roundShouldSpeculateInt32(node, FixupPass)) {
649                 fixIntOrBooleanEdge(node->child1());
650                 insertCheck<Int32Use>(node->child1().node());
651                 node->convertToIdentity();
652                 break;
653             }
654             if (node->child1()->shouldSpeculateNotCell()) {
655                 fixDoubleOrBooleanEdge(node->child1());
656
657                 if (isInt32OrBooleanSpeculation(node->getHeapPrediction()) && m_graph.roundShouldSpeculateInt32(node, FixupPass)) {
658                     node->setResult(NodeResultInt32);
659                     if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
660                         node->setArithRoundingMode(Arith::RoundingMode::Int32);
661                     else
662                         node->setArithRoundingMode(Arith::RoundingMode::Int32WithNegativeZeroCheck);
663                 } else {
664                     node->setResult(NodeResultDouble);
665                     node->setArithRoundingMode(Arith::RoundingMode::Double);
666                 }
667                 node->clearFlags(NodeMustGenerate);
668             } else
669                 fixEdge<UntypedUse>(node->child1());
670             break;
671         }
672
673         case ArithFRound:
674         case ArithSqrt:
675         case ArithUnary: {
676             Edge& child1 = node->child1();
677             if (child1->shouldSpeculateNotCell()) {
678                 fixDoubleOrBooleanEdge(child1);
679                 node->clearFlags(NodeMustGenerate);
680             } else
681                 fixEdge<UntypedUse>(child1);
682             break;
683         }
684             
685         case LogicalNot: {
686             if (node->child1()->shouldSpeculateBoolean()) {
687                 if (node->child1()->result() == NodeResultBoolean) {
688                     // This is necessary in case we have a bytecode instruction implemented by:
689                     //
690                     // a: CompareEq(...)
691                     // b: LogicalNot(@a)
692                     //
693                     // In that case, CompareEq might have a side-effect. Then, we need to make
694                     // sure that we know that Branch does not exit.
695                     fixEdge<KnownBooleanUse>(node->child1());
696                 } else
697                     fixEdge<BooleanUse>(node->child1());
698             } else if (node->child1()->shouldSpeculateObjectOrOther())
699                 fixEdge<ObjectOrOtherUse>(node->child1());
700             else if (node->child1()->shouldSpeculateInt32OrBoolean())
701                 fixIntOrBooleanEdge(node->child1());
702             else if (node->child1()->shouldSpeculateNumber())
703                 fixEdge<DoubleRepUse>(node->child1());
704             else if (node->child1()->shouldSpeculateString())
705                 fixEdge<StringUse>(node->child1());
706             else if (node->child1()->shouldSpeculateStringOrOther())
707                 fixEdge<StringOrOtherUse>(node->child1());
708             else {
709                 WatchpointSet* masqueradesAsUndefinedWatchpoint = m_graph.globalObjectFor(node->origin.semantic)->masqueradesAsUndefinedWatchpoint();
710                 if (masqueradesAsUndefinedWatchpoint->isStillValid())
711                     m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
712             }
713             break;
714         }
715
716         case CompareEq:
717         case CompareLess:
718         case CompareLessEq:
719         case CompareGreater:
720         case CompareGreaterEq: {
721             if (node->op() == CompareEq
722                 && Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
723                 fixEdge<BooleanUse>(node->child1());
724                 fixEdge<BooleanUse>(node->child2());
725                 node->clearFlags(NodeMustGenerate);
726                 break;
727             }
728             if (Node::shouldSpeculateInt32OrBoolean(node->child1().node(), node->child2().node())) {
729                 fixIntOrBooleanEdge(node->child1());
730                 fixIntOrBooleanEdge(node->child2());
731                 node->clearFlags(NodeMustGenerate);
732                 break;
733             }
734             if (Node::shouldSpeculateInt52(node->child1().node(), node->child2().node())) {
735                 fixEdge<Int52RepUse>(node->child1());
736                 fixEdge<Int52RepUse>(node->child2());
737                 node->clearFlags(NodeMustGenerate);
738                 break;
739             }
740             if (Node::shouldSpeculateNumberOrBoolean(node->child1().node(), node->child2().node())) {
741                 fixDoubleOrBooleanEdge(node->child1());
742                 fixDoubleOrBooleanEdge(node->child2());
743             }
744             if (node->op() != CompareEq
745                 && node->child1()->shouldSpeculateNotCell()
746                 && node->child2()->shouldSpeculateNotCell()) {
747                 if (node->child1()->shouldSpeculateNumberOrBoolean())
748                     fixDoubleOrBooleanEdge(node->child1());
749                 else
750                     fixEdge<DoubleRepUse>(node->child1());
751                 if (node->child2()->shouldSpeculateNumberOrBoolean())
752                     fixDoubleOrBooleanEdge(node->child2());
753                 else
754                     fixEdge<DoubleRepUse>(node->child2());
755                 node->clearFlags(NodeMustGenerate);
756                 break;
757             }
758             if (node->child1()->shouldSpeculateStringIdent() && node->child2()->shouldSpeculateStringIdent()) {
759                 fixEdge<StringIdentUse>(node->child1());
760                 fixEdge<StringIdentUse>(node->child2());
761                 node->clearFlags(NodeMustGenerate);
762                 break;
763             }
764             if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && GPRInfo::numberOfRegisters >= 7) {
765                 fixEdge<StringUse>(node->child1());
766                 fixEdge<StringUse>(node->child2());
767                 node->clearFlags(NodeMustGenerate);
768                 break;
769             }
770
771             if (node->op() != CompareEq)
772                 break;
773             if (Node::shouldSpeculateSymbol(node->child1().node(), node->child2().node())) {
774                 fixEdge<SymbolUse>(node->child1());
775                 fixEdge<SymbolUse>(node->child2());
776                 node->clearFlags(NodeMustGenerate);
777                 break;
778             }
779             if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
780                 fixEdge<ObjectUse>(node->child1());
781                 fixEdge<ObjectUse>(node->child2());
782                 node->clearFlags(NodeMustGenerate);
783                 break;
784             }
785
786             // If either child can be proved to be Null or Undefined, comparing them is greatly simplified.
787             bool oneArgumentIsUsedAsSpecOther = false;
788             if (node->child1()->isUndefinedOrNullConstant()) {
789                 fixEdge<KnownOtherUse>(node->child1());
790                 oneArgumentIsUsedAsSpecOther = true;
791             } else if (node->child1()->shouldSpeculateOther()) {
792                 m_insertionSet.insertNode(m_indexInBlock, SpecNone, Check, node->origin,
793                     Edge(node->child1().node(), OtherUse));
794                 fixEdge<KnownOtherUse>(node->child1());
795                 oneArgumentIsUsedAsSpecOther = true;
796             }
797             if (node->child2()->isUndefinedOrNullConstant()) {
798                 fixEdge<KnownOtherUse>(node->child2());
799                 oneArgumentIsUsedAsSpecOther = true;
800             } else if (node->child2()->shouldSpeculateOther()) {
801                 m_insertionSet.insertNode(m_indexInBlock, SpecNone, Check, node->origin,
802                     Edge(node->child2().node(), OtherUse));
803                 fixEdge<KnownOtherUse>(node->child2());
804                 oneArgumentIsUsedAsSpecOther = true;
805             }
806             if (oneArgumentIsUsedAsSpecOther) {
807                 node->clearFlags(NodeMustGenerate);
808                 break;
809             }
810
811             if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObjectOrOther()) {
812                 fixEdge<ObjectUse>(node->child1());
813                 fixEdge<ObjectOrOtherUse>(node->child2());
814                 node->clearFlags(NodeMustGenerate);
815                 break;
816             }
817             if (node->child1()->shouldSpeculateObjectOrOther() && node->child2()->shouldSpeculateObject()) {
818                 fixEdge<ObjectOrOtherUse>(node->child1());
819                 fixEdge<ObjectUse>(node->child2());
820                 node->clearFlags(NodeMustGenerate);
821                 break;
822             }
823
824             break;
825         }
826             
827         case CompareStrictEq:
828         case SameValue: {
829             fixupCompareStrictEqAndSameValue(node);
830             break;
831         }
832
833         case StringFromCharCode:
834             if (node->child1()->shouldSpeculateInt32()) {
835                 fixEdge<Int32Use>(node->child1());
836                 node->clearFlags(NodeMustGenerate);
837             } else
838                 fixEdge<UntypedUse>(node->child1());
839             break;
840
841         case StringCharAt:
842         case StringCharCodeAt:
843         case StringCodePointAt: {
844             // Currently we have no good way of refining these.
845             ASSERT(node->arrayMode() == ArrayMode(Array::String, Array::Read));
846             blessArrayOperation(node->child1(), node->child2(), node->child3());
847             fixEdge<KnownStringUse>(node->child1());
848             fixEdge<Int32Use>(node->child2());
849             break;
850         }
851
852         case GetByVal: {
853             if (!node->prediction()) {
854                 m_insertionSet.insertNode(
855                     m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
856             }
857             
858             node->setArrayMode(
859                 node->arrayMode().refine(
860                     m_graph, node,
861                     m_graph.varArgChild(node, 0)->prediction(),
862                     m_graph.varArgChild(node, 1)->prediction(),
863                     SpecNone));
864             
865             blessArrayOperation(m_graph.varArgChild(node, 0), m_graph.varArgChild(node, 1), m_graph.varArgChild(node, 2));
866             
867             ArrayMode arrayMode = node->arrayMode();
868             switch (arrayMode.type()) {
869             case Array::Contiguous:
870             case Array::Double:
871                 if (arrayMode.isJSArrayWithOriginalStructure() && arrayMode.speculation() == Array::InBounds) {
872                     // Check if SaneChain will work on a per-type basis. Note that:
873                     //
874                     // 1) We don't want double arrays to sometimes return undefined, since
875                     // that would require a change to the return type and it would pessimise
876                     // things a lot. So, we'd only want to do that if we actually had
877                     // evidence that we could read from a hole. That's pretty annoying.
878                     // Likely the best way to handle that case is with an equivalent of
879                     // SaneChain for OutOfBounds. For now we just detect when Undefined and
880                     // NaN are indistinguishable according to backwards propagation, and just
881                     // use SaneChain in that case. This happens to catch a lot of cases.
882                     //
883                     // 2) We don't want int32 array loads to have to do a hole check just to
884                     // coerce to Undefined, since that would mean twice the checks.
885                     //
886                     // This has two implications. First, we have to do more checks than we'd
887                     // like. It's unfortunate that we have to do the hole check. Second,
888                     // some accesses that hit a hole will now need to take the full-blown
889                     // out-of-bounds slow path. We can fix that with:
890                     // https://bugs.webkit.org/show_bug.cgi?id=144668
891                     
892                     bool canDoSaneChain = false;
893                     switch (arrayMode.type()) {
894                     case Array::Contiguous:
895                         // This is happens to be entirely natural. We already would have
896                         // returned any JSValue, and now we'll return Undefined. We still do
897                         // the check but it doesn't require taking any kind of slow path.
898                         canDoSaneChain = true;
899                         break;
900                         
901                     case Array::Double:
902                         if (!(node->flags() & NodeBytecodeUsesAsOther)) {
903                             // Holes look like NaN already, so if the user doesn't care
904                             // about the difference between Undefined and NaN then we can
905                             // do this.
906                             canDoSaneChain = true;
907                         }
908                         break;
909                         
910                     default:
911                         break;
912                     }
913                     
914                     if (canDoSaneChain) {
915                         JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
916                         Structure* arrayPrototypeStructure = globalObject->arrayPrototype()->structure(vm());
917                         Structure* objectPrototypeStructure = globalObject->objectPrototype()->structure(vm());
918                         if (arrayPrototypeStructure->transitionWatchpointSetIsStillValid()
919                             && objectPrototypeStructure->transitionWatchpointSetIsStillValid()
920                             && globalObject->arrayPrototypeChainIsSane()) {
921                             m_graph.registerAndWatchStructureTransition(arrayPrototypeStructure);
922                             m_graph.registerAndWatchStructureTransition(objectPrototypeStructure);
923                             node->setArrayMode(arrayMode.withSpeculation(Array::SaneChain));
924                         }
925                     }
926                 }
927                 break;
928                 
929             case Array::String:
930                 if ((node->prediction() & ~SpecString)
931                     || m_graph.hasExitSite(node->origin.semantic, OutOfBounds))
932                     node->setArrayMode(arrayMode.withSpeculation(Array::OutOfBounds));
933                 break;
934                 
935             default:
936                 break;
937             }
938             
939             arrayMode = node->arrayMode();
940             switch (arrayMode.type()) {
941             case Array::SelectUsingPredictions:
942             case Array::Unprofiled:
943                 RELEASE_ASSERT_NOT_REACHED();
944                 break;
945             case Array::Generic:
946                 if (m_graph.varArgChild(node, 0)->shouldSpeculateObject()) {
947                     if (m_graph.varArgChild(node, 1)->shouldSpeculateString()) {
948                         fixEdge<ObjectUse>(m_graph.varArgChild(node, 0));
949                         fixEdge<StringUse>(m_graph.varArgChild(node, 1));
950                         break;
951                     }
952
953                     if (m_graph.varArgChild(node, 1)->shouldSpeculateSymbol()) {
954                         fixEdge<ObjectUse>(m_graph.varArgChild(node, 0));
955                         fixEdge<SymbolUse>(m_graph.varArgChild(node, 1));
956                         break;
957                     }
958                 }
959 #if USE(JSVALUE32_64)
960                 fixEdge<CellUse>(m_graph.varArgChild(node, 0)); // Speculating cell due to register pressure on 32-bit.
961 #endif
962                 break;
963             case Array::ForceExit:
964                 break;
965             case Array::String:
966                 fixEdge<KnownStringUse>(m_graph.varArgChild(node, 0));
967                 fixEdge<Int32Use>(m_graph.varArgChild(node, 1));
968                 break;
969             default:
970                 fixEdge<KnownCellUse>(m_graph.varArgChild(node, 0));
971                 fixEdge<Int32Use>(m_graph.varArgChild(node, 1));
972                 break;
973             }
974             
975             switch (arrayMode.type()) {
976             case Array::Double:
977                 if (!arrayMode.isOutOfBounds())
978                     node->setResult(NodeResultDouble);
979                 break;
980                 
981             case Array::Float32Array:
982             case Array::Float64Array:
983                 node->setResult(NodeResultDouble);
984                 break;
985                 
986             case Array::Uint32Array:
987                 if (node->shouldSpeculateInt32())
988                     break;
989                 if (node->shouldSpeculateInt52())
990                     node->setResult(NodeResultInt52);
991                 else
992                     node->setResult(NodeResultDouble);
993                 break;
994                 
995             default:
996                 break;
997             }
998             
999             break;
1000         }
1001
1002         case PutByValDirect:
1003         case PutByVal:
1004         case PutByValAlias: {
1005             Edge& child1 = m_graph.varArgChild(node, 0);
1006             Edge& child2 = m_graph.varArgChild(node, 1);
1007             Edge& child3 = m_graph.varArgChild(node, 2);
1008
1009             node->setArrayMode(
1010                 node->arrayMode().refine(
1011                     m_graph, node,
1012                     child1->prediction(),
1013                     child2->prediction(),
1014                     child3->prediction()));
1015             
1016             blessArrayOperation(child1, child2, m_graph.varArgChild(node, 3));
1017             
1018             switch (node->arrayMode().modeForPut().type()) {
1019             case Array::SelectUsingPredictions:
1020             case Array::SelectUsingArguments:
1021             case Array::Unprofiled:
1022             case Array::Undecided:
1023                 RELEASE_ASSERT_NOT_REACHED();
1024                 break;
1025             case Array::ForceExit:
1026             case Array::Generic:
1027                 if (child1->shouldSpeculateCell()) {
1028                     if (child2->shouldSpeculateString()) {
1029                         fixEdge<CellUse>(child1);
1030                         fixEdge<StringUse>(child2);
1031                         break;
1032                     }
1033
1034                     if (child2->shouldSpeculateSymbol()) {
1035                         fixEdge<CellUse>(child1);
1036                         fixEdge<SymbolUse>(child2);
1037                         break;
1038                     }
1039                 }
1040 #if USE(JSVALUE32_64)
1041                 // Due to register pressure on 32-bit, we speculate cell and
1042                 // ignore the base-is-not-cell case entirely by letting the
1043                 // baseline JIT handle it.
1044                 fixEdge<CellUse>(child1);
1045 #endif
1046                 break;
1047             case Array::Int32:
1048                 fixEdge<KnownCellUse>(child1);
1049                 fixEdge<Int32Use>(child2);
1050                 fixEdge<Int32Use>(child3);
1051                 break;
1052             case Array::Double:
1053                 fixEdge<KnownCellUse>(child1);
1054                 fixEdge<Int32Use>(child2);
1055                 fixEdge<DoubleRepRealUse>(child3);
1056                 break;
1057             case Array::Int8Array:
1058             case Array::Int16Array:
1059             case Array::Int32Array:
1060             case Array::Uint8Array:
1061             case Array::Uint8ClampedArray:
1062             case Array::Uint16Array:
1063             case Array::Uint32Array:
1064                 fixEdge<KnownCellUse>(child1);
1065                 fixEdge<Int32Use>(child2);
1066                 if (child3->shouldSpeculateInt32())
1067                     fixIntOrBooleanEdge(child3);
1068                 else if (child3->shouldSpeculateInt52())
1069                     fixEdge<Int52RepUse>(child3);
1070                 else
1071                     fixDoubleOrBooleanEdge(child3);
1072                 break;
1073             case Array::Float32Array:
1074             case Array::Float64Array:
1075                 fixEdge<KnownCellUse>(child1);
1076                 fixEdge<Int32Use>(child2);
1077                 fixDoubleOrBooleanEdge(child3);
1078                 break;
1079             case Array::Contiguous:
1080             case Array::ArrayStorage:
1081             case Array::SlowPutArrayStorage:
1082                 fixEdge<KnownCellUse>(child1);
1083                 fixEdge<Int32Use>(child2);
1084                 speculateForBarrier(child3);
1085                 break;
1086             default:
1087                 fixEdge<KnownCellUse>(child1);
1088                 fixEdge<Int32Use>(child2);
1089                 break;
1090             }
1091             break;
1092         }
1093             
1094         case AtomicsAdd:
1095         case AtomicsAnd:
1096         case AtomicsCompareExchange:
1097         case AtomicsExchange:
1098         case AtomicsLoad:
1099         case AtomicsOr:
1100         case AtomicsStore:
1101         case AtomicsSub:
1102         case AtomicsXor: {
1103             Edge& base = m_graph.child(node, 0);
1104             Edge& index = m_graph.child(node, 1);
1105             
1106             bool badNews = false;
1107             for (unsigned i = numExtraAtomicsArgs(node->op()); i--;) {
1108                 Edge& child = m_graph.child(node, 2 + i);
1109                 // NOTE: DFG is not smart enough to handle double->int conversions in atomics. So, we
1110                 // just call the function when that happens. But the FTL is totally cool with those
1111                 // conversions.
1112                 if (!child->shouldSpeculateInt32()
1113                     && !child->shouldSpeculateInt52()
1114                     && !(child->shouldSpeculateNumberOrBoolean() && m_graph.m_plan.isFTL()))
1115                     badNews = true;
1116             }
1117             
1118             if (badNews) {
1119                 node->setArrayMode(ArrayMode(Array::Generic, node->arrayMode().action()));
1120                 break;
1121             }
1122             
1123             node->setArrayMode(
1124                 node->arrayMode().refine(
1125                     m_graph, node, base->prediction(), index->prediction()));
1126             
1127             if (node->arrayMode().type() == Array::Generic)
1128                 break;
1129             
1130             for (unsigned i = numExtraAtomicsArgs(node->op()); i--;) {
1131                 Edge& child = m_graph.child(node, 2 + i);
1132                 if (child->shouldSpeculateInt32())
1133                     fixIntOrBooleanEdge(child);
1134                 else if (child->shouldSpeculateInt52())
1135                     fixEdge<Int52RepUse>(child);
1136                 else {
1137                     RELEASE_ASSERT(child->shouldSpeculateNumberOrBoolean() && m_graph.m_plan.isFTL());
1138                     fixDoubleOrBooleanEdge(child);
1139                 }
1140             }
1141             
1142             blessArrayOperation(base, index, m_graph.child(node, 2 + numExtraAtomicsArgs(node->op())));
1143             fixEdge<CellUse>(base);
1144             fixEdge<Int32Use>(index);
1145             
1146             if (node->arrayMode().type() == Array::Uint32Array) {
1147                 // NOTE: This means basically always doing Int52.
1148                 if (node->shouldSpeculateInt52())
1149                     node->setResult(NodeResultInt52);
1150                 else
1151                     node->setResult(NodeResultDouble);
1152             }
1153             break;
1154         }
1155             
1156         case AtomicsIsLockFree:
1157             if (node->child1()->shouldSpeculateInt32())
1158                 fixIntOrBooleanEdge(node->child1());
1159             break;
1160             
1161         case ArrayPush: {
1162             // May need to refine the array mode in case the value prediction contravenes
1163             // the array prediction. For example, we may have evidence showing that the
1164             // array is in Int32 mode, but the value we're storing is likely to be a double.
1165             // Then we should turn this into a conversion to Double array followed by the
1166             // push. On the other hand, we absolutely don't want to refine based on the
1167             // base prediction. If it has non-cell garbage in it, then we want that to be
1168             // ignored. That's because ArrayPush can't handle any array modes that aren't
1169             // array-related - so if refine() turned this into a "Generic" ArrayPush then
1170             // that would break things.
1171             Edge& storageEdge = m_graph.varArgChild(node, 0);
1172             Edge& arrayEdge = m_graph.varArgChild(node, 1);
1173             unsigned elementOffset = 2;
1174             unsigned elementCount = node->numChildren() - elementOffset;
1175             for (unsigned i = 0; i < elementCount; ++i) {
1176                 Edge& element = m_graph.varArgChild(node, i + elementOffset);
1177                 node->setArrayMode(
1178                     node->arrayMode().refine(
1179                         m_graph, node,
1180                         arrayEdge->prediction() & SpecCell,
1181                         SpecInt32Only,
1182                         element->prediction()));
1183             }
1184             blessArrayOperation(arrayEdge, Edge(), storageEdge);
1185             fixEdge<KnownCellUse>(arrayEdge);
1186
1187             // Convert `array.push()` to GetArrayLength.
1188             if (!elementCount && node->arrayMode().supportsSelfLength()) {
1189                 node->setOpAndDefaultFlags(GetArrayLength);
1190                 node->child1() = arrayEdge;
1191                 node->child2() = storageEdge;
1192                 fixEdge<KnownCellUse>(node->child1());
1193                 break;
1194             }
1195
1196             // We do not want to perform osr exit and retry for ArrayPush. We insert Check with appropriate type,
1197             // and ArrayPush uses the edge as known typed edge. Therefore, ArrayPush do not need to perform type checks.
1198             for (unsigned i = 0; i < elementCount; ++i) {
1199                 Edge& element = m_graph.varArgChild(node, i + elementOffset);
1200                 switch (node->arrayMode().type()) {
1201                 case Array::Int32:
1202                     fixEdge<Int32Use>(element);
1203                     break;
1204                 case Array::Double:
1205                     fixEdge<DoubleRepRealUse>(element);
1206                     break;
1207                 case Array::Contiguous:
1208                 case Array::ArrayStorage:
1209                     speculateForBarrier(element);
1210                     break;
1211                 default:
1212                     break;
1213                 }
1214             }
1215             break;
1216         }
1217             
1218         case ArrayPop: {
1219             blessArrayOperation(node->child1(), Edge(), node->child2());
1220             fixEdge<KnownCellUse>(node->child1());
1221             break;
1222         }
1223
1224         case ArraySlice: {
1225             fixEdge<KnownCellUse>(m_graph.varArgChild(node, 0));
1226             if (node->numChildren() >= 3) {
1227                 fixEdge<Int32Use>(m_graph.varArgChild(node, 1));
1228                 if (node->numChildren() == 4)
1229                     fixEdge<Int32Use>(m_graph.varArgChild(node, 2));
1230             }
1231             break;
1232         }
1233
1234         case ArrayIndexOf:
1235             fixupArrayIndexOf(node);
1236             break;
1237             
1238         case RegExpExec:
1239         case RegExpTest: {
1240             fixEdge<KnownCellUse>(node->child1());
1241             
1242             if (node->child2()->shouldSpeculateRegExpObject()) {
1243                 fixEdge<RegExpObjectUse>(node->child2());
1244
1245                 if (node->child3()->shouldSpeculateString())
1246                     fixEdge<StringUse>(node->child3());
1247             }
1248             break;
1249         }
1250
1251         case RegExpMatchFast: {
1252             fixEdge<KnownCellUse>(node->child1());
1253             fixEdge<RegExpObjectUse>(node->child2());
1254             fixEdge<StringUse>(node->child3());
1255             break;
1256         }
1257
1258         case StringReplace:
1259         case StringReplaceRegExp: {
1260             if (node->child2()->shouldSpeculateString()) {
1261                 m_insertionSet.insertNode(
1262                     m_indexInBlock, SpecNone, Check, node->origin,
1263                     Edge(node->child2().node(), StringUse));
1264                 fixEdge<StringUse>(node->child2());
1265             } else if (op == StringReplace) {
1266                 if (node->child2()->shouldSpeculateRegExpObject())
1267                     addStringReplacePrimordialChecks(node->child2().node());
1268                 else 
1269                     m_insertionSet.insertNode(
1270                         m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
1271             }
1272
1273             if (node->child1()->shouldSpeculateString()
1274                 && node->child2()->shouldSpeculateRegExpObject()
1275                 && node->child3()->shouldSpeculateString()) {
1276
1277                 fixEdge<StringUse>(node->child1());
1278                 fixEdge<RegExpObjectUse>(node->child2());
1279                 fixEdge<StringUse>(node->child3());
1280                 break;
1281             }
1282             break;
1283         }
1284             
1285         case Branch: {
1286             if (node->child1()->shouldSpeculateBoolean()) {
1287                 if (node->child1()->result() == NodeResultBoolean) {
1288                     // This is necessary in case we have a bytecode instruction implemented by:
1289                     //
1290                     // a: CompareEq(...)
1291                     // b: Branch(@a)
1292                     //
1293                     // In that case, CompareEq might have a side-effect. Then, we need to make
1294                     // sure that we know that Branch does not exit.
1295                     fixEdge<KnownBooleanUse>(node->child1());
1296                 } else
1297                     fixEdge<BooleanUse>(node->child1());
1298             } else if (node->child1()->shouldSpeculateObjectOrOther())
1299                 fixEdge<ObjectOrOtherUse>(node->child1());
1300             else if (node->child1()->shouldSpeculateInt32OrBoolean())
1301                 fixIntOrBooleanEdge(node->child1());
1302             else if (node->child1()->shouldSpeculateNumber())
1303                 fixEdge<DoubleRepUse>(node->child1());
1304             else if (node->child1()->shouldSpeculateString())
1305                 fixEdge<StringUse>(node->child1());
1306             else if (node->child1()->shouldSpeculateStringOrOther())
1307                 fixEdge<StringOrOtherUse>(node->child1());
1308             else {
1309                 WatchpointSet* masqueradesAsUndefinedWatchpoint = m_graph.globalObjectFor(node->origin.semantic)->masqueradesAsUndefinedWatchpoint();
1310                 if (masqueradesAsUndefinedWatchpoint->isStillValid())
1311                     m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
1312             }
1313             break;
1314         }
1315             
1316         case Switch: {
1317             SwitchData* data = node->switchData();
1318             switch (data->kind) {
1319             case SwitchImm:
1320                 if (node->child1()->shouldSpeculateInt32())
1321                     fixEdge<Int32Use>(node->child1());
1322                 break;
1323             case SwitchChar:
1324                 if (node->child1()->shouldSpeculateString())
1325                     fixEdge<StringUse>(node->child1());
1326                 break;
1327             case SwitchString:
1328                 if (node->child1()->shouldSpeculateStringIdent())
1329                     fixEdge<StringIdentUse>(node->child1());
1330                 else if (node->child1()->shouldSpeculateString())
1331                     fixEdge<StringUse>(node->child1());
1332                 break;
1333             case SwitchCell:
1334                 if (node->child1()->shouldSpeculateCell())
1335                     fixEdge<CellUse>(node->child1());
1336                 // else it's fine for this to have UntypedUse; we will handle this by just making
1337                 // non-cells take the default case.
1338                 break;
1339             }
1340             break;
1341         }
1342             
1343         case ToPrimitive: {
1344             fixupToPrimitive(node);
1345             break;
1346         }
1347
1348         case ToNumber: {
1349             fixupToNumber(node);
1350             break;
1351         }
1352             
1353         case ToString:
1354         case CallStringConstructor: {
1355             fixupToStringOrCallStringConstructor(node);
1356             break;
1357         }
1358             
1359         case NewStringObject: {
1360             fixEdge<KnownStringUse>(node->child1());
1361             break;
1362         }
1363
1364         case NewSymbol: {
1365             if (node->child1())
1366                 fixEdge<KnownStringUse>(node->child1());
1367             break;
1368         }
1369
1370         case NewArrayWithSpread: {
1371             watchHavingABadTime(node);
1372             
1373             BitVector* bitVector = node->bitVector();
1374             for (unsigned i = node->numChildren(); i--;) {
1375                 if (bitVector->get(i))
1376                     fixEdge<KnownCellUse>(m_graph.m_varArgChildren[node->firstChild() + i]);
1377                 else
1378                     fixEdge<UntypedUse>(m_graph.m_varArgChildren[node->firstChild() + i]);
1379             }
1380
1381             break;
1382         }
1383
1384         case Spread: {
1385             // Note: We care about performing the protocol on our child's global object, not necessarily ours.
1386             
1387             watchHavingABadTime(node->child1().node());
1388
1389             JSGlobalObject* globalObject = m_graph.globalObjectFor(node->child1()->origin.semantic);
1390             // When we go down the fast path, we don't consult the prototype chain, so we must prove
1391             // that it doesn't contain any indexed properties, and that any holes will result in
1392             // jsUndefined().
1393             Structure* arrayPrototypeStructure = globalObject->arrayPrototype()->structure(vm());
1394             Structure* objectPrototypeStructure = globalObject->objectPrototype()->structure(vm());
1395             if (node->child1()->shouldSpeculateArray()
1396                 && arrayPrototypeStructure->transitionWatchpointSetIsStillValid()
1397                 && objectPrototypeStructure->transitionWatchpointSetIsStillValid()
1398                 && globalObject->arrayPrototypeChainIsSane()
1399                 && m_graph.isWatchingArrayIteratorProtocolWatchpoint(node->child1().node())
1400                 && m_graph.isWatchingHavingABadTimeWatchpoint(node->child1().node())) {
1401                 m_graph.registerAndWatchStructureTransition(objectPrototypeStructure);
1402                 m_graph.registerAndWatchStructureTransition(arrayPrototypeStructure);
1403                 fixEdge<ArrayUse>(node->child1());
1404             } else
1405                 fixEdge<CellUse>(node->child1());
1406             break;
1407         }
1408             
1409         case NewArray: {
1410             watchHavingABadTime(node);
1411             
1412             for (unsigned i = m_graph.varArgNumChildren(node); i--;) {
1413                 node->setIndexingType(
1414                     leastUpperBoundOfIndexingTypeAndType(
1415                         node->indexingType(), m_graph.varArgChild(node, i)->prediction()));
1416             }
1417             switch (node->indexingType()) {
1418             case ALL_BLANK_INDEXING_TYPES:
1419                 CRASH();
1420                 break;
1421             case ALL_UNDECIDED_INDEXING_TYPES:
1422                 if (node->numChildren()) {
1423                     // This will only happen if the children have no type predictions. We
1424                     // would have already exited by now, but insert a forced exit just to
1425                     // be safe.
1426                     m_insertionSet.insertNode(
1427                         m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
1428                 }
1429                 break;
1430             case ALL_INT32_INDEXING_TYPES:
1431                 for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
1432                     fixEdge<Int32Use>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
1433                 break;
1434             case ALL_DOUBLE_INDEXING_TYPES:
1435                 for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
1436                     fixEdge<DoubleRepRealUse>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
1437                 break;
1438             case ALL_CONTIGUOUS_INDEXING_TYPES:
1439             case ALL_ARRAY_STORAGE_INDEXING_TYPES:
1440                 break;
1441             default:
1442                 CRASH();
1443                 break;
1444             }
1445             break;
1446         }
1447             
1448         case NewTypedArray: {
1449             watchHavingABadTime(node);
1450             
1451             if (node->child1()->shouldSpeculateInt32()) {
1452                 fixEdge<Int32Use>(node->child1());
1453                 node->clearFlags(NodeMustGenerate);
1454                 break;
1455             }
1456             break;
1457         }
1458             
1459         case NewArrayWithSize: {
1460             watchHavingABadTime(node);
1461             fixEdge<Int32Use>(node->child1());
1462             break;
1463         }
1464
1465         case NewArrayBuffer: {
1466             watchHavingABadTime(node);
1467             break;
1468         }
1469
1470         case ToObject: {
1471             fixupToObject(node);
1472             break;
1473         }
1474
1475         case CallObjectConstructor: {
1476             fixupCallObjectConstructor(node);
1477             break;
1478         }
1479
1480         case ToThis: {
1481             fixupToThis(node);
1482             break;
1483         }
1484             
1485         case PutStructure: {
1486             fixEdge<KnownCellUse>(node->child1());
1487             break;
1488         }
1489             
1490         case GetClosureVar:
1491         case GetFromArguments:
1492         case GetInternalField: {
1493             fixEdge<KnownCellUse>(node->child1());
1494             break;
1495         }
1496
1497         case PutClosureVar:
1498         case PutToArguments:
1499         case PutInternalField: {
1500             fixEdge<KnownCellUse>(node->child1());
1501             speculateForBarrier(node->child2());
1502             break;
1503         }
1504
1505         case SkipScope:
1506         case GetScope:
1507         case GetGetter:
1508         case GetSetter:
1509         case GetGlobalObject: {
1510             fixEdge<KnownCellUse>(node->child1());
1511             break;
1512         }
1513             
1514         case AllocatePropertyStorage:
1515         case ReallocatePropertyStorage: {
1516             fixEdge<KnownCellUse>(node->child1());
1517             break;
1518         }
1519             
1520         case NukeStructureAndSetButterfly: {
1521             fixEdge<KnownCellUse>(node->child1());
1522             break;
1523         }
1524
1525         case TryGetById: {
1526             if (node->child1()->shouldSpeculateCell())
1527                 fixEdge<CellUse>(node->child1());
1528             break;
1529         }
1530
1531         case GetByIdDirect:
1532         case GetByIdDirectFlush: {
1533             if (node->child1()->shouldSpeculateCell())
1534                 fixEdge<CellUse>(node->child1());
1535             break;
1536         }
1537
1538         case GetById:
1539         case GetByIdFlush: {
1540             // FIXME: This should be done in the ByteCodeParser based on reading the
1541             // PolymorphicAccess, which will surely tell us that this is a AccessCase::ArrayLength.
1542             // https://bugs.webkit.org/show_bug.cgi?id=154990
1543             auto uid = m_graph.identifiers()[node->identifierNumber()];
1544             if (node->child1()->shouldSpeculateCellOrOther()
1545                 && !m_graph.hasExitSite(node->origin.semantic, BadType)
1546                 && !m_graph.hasExitSite(node->origin.semantic, BadCache)
1547                 && !m_graph.hasExitSite(node->origin.semantic, BadIndexingType)
1548                 && !m_graph.hasExitSite(node->origin.semantic, ExoticObjectMode)) {
1549                 
1550                 if (uid == vm().propertyNames->length.impl()) {
1551                     attemptToMakeGetArrayLength(node);
1552                     break;
1553                 }
1554
1555                 if (uid == vm().propertyNames->lastIndex.impl()
1556                     && node->child1()->shouldSpeculateRegExpObject()) {
1557                     node->setOp(GetRegExpObjectLastIndex);
1558                     node->clearFlags(NodeMustGenerate);
1559                     fixEdge<RegExpObjectUse>(node->child1());
1560                     break;
1561                 }
1562             }
1563
1564             if (node->child1()->shouldSpeculateNumber()) {
1565                 if (uid == vm().propertyNames->toString.impl()) {
1566                     if (m_graph.isWatchingNumberToStringWatchpoint(node)) {
1567                         JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
1568                         if (node->child1()->shouldSpeculateInt32()) {
1569                             insertCheck<Int32Use>(node->child1().node());
1570                             m_graph.convertToConstant(node, m_graph.freeze(globalObject->numberProtoToStringFunction()));
1571                             break;
1572                         }
1573
1574                         if (node->child1()->shouldSpeculateInt52()) {
1575                             insertCheck<Int52RepUse>(node->child1().node());
1576                             m_graph.convertToConstant(node, m_graph.freeze(globalObject->numberProtoToStringFunction()));
1577                             break;
1578                         }
1579
1580                         ASSERT(node->child1()->shouldSpeculateNumber());
1581                         insertCheck<DoubleRepUse>(node->child1().node());
1582                         m_graph.convertToConstant(node, m_graph.freeze(globalObject->numberProtoToStringFunction()));
1583                         break;
1584                     }
1585                 }
1586             }
1587
1588             if (node->child1()->shouldSpeculateCell())
1589                 fixEdge<CellUse>(node->child1());
1590             break;
1591         }
1592         
1593         case GetByIdWithThis: {
1594             if (node->child1()->shouldSpeculateCell() && node->child2()->shouldSpeculateCell()) {
1595                 fixEdge<CellUse>(node->child1());
1596                 fixEdge<CellUse>(node->child2());
1597             }
1598             break;
1599         }
1600
1601         case PutById:
1602         case PutByIdFlush:
1603         case PutByIdDirect: {
1604             if (node->child1()->shouldSpeculateCellOrOther()
1605                 && !m_graph.hasExitSite(node->origin.semantic, BadType)
1606                 && !m_graph.hasExitSite(node->origin.semantic, BadCache)
1607                 && !m_graph.hasExitSite(node->origin.semantic, BadIndexingType)
1608                 && !m_graph.hasExitSite(node->origin.semantic, ExoticObjectMode)) {
1609                 
1610                 auto uid = m_graph.identifiers()[node->identifierNumber()];
1611                 
1612                 if (uid == vm().propertyNames->lastIndex.impl()
1613                     && node->child1()->shouldSpeculateRegExpObject()) {
1614                     node->convertToSetRegExpObjectLastIndex();
1615                     fixEdge<RegExpObjectUse>(node->child1());
1616                     speculateForBarrier(node->child2());
1617                     break;
1618                 }
1619             }
1620             
1621             fixEdge<CellUse>(node->child1());
1622             break;
1623         }
1624
1625         case PutGetterById:
1626         case PutSetterById: {
1627             fixEdge<KnownCellUse>(node->child1());
1628             fixEdge<KnownCellUse>(node->child2());
1629             break;
1630         }
1631
1632         case PutGetterSetterById: {
1633             fixEdge<KnownCellUse>(node->child1());
1634             break;
1635         }
1636
1637         case PutGetterByVal:
1638         case PutSetterByVal: {
1639             fixEdge<KnownCellUse>(node->child1());
1640             fixEdge<KnownCellUse>(node->child3());
1641             break;
1642         }
1643
1644         case GetExecutable: {
1645             fixEdge<FunctionUse>(node->child1());
1646             break;
1647         }
1648
1649         case OverridesHasInstance:
1650         case CheckStructure:
1651         case CheckCell:
1652         case CreateThis:
1653         case CreatePromise:
1654         case CreateGenerator:
1655         case CreateAsyncGenerator:
1656         case GetButterfly: {
1657             fixEdge<CellUse>(node->child1());
1658             break;
1659         }
1660
1661         case ObjectCreate: {
1662             if (node->child1()->shouldSpeculateObject()) {
1663                 fixEdge<ObjectUse>(node->child1());
1664                 node->clearFlags(NodeMustGenerate);
1665                 break;
1666             }
1667             break;
1668         }
1669
1670         case ObjectKeys: {
1671             if (node->child1()->shouldSpeculateObject()) {
1672                 watchHavingABadTime(node);
1673                 fixEdge<ObjectUse>(node->child1());
1674             }
1675             break;
1676         }
1677
1678         case CheckStringIdent: {
1679             fixEdge<StringIdentUse>(node->child1());
1680             break;
1681         }
1682             
1683         case Arrayify:
1684         case ArrayifyToStructure: {
1685             fixEdge<CellUse>(node->child1());
1686             if (node->child2())
1687                 fixEdge<Int32Use>(node->child2());
1688             break;
1689         }
1690             
1691         case GetByOffset:
1692         case GetGetterSetterByOffset: {
1693             if (!node->child1()->hasStorageResult())
1694                 fixEdge<KnownCellUse>(node->child1());
1695             fixEdge<KnownCellUse>(node->child2());
1696             break;
1697         }
1698             
1699         case MultiGetByOffset: {
1700             fixEdge<CellUse>(node->child1());
1701             break;
1702         }
1703             
1704         case PutByOffset: {
1705             if (!node->child1()->hasStorageResult())
1706                 fixEdge<KnownCellUse>(node->child1());
1707             fixEdge<KnownCellUse>(node->child2());
1708             speculateForBarrier(node->child3());
1709             break;
1710         }
1711             
1712         case MultiPutByOffset: {
1713             fixEdge<CellUse>(node->child1());
1714             break;
1715         }
1716             
1717         case MatchStructure: {
1718             // FIXME: Introduce a variant of MatchStructure that doesn't do a cell check.
1719             // https://bugs.webkit.org/show_bug.cgi?id=185784
1720             fixEdge<CellUse>(node->child1());
1721             break;
1722         }
1723             
1724         case InstanceOf: {
1725             if (node->child1()->shouldSpeculateCell()
1726                 && node->child2()->shouldSpeculateCell()
1727                 && is64Bit()) {
1728                 fixEdge<CellUse>(node->child1());
1729                 fixEdge<CellUse>(node->child2());
1730                 break;
1731             }
1732             break;
1733         }
1734
1735         case InstanceOfCustom:
1736             fixEdge<CellUse>(node->child2());
1737             break;
1738
1739         case InById: {
1740             fixEdge<CellUse>(node->child1());
1741             break;
1742         }
1743
1744         case InByVal: {
1745             if (node->child2()->shouldSpeculateInt32()) {
1746                 convertToHasIndexedProperty(node);
1747                 break;
1748             }
1749
1750             fixEdge<CellUse>(node->child1());
1751             break;
1752         }
1753
1754         case HasOwnProperty: {
1755             fixEdge<ObjectUse>(node->child1());
1756             if (node->child2()->shouldSpeculateString())
1757                 fixEdge<StringUse>(node->child2());
1758             else if (node->child2()->shouldSpeculateSymbol())
1759                 fixEdge<SymbolUse>(node->child2());
1760             else
1761                 fixEdge<UntypedUse>(node->child2());
1762             break;
1763         }
1764
1765         case CheckVarargs:
1766         case Check: {
1767             m_graph.doToChildren(
1768                 node,
1769                 [&] (Edge& edge) {
1770                     switch (edge.useKind()) {
1771                     case NumberUse:
1772                         if (edge->shouldSpeculateInt32ForArithmetic())
1773                             edge.setUseKind(Int32Use);
1774                         break;
1775                     default:
1776                         break;
1777                     }
1778                     observeUseKindOnEdge(edge);
1779                 });
1780             break;
1781         }
1782
1783         case Phantom:
1784             // Phantoms are meaningless past Fixup. We recreate them on-demand in the backend.
1785             node->remove(m_graph);
1786             break;
1787
1788         case FiatInt52: {
1789             RELEASE_ASSERT(enableInt52());
1790             node->convertToIdentity();
1791             fixEdge<Int52RepUse>(node->child1());
1792             node->setResult(NodeResultInt52);
1793             break;
1794         }
1795
1796         case GetArrayLength: {
1797             fixEdge<KnownCellUse>(node->child1());
1798             break;
1799         }
1800
1801         case GetTypedArrayByteOffset: {
1802             fixEdge<KnownCellUse>(node->child1());
1803             break;
1804         }
1805
1806         case CompareBelow:
1807         case CompareBelowEq: {
1808             fixEdge<Int32Use>(node->child1());
1809             fixEdge<Int32Use>(node->child2());
1810             break;
1811         }
1812
1813         case GetPrototypeOf: {
1814             fixupGetPrototypeOf(node);
1815             break;
1816         }
1817
1818         case Phi:
1819         case Upsilon:
1820         case EntrySwitch:
1821         case GetIndexedPropertyStorage:
1822         case LastNodeType:
1823         case CheckTierUpInLoop:
1824         case CheckTierUpAtReturn:
1825         case CheckTierUpAndOSREnter:
1826         case CheckArray:
1827         case CheckInBounds:
1828         case ConstantStoragePointer:
1829         case DoubleAsInt32:
1830         case ValueToInt32:
1831         case DoubleRep:
1832         case ValueRep:
1833         case Int52Rep:
1834         case Int52Constant:
1835         case Identity: // This should have been cleaned up.
1836         case BooleanToNumber:
1837         case PhantomNewObject:
1838         case PhantomNewFunction:
1839         case PhantomNewGeneratorFunction:
1840         case PhantomNewAsyncGeneratorFunction:
1841         case PhantomNewAsyncFunction:
1842         case PhantomCreateActivation:
1843         case PhantomDirectArguments:
1844         case PhantomCreateRest:
1845         case PhantomSpread:
1846         case PhantomNewArrayWithSpread:
1847         case PhantomNewArrayBuffer:
1848         case PhantomClonedArguments:
1849         case PhantomNewRegexp:
1850         case GetMyArgumentByVal:
1851         case GetMyArgumentByValOutOfBounds:
1852         case GetVectorLength:
1853         case PutHint:
1854         case CheckStructureImmediate:
1855         case CheckStructureOrEmpty:
1856         case MaterializeNewObject:
1857         case MaterializeCreateActivation:
1858         case PutStack:
1859         case KillStack:
1860         case GetStack:
1861         case StoreBarrier:
1862         case FencedStoreBarrier:
1863         case GetRegExpObjectLastIndex:
1864         case SetRegExpObjectLastIndex:
1865         case RecordRegExpCachedResult:
1866         case RegExpExecNonGlobalOrSticky:
1867         case RegExpMatchFastGlobal:
1868             // These are just nodes that we don't currently expect to see during fixup.
1869             // If we ever wanted to insert them prior to fixup, then we just have to create
1870             // fixup rules for them.
1871             DFG_CRASH(m_graph, node, "Unexpected node during fixup");
1872             break;
1873
1874         case PutGlobalVariable: {
1875             fixEdge<CellUse>(node->child1());
1876             speculateForBarrier(node->child2());
1877             break;
1878         }
1879
1880         case IsObject:
1881             if (node->child1()->shouldSpeculateObject()) {
1882                 m_insertionSet.insertNode(
1883                     m_indexInBlock, SpecNone, Check, node->origin,
1884                     Edge(node->child1().node(), ObjectUse));
1885                 m_graph.convertToConstant(node, jsBoolean(true));
1886                 observeUseKindOnNode<ObjectUse>(node);
1887             }
1888             break;
1889
1890         case IsCellWithType: {
1891             fixupIsCellWithType(node);
1892             break;
1893         }
1894
1895         case GetEnumerableLength: {
1896             fixEdge<CellUse>(node->child1());
1897             break;
1898         }
1899         case HasGenericProperty: {
1900             fixEdge<CellUse>(node->child2());
1901             break;
1902         }
1903         case HasStructureProperty: {
1904             fixEdge<StringUse>(node->child2());
1905             fixEdge<KnownCellUse>(node->child3());
1906             break;
1907         }
1908         case HasIndexedProperty: {
1909             node->setArrayMode(
1910                 node->arrayMode().refine(
1911                     m_graph, node,
1912                     m_graph.varArgChild(node, 0)->prediction(),
1913                     m_graph.varArgChild(node, 1)->prediction(),
1914                     SpecNone));
1915             
1916             blessArrayOperation(m_graph.varArgChild(node, 0), m_graph.varArgChild(node, 1), m_graph.varArgChild(node, 2));
1917             fixEdge<CellUse>(m_graph.varArgChild(node, 0));
1918             fixEdge<Int32Use>(m_graph.varArgChild(node, 1));
1919             break;
1920         }
1921         case GetDirectPname: {
1922             Edge& base = m_graph.varArgChild(node, 0);
1923             Edge& property = m_graph.varArgChild(node, 1);
1924             Edge& index = m_graph.varArgChild(node, 2);
1925             Edge& enumerator = m_graph.varArgChild(node, 3);
1926             fixEdge<CellUse>(base);
1927             fixEdge<KnownCellUse>(property);
1928             fixEdge<Int32Use>(index);
1929             fixEdge<KnownCellUse>(enumerator);
1930             break;
1931         }
1932         case GetPropertyEnumerator: {
1933             if (node->child1()->shouldSpeculateCell())
1934                 fixEdge<CellUse>(node->child1());
1935             break;
1936         }
1937         case GetEnumeratorStructurePname: {
1938             fixEdge<KnownCellUse>(node->child1());
1939             fixEdge<Int32Use>(node->child2());
1940             break;
1941         }
1942         case GetEnumeratorGenericPname: {
1943             fixEdge<KnownCellUse>(node->child1());
1944             fixEdge<Int32Use>(node->child2());
1945             break;
1946         }
1947         case ToIndexString: {
1948             fixEdge<Int32Use>(node->child1());
1949             break;
1950         }
1951         case ProfileType: {
1952             // We want to insert type checks based on the instructionTypeSet of the TypeLocation, not the globalTypeSet.
1953             // Because the instructionTypeSet is contained in globalTypeSet, if we produce a type check for
1954             // type T for the instructionTypeSet, the global type set must also have information for type T.
1955             // So if it the type check succeeds for type T in the instructionTypeSet, a type check for type T 
1956             // in the globalTypeSet would've also succeeded.
1957             // (The other direction does not hold in general).
1958
1959             RefPtr<TypeSet> typeSet = node->typeLocation()->m_instructionTypeSet;
1960             RuntimeTypeMask seenTypes = typeSet->seenTypes();
1961             if (typeSet->doesTypeConformTo(TypeAnyInt)) {
1962                 if (node->child1()->shouldSpeculateInt32()) {
1963                     fixEdge<Int32Use>(node->child1());
1964                     node->remove(m_graph);
1965                     break;
1966                 }
1967
1968                 if (enableInt52()) {
1969                     fixEdge<AnyIntUse>(node->child1());
1970                     node->remove(m_graph);
1971                     break;
1972                 }
1973
1974                 // Must not perform fixEdge<NumberUse> here since the type set only includes TypeAnyInt. Double values should be logged.
1975             }
1976
1977             if (typeSet->doesTypeConformTo(TypeNumber | TypeAnyInt)) {
1978                 fixEdge<NumberUse>(node->child1());
1979                 node->remove(m_graph);
1980             } else if (typeSet->doesTypeConformTo(TypeString)) {
1981                 fixEdge<StringUse>(node->child1());
1982                 node->remove(m_graph);
1983             } else if (typeSet->doesTypeConformTo(TypeBoolean)) {
1984                 fixEdge<BooleanUse>(node->child1());
1985                 node->remove(m_graph);
1986             } else if (typeSet->doesTypeConformTo(TypeUndefined | TypeNull) && (seenTypes & TypeUndefined) && (seenTypes & TypeNull)) {
1987                 fixEdge<OtherUse>(node->child1());
1988                 node->remove(m_graph);
1989             } else if (typeSet->doesTypeConformTo(TypeObject)) {
1990                 StructureSet set;
1991                 {
1992                     ConcurrentJSLocker locker(typeSet->m_lock);
1993                     set = typeSet->structureSet(locker);
1994                 }
1995                 if (!set.isEmpty()) {
1996                     fixEdge<CellUse>(node->child1());
1997                     node->convertToCheckStructureOrEmpty(m_graph.addStructureSet(set));
1998                 }
1999             }
2000
2001             break;
2002         }
2003
2004         case CreateClonedArguments: {
2005             watchHavingABadTime(node);
2006             break;
2007         }
2008
2009         case CreateScopedArguments:
2010         case CreateActivation:
2011         case NewFunction:
2012         case NewGeneratorFunction:
2013         case NewAsyncGeneratorFunction:
2014         case NewAsyncFunction: {
2015             // Child 1 is always the current scope, which is guaranteed to be an object
2016             // FIXME: should be KnownObjectUse once that exists (https://bugs.webkit.org/show_bug.cgi?id=175689)
2017             fixEdge<KnownCellUse>(node->child1());
2018             break;
2019         }
2020
2021         case PushWithScope: {
2022             // Child 1 is always the current scope, which is guaranteed to be an object
2023             // FIXME: should be KnownObjectUse once that exists (https://bugs.webkit.org/show_bug.cgi?id=175689)
2024             fixEdge<KnownCellUse>(node->child1());
2025             if (node->child2()->shouldSpeculateObject())
2026                 fixEdge<ObjectUse>(node->child2());
2027             break;
2028         }
2029
2030         case SetFunctionName: {
2031             // The first child is guaranteed to be a cell because op_set_function_name is only used
2032             // on a newly instantiated function object (the first child).
2033             fixEdge<KnownCellUse>(node->child1());
2034             fixEdge<UntypedUse>(node->child2());
2035             break;
2036         }
2037
2038         case CreateRest: {
2039             watchHavingABadTime(node);
2040             fixEdge<Int32Use>(node->child1());
2041             break;
2042         }
2043
2044         case ResolveScopeForHoistingFuncDeclInEval: {
2045             fixEdge<KnownCellUse>(node->child1());
2046             break;
2047         }
2048         case ResolveScope:
2049         case GetDynamicVar:
2050         case PutDynamicVar: {
2051             fixEdge<KnownCellUse>(node->child1());
2052             break;
2053         }
2054
2055         case LogShadowChickenPrologue: {
2056             fixEdge<KnownCellUse>(node->child1());
2057             break;
2058         }
2059         case LogShadowChickenTail: {
2060             fixEdge<UntypedUse>(node->child1());
2061             fixEdge<KnownCellUse>(node->child2());
2062             break;
2063         }
2064
2065         case GetMapBucket:
2066             if (node->child1().useKind() == MapObjectUse)
2067                 fixEdge<MapObjectUse>(node->child1());
2068             else if (node->child1().useKind() == SetObjectUse)
2069                 fixEdge<SetObjectUse>(node->child1());
2070             else
2071                 RELEASE_ASSERT_NOT_REACHED();
2072
2073 #if USE(JSVALUE64)
2074             if (node->child2()->shouldSpeculateBoolean())
2075                 fixEdge<BooleanUse>(node->child2());
2076             else if (node->child2()->shouldSpeculateInt32())
2077                 fixEdge<Int32Use>(node->child2());
2078             else if (node->child2()->shouldSpeculateSymbol())
2079                 fixEdge<SymbolUse>(node->child2());
2080             else if (node->child2()->shouldSpeculateObject())
2081                 fixEdge<ObjectUse>(node->child2());
2082             else if (node->child2()->shouldSpeculateString())
2083                 fixEdge<StringUse>(node->child2());
2084             else if (node->child2()->shouldSpeculateCell())
2085                 fixEdge<CellUse>(node->child2());
2086             else
2087                 fixEdge<UntypedUse>(node->child2());
2088 #else
2089             fixEdge<UntypedUse>(node->child2());
2090 #endif // USE(JSVALUE64)
2091
2092             fixEdge<Int32Use>(node->child3());
2093             break;
2094
2095         case GetMapBucketHead:
2096             if (node->child1().useKind() == MapObjectUse)
2097                 fixEdge<MapObjectUse>(node->child1());
2098             else if (node->child1().useKind() == SetObjectUse)
2099                 fixEdge<SetObjectUse>(node->child1());
2100             else
2101                 RELEASE_ASSERT_NOT_REACHED();
2102             break;
2103
2104         case GetMapBucketNext:
2105         case LoadKeyFromMapBucket:
2106         case LoadValueFromMapBucket:
2107             fixEdge<CellUse>(node->child1());
2108             break;
2109
2110         case MapHash: {
2111 #if USE(JSVALUE64)
2112             if (node->child1()->shouldSpeculateBoolean()) {
2113                 fixEdge<BooleanUse>(node->child1());
2114                 break;
2115             }
2116
2117             if (node->child1()->shouldSpeculateInt32()) {
2118                 fixEdge<Int32Use>(node->child1());
2119                 break;
2120             }
2121
2122             if (node->child1()->shouldSpeculateSymbol()) {
2123                 fixEdge<SymbolUse>(node->child1());
2124                 break;
2125             }
2126
2127             if (node->child1()->shouldSpeculateObject()) {
2128                 fixEdge<ObjectUse>(node->child1());
2129                 break;
2130             }
2131
2132             if (node->child1()->shouldSpeculateString()) {
2133                 fixEdge<StringUse>(node->child1());
2134                 break;
2135             }
2136
2137             if (node->child1()->shouldSpeculateCell()) {
2138                 fixEdge<CellUse>(node->child1());
2139                 break;
2140             }
2141
2142             fixEdge<UntypedUse>(node->child1());
2143 #else
2144             fixEdge<UntypedUse>(node->child1());
2145 #endif // USE(JSVALUE64)
2146             break;
2147         }
2148
2149         case NormalizeMapKey: {
2150             fixupNormalizeMapKey(node);
2151             break;
2152         }
2153
2154         case WeakMapGet: {
2155             if (node->child1().useKind() == WeakMapObjectUse)
2156                 fixEdge<WeakMapObjectUse>(node->child1());
2157             else if (node->child1().useKind() == WeakSetObjectUse)
2158                 fixEdge<WeakSetObjectUse>(node->child1());
2159             else
2160                 RELEASE_ASSERT_NOT_REACHED();
2161             fixEdge<ObjectUse>(node->child2());
2162             fixEdge<Int32Use>(node->child3());
2163             break;
2164         }
2165
2166         case SetAdd: {
2167             fixEdge<SetObjectUse>(node->child1());
2168             fixEdge<Int32Use>(node->child3());
2169             break;
2170         }
2171
2172         case MapSet: {
2173             fixEdge<MapObjectUse>(m_graph.varArgChild(node, 0));
2174             fixEdge<Int32Use>(m_graph.varArgChild(node, 3));
2175             break;
2176         }
2177
2178         case WeakSetAdd: {
2179             fixEdge<WeakSetObjectUse>(node->child1());
2180             fixEdge<ObjectUse>(node->child2());
2181             fixEdge<Int32Use>(node->child3());
2182             break;
2183         }
2184
2185         case WeakMapSet: {
2186             fixEdge<WeakMapObjectUse>(m_graph.varArgChild(node, 0));
2187             fixEdge<ObjectUse>(m_graph.varArgChild(node, 1));
2188             fixEdge<Int32Use>(m_graph.varArgChild(node, 3));
2189             break;
2190         }
2191
2192         case DefineDataProperty: {
2193             fixEdge<CellUse>(m_graph.varArgChild(node, 0));
2194             Edge& propertyEdge = m_graph.varArgChild(node, 1);
2195             if (propertyEdge->shouldSpeculateSymbol())
2196                 fixEdge<SymbolUse>(propertyEdge);
2197             else if (propertyEdge->shouldSpeculateStringIdent())
2198                 fixEdge<StringIdentUse>(propertyEdge);
2199             else if (propertyEdge->shouldSpeculateString())
2200                 fixEdge<StringUse>(propertyEdge);
2201             else
2202                 fixEdge<UntypedUse>(propertyEdge);
2203             fixEdge<UntypedUse>(m_graph.varArgChild(node, 2));
2204             fixEdge<Int32Use>(m_graph.varArgChild(node, 3));
2205             break;
2206         }
2207
2208         case StringValueOf: {
2209             fixupStringValueOf(node);
2210             break;
2211         }
2212
2213         case StringSlice: {
2214             fixEdge<StringUse>(node->child1());
2215             fixEdge<Int32Use>(node->child2());
2216             if (node->child3())
2217                 fixEdge<Int32Use>(node->child3());
2218             break;
2219         }
2220
2221         case ToLowerCase: {
2222             // We currently only support StringUse since that will ensure that
2223             // ToLowerCase is a pure operation. If we decide to update this with
2224             // more types in the future, we need to ensure that the clobberize rules
2225             // are correct.
2226             fixEdge<StringUse>(node->child1());
2227             break;
2228         }
2229
2230         case NumberToStringWithRadix: {
2231             if (node->child1()->shouldSpeculateInt32())
2232                 fixEdge<Int32Use>(node->child1());
2233             else if (node->child1()->shouldSpeculateInt52())
2234                 fixEdge<Int52RepUse>(node->child1());
2235             else
2236                 fixEdge<DoubleRepUse>(node->child1());
2237             fixEdge<Int32Use>(node->child2());
2238             break;
2239         }
2240
2241         case DefineAccessorProperty: {
2242             fixEdge<CellUse>(m_graph.varArgChild(node, 0));
2243             Edge& propertyEdge = m_graph.varArgChild(node, 1);
2244             if (propertyEdge->shouldSpeculateSymbol())
2245                 fixEdge<SymbolUse>(propertyEdge);
2246             else if (propertyEdge->shouldSpeculateStringIdent())
2247                 fixEdge<StringIdentUse>(propertyEdge);
2248             else if (propertyEdge->shouldSpeculateString())
2249                 fixEdge<StringUse>(propertyEdge);
2250             else
2251                 fixEdge<UntypedUse>(propertyEdge);
2252             fixEdge<CellUse>(m_graph.varArgChild(node, 2));
2253             fixEdge<CellUse>(m_graph.varArgChild(node, 3));
2254             fixEdge<Int32Use>(m_graph.varArgChild(node, 4));
2255             break;
2256         }
2257
2258         case CheckSubClass: {
2259             fixupCheckSubClass(node);
2260             break;
2261         }
2262
2263         case CallDOMGetter: {
2264             DOMJIT::CallDOMGetterSnippet* snippet = node->callDOMGetterData()->snippet;
2265             fixEdge<CellUse>(node->child1()); // DOM.
2266             if (snippet && snippet->requireGlobalObject)
2267                 fixEdge<KnownCellUse>(node->child2()); // GlobalObject.
2268             break;
2269         }
2270
2271         case CallDOM: {
2272             fixupCallDOM(node);
2273             break;
2274         }
2275
2276         case Call: {
2277             attemptToMakeCallDOM(node);
2278             break;
2279         }
2280
2281         case ParseInt: {
2282             if (node->child1()->shouldSpeculateInt32() && !node->child2()) {
2283                 fixEdge<Int32Use>(node->child1());
2284                 node->convertToIdentity();
2285                 break;
2286             }
2287
2288             if (node->child1()->shouldSpeculateString()) {
2289                 fixEdge<StringUse>(node->child1());
2290                 node->clearFlags(NodeMustGenerate);
2291             }
2292
2293             if (node->child2())
2294                 fixEdge<Int32Use>(node->child2());
2295
2296             break;
2297         }
2298
2299         case IdentityWithProfile: {
2300             node->clearFlags(NodeMustGenerate);
2301             break;
2302         }
2303
2304         case ThrowStaticError:
2305             fixEdge<StringUse>(node->child1());
2306             break;
2307
2308         case NumberIsInteger:
2309             if (node->child1()->shouldSpeculateInt32()) {
2310                 m_insertionSet.insertNode(
2311                     m_indexInBlock, SpecNone, Check, node->origin,
2312                     Edge(node->child1().node(), Int32Use));
2313                 m_graph.convertToConstant(node, jsBoolean(true));
2314                 break;
2315             }
2316             break;
2317
2318         case SetCallee:
2319             fixEdge<CellUse>(node->child1());
2320             break;
2321
2322         case DataViewGetInt:
2323         case DataViewGetFloat: {
2324             fixEdge<DataViewObjectUse>(node->child1());
2325             fixEdge<Int32Use>(node->child2());
2326             if (node->child3())
2327                 fixEdge<BooleanUse>(node->child3());
2328
2329             if (node->op() == DataViewGetInt) {
2330                 DataViewData data = node->dataViewData();
2331                 switch (data.byteSize) {
2332                 case 1:
2333                 case 2:
2334                     node->setResult(NodeResultInt32);
2335                     break;
2336                 case 4:
2337                     if (data.isSigned)
2338                         node->setResult(NodeResultInt32);
2339                     else
2340                         node->setResult(NodeResultInt52);
2341                     break;
2342                 default:
2343                     RELEASE_ASSERT_NOT_REACHED();
2344                 }
2345             }
2346             break;
2347         }
2348
2349         case DataViewSet: {
2350             fixEdge<DataViewObjectUse>(m_graph.varArgChild(node, 0));
2351             fixEdge<Int32Use>(m_graph.varArgChild(node, 1));
2352             if (m_graph.varArgChild(node, 3))
2353                 fixEdge<BooleanUse>(m_graph.varArgChild(node, 3));
2354             
2355             DataViewData data = node->dataViewData();
2356             Edge& valueToStore = m_graph.varArgChild(node, 2);
2357             if (data.isFloatingPoint)
2358                 fixEdge<DoubleRepUse>(valueToStore);
2359             else {
2360                 switch (data.byteSize) {
2361                 case 1:
2362                 case 2:
2363                     fixEdge<Int32Use>(valueToStore);
2364                     break;
2365                 case 4:
2366                     if (data.isSigned)
2367                         fixEdge<Int32Use>(valueToStore);
2368                     else
2369                         fixEdge<Int52RepUse>(valueToStore);
2370                     break;
2371                 }
2372             }
2373             break;
2374         }
2375
2376 #if !ASSERT_DISABLED
2377         // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
2378         case SetArgumentDefinitely:
2379         case SetArgumentMaybe:
2380         case JSConstant:
2381         case LazyJSConstant:
2382         case DoubleConstant:
2383         case GetLocal:
2384         case GetCallee:
2385         case GetArgumentCountIncludingThis:
2386         case SetArgumentCountIncludingThis:
2387         case GetRestLength:
2388         case GetArgument:
2389         case Flush:
2390         case PhantomLocal:
2391         case GetGlobalVar:
2392         case GetGlobalLexicalVariable:
2393         case NotifyWrite:
2394         case DirectCall:
2395         case CheckTypeInfoFlags:
2396         case TailCallInlinedCaller:
2397         case DirectTailCallInlinedCaller:
2398         case Construct:
2399         case DirectConstruct:
2400         case CallVarargs:
2401         case CallEval:
2402         case TailCallVarargsInlinedCaller:
2403         case ConstructVarargs:
2404         case CallForwardVarargs:
2405         case ConstructForwardVarargs:
2406         case TailCallForwardVarargs:
2407         case TailCallForwardVarargsInlinedCaller:
2408         case LoadVarargs:
2409         case ForwardVarargs:
2410         case ProfileControlFlow:
2411         case NewObject:
2412         case NewPromise:
2413         case NewGenerator:
2414         case NewAsyncGenerator:
2415         case NewRegexp:
2416         case DeleteById:
2417         case DeleteByVal:
2418         case IsTypedArrayView:
2419         case IsEmpty:
2420         case IsUndefined:
2421         case IsUndefinedOrNull:
2422         case IsBoolean:
2423         case IsNumber:
2424         case IsObjectOrNull:
2425         case IsFunction:
2426         case CreateDirectArguments:
2427         case Jump:
2428         case Return:
2429         case TailCall:
2430         case DirectTailCall:
2431         case TailCallVarargs:
2432         case Throw:
2433         case CountExecution:
2434         case SuperSamplerBegin:
2435         case SuperSamplerEnd:
2436         case ForceOSRExit:
2437         case CheckBadCell:
2438         case CheckNotEmpty:
2439         case AssertNotEmpty:
2440         case CheckTraps:
2441         case Unreachable:
2442         case ExtractOSREntryLocal:
2443         case ExtractCatchLocal:
2444         case ClearCatchLocals:
2445         case LoopHint:
2446         case MovHint:
2447         case InitializeEntrypointArguments:
2448         case ZombieHint:
2449         case ExitOK:
2450         case BottomValue:
2451         case TypeOf:
2452         case PutByIdWithThis:
2453         case PutByValWithThis:
2454         case GetByValWithThis:
2455         case CompareEqPtr:
2456         case NumberToStringWithValidRadixConstant:
2457         case GetGlobalThis:
2458         case ExtractValueFromWeakMapGet:
2459         case CPUIntrinsic:
2460         case FilterCallLinkStatus:
2461         case FilterGetByIdStatus:
2462         case FilterPutByIdStatus:
2463         case FilterInByIdStatus:
2464         case InvalidationPoint:
2465             break;
2466 #else
2467         default:
2468             break;
2469 #endif
2470         }
2471     }
2472
2473     void watchHavingABadTime(Node* node)
2474     {
2475         JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
2476
2477         // If this global object is not having a bad time, watch it. We go down this path anytime the code
2478         // does an array allocation. The types of array allocations may change if we start to have a bad
2479         // time. It's easier to reason about this if we know that whenever the types change after we start
2480         // optimizing, the code just gets thrown out. Doing this at FixupPhase is just early enough, since
2481         // prior to this point nobody should have been doing optimizations based on the indexing type of
2482         // the allocation.
2483         if (!globalObject->isHavingABadTime()) {
2484             m_graph.watchpoints().addLazily(globalObject->havingABadTimeWatchpoint());
2485             m_graph.freeze(globalObject);
2486         }
2487     }
2488     
2489     template<UseKind useKind>
2490     void createToString(Node* node, Edge& edge)
2491     {
2492         Node* toString = m_insertionSet.insertNode(
2493             m_indexInBlock, SpecString, ToString, node->origin,
2494             Edge(edge.node(), useKind));
2495         switch (useKind) {
2496         case Int32Use:
2497         case Int52RepUse:
2498         case DoubleRepUse:
2499         case NotCellUse:
2500             toString->clearFlags(NodeMustGenerate);
2501             break;
2502         default:
2503             break;
2504         }
2505         edge.setNode(toString);
2506     }
2507     
2508     template<UseKind useKind>
2509     void attemptToForceStringArrayModeByToStringConversion(ArrayMode& arrayMode, Node* node)
2510     {
2511         ASSERT(arrayMode == ArrayMode(Array::Generic, Array::Read) || arrayMode == ArrayMode(Array::Generic, Array::OriginalNonArray, Array::Read));
2512         
2513         if (!m_graph.canOptimizeStringObjectAccess(node->origin.semantic))
2514             return;
2515         
2516         addCheckStructureForOriginalStringObjectUse(useKind, node->origin, node->child1().node());
2517         createToString<useKind>(node, node->child1());
2518         arrayMode = ArrayMode(Array::String, Array::Read);
2519     }
2520
2521     void addCheckStructureForOriginalStringObjectUse(UseKind useKind, const NodeOrigin& origin, Node* node)
2522     {
2523         RELEASE_ASSERT(useKind == StringObjectUse || useKind == StringOrStringObjectUse);
2524
2525         StructureSet set;
2526         set.add(m_graph.globalObjectFor(node->origin.semantic)->stringObjectStructure());
2527         if (useKind == StringOrStringObjectUse)
2528             set.add(vm().stringStructure.get());
2529
2530         m_insertionSet.insertNode(
2531             m_indexInBlock, SpecNone, CheckStructure, origin,
2532             OpInfo(m_graph.addStructureSet(set)), Edge(node, CellUse));
2533     }
2534     
2535     template<UseKind useKind>
2536     void convertStringAddUse(Node* node, Edge& edge)
2537     {
2538         if (useKind == StringUse) {
2539             observeUseKindOnNode<StringUse>(edge.node());
2540             m_insertionSet.insertNode(
2541                 m_indexInBlock, SpecNone, Check, node->origin,
2542                 Edge(edge.node(), StringUse));
2543             edge.setUseKind(KnownStringUse);
2544             return;
2545         }
2546         
2547         observeUseKindOnNode<useKind>(edge.node());
2548         createToString<useKind>(node, edge);
2549     }
2550     
2551     void convertToMakeRope(Node* node)
2552     {
2553         node->setOpAndDefaultFlags(MakeRope);
2554         fixupMakeRope(node);
2555     }
2556     
2557     void fixupMakeRope(Node* node)
2558     {
2559         for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
2560             Edge& edge = node->children.child(i);
2561             if (!edge)
2562                 break;
2563             edge.setUseKind(KnownStringUse);
2564             JSString* string = edge->dynamicCastConstant<JSString*>(vm());
2565             if (!string)
2566                 continue;
2567             if (string->length())
2568                 continue;
2569             
2570             // Don't allow the MakeRope to have zero children.
2571             if (!i && !node->child2())
2572                 break;
2573             
2574             node->children.removeEdge(i--);
2575         }
2576         
2577         if (!node->child2()) {
2578             ASSERT(!node->child3());
2579             node->convertToIdentity();
2580         }
2581     }
2582
2583     void fixupIsCellWithType(Node* node)
2584     {
2585         Optional<SpeculatedType> filter = node->speculatedTypeForQuery();
2586         if (filter) {
2587             switch (filter.value()) {
2588             case SpecString:
2589                 if (node->child1()->shouldSpeculateString()) {
2590                     m_insertionSet.insertNode(
2591                         m_indexInBlock, SpecNone, Check, node->origin,
2592                         Edge(node->child1().node(), StringUse));
2593                     m_graph.convertToConstant(node, jsBoolean(true));
2594                     observeUseKindOnNode<StringUse>(node);
2595                     return;
2596                 }
2597                 break;
2598
2599             case SpecProxyObject:
2600                 if (node->child1()->shouldSpeculateProxyObject()) {
2601                     m_insertionSet.insertNode(
2602                         m_indexInBlock, SpecNone, Check, node->origin,
2603                         Edge(node->child1().node(), ProxyObjectUse));
2604                     m_graph.convertToConstant(node, jsBoolean(true));
2605                     observeUseKindOnNode<ProxyObjectUse>(node);
2606                     return;
2607                 }
2608                 break;
2609
2610             case SpecRegExpObject:
2611                 if (node->child1()->shouldSpeculateRegExpObject()) {
2612                     m_insertionSet.insertNode(
2613                         m_indexInBlock, SpecNone, Check, node->origin,
2614                         Edge(node->child1().node(), RegExpObjectUse));
2615                     m_graph.convertToConstant(node, jsBoolean(true));
2616                     observeUseKindOnNode<RegExpObjectUse>(node);
2617                     return;
2618                 }
2619                 break;
2620
2621             case SpecArray:
2622                 if (node->child1()->shouldSpeculateArray()) {
2623                     m_insertionSet.insertNode(
2624                         m_indexInBlock, SpecNone, Check, node->origin,
2625                         Edge(node->child1().node(), ArrayUse));
2626                     m_graph.convertToConstant(node, jsBoolean(true));
2627                     observeUseKindOnNode<ArrayUse>(node);
2628                     return;
2629                 }
2630                 break;
2631
2632             case SpecDerivedArray:
2633                 if (node->child1()->shouldSpeculateDerivedArray()) {
2634                     m_insertionSet.insertNode(
2635                         m_indexInBlock, SpecNone, Check, node->origin,
2636                         Edge(node->child1().node(), DerivedArrayUse));
2637                     m_graph.convertToConstant(node, jsBoolean(true));
2638                     observeUseKindOnNode<DerivedArrayUse>(node);
2639                     return;
2640                 }
2641                 break;
2642             }
2643         }
2644
2645         if (node->child1()->shouldSpeculateCell()) {
2646             fixEdge<CellUse>(node->child1());
2647             return;
2648         }
2649
2650         if (node->child1()->shouldSpeculateNotCell()) {
2651             m_insertionSet.insertNode(
2652                 m_indexInBlock, SpecNone, Check, node->origin,
2653                 Edge(node->child1().node(), NotCellUse));
2654             m_graph.convertToConstant(node, jsBoolean(false));
2655             observeUseKindOnNode<NotCellUse>(node);
2656             return;
2657         }
2658     }
2659
2660     void fixupGetPrototypeOf(Node* node)
2661     {
2662         // Reflect.getPrototypeOf only accepts Objects. For Reflect.getPrototypeOf, ByteCodeParser attaches ObjectUse edge filter before fixup phase.
2663         if (node->child1().useKind() != ObjectUse) {
2664             if (node->child1()->shouldSpeculateString()) {
2665                 insertCheck<StringUse>(node->child1().node());
2666                 m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->stringPrototype()));
2667                 return;
2668             }
2669             if (node->child1()->shouldSpeculateInt32()) {
2670                 insertCheck<Int32Use>(node->child1().node());
2671                 m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->numberPrototype()));
2672                 return;
2673             }
2674             if (node->child1()->shouldSpeculateInt52()) {
2675                 insertCheck<Int52RepUse>(node->child1().node());
2676                 m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->numberPrototype()));
2677                 return;
2678             }
2679             if (node->child1()->shouldSpeculateNumber()) {
2680                 insertCheck<NumberUse>(node->child1().node());
2681                 m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->numberPrototype()));
2682                 return;
2683             }
2684             if (node->child1()->shouldSpeculateSymbol()) {
2685                 insertCheck<SymbolUse>(node->child1().node());
2686                 m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->symbolPrototype()));
2687                 return;
2688             }
2689             if (node->child1()->shouldSpeculateBoolean()) {
2690                 insertCheck<BooleanUse>(node->child1().node());
2691                 m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->booleanPrototype()));
2692                 return;
2693             }
2694         }
2695
2696         if (node->child1()->shouldSpeculateFinalObject()) {
2697             fixEdge<FinalObjectUse>(node->child1());
2698             node->clearFlags(NodeMustGenerate);
2699             return;
2700         }
2701         if (node->child1()->shouldSpeculateArray()) {
2702             fixEdge<ArrayUse>(node->child1());
2703             node->clearFlags(NodeMustGenerate);
2704             return;
2705         }
2706         if (node->child1()->shouldSpeculateFunction()) {
2707             fixEdge<FunctionUse>(node->child1());
2708             node->clearFlags(NodeMustGenerate);
2709             return;
2710         }
2711     }
2712
2713     void fixupToThis(Node* node)
2714     {
2715         bool isStrictMode = m_graph.isStrictModeFor(node->origin.semantic);
2716
2717         if (isStrictMode) {
2718             if (node->child1()->shouldSpeculateBoolean()) {
2719                 fixEdge<BooleanUse>(node->child1());
2720                 node->convertToIdentity();
2721                 return;
2722             }
2723
2724             if (node->child1()->shouldSpeculateInt32()) {
2725                 fixEdge<Int32Use>(node->child1());
2726                 node->convertToIdentity();
2727                 return;
2728             }
2729
2730             if (node->child1()->shouldSpeculateInt52()) {
2731                 fixEdge<Int52RepUse>(node->child1());
2732                 node->convertToIdentity();
2733                 node->setResult(NodeResultInt52);
2734                 return;
2735             }
2736
2737             if (node->child1()->shouldSpeculateNumber()) {
2738                 fixEdge<DoubleRepUse>(node->child1());
2739                 node->convertToIdentity();
2740                 node->setResult(NodeResultDouble);
2741                 return;
2742             }
2743
2744             if (node->child1()->shouldSpeculateSymbol()) {
2745                 fixEdge<SymbolUse>(node->child1());
2746                 node->convertToIdentity();
2747                 return;
2748             }
2749
2750             if (node->child1()->shouldSpeculateStringIdent()) {
2751                 fixEdge<StringIdentUse>(node->child1());
2752                 node->convertToIdentity();
2753                 return;
2754             }
2755
2756             if (node->child1()->shouldSpeculateString()) {
2757                 fixEdge<StringUse>(node->child1());
2758                 node->convertToIdentity();
2759                 return;
2760             }
2761             
2762             if (node->child1()->shouldSpeculateBigInt()) {
2763                 fixEdge<BigIntUse>(node->child1());
2764                 node->convertToIdentity();
2765                 return;
2766             }
2767         }
2768
2769         if (node->child1()->shouldSpeculateOther()) {
2770             if (isStrictMode) {
2771                 fixEdge<OtherUse>(node->child1());
2772                 node->convertToIdentity();
2773                 return;
2774             }
2775
2776             m_insertionSet.insertNode(
2777                 m_indexInBlock, SpecNone, Check, node->origin,
2778                 Edge(node->child1().node(), OtherUse));
2779             observeUseKindOnNode<OtherUse>(node->child1().node());
2780             m_graph.convertToConstant(
2781                 node, m_graph.globalThisObjectFor(node->origin.semantic));
2782             return;
2783         }
2784
2785         // FIXME: This should cover other use cases but we don't have use kinds for them. It's not critical,
2786         // however, since we cover all the missing cases in constant folding.
2787         // https://bugs.webkit.org/show_bug.cgi?id=157213
2788         if (node->child1()->shouldSpeculateStringObject()) {
2789             fixEdge<StringObjectUse>(node->child1());
2790             node->convertToIdentity();
2791             return;
2792         }
2793
2794         if (isFinalObjectSpeculation(node->child1()->prediction())) {
2795             fixEdge<FinalObjectUse>(node->child1());
2796             node->convertToIdentity();
2797             return;
2798         }
2799     }
2800     
2801     void fixupToPrimitive(Node* node)
2802     {
2803         if (node->child1()->shouldSpeculateInt32()) {
2804             fixEdge<Int32Use>(node->child1());
2805             node->convertToIdentity();
2806             return;
2807         }
2808         
2809         if (node->child1()->shouldSpeculateString()) {
2810             fixEdge<StringUse>(node->child1());
2811             node->convertToIdentity();
2812             return;
2813         }
2814         
2815         if (node->child1()->shouldSpeculateStringObject()
2816             && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
2817             addCheckStructureForOriginalStringObjectUse(StringObjectUse, node->origin, node->child1().node());
2818             fixEdge<StringObjectUse>(node->child1());
2819             node->convertToToString();
2820             return;
2821         }
2822         
2823         if (node->child1()->shouldSpeculateStringOrStringObject()
2824             && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
2825             addCheckStructureForOriginalStringObjectUse(StringOrStringObjectUse, node->origin, node->child1().node());
2826             fixEdge<StringOrStringObjectUse>(node->child1());
2827             node->convertToToString();
2828             return;
2829         }
2830     }
2831
2832     void fixupToNumber(Node* node)
2833     {
2834         // At first, attempt to fold Boolean or Int32 to Int32.
2835         if (node->child1()->shouldSpeculateInt32OrBoolean()) {
2836             if (isInt32Speculation(node->getHeapPrediction())) {
2837                 fixIntOrBooleanEdge(node->child1());
2838                 node->convertToIdentity();
2839                 return;
2840             }
2841         }
2842
2843         // If the prediction of the child is Number, we attempt to convert ToNumber to Identity.
2844         if (node->child1()->shouldSpeculateNumber()) {
2845             if (isInt32Speculation(node->getHeapPrediction())) {
2846                 // If the both predictions of this node and the child is Int32, we just convert ToNumber to Identity, that's simple.
2847                 if (node->child1()->shouldSpeculateInt32()) {
2848                     fixEdge<Int32Use>(node->child1());
2849                     node->convertToIdentity();
2850                     return;
2851                 }
2852
2853                 // 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.
2854                 // 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.
2855                 fixEdge<DoubleRepUse>(node->child1());
2856                 node->setOp(DoubleAsInt32);
2857                 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
2858                     node->setArithMode(Arith::CheckOverflow);
2859                 else
2860                     node->setArithMode(Arith::CheckOverflowAndNegativeZero);
2861                 return;
2862             }
2863
2864             fixEdge<DoubleRepUse>(node->child1());
2865             node->convertToIdentity();
2866             node->setResult(NodeResultDouble);
2867             return;
2868         }
2869
2870         fixEdge<UntypedUse>(node->child1());
2871         node->setResult(NodeResultJS);
2872     }
2873
2874     void fixupToObject(Node* node)
2875     {
2876         if (node->child1()->shouldSpeculateObject()) {
2877             fixEdge<ObjectUse>(node->child1());
2878             node->convertToIdentity();
2879             return;
2880         }
2881
2882         // ToObject(Null/Undefined) can throw an error. We can emit filters to convert ToObject to CallObjectConstructor.
2883
2884         JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
2885
2886         if (node->child1()->shouldSpeculateString()) {
2887             insertCheck<StringUse>(node->child1().node());
2888             fixEdge<KnownStringUse>(node->child1());
2889             node->convertToNewStringObject(m_graph.registerStructure(globalObject->stringObjectStructure()));
2890             return;
2891         }
2892
2893         if (node->child1()->shouldSpeculateSymbol()) {
2894             insertCheck<SymbolUse>(node->child1().node());
2895             node->convertToCallObjectConstructor(m_graph.freeze(globalObject));
2896             return;
2897         }
2898
2899         if (node->child1()->shouldSpeculateNumber()) {
2900             insertCheck<NumberUse>(node->child1().node());
2901             node->convertToCallObjectConstructor(m_graph.freeze(globalObject));
2902             return;
2903         }
2904
2905         if (node->child1()->shouldSpeculateBoolean()) {
2906             insertCheck<BooleanUse>(node->child1().node());
2907             node->convertToCallObjectConstructor(m_graph.freeze(globalObject));
2908             return;
2909         }
2910
2911         fixEdge<UntypedUse>(node->child1());
2912     }
2913
2914     void fixupCallObjectConstructor(Node* node)
2915     {
2916         if (node->child1()->shouldSpeculateObject()) {
2917             fixEdge<ObjectUse>(node->child1());
2918             node->convertToIdentity();
2919             return;
2920         }
2921
2922         if (node->child1()->shouldSpeculateString()) {
2923             auto* globalObject = jsCast<JSGlobalObject*>(node->cellOperand()->cell());
2924             insertCheck<StringUse>(node->child1().node());
2925             fixEdge<KnownStringUse>(node->child1());
2926             node->convertToNewStringObject(m_graph.registerStructure(globalObject->stringObjectStructure()));
2927             return;
2928         }
2929
2930         // While ToObject(Null/Undefined) throws an error, CallObjectConstructor(Null/Undefined) generates a new empty object.
2931         if (node->child1()->shouldSpeculateOther()) {
2932             insertCheck<OtherUse>(node->child1().node());
2933             node->convertToNewObject(m_graph.registerStructure(jsCast<JSGlobalObject*>(node->cellOperand()->cell())->objectStructureForObjectConstructor()));
2934             return;
2935         }
2936
2937         fixEdge<UntypedUse>(node->child1());
2938     }
2939     
2940     void fixupToStringOrCallStringConstructor(Node* node)
2941     {
2942         if (node->child1()->shouldSpeculateString()) {
2943             fixEdge<StringUse>(node->child1());
2944             node->convertToIdentity();
2945             return;
2946         }
2947         
2948         if (node->child1()->shouldSpeculateStringObject()
2949             && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
2950             addCheckStructureForOriginalStringObjectUse(StringObjectUse, node->origin, node->child1().node());
2951             fixEdge<StringObjectUse>(node->child1());
2952             return;
2953         }
2954         
2955         if (node->child1()->shouldSpeculateStringOrStringObject()
2956             && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
2957             addCheckStructureForOriginalStringObjectUse(StringOrStringObjectUse, node->origin, node->child1().node());
2958             fixEdge<StringOrStringObjectUse>(node->child1());
2959             return;
2960         }
2961         
2962         if (node->child1()->shouldSpeculateCell()) {
2963             fixEdge<CellUse>(node->child1());
2964             return;
2965         }
2966
2967         if (node->child1()->shouldSpeculateInt32()) {
2968             fixEdge<Int32Use>(node->child1());
2969             node->clearFlags(NodeMustGenerate);
2970             return;
2971         }
2972
2973         if (node->child1()->shouldSpeculateInt52()) {
2974             fixEdge<Int52RepUse>(node->child1());
2975             node->clearFlags(NodeMustGenerate);
2976             return;
2977         }
2978
2979         if (node->child1()->shouldSpeculateNumber()) {
2980             fixEdge<DoubleRepUse>(node->child1());
2981             node->clearFlags(NodeMustGenerate);
2982             return;
2983         }
2984
2985         // ToString(Symbol) throws an error. So if the child1 can include Symbols,
2986         // we need to care about it in the clobberize. In the following case,
2987         // since NotCellUse edge filter is used and this edge filters Symbols,
2988         // we can say that ToString never throws an error!
2989         if (node->child1()->shouldSpeculateNotCell()) {
2990             fixEdge<NotCellUse>(node->child1());
2991             node->clearFlags(NodeMustGenerate);
2992             return;
2993         }
2994     }
2995
2996     void fixupStringValueOf(Node* node)
2997     {
2998         if (node->child1()->shouldSpeculateString()) {
2999             fixEdge<StringUse>(node->child1());
3000             node->convertToIdentity();
3001             return;
3002         }
3003
3004         if (node->child1()->shouldSpeculateStringObject()) {
3005             fixEdge<StringObjectUse>(node->child1());
3006             node->convertToToString();
3007             // It does not need to look up a toString property for the StringObject case. So we can clear NodeMustGenerate.
3008             node->clearFlags(NodeMustGenerate);
3009             return;
3010         }
3011
3012         if (node->child1()->shouldSpeculateStringOrStringObject()) {
3013             fixEdge<StringOrStringObjectUse>(node->child1());
3014             node->convertToToString();
3015             // It does not need to look up a toString property for the StringObject case. So we can clear NodeMustGenerate.
3016             node->clearFlags(NodeMustGenerate);
3017             return;
3018         }
3019     }
3020
3021     bool attemptToMakeFastStringAdd(Node* node)
3022     {
3023         bool goodToGo = true;
3024         m_graph.doToChildren(
3025             node,
3026             [&] (Edge& edge) {
3027                 if (edge->shouldSpeculateString())
3028                     return;
3029                 if (m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
3030                     if (edge->shouldSpeculateStringObject())
3031                         return;
3032                     if (edge->shouldSpeculateStringOrStringObject())
3033                         return;
3034                 }
3035                 goodToGo = false;
3036             });
3037         if (!goodToGo)
3038             return false;
3039
3040         m_graph.doToChildren(
3041             node,
3042             [&] (Edge& edge) {
3043                 if (edge->shouldSpeculateString()) {
3044                     convertStringAddUse<StringUse>(node, edge);
3045                     return;
3046                 }
3047                 if (!Options::useConcurrentJIT())
3048                     ASSERT(m_graph.canOptimizeStringObjectAccess(node->origin.semantic));
3049                 if (edge->shouldSpeculateStringObject()) {
3050                     addCheckStructureForOriginalStringObjectUse(StringObjectUse, node->origin, edge.node());
3051                     convertStringAddUse<StringObjectUse>(node, edge);
3052                     return;
3053                 }
3054                 if (edge->shouldSpeculateStringOrStringObject()) {
3055                     addCheckStructureForOriginalStringObjectUse(StringOrStringObjectUse, node->origin, edge.node());
3056                     convertStringAddUse<StringOrStringObjectUse>(node, edge);
3057                     return;
3058                 }
3059                 RELEASE_ASSERT_NOT_REACHED();
3060             });
3061         
3062         convertToMakeRope(node);
3063         return true;
3064     }
3065
3066     void fixupGetAndSetLocalsInBlock(BasicBlock* block)
3067     {
3068         if (!block)
3069             return;
3070         ASSERT(block->isReachable);
3071         m_block = block;
3072         for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
3073             Node* node = m_currentNode = block->at(m_indexInBlock);
3074             if (node->op() != SetLocal && node->op() != GetLocal)
3075                 continue;
3076             
3077             VariableAccessData* variable = node->variableAccessData();
3078             switch (node->op()) {
3079             case GetLocal:
3080                 switch (variable->flushFormat()) {
3081                 case FlushedDouble:
3082                     node->setResult(NodeResultDouble);
3083                     break;
3084                 case FlushedInt52:
3085                     node->setResult(NodeResultInt52);
3086                     break;
3087                 default:
3088                     break;
3089                 }
3090                 break;
3091                 
3092             case SetLocal:
3093                 // NOTE: Any type checks we put here may get hoisted by fixupChecksInBlock(). So, if we
3094                 // add new type checking use kind for SetLocals, we need to modify that code as well.
3095                 
3096                 switch (variable->flushFormat()) {
3097                 case FlushedJSValue:
3098                     break;
3099                 case FlushedDouble:
3100                     fixEdge<DoubleRepUse>(node->child1());
3101                     break;
3102                 case FlushedInt32:
3103                     fixEdge<Int32Use>(node->child1());
3104                     break;
3105                 case FlushedInt52:
3106                     fixEdge<Int52RepUse>(node->child1());
3107                     break;
3108                 case FlushedCell:
3109                     fixEdge<CellUse>(node->child1());
3110                     break;
3111                 case FlushedBoolean:
3112                     fixEdge<BooleanUse>(node->child1());
3113                     break;
3114                 default:
3115                     RELEASE_ASSERT_NOT_REACHED();
3116                     break;
3117                 }
3118                 break;
3119                 
3120             default:
3121                 RELEASE_ASSERT_NOT_REACHED();
3122                 break;
3123             }
3124         }
3125         m_insertionSet.execute(block);
3126     }
3127     
3128     void addStringReplacePrimordialChecks(Node* searchRegExp)
3129     {
3130         Node* node = m_currentNode;
3131
3132         // Check that structure of searchRegExp is RegExp object
3133         m_insertionSet.insertNode(
3134             m_indexInBlock, SpecNone, Check, node->origin,
3135             Edge(searchRegExp, RegExpObjectUse));
3136
3137         auto emitPrimordialCheckFor = [&] (JSValue primordialProperty, UniquedStringImpl* propertyUID) {
3138             unsigned index = m_graph.identifiers().ensure(propertyUID);
3139
3140             Node* actualProperty = m_insertionSet.insertNode(
3141                 m_indexInBlock, SpecNone, TryGetById, node->origin,
3142                 OpInfo(index), OpInfo(SpecFunction), Edge(searchRegExp, CellUse));
3143
3144             m_insertionSet.insertNode(
3145                 m_indexInBlock, SpecNone, CheckCell, node->origin,
3146                 OpInfo(m_graph.freeze(primordialProperty)), Edge(actualProperty, CellUse));
3147         };
3148
3149         JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
3150
3151         // Check that searchRegExp.exec is the primordial RegExp.prototype.exec
3152         emitPrimordialCheckFor(globalObject->regExpProtoExecFunction(), vm().propertyNames->exec.impl());
3153         // Check that searchRegExp.global is the primordial RegExp.prototype.global
3154         emitPrimordialCheckFor(globalObject->regExpProtoGlobalGetter(), vm().propertyNames->global.impl());
3155         // Check that searchRegExp.unicode is the primordial RegExp.prototype.unicode
3156         emitPrimordialCheckFor(globalObject->regExpProtoUnicodeGetter(), vm().propertyNames->unicode.impl());
3157         // Check that searchRegExp[Symbol.match] is the primordial RegExp.prototype[Symbol.replace]
3158         emitPrimordialCheckFor(globalObject->regExpProtoSymbolReplaceFunction(), vm().propertyNames->replaceSymbol.impl());
3159     }
3160
3161     Node* checkArray(ArrayMode arrayMode, const NodeOrigin& origin, Node* array, Node* index, bool (*storageCheck)(const ArrayMode&) = canCSEStorage)
3162     {
3163         ASSERT(arrayMode.isSpecific());
3164         
3165         if (arrayMode.type() == Array::String) {
3166             m_insertionSet.insertNode(
3167                 m_indexInBlock, SpecNone, Check, origin, Edge(array, StringUse));
3168         } else {
3169             // Note that we only need to be using a structure check if we opt for SaneChain, since
3170             // that needs to protect against JSArray's __proto__ being changed.
3171             Structure* structure = arrayMode.originalArrayStructure(m_graph, origin.semantic);
3172         
3173             Edge indexEdge = index ? Edge(index, Int32Use) : Edge();
3174             
3175             if (arrayMode.doesConversion()) {
3176                 if (structure) {
3177                     m_insertionSet.insertNode(
3178                         m_indexInBlock, SpecNone, ArrayifyToStructure, origin,
3179                         OpInfo(m_graph.registerStructure(structure)), OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
3180                 } else {
3181                     m_insertionSet.insertNode(
3182                         m_indexInBlock, SpecNone, Arrayify, origin,
3183                         OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
3184                 }
3185             } else {
3186                 if (structure) {
3187                     m_insertionSet.insertNode(
3188                         m_indexInBlock, SpecNone, CheckStructure, origin,
3189                         OpInfo(m_graph.addStructureSet(structure)), Edge(array, CellUse));
3190                 } else {
3191                     m_insertionSet.insertNode(
3192                         m_indexInBlock, SpecNone, CheckArray, origin,
3193                         OpInfo(arrayMode.asWord()), Edge(array, CellUse));
3194                 }
3195             }
3196         }
3197         
3198         if (!storageCheck(arrayMode))
3199             return nullptr;
3200         
3201         if (arrayMode.usesButterfly()) {
3202             return m_insertionSet.insertNode(
3203                 m_indexInBlock, SpecNone, GetButterfly, origin, Edge(array, CellUse));
3204         }
3205         
3206         return m_insertionSet.insertNode(
3207             m_indexInBlock, SpecNone, GetIndexedPropertyStorage, origin,
3208             OpInfo(arrayMode.asWord()), Edge(array, KnownCellUse));
3209     }
3210     
3211     void blessArrayOperation(Edge base, Edge index, Edge& storageChild)
3212     {
3213         Node* node = m_currentNode;
3214         
3215         switch (node->arrayMode().type()) {
3216         case Array::ForceExit: {
3217             m_insertionSet.insertNode(
3218                 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
3219             return;
3220         }
3221             
3222         case Array::SelectUsingPredictions:
3223         case Array::Unprofiled:
3224             RELEASE_ASSERT_NOT_REACHED();
3225             return;
3226             
3227         case Array::Generic:
3228             return;
3229             
3230         default: {
3231             Node* storage = checkArray(node->arrayMode(), node->origin, base.node(), index.node());
3232             if (!storage)
3233                 return;
3234             
3235             storageChild = Edge(storage);
3236             return;
3237         } }
3238     }
3239     
3240     bool alwaysUnboxSimplePrimitives()
3241     {
3242 #if USE(JSVALUE64)
3243         return false;
3244 #else
3245         // Any boolean, int, or cell value is profitable to unbox on 32-bit because it
3246         // reduces traffic.
3247         return true;
3248 #endif
3249     }
3250
3251     template<UseKind useKind>
3252     void observeUseKindOnNode(Node* node)
3253     {
3254         if (useKind == UntypedUse)
3255             return;
3256         observeUseKindOnNode(node, useKind);
3257     }
3258
3259     void observeUseKindOnEdge(Edge edge)
3260     {
3261         observeUseKindOnNode(edge.node(), edge.useKind());
3262     }
3263
3264     void observeUseKindOnNode(Node* node, UseKind useKind)
3265     {
3266         if (node->op() != GetLocal)
3267             return;
3268         
3269         // FIXME: The way this uses alwaysUnboxSimplePrimitives() is suspicious.
3270         // https://bugs.webkit.org/show_bug.cgi?id=121518
3271         
3272         VariableAccessData* variable = node->variableAccessData();
3273         switch (useKind) {
3274         case Int32Use:
3275         case KnownInt32Use:
3276             if (alwaysUnboxSimplePrimitives()
3277                 || isInt32Speculation(variable->prediction()))
3278                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
3279             break;
3280         case NumberUse:
3281         case RealNumberUse:
3282         case DoubleRepUse:
3283         case DoubleRepRealUse:
3284             if (variable->doubleFormatState() == UsingDoubleFormat)
3285                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
3286             break;
3287         case BooleanUse:
3288         case KnownBooleanUse:
3289             if (alwaysUnboxSimplePrimitives()
3290                 || isBooleanSpeculation(variable->prediction()))
3291                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
3292             break;
3293         case Int52RepUse:
3294             if (!isInt32Speculation(variable->prediction()) && isInt32OrInt52Speculation(variable->prediction()))
3295                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
3296             break;
3297         case CellUse:
3298         case KnownCellUse:
3299         case ObjectUse:
3300         case FunctionUse:
3301         case StringUse:
3302         case KnownStringUse:
3303         case SymbolUse:
3304         case BigIntUse:
3305         case StringObjectUse:
3306         case StringOrStringObjectUse:
3307             if (alwaysUnboxSimplePrimitives()
3308                 || isCellSpeculation(variable->prediction()))
3309                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
3310             break;
3311         default:
3312             break;
3313         }
3314     }
3315     
3316     template<UseKind useKind>
3317     void fixEdge(Edge& edge)
3318     {
3319         observeUseKindOnNode<useKind>(edge.node());
3320         edge.setUseKind(useKind);
3321     }
3322     
3323     unsigned indexForChecks()
3324     {
3325         unsigned index = m_indexInBlock;
3326         while (!m_block->at(index)->origin.exitOK)
3327             index--;
3328         return index;
3329     }
3330     
3331     NodeOrigin originForCheck(unsigned index)
3332     {
3333         return m_block->at(index)->origin.withSemantic(m_currentNode->origin.semantic);
3334     }
3335     
3336     void speculateForBarrier(Edge value)
3337     {
3338         // Currently, the DFG won't take advantage of this speculation. But, we want to do it in
3339         // the DFG anyway because if such a speculation would be wrong, we want to know before
3340         // we do an expensive compile.
3341         
3342         if (value->shouldSpeculateInt32()) {
3343             insertCheck<Int32Use>(value.node());
3344             return;
3345         }
3346             
3347         if (value->shouldSpeculateBoolean()) {
3348             insertCheck<BooleanUse>(value.node());
3349             return;
3350         }
3351             
3352         if (value->shouldSpeculateOther()) {
3353             insertCheck<OtherUse>(value.node());
3354             return;
3355         }
3356             
3357         if (value->shouldSpeculateNumber()) {
3358             insertCheck<NumberUse>(value.node());
3359             return;
3360         }
3361             
3362         if (value->shouldSpeculateNotCell()) {
3363             insertCheck<NotCellUse>(value.node());
3364             return;
3365         }
3366     }
3367     
3368     template<UseKind useKind>
3369     void insertCheck(Node* node)
3370     {
3371         observeUseKindOnNode<useKind>(node);
3372         unsigned index = indexForChecks();
3373         m_insertionSet.insertNode(index, SpecNone, Check, originForCheck(index), Edge(node, useKind));
3374     }
3375
3376     void fixIntConvertingEdge(Edge& edge)
3377     {
3378         Node* node = edge.node();
3379         if (node->shouldSpeculateInt32OrBoolean()) {
3380             fixIntOrBooleanEdge(edge);
3381             return;
3382         }
3383         
3384         UseKind useKind;
3385         if (node->shouldSpeculateInt52())
3386             useKind = Int52RepUse;
3387         else if (node->shouldSpeculateNumber())
3388             useKind = DoubleRepUse;
3389         else
3390             useKind = NotCellUse;
3391         Node* newNode = m_insertionSet.insertNode(
3392             m_indexInBlock, SpecInt32Only, ValueToInt32, m_currentNode->origin,
3393             Edge(node, useKind));
3394         observeUseKindOnNode(node, useKind);
3395         
3396         edge = Edge(newNode, KnownInt32Use);
3397     }
3398     
3399     void fixIntOrBooleanEdge(Edge& edge)
3400     {
3401         Node* node = edge.node();
3402         if (!node->sawBooleans()) {
3403             fixEdge<Int32Use>(edge);
3404             return;
3405         }
3406         
3407         UseKind useKind;
3408         if (node->shouldSpeculateBoolean())
3409             useKind = BooleanUse;
3410         else
3411             useKind = UntypedUse;
3412         Node* newNode = m_insertionSet.insertNode(
3413             m_indexInBlock, SpecInt32Only, BooleanToNumber, m_currentNode->origin,
3414             Edge(node, useKind));
3415         observeUseKindOnNode(node, useKind);
3416         
3417         edge = Edge(newNode, Int32Use);
3418     }
3419     
3420     void fixDoubleOrBooleanEdge(Edge& edge)
3421     {
3422         Node* node = edge.node();
3423         if (!node->sawBooleans()) {
3424             fixEdge<DoubleRepUse>(edge);
3425             return;
3426         }
3427         
3428         UseKind useKind;
3429         if (node->shouldSpeculateBoolean())
3430             useKind = BooleanUse;
3431         else
3432             useKind = UntypedUse;
3433         Node* newNode = m_insertionSet.insertNode(
3434             m_indexInBlock, SpecInt32Only, BooleanToNumber, m_currentNode->origin,
3435             Edge(node, useKind));
3436         observeUseKindOnNode(node, useKind);
3437         
3438         edge = Edge(newNode, DoubleRepUse);
3439     }
3440     
3441     void truncateConstantToInt32(Edge& edge)
3442     {
3443         Node* oldNode = edge.node();
3444         
3445         JSValue value = oldNode->asJSValue();
3446         if (value.isInt32())
3447             return;
3448         
3449         value = jsNumber(JSC::toInt32(value.asNumber()));
3450         ASSERT(value.isInt32());
3451         edge.setNode(m_insertionSet.insertNode(
3452             m_indexInBlock, SpecInt32Only, JSConstant, m_currentNode->origin,
3453             OpInfo(m_graph.freeze(value))));
3454     }
3455     
3456     void truncateConstantsIfNecessary(Node* node, AddSpeculationMode mode)
3457     {
3458         if (mode != SpeculateInt32AndTruncateConstants)
3459             return;
3460         
3461         ASSERT(node->child1()->hasConstant() || node->child2()->hasConstant());
3462         if (node->child1()->hasConstant())
3463             truncateConstantToInt32(node->child1());
3464         else
3465             truncateConstantToInt32(node->child2());
3466     }
3467
3468     bool attemptToMakeIntegerAdd(Node* node)
3469     {
3470         AddSpeculationMode mode = m_graph.addSpeculationMode(node, FixupPass);
3471         if (mode != DontSpeculateInt32) {
3472             truncateConstantsIfNecessary(node, mode);
3473             fixIntOrBooleanEdge(node->child1());
3474             fixIntOrBooleanEdge(node->child2());
3475             if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
3476                 node->setArithMode(Arith::Unchecked);
3477             else
3478                 node->setArithMode(Arith::CheckOverflow);
3479             return true;
3480         }
3481         
3482         if (m_graph.addShouldSpeculateInt52(node)) {
3483             fixEdge<Int52RepUse>(node->child1());
3484             fixEdge<Int52RepUse>(node->child2());
3485             node->setArithMode(Arith::CheckOverflow);
3486             node->setResult(NodeResultInt52);
3487             return true;
3488         }
3489         
3490         return false;
3491     }
3492     
3493     bool attemptToMakeGetArrayLength(Node* node)
3494     {
3495         if (!isInt32Speculation(node->prediction()))
3496             return false;
3497         CodeBlock* profiledBlock = m_graph.baselineCodeBlockFor(node->origin.semantic);
3498         ArrayProfile* arrayProfile = 
3499             profiledBlock->getArrayProfile(node->origin.semantic.bytecodeIndex());
3500         ArrayMode arrayMode = ArrayMode(Array::SelectUsingPredictions, Array::Read);
3501         if (arrayProfile) {
3502             ConcurrentJSLocker locker(profiledBlock->m_lock);
3503             arrayProfile->computeUpdatedPrediction(locker, profiledBlock);
3504             arrayMode = ArrayMode::fromObserved(locker, arrayProfile, Array::Read, false);
3505             if (arrayMode.type() == Array::Unprofiled) {
3506                 // For normal array operations, it makes sense to treat Unprofiled
3507                 // accesses as ForceExit and get more data rather than using
3508                 // predictions and then possibly ending up with a Generic. But here,
3509                 // we treat anything that is Unprofiled as Generic and keep the
3510                 // GetById. I.e. ForceExit = Generic. So, there is no harm - and only
3511                 // profit - from treating the Unprofiled case as
3512                 // SelectUsingPredictions.
3513                 arrayMode = ArrayMode(Array::SelectUsingPredictions, Array::Read);
3514             }
3515         }
3516             
3517         arrayMode = arrayMode.refine(
3518             m_graph, node, node->child1()->prediction(), node->prediction());
3519             
3520         if (arrayMode.type() == Array::Generic) {
3521             // Check if the input is something that we can't get array length for, but for which we
3522             // could insert some conversions in order to transform it into something that we can do it
3523             // for.
3524             if (node->child1()->shouldSpeculateStringObject())
3525                 attemptToForceStringArrayModeByToStringConversion<StringObjectUse>(arrayMode, node);
3526             else if (node->child1()->shouldSpeculateStringOrStringObject())
3527                 attemptToForceStringArrayModeByToStringConversion<StringOrStringObjectUse>(arrayMode, node);
3528         }
3529             
3530         if (!arrayMode.supportsSelfLength())
3531             return false;
3532         
3533         convertToGetArrayLength(node, arrayMode);
3534         return true;
3535     }
3536
3537     void convertToGetArrayLength(Node* node, ArrayMode arrayMode)
3538     {
3539         node->setOp(GetArrayLength);
3540         node->clearFlags(NodeMustGenerate);
3541         fixEdge<KnownCellUse>(node->child1());
3542         node->setArrayMode(arrayMode);
3543             
3544         Node* storage = checkArray(arrayMode, node->origin, node->child1().node(), 0, lengthNeedsStorage);
3545         if (!storage)
3546             return;
3547             
3548         node->child2() = Edge(storage);
3549     }
3550     
3551     Node* prependGetArrayLength(NodeOrigin origin, Node* child, ArrayMode arrayMode)
3552     {
3553         Node* storage = checkArray(arrayMode, origin, child, 0, lengthNeedsStorage);
3554         return m_insertionSet.insertNode(
3555             m_indexInBlock, SpecInt32Only, GetArrayLength, origin,
3556             OpInfo(arrayMode.asWord()), Edge(child, KnownCellUse), Edge(storage));
3557     }
3558
3559     void convertToHasIndexedProperty(Node* node)
3560     {
3561         node->setOp(HasIndexedProperty);
3562         node->clearFlags(NodeMustGenerate);
3563