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