948a57ebbcd7ffd9b3165a6bc1aea8738d0299d4
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGFixupPhase.cpp
1 /*
2  * Copyright (C) 2012-2016 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             fixIntConvertingEdge(node->child1());
130             node->setArithMode(Arith::Unchecked);
131             break;
132         }
133             
134         case UInt32ToNumber: {
135             fixIntConvertingEdge(node->child1());
136             if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
137                 node->convertToIdentity();
138             else if (node->canSpeculateInt32(FixupPass))
139                 node->setArithMode(Arith::CheckOverflow);
140             else {
141                 node->setArithMode(Arith::DoOverflow);
142                 node->clearFlags(NodeMustGenerate);
143                 node->setResult(enableInt52() ? NodeResultInt52 : NodeResultDouble);
144             }
145             break;
146         }
147             
148         case ValueAdd: {
149             if (attemptToMakeIntegerAdd(node)) {
150                 node->setOp(ArithAdd);
151                 break;
152             }
153             if (Node::shouldSpeculateNumberOrBooleanExpectingDefined(node->child1().node(), node->child2().node())) {
154                 fixDoubleOrBooleanEdge(node->child1());
155                 fixDoubleOrBooleanEdge(node->child2());
156                 node->setOp(ArithAdd);
157                 node->setResult(NodeResultDouble);
158                 break;
159             }
160             
161             if (attemptToMakeFastStringAdd(node))
162                 break;
163
164             fixEdge<UntypedUse>(node->child1());
165             fixEdge<UntypedUse>(node->child2());
166             node->setResult(NodeResultJS);
167             break;
168         }
169
170         case StrCat: {
171             if (attemptToMakeFastStringAdd(node))
172                 break;
173
174             // FIXME: Remove empty string arguments and possibly turn this into a ToString operation. That
175             // would require a form of ToString that takes a KnownPrimitiveUse. This is necessary because
176             // the implementation of StrCat doesn't dynamically optimize for empty strings.
177             // https://bugs.webkit.org/show_bug.cgi?id=148540
178             m_graph.doToChildren(
179                 node,
180                 [&] (Edge& edge) {
181                     fixEdge<KnownPrimitiveUse>(edge);
182                 });
183             break;
184         }
185             
186         case MakeRope: {
187             fixupMakeRope(node);
188             break;
189         }
190             
191         case ArithAdd:
192         case ArithSub: {
193             if (op == ArithSub
194                 && Node::shouldSpeculateUntypedForArithmetic(node->child1().node(), node->child2().node())) {
195                 fixEdge<UntypedUse>(node->child1());
196                 fixEdge<UntypedUse>(node->child2());
197                 node->setResult(NodeResultJS);
198                 break;
199             }
200             if (attemptToMakeIntegerAdd(node))
201                 break;
202             fixDoubleOrBooleanEdge(node->child1());
203             fixDoubleOrBooleanEdge(node->child2());
204             node->setResult(NodeResultDouble);
205             break;
206         }
207             
208         case ArithNegate: {
209             if (m_graph.unaryArithShouldSpeculateInt32(node, FixupPass)) {
210                 fixIntOrBooleanEdge(node->child1());
211                 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
212                     node->setArithMode(Arith::Unchecked);
213                 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
214                     node->setArithMode(Arith::CheckOverflow);
215                 else
216                     node->setArithMode(Arith::CheckOverflowAndNegativeZero);
217                 break;
218             }
219             if (m_graph.unaryArithShouldSpeculateAnyInt(node, FixupPass)) {
220                 fixEdge<Int52RepUse>(node->child1());
221                 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
222                     node->setArithMode(Arith::CheckOverflow);
223                 else
224                     node->setArithMode(Arith::CheckOverflowAndNegativeZero);
225                 node->setResult(NodeResultInt52);
226                 break;
227             }
228             fixDoubleOrBooleanEdge(node->child1());
229             node->setResult(NodeResultDouble);
230             break;
231         }
232             
233         case ArithMul: {
234             Edge& leftChild = node->child1();
235             Edge& rightChild = node->child2();
236             if (Node::shouldSpeculateUntypedForArithmetic(leftChild.node(), rightChild.node())) {
237                 fixEdge<UntypedUse>(leftChild);
238                 fixEdge<UntypedUse>(rightChild);
239                 node->setResult(NodeResultJS);
240                 break;
241             }
242             if (m_graph.binaryArithShouldSpeculateInt32(node, FixupPass)) {
243                 fixIntOrBooleanEdge(leftChild);
244                 fixIntOrBooleanEdge(rightChild);
245                 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
246                     node->setArithMode(Arith::Unchecked);
247                 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())
248                     || leftChild.node() == rightChild.node())
249                     node->setArithMode(Arith::CheckOverflow);
250                 else
251                     node->setArithMode(Arith::CheckOverflowAndNegativeZero);
252                 break;
253             }
254             if (m_graph.binaryArithShouldSpeculateAnyInt(node, FixupPass)) {
255                 fixEdge<Int52RepUse>(leftChild);
256                 fixEdge<Int52RepUse>(rightChild);
257                 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())
258                     || leftChild.node() == rightChild.node())
259                     node->setArithMode(Arith::CheckOverflow);
260                 else
261                     node->setArithMode(Arith::CheckOverflowAndNegativeZero);
262                 node->setResult(NodeResultInt52);
263                 break;
264             }
265             fixDoubleOrBooleanEdge(leftChild);
266             fixDoubleOrBooleanEdge(rightChild);
267             node->setResult(NodeResultDouble);
268             break;
269         }
270
271         case ArithDiv:
272         case ArithMod: {
273             Edge& leftChild = node->child1();
274             Edge& rightChild = node->child2();
275             if (op == ArithDiv
276                 && Node::shouldSpeculateUntypedForArithmetic(leftChild.node(), rightChild.node())
277                 && m_graph.hasExitSite(node->origin.semantic, BadType)) {
278                 fixEdge<UntypedUse>(leftChild);
279                 fixEdge<UntypedUse>(rightChild);
280                 node->setResult(NodeResultJS);
281                 break;
282             }
283             if (m_graph.binaryArithShouldSpeculateInt32(node, FixupPass)) {
284                 if (optimizeForX86() || optimizeForARM64() || optimizeForARMv7IDIVSupported()) {
285                     fixIntOrBooleanEdge(leftChild);
286                     fixIntOrBooleanEdge(rightChild);
287                     if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
288                         node->setArithMode(Arith::Unchecked);
289                     else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
290                         node->setArithMode(Arith::CheckOverflow);
291                     else
292                         node->setArithMode(Arith::CheckOverflowAndNegativeZero);
293                     break;
294                 }
295                 
296                 // This will cause conversion nodes to be inserted later.
297                 fixDoubleOrBooleanEdge(leftChild);
298                 fixDoubleOrBooleanEdge(rightChild);
299                 
300                 // We don't need to do ref'ing on the children because we're stealing them from
301                 // the original division.
302                 Node* newDivision = m_insertionSet.insertNode(
303                     m_indexInBlock, SpecBytecodeDouble, *node);
304                 newDivision->setResult(NodeResultDouble);
305                 
306                 node->setOp(DoubleAsInt32);
307                 node->children.initialize(Edge(newDivision, DoubleRepUse), Edge(), Edge());
308                 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
309                     node->setArithMode(Arith::CheckOverflow);
310                 else
311                     node->setArithMode(Arith::CheckOverflowAndNegativeZero);
312                 break;
313             }
314             fixDoubleOrBooleanEdge(leftChild);
315             fixDoubleOrBooleanEdge(rightChild);
316             node->setResult(NodeResultDouble);
317             break;
318         }
319             
320         case ArithMin:
321         case ArithMax: {
322             if (m_graph.binaryArithShouldSpeculateInt32(node, FixupPass)) {
323                 fixIntOrBooleanEdge(node->child1());
324                 fixIntOrBooleanEdge(node->child2());
325                 break;
326             }
327             fixDoubleOrBooleanEdge(node->child1());
328             fixDoubleOrBooleanEdge(node->child2());
329             node->setResult(NodeResultDouble);
330             break;
331         }
332             
333         case ArithAbs: {
334             if (m_graph.unaryArithShouldSpeculateInt32(node, FixupPass)) {
335                 fixIntOrBooleanEdge(node->child1());
336                 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
337                     node->setArithMode(Arith::Unchecked);
338                 else
339                     node->setArithMode(Arith::CheckOverflow);
340                 break;
341             }
342             fixDoubleOrBooleanEdge(node->child1());
343             node->setResult(NodeResultDouble);
344             break;
345         }
346
347         case ArithPow: {
348             if (node->child2()->shouldSpeculateInt32OrBooleanForArithmetic()) {
349                 fixDoubleOrBooleanEdge(node->child1());
350                 fixIntOrBooleanEdge(node->child2());
351                 break;
352             }
353
354             fixDoubleOrBooleanEdge(node->child1());
355             fixDoubleOrBooleanEdge(node->child2());
356             break;
357         }
358
359         case ArithRandom: {
360             node->setResult(NodeResultDouble);
361             break;
362         }
363
364         case ArithRound:
365         case ArithFloor:
366         case ArithCeil:
367         case ArithTrunc: {
368             if (m_graph.unaryArithShouldSpeculateInt32(node, FixupPass)) {
369                 fixIntOrBooleanEdge(node->child1());
370                 insertCheck<Int32Use>(m_indexInBlock, node->child1().node());
371                 node->convertToIdentity();
372                 break;
373             }
374             fixDoubleOrBooleanEdge(node->child1());
375
376             if (isInt32OrBooleanSpeculation(node->getHeapPrediction()) && m_graph.roundShouldSpeculateInt32(node, FixupPass)) {
377                 node->setResult(NodeResultInt32);
378                 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
379                     node->setArithRoundingMode(Arith::RoundingMode::Int32);
380                 else
381                     node->setArithRoundingMode(Arith::RoundingMode::Int32WithNegativeZeroCheck);
382             } else {
383                 node->setResult(NodeResultDouble);
384                 node->setArithRoundingMode(Arith::RoundingMode::Double);
385             }
386             break;
387         }
388             
389         case ArithSqrt: {
390             Edge& child1 = node->child1();
391             if (child1->shouldSpeculateNumberOrBoolean())
392                 fixDoubleOrBooleanEdge(child1);
393             else
394                 fixEdge<UntypedUse>(child1);
395             break;
396         }
397         case ArithFRound:
398         case ArithSin:
399         case ArithCos:
400         case ArithLog: {
401             fixDoubleOrBooleanEdge(node->child1());
402             node->setResult(NodeResultDouble);
403             break;
404         }
405             
406         case LogicalNot: {
407             if (node->child1()->shouldSpeculateBoolean()) {
408                 if (node->child1()->result() == NodeResultBoolean) {
409                     // This is necessary in case we have a bytecode instruction implemented by:
410                     //
411                     // a: CompareEq(...)
412                     // b: LogicalNot(@a)
413                     //
414                     // In that case, CompareEq might have a side-effect. Then, we need to make
415                     // sure that we know that Branch does not exit.
416                     fixEdge<KnownBooleanUse>(node->child1());
417                 } else
418                     fixEdge<BooleanUse>(node->child1());
419             } else if (node->child1()->shouldSpeculateObjectOrOther())
420                 fixEdge<ObjectOrOtherUse>(node->child1());
421             else if (node->child1()->shouldSpeculateInt32OrBoolean())
422                 fixIntOrBooleanEdge(node->child1());
423             else if (node->child1()->shouldSpeculateNumber())
424                 fixEdge<DoubleRepUse>(node->child1());
425             else if (node->child1()->shouldSpeculateString())
426                 fixEdge<StringUse>(node->child1());
427             else if (node->child1()->shouldSpeculateStringOrOther())
428                 fixEdge<StringOrOtherUse>(node->child1());
429             break;
430         }
431
432         case CompareEq:
433         case CompareLess:
434         case CompareLessEq:
435         case CompareGreater:
436         case CompareGreaterEq: {
437             if (node->op() == CompareEq
438                 && Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
439                 fixEdge<BooleanUse>(node->child1());
440                 fixEdge<BooleanUse>(node->child2());
441                 node->clearFlags(NodeMustGenerate);
442                 break;
443             }
444             if (Node::shouldSpeculateInt32OrBoolean(node->child1().node(), node->child2().node())) {
445                 fixIntOrBooleanEdge(node->child1());
446                 fixIntOrBooleanEdge(node->child2());
447                 node->clearFlags(NodeMustGenerate);
448                 break;
449             }
450             if (enableInt52()
451                 && Node::shouldSpeculateAnyInt(node->child1().node(), node->child2().node())) {
452                 fixEdge<Int52RepUse>(node->child1());
453                 fixEdge<Int52RepUse>(node->child2());
454                 node->clearFlags(NodeMustGenerate);
455                 break;
456             }
457             if (Node::shouldSpeculateNumberOrBoolean(node->child1().node(), node->child2().node())) {
458                 fixDoubleOrBooleanEdge(node->child1());
459                 fixDoubleOrBooleanEdge(node->child2());
460             }
461             if (node->op() != CompareEq
462                 && node->child1()->shouldSpeculateNotCell()
463                 && node->child2()->shouldSpeculateNotCell()) {
464                 if (node->child1()->shouldSpeculateNumberOrBoolean())
465                     fixDoubleOrBooleanEdge(node->child1());
466                 else
467                     fixEdge<DoubleRepUse>(node->child1());
468                 if (node->child2()->shouldSpeculateNumberOrBoolean())
469                     fixDoubleOrBooleanEdge(node->child2());
470                 else
471                     fixEdge<DoubleRepUse>(node->child2());
472                 node->clearFlags(NodeMustGenerate);
473                 break;
474             }
475             if (node->child1()->shouldSpeculateStringIdent() && node->child2()->shouldSpeculateStringIdent()) {
476                 fixEdge<StringIdentUse>(node->child1());
477                 fixEdge<StringIdentUse>(node->child2());
478                 node->clearFlags(NodeMustGenerate);
479                 break;
480             }
481             if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && GPRInfo::numberOfRegisters >= 7) {
482                 fixEdge<StringUse>(node->child1());
483                 fixEdge<StringUse>(node->child2());
484                 node->clearFlags(NodeMustGenerate);
485                 break;
486             }
487
488             if (node->op() != CompareEq)
489                 break;
490             if (Node::shouldSpeculateSymbol(node->child1().node(), node->child2().node())) {
491                 fixEdge<SymbolUse>(node->child1());
492                 fixEdge<SymbolUse>(node->child2());
493                 node->clearFlags(NodeMustGenerate);
494                 break;
495             }
496             if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
497                 fixEdge<ObjectUse>(node->child1());
498                 fixEdge<ObjectUse>(node->child2());
499                 node->clearFlags(NodeMustGenerate);
500                 break;
501             }
502
503             // If either child can be proved to be Null or Undefined, comparing them is greatly simplified.
504             bool oneArgumentIsUsedAsSpecOther = false;
505             if (node->child1()->isUndefinedOrNullConstant()) {
506                 fixEdge<OtherUse>(node->child1());
507                 oneArgumentIsUsedAsSpecOther = true;
508             } else if (node->child1()->shouldSpeculateOther()) {
509                 m_insertionSet.insertNode(m_indexInBlock, SpecNone, Check, node->origin,
510                     Edge(node->child1().node(), OtherUse));
511                 fixEdge<OtherUse>(node->child1());
512                 oneArgumentIsUsedAsSpecOther = true;
513             }
514             if (node->child2()->isUndefinedOrNullConstant()) {
515                 fixEdge<OtherUse>(node->child2());
516                 oneArgumentIsUsedAsSpecOther = true;
517             } else if (node->child2()->shouldSpeculateOther()) {
518                 m_insertionSet.insertNode(m_indexInBlock, SpecNone, Check, node->origin,
519                     Edge(node->child2().node(), OtherUse));
520                 fixEdge<OtherUse>(node->child2());
521                 oneArgumentIsUsedAsSpecOther = true;
522             }
523             if (oneArgumentIsUsedAsSpecOther) {
524                 node->clearFlags(NodeMustGenerate);
525                 break;
526             }
527
528             if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObjectOrOther()) {
529                 fixEdge<ObjectUse>(node->child1());
530                 fixEdge<ObjectOrOtherUse>(node->child2());
531                 node->clearFlags(NodeMustGenerate);
532                 break;
533             }
534             if (node->child1()->shouldSpeculateObjectOrOther() && node->child2()->shouldSpeculateObject()) {
535                 fixEdge<ObjectOrOtherUse>(node->child1());
536                 fixEdge<ObjectUse>(node->child2());
537                 node->clearFlags(NodeMustGenerate);
538                 break;
539             }
540
541             break;
542         }
543             
544         case CompareStrictEq: {
545             if (Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
546                 fixEdge<BooleanUse>(node->child1());
547                 fixEdge<BooleanUse>(node->child2());
548                 break;
549             }
550             if (Node::shouldSpeculateInt32(node->child1().node(), node->child2().node())) {
551                 fixEdge<Int32Use>(node->child1());
552                 fixEdge<Int32Use>(node->child2());
553                 break;
554             }
555             if (enableInt52()
556                 && Node::shouldSpeculateAnyInt(node->child1().node(), node->child2().node())) {
557                 fixEdge<Int52RepUse>(node->child1());
558                 fixEdge<Int52RepUse>(node->child2());
559                 break;
560             }
561             if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
562                 fixEdge<DoubleRepUse>(node->child1());
563                 fixEdge<DoubleRepUse>(node->child2());
564                 break;
565             }
566             if (Node::shouldSpeculateSymbol(node->child1().node(), node->child2().node())) {
567                 fixEdge<SymbolUse>(node->child1());
568                 fixEdge<SymbolUse>(node->child2());
569                 break;
570             }
571             if (node->child1()->shouldSpeculateStringIdent() && node->child2()->shouldSpeculateStringIdent()) {
572                 fixEdge<StringIdentUse>(node->child1());
573                 fixEdge<StringIdentUse>(node->child2());
574                 break;
575             }
576             if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 7) || isFTL(m_graph.m_plan.mode))) {
577                 fixEdge<StringUse>(node->child1());
578                 fixEdge<StringUse>(node->child2());
579                 break;
580             }
581             WatchpointSet* masqueradesAsUndefinedWatchpoint = m_graph.globalObjectFor(node->origin.semantic)->masqueradesAsUndefinedWatchpoint();
582             if (masqueradesAsUndefinedWatchpoint->isStillValid()) {
583                 
584                 if (node->child1()->shouldSpeculateObject()) {
585                     m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
586                     fixEdge<ObjectUse>(node->child1());
587                     break;
588                 }
589                 if (node->child2()->shouldSpeculateObject()) {
590                     m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
591                     fixEdge<ObjectUse>(node->child2());
592                     break;
593                 }
594                 
595             } else if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
596                 fixEdge<ObjectUse>(node->child1());
597                 fixEdge<ObjectUse>(node->child2());
598                 break;
599             }
600             if (node->child1()->shouldSpeculateSymbol()) {
601                 fixEdge<SymbolUse>(node->child1());
602                 break;
603             }
604             if (node->child2()->shouldSpeculateSymbol()) {
605                 fixEdge<SymbolUse>(node->child2());
606                 break;
607             }
608             if (node->child1()->shouldSpeculateMisc()) {
609                 fixEdge<MiscUse>(node->child1());
610                 break;
611             }
612             if (node->child2()->shouldSpeculateMisc()) {
613                 fixEdge<MiscUse>(node->child2());
614                 break;
615             }
616             if (node->child1()->shouldSpeculateStringIdent()
617                 && node->child2()->shouldSpeculateNotStringVar()) {
618                 fixEdge<StringIdentUse>(node->child1());
619                 fixEdge<NotStringVarUse>(node->child2());
620                 break;
621             }
622             if (node->child2()->shouldSpeculateStringIdent()
623                 && node->child1()->shouldSpeculateNotStringVar()) {
624                 fixEdge<StringIdentUse>(node->child2());
625                 fixEdge<NotStringVarUse>(node->child1());
626                 break;
627             }
628             if (node->child1()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 8) || isFTL(m_graph.m_plan.mode))) {
629                 fixEdge<StringUse>(node->child1());
630                 break;
631             }
632             if (node->child2()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 8) || isFTL(m_graph.m_plan.mode))) {
633                 fixEdge<StringUse>(node->child2());
634                 break;
635             }
636             break;
637         }
638             
639         case StringFromCharCode:
640             if (node->child1()->shouldSpeculateInt32())
641                 fixEdge<Int32Use>(node->child1());
642             else
643                 fixEdge<UntypedUse>(node->child1());
644             break;
645
646         case StringCharAt:
647         case StringCharCodeAt: {
648             // Currently we have no good way of refining these.
649             ASSERT(node->arrayMode() == ArrayMode(Array::String));
650             blessArrayOperation(node->child1(), node->child2(), node->child3());
651             fixEdge<KnownCellUse>(node->child1());
652             fixEdge<Int32Use>(node->child2());
653             break;
654         }
655
656         case GetByVal: {
657             if (!node->prediction()) {
658                 m_insertionSet.insertNode(
659                     m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
660             }
661             
662             node->setArrayMode(
663                 node->arrayMode().refine(
664                     m_graph, node,
665                     node->child1()->prediction(),
666                     node->child2()->prediction(),
667                     SpecNone));
668             
669             blessArrayOperation(node->child1(), node->child2(), node->child3());
670             
671             ArrayMode arrayMode = node->arrayMode();
672             switch (arrayMode.type()) {
673             case Array::Contiguous:
674             case Array::Double:
675                 if (arrayMode.arrayClass() == Array::OriginalArray
676                     && arrayMode.speculation() == Array::InBounds) {
677                     JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
678                     if (globalObject->arrayPrototypeChainIsSane()) {
679                         // Check if SaneChain will work on a per-type basis. Note that:
680                         //
681                         // 1) We don't want double arrays to sometimes return undefined, since
682                         // that would require a change to the return type and it would pessimise
683                         // things a lot. So, we'd only want to do that if we actually had
684                         // evidence that we could read from a hole. That's pretty annoying.
685                         // Likely the best way to handle that case is with an equivalent of
686                         // SaneChain for OutOfBounds. For now we just detect when Undefined and
687                         // NaN are indistinguishable according to backwards propagation, and just
688                         // use SaneChain in that case. This happens to catch a lot of cases.
689                         //
690                         // 2) We don't want int32 array loads to have to do a hole check just to
691                         // coerce to Undefined, since that would mean twice the checks.
692                         //
693                         // This has two implications. First, we have to do more checks than we'd
694                         // like. It's unfortunate that we have to do the hole check. Second,
695                         // some accesses that hit a hole will now need to take the full-blown
696                         // out-of-bounds slow path. We can fix that with:
697                         // https://bugs.webkit.org/show_bug.cgi?id=144668
698                         
699                         bool canDoSaneChain = false;
700                         switch (arrayMode.type()) {
701                         case Array::Contiguous:
702                             // This is happens to be entirely natural. We already would have
703                             // returned any JSValue, and now we'll return Undefined. We still do
704                             // the check but it doesn't require taking any kind of slow path.
705                             canDoSaneChain = true;
706                             break;
707                             
708                         case Array::Double:
709                             if (!(node->flags() & NodeBytecodeUsesAsOther)) {
710                                 // Holes look like NaN already, so if the user doesn't care
711                                 // about the difference between Undefined and NaN then we can
712                                 // do this.
713                                 canDoSaneChain = true;
714                             }
715                             break;
716                             
717                         default:
718                             break;
719                         }
720                         
721                         if (canDoSaneChain) {
722                             m_graph.watchpoints().addLazily(
723                                 globalObject->arrayPrototype()->structure()->transitionWatchpointSet());
724                             m_graph.watchpoints().addLazily(
725                                 globalObject->objectPrototype()->structure()->transitionWatchpointSet());
726                             if (globalObject->arrayPrototypeChainIsSane())
727                                 node->setArrayMode(arrayMode.withSpeculation(Array::SaneChain));
728                         }
729                     }
730                 }
731                 break;
732                 
733             case Array::String:
734                 if ((node->prediction() & ~SpecString)
735                     || m_graph.hasExitSite(node->origin.semantic, OutOfBounds))
736                     node->setArrayMode(arrayMode.withSpeculation(Array::OutOfBounds));
737                 break;
738                 
739             default:
740                 break;
741             }
742             
743             arrayMode = node->arrayMode();
744             switch (arrayMode.type()) {
745             case Array::SelectUsingPredictions:
746             case Array::Unprofiled:
747                 RELEASE_ASSERT_NOT_REACHED();
748                 break;
749             case Array::Generic:
750 #if USE(JSVALUE32_64)
751                 fixEdge<CellUse>(node->child1()); // Speculating cell due to register pressure on 32-bit.
752 #endif
753                 break;
754             case Array::ForceExit:
755                 break;
756             default:
757                 fixEdge<KnownCellUse>(node->child1());
758                 fixEdge<Int32Use>(node->child2());
759                 break;
760             }
761             
762             switch (arrayMode.type()) {
763             case Array::Double:
764                 if (!arrayMode.isOutOfBounds())
765                     node->setResult(NodeResultDouble);
766                 break;
767                 
768             case Array::Float32Array:
769             case Array::Float64Array:
770                 node->setResult(NodeResultDouble);
771                 break;
772                 
773             case Array::Uint32Array:
774                 if (node->shouldSpeculateInt32())
775                     break;
776                 if (node->shouldSpeculateAnyInt() && enableInt52())
777                     node->setResult(NodeResultInt52);
778                 else
779                     node->setResult(NodeResultDouble);
780                 break;
781                 
782             default:
783                 break;
784             }
785             
786             break;
787         }
788
789         case PutByValDirect:
790         case PutByVal:
791         case PutByValAlias: {
792             Edge& child1 = m_graph.varArgChild(node, 0);
793             Edge& child2 = m_graph.varArgChild(node, 1);
794             Edge& child3 = m_graph.varArgChild(node, 2);
795
796             node->setArrayMode(
797                 node->arrayMode().refine(
798                     m_graph, node,
799                     child1->prediction(),
800                     child2->prediction(),
801                     child3->prediction()));
802             
803             blessArrayOperation(child1, child2, m_graph.varArgChild(node, 3));
804             
805             switch (node->arrayMode().modeForPut().type()) {
806             case Array::SelectUsingPredictions:
807             case Array::SelectUsingArguments:
808             case Array::Unprofiled:
809             case Array::Undecided:
810                 RELEASE_ASSERT_NOT_REACHED();
811                 break;
812             case Array::ForceExit:
813             case Array::Generic:
814 #if USE(JSVALUE32_64)
815                 // Due to register pressure on 32-bit, we speculate cell and
816                 // ignore the base-is-not-cell case entirely by letting the
817                 // baseline JIT handle it.
818                 fixEdge<CellUse>(child1);
819 #endif
820                 break;
821             case Array::Int32:
822                 fixEdge<KnownCellUse>(child1);
823                 fixEdge<Int32Use>(child2);
824                 fixEdge<Int32Use>(child3);
825                 break;
826             case Array::Double:
827                 fixEdge<KnownCellUse>(child1);
828                 fixEdge<Int32Use>(child2);
829                 fixEdge<DoubleRepRealUse>(child3);
830                 break;
831             case Array::Int8Array:
832             case Array::Int16Array:
833             case Array::Int32Array:
834             case Array::Uint8Array:
835             case Array::Uint8ClampedArray:
836             case Array::Uint16Array:
837             case Array::Uint32Array:
838                 fixEdge<KnownCellUse>(child1);
839                 fixEdge<Int32Use>(child2);
840                 if (child3->shouldSpeculateInt32())
841                     fixIntOrBooleanEdge(child3);
842                 else if (child3->shouldSpeculateAnyInt())
843                     fixEdge<Int52RepUse>(child3);
844                 else
845                     fixDoubleOrBooleanEdge(child3);
846                 break;
847             case Array::Float32Array:
848             case Array::Float64Array:
849                 fixEdge<KnownCellUse>(child1);
850                 fixEdge<Int32Use>(child2);
851                 fixDoubleOrBooleanEdge(child3);
852                 break;
853             case Array::Contiguous:
854             case Array::ArrayStorage:
855             case Array::SlowPutArrayStorage:
856                 fixEdge<KnownCellUse>(child1);
857                 fixEdge<Int32Use>(child2);
858                 speculateForBarrier(child3);
859                 break;
860             default:
861                 fixEdge<KnownCellUse>(child1);
862                 fixEdge<Int32Use>(child2);
863                 break;
864             }
865             break;
866         }
867             
868         case ArrayPush: {
869             // May need to refine the array mode in case the value prediction contravenes
870             // the array prediction. For example, we may have evidence showing that the
871             // array is in Int32 mode, but the value we're storing is likely to be a double.
872             // Then we should turn this into a conversion to Double array followed by the
873             // push. On the other hand, we absolutely don't want to refine based on the
874             // base prediction. If it has non-cell garbage in it, then we want that to be
875             // ignored. That's because ArrayPush can't handle any array modes that aren't
876             // array-related - so if refine() turned this into a "Generic" ArrayPush then
877             // that would break things.
878             node->setArrayMode(
879                 node->arrayMode().refine(
880                     m_graph, node,
881                     node->child1()->prediction() & SpecCell,
882                     SpecInt32Only,
883                     node->child2()->prediction()));
884             blessArrayOperation(node->child1(), Edge(), node->child3());
885             fixEdge<KnownCellUse>(node->child1());
886             
887             switch (node->arrayMode().type()) {
888             case Array::Int32:
889                 fixEdge<Int32Use>(node->child2());
890                 break;
891             case Array::Double:
892                 fixEdge<DoubleRepRealUse>(node->child2());
893                 break;
894             case Array::Contiguous:
895             case Array::ArrayStorage:
896                 speculateForBarrier(node->child2());
897                 break;
898             default:
899                 break;
900             }
901             break;
902         }
903             
904         case ArrayPop: {
905             blessArrayOperation(node->child1(), Edge(), node->child2());
906             fixEdge<KnownCellUse>(node->child1());
907             break;
908         }
909             
910         case RegExpExec:
911         case RegExpTest: {
912             fixEdge<KnownCellUse>(node->child1());
913             
914             if (node->child2()->shouldSpeculateRegExpObject()) {
915                 fixEdge<RegExpObjectUse>(node->child2());
916
917                 if (node->child3()->shouldSpeculateString())
918                     fixEdge<StringUse>(node->child3());
919             }
920             break;
921         }
922
923         case StringReplace:
924         case StringReplaceRegExp: {
925             if (node->child2()->shouldSpeculateString()) {
926                 m_insertionSet.insertNode(
927                     m_indexInBlock, SpecNone, Check, node->origin,
928                     Edge(node->child2().node(), StringUse));
929                 fixEdge<StringUse>(node->child2());
930             } else if (op == StringReplace) {
931                 if (node->child2()->shouldSpeculateRegExpObject())
932                     addStringReplacePrimordialChecks(node->child2().node());
933                 else 
934                     m_insertionSet.insertNode(
935                         m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
936             }
937
938             if (node->child1()->shouldSpeculateString()
939                 && node->child2()->shouldSpeculateRegExpObject()
940                 && node->child3()->shouldSpeculateString()) {
941
942                 fixEdge<StringUse>(node->child1());
943                 fixEdge<RegExpObjectUse>(node->child2());
944                 fixEdge<StringUse>(node->child3());
945                 break;
946             }
947             break;
948         }
949             
950         case Branch: {
951             if (node->child1()->shouldSpeculateBoolean()) {
952                 if (node->child1()->result() == NodeResultBoolean) {
953                     // This is necessary in case we have a bytecode instruction implemented by:
954                     //
955                     // a: CompareEq(...)
956                     // b: Branch(@a)
957                     //
958                     // In that case, CompareEq might have a side-effect. Then, we need to make
959                     // sure that we know that Branch does not exit.
960                     fixEdge<KnownBooleanUse>(node->child1());
961                 } else
962                     fixEdge<BooleanUse>(node->child1());
963             } else if (node->child1()->shouldSpeculateObjectOrOther())
964                 fixEdge<ObjectOrOtherUse>(node->child1());
965             else if (node->child1()->shouldSpeculateInt32OrBoolean())
966                 fixIntOrBooleanEdge(node->child1());
967             else if (node->child1()->shouldSpeculateNumber())
968                 fixEdge<DoubleRepUse>(node->child1());
969             else if (node->child1()->shouldSpeculateString())
970                 fixEdge<StringUse>(node->child1());
971             else if (node->child1()->shouldSpeculateStringOrOther())
972                 fixEdge<StringOrOtherUse>(node->child1());
973             break;
974         }
975             
976         case Switch: {
977             SwitchData* data = node->switchData();
978             switch (data->kind) {
979             case SwitchImm:
980                 if (node->child1()->shouldSpeculateInt32())
981                     fixEdge<Int32Use>(node->child1());
982                 break;
983             case SwitchChar:
984                 if (node->child1()->shouldSpeculateString())
985                     fixEdge<StringUse>(node->child1());
986                 break;
987             case SwitchString:
988                 if (node->child1()->shouldSpeculateStringIdent())
989                     fixEdge<StringIdentUse>(node->child1());
990                 else if (node->child1()->shouldSpeculateString())
991                     fixEdge<StringUse>(node->child1());
992                 break;
993             case SwitchCell:
994                 if (node->child1()->shouldSpeculateCell())
995                     fixEdge<CellUse>(node->child1());
996                 // else it's fine for this to have UntypedUse; we will handle this by just making
997                 // non-cells take the default case.
998                 break;
999             }
1000             break;
1001         }
1002             
1003         case ToPrimitive: {
1004             fixupToPrimitive(node);
1005             break;
1006         }
1007
1008         case ToNumber: {
1009             fixupToNumber(node);
1010             break;
1011         }
1012             
1013         case ToString:
1014         case CallStringConstructor: {
1015             fixupToStringOrCallStringConstructor(node);
1016             break;
1017         }
1018             
1019         case NewStringObject: {
1020             fixEdge<KnownStringUse>(node->child1());
1021             break;
1022         }
1023             
1024         case NewArray: {
1025             watchHavingABadTime(node);
1026             
1027             for (unsigned i = m_graph.varArgNumChildren(node); i--;) {
1028                 node->setIndexingType(
1029                     leastUpperBoundOfIndexingTypeAndType(
1030                         node->indexingType(), m_graph.varArgChild(node, i)->prediction()));
1031             }
1032             switch (node->indexingType()) {
1033             case ALL_BLANK_INDEXING_TYPES:
1034                 CRASH();
1035                 break;
1036             case ALL_UNDECIDED_INDEXING_TYPES:
1037                 if (node->numChildren()) {
1038                     // This will only happen if the children have no type predictions. We
1039                     // would have already exited by now, but insert a forced exit just to
1040                     // be safe.
1041                     m_insertionSet.insertNode(
1042                         m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
1043                 }
1044                 break;
1045             case ALL_INT32_INDEXING_TYPES:
1046                 for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
1047                     fixEdge<Int32Use>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
1048                 break;
1049             case ALL_DOUBLE_INDEXING_TYPES:
1050                 for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
1051                     fixEdge<DoubleRepRealUse>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
1052                 break;
1053             case ALL_CONTIGUOUS_INDEXING_TYPES:
1054             case ALL_ARRAY_STORAGE_INDEXING_TYPES:
1055                 break;
1056             default:
1057                 CRASH();
1058                 break;
1059             }
1060             break;
1061         }
1062             
1063         case NewTypedArray: {
1064             watchHavingABadTime(node);
1065             
1066             if (node->child1()->shouldSpeculateInt32()) {
1067                 fixEdge<Int32Use>(node->child1());
1068                 node->clearFlags(NodeMustGenerate);
1069                 break;
1070             }
1071             break;
1072         }
1073             
1074         case NewArrayWithSize: {
1075             watchHavingABadTime(node);
1076             fixEdge<Int32Use>(node->child1());
1077             break;
1078         }
1079
1080         case CallObjectConstructor: {
1081             if (node->child1()->shouldSpeculateObject()) {
1082                 fixEdge<ObjectUse>(node->child1());
1083                 node->convertToIdentity();
1084                 break;
1085             }
1086
1087             fixEdge<UntypedUse>(node->child1());
1088             break;
1089         }
1090
1091         case ToThis: {
1092             fixupToThis(node);
1093             break;
1094         }
1095             
1096         case PutStructure: {
1097             fixEdge<KnownCellUse>(node->child1());
1098             break;
1099         }
1100             
1101         case GetClosureVar:
1102         case GetFromArguments: {
1103             fixEdge<KnownCellUse>(node->child1());
1104             break;
1105         }
1106
1107         case PutClosureVar:
1108         case PutToArguments: {
1109             fixEdge<KnownCellUse>(node->child1());
1110             speculateForBarrier(node->child2());
1111             break;
1112         }
1113
1114         case SkipScope:
1115         case GetScope:
1116         case GetGetter:
1117         case GetSetter:
1118         case GetGlobalObject: {
1119             fixEdge<KnownCellUse>(node->child1());
1120             break;
1121         }
1122             
1123         case AllocatePropertyStorage:
1124         case ReallocatePropertyStorage: {
1125             fixEdge<KnownCellUse>(node->child1());
1126             break;
1127         }
1128
1129         case TryGetById: {
1130             if (node->child1()->shouldSpeculateCell())
1131                 fixEdge<CellUse>(node->child1());
1132             break;
1133         }
1134
1135         case GetById:
1136         case GetByIdFlush: {
1137             // FIXME: This should be done in the ByteCodeParser based on reading the
1138             // PolymorphicAccess, which will surely tell us that this is a AccessCase::ArrayLength.
1139             // https://bugs.webkit.org/show_bug.cgi?id=154990
1140             if (node->child1()->shouldSpeculateCellOrOther()
1141                 && !m_graph.hasExitSite(node->origin.semantic, BadType)
1142                 && !m_graph.hasExitSite(node->origin.semantic, BadCache)
1143                 && !m_graph.hasExitSite(node->origin.semantic, BadIndexingType)
1144                 && !m_graph.hasExitSite(node->origin.semantic, ExoticObjectMode)) {
1145                 
1146                 auto uid = m_graph.identifiers()[node->identifierNumber()];
1147                 
1148                 if (uid == vm().propertyNames->length.impl()) {
1149                     attemptToMakeGetArrayLength(node);
1150                     break;
1151                 }
1152
1153                 if (uid == vm().propertyNames->lastIndex.impl()
1154                     && node->child1()->shouldSpeculateRegExpObject()) {
1155                     node->setOp(GetRegExpObjectLastIndex);
1156                     node->clearFlags(NodeMustGenerate);
1157                     fixEdge<RegExpObjectUse>(node->child1());
1158                     break;
1159                 }
1160             }
1161
1162             if (node->child1()->shouldSpeculateCell())
1163                 fixEdge<CellUse>(node->child1());
1164             break;
1165         }
1166
1167         case PutById:
1168         case PutByIdFlush:
1169         case PutByIdDirect: {
1170             if (node->child1()->shouldSpeculateCellOrOther()
1171                 && !m_graph.hasExitSite(node->origin.semantic, BadType)
1172                 && !m_graph.hasExitSite(node->origin.semantic, BadCache)
1173                 && !m_graph.hasExitSite(node->origin.semantic, BadIndexingType)
1174                 && !m_graph.hasExitSite(node->origin.semantic, ExoticObjectMode)) {
1175                 
1176                 auto uid = m_graph.identifiers()[node->identifierNumber()];
1177                 
1178                 if (uid == vm().propertyNames->lastIndex.impl()
1179                     && node->child1()->shouldSpeculateRegExpObject()) {
1180                     node->setOp(SetRegExpObjectLastIndex);
1181                     fixEdge<RegExpObjectUse>(node->child1());
1182                     speculateForBarrier(node->child2());
1183                     break;
1184                 }
1185             }
1186             
1187             fixEdge<CellUse>(node->child1());
1188             break;
1189         }
1190
1191         case PutGetterById:
1192         case PutSetterById: {
1193             fixEdge<KnownCellUse>(node->child1());
1194             fixEdge<KnownCellUse>(node->child2());
1195             break;
1196         }
1197
1198         case PutGetterSetterById: {
1199             fixEdge<KnownCellUse>(node->child1());
1200             break;
1201         }
1202
1203         case PutGetterByVal:
1204         case PutSetterByVal: {
1205             fixEdge<KnownCellUse>(node->child1());
1206             fixEdge<KnownCellUse>(node->child3());
1207             break;
1208         }
1209
1210         case GetExecutable: {
1211             fixEdge<FunctionUse>(node->child1());
1212             break;
1213         }
1214
1215         case OverridesHasInstance:
1216         case CheckStructure:
1217         case CheckCell:
1218         case CreateThis:
1219         case GetButterfly: {
1220             fixEdge<CellUse>(node->child1());
1221             break;
1222         }
1223
1224         case CheckStringIdent: {
1225             fixEdge<StringIdentUse>(node->child1());
1226             break;
1227         }
1228             
1229         case Arrayify:
1230         case ArrayifyToStructure: {
1231             fixEdge<CellUse>(node->child1());
1232             if (node->child2())
1233                 fixEdge<Int32Use>(node->child2());
1234             break;
1235         }
1236             
1237         case GetByOffset:
1238         case GetGetterSetterByOffset: {
1239             if (!node->child1()->hasStorageResult())
1240                 fixEdge<KnownCellUse>(node->child1());
1241             fixEdge<KnownCellUse>(node->child2());
1242             break;
1243         }
1244             
1245         case MultiGetByOffset: {
1246             fixEdge<CellUse>(node->child1());
1247             break;
1248         }
1249             
1250         case PutByOffset: {
1251             if (!node->child1()->hasStorageResult())
1252                 fixEdge<KnownCellUse>(node->child1());
1253             fixEdge<KnownCellUse>(node->child2());
1254             insertInferredTypeCheck(
1255                 m_insertionSet, m_indexInBlock, node->origin, node->child3().node(),
1256                 node->storageAccessData().inferredType);
1257             speculateForBarrier(node->child3());
1258             break;
1259         }
1260             
1261         case MultiPutByOffset: {
1262             fixEdge<CellUse>(node->child1());
1263             speculateForBarrier(node->child2());
1264             break;
1265         }
1266             
1267         case InstanceOf: {
1268             if (!(node->child1()->prediction() & ~SpecCell))
1269                 fixEdge<CellUse>(node->child1());
1270             fixEdge<CellUse>(node->child2());
1271             break;
1272         }
1273
1274         case InstanceOfCustom:
1275             fixEdge<CellUse>(node->child2());
1276             break;
1277
1278         case In: {
1279             // FIXME: We should at some point have array profiling on op_in, in which
1280             // case we would be able to turn this into a kind of GetByVal.
1281             
1282             fixEdge<CellUse>(node->child2());
1283             break;
1284         }
1285
1286         case Check: {
1287             m_graph.doToChildren(
1288                 node,
1289                 [&] (Edge& edge) {
1290                     switch (edge.useKind()) {
1291                     case NumberUse:
1292                         if (edge->shouldSpeculateInt32ForArithmetic())
1293                             edge.setUseKind(Int32Use);
1294                         break;
1295                     default:
1296                         break;
1297                     }
1298                     observeUseKindOnEdge(edge);
1299                 });
1300             break;
1301         }
1302
1303         case Phantom:
1304             // Phantoms are meaningless past Fixup. We recreate them on-demand in the backend.
1305             node->remove();
1306             break;
1307
1308         case FiatInt52: {
1309             RELEASE_ASSERT(enableInt52());
1310             node->convertToIdentity();
1311             fixEdge<Int52RepUse>(node->child1());
1312             node->setResult(NodeResultInt52);
1313             break;
1314         }
1315
1316         case GetArrayLength: {
1317             fixEdge<KnownCellUse>(node->child1());
1318             break;
1319         }
1320
1321         case GetTypedArrayByteOffset: {
1322             fixEdge<KnownCellUse>(node->child1());
1323             break;
1324         }
1325
1326         case Phi:
1327         case Upsilon:
1328         case GetIndexedPropertyStorage:
1329         case LastNodeType:
1330         case CheckTierUpInLoop:
1331         case CheckTierUpAtReturn:
1332         case CheckTierUpAndOSREnter:
1333         case InvalidationPoint:
1334         case CheckArray:
1335         case CheckInBounds:
1336         case ConstantStoragePointer:
1337         case DoubleAsInt32:
1338         case ValueToInt32:
1339         case DoubleRep:
1340         case ValueRep:
1341         case Int52Rep:
1342         case Int52Constant:
1343         case Identity: // This should have been cleaned up.
1344         case BooleanToNumber:
1345         case PhantomNewObject:
1346         case PhantomNewFunction:
1347         case PhantomNewGeneratorFunction:
1348         case PhantomCreateActivation:
1349         case PhantomDirectArguments:
1350         case PhantomClonedArguments:
1351         case GetMyArgumentByVal:
1352         case GetMyArgumentByValOutOfBounds:
1353         case PutHint:
1354         case CheckStructureImmediate:
1355         case MaterializeNewObject:
1356         case MaterializeCreateActivation:
1357         case PutStack:
1358         case KillStack:
1359         case GetStack:
1360         case StoreBarrier:
1361         case GetRegExpObjectLastIndex:
1362         case SetRegExpObjectLastIndex:
1363         case RecordRegExpCachedResult:
1364             // These are just nodes that we don't currently expect to see during fixup.
1365             // If we ever wanted to insert them prior to fixup, then we just have to create
1366             // fixup rules for them.
1367             DFG_CRASH(m_graph, node, "Unexpected node during fixup");
1368             break;
1369         
1370         case PutGlobalVariable: {
1371             fixEdge<CellUse>(node->child1());
1372             speculateForBarrier(node->child2());
1373             break;
1374         }
1375
1376         case IsString:
1377             if (node->child1()->shouldSpeculateString()) {
1378                 m_insertionSet.insertNode(
1379                     m_indexInBlock, SpecNone, Check, node->origin,
1380                     Edge(node->child1().node(), StringUse));
1381                 m_graph.convertToConstant(node, jsBoolean(true));
1382                 observeUseKindOnNode<StringUse>(node);
1383             }
1384             break;
1385
1386         case IsObject:
1387             if (node->child1()->shouldSpeculateObject()) {
1388                 m_insertionSet.insertNode(
1389                     m_indexInBlock, SpecNone, Check, node->origin,
1390                     Edge(node->child1().node(), ObjectUse));
1391                 m_graph.convertToConstant(node, jsBoolean(true));
1392                 observeUseKindOnNode<ObjectUse>(node);
1393             }
1394             break;
1395
1396         case GetEnumerableLength: {
1397             fixEdge<CellUse>(node->child1());
1398             break;
1399         }
1400         case HasGenericProperty: {
1401             fixEdge<CellUse>(node->child2());
1402             break;
1403         }
1404         case HasStructureProperty: {
1405             fixEdge<StringUse>(node->child2());
1406             fixEdge<KnownCellUse>(node->child3());
1407             break;
1408         }
1409         case HasIndexedProperty: {
1410             node->setArrayMode(
1411                 node->arrayMode().refine(
1412                     m_graph, node,
1413                     node->child1()->prediction(),
1414                     node->child2()->prediction(),
1415                     SpecNone));
1416             
1417             blessArrayOperation(node->child1(), node->child2(), node->child3());
1418             fixEdge<CellUse>(node->child1());
1419             fixEdge<KnownInt32Use>(node->child2());
1420             break;
1421         }
1422         case GetDirectPname: {
1423             Edge& base = m_graph.varArgChild(node, 0);
1424             Edge& property = m_graph.varArgChild(node, 1);
1425             Edge& index = m_graph.varArgChild(node, 2);
1426             Edge& enumerator = m_graph.varArgChild(node, 3);
1427             fixEdge<CellUse>(base);
1428             fixEdge<KnownCellUse>(property);
1429             fixEdge<KnownInt32Use>(index);
1430             fixEdge<KnownCellUse>(enumerator);
1431             break;
1432         }
1433         case GetPropertyEnumerator: {
1434             fixEdge<CellUse>(node->child1());
1435             break;
1436         }
1437         case GetEnumeratorStructurePname: {
1438             fixEdge<KnownCellUse>(node->child1());
1439             fixEdge<KnownInt32Use>(node->child2());
1440             break;
1441         }
1442         case GetEnumeratorGenericPname: {
1443             fixEdge<KnownCellUse>(node->child1());
1444             fixEdge<KnownInt32Use>(node->child2());
1445             break;
1446         }
1447         case ToIndexString: {
1448             fixEdge<KnownInt32Use>(node->child1());
1449             break;
1450         }
1451         case ProfileType: {
1452             // We want to insert type checks based on the instructionTypeSet of the TypeLocation, not the globalTypeSet.
1453             // Because the instructionTypeSet is contained in globalTypeSet, if we produce a type check for
1454             // type T for the instructionTypeSet, the global type set must also have information for type T.
1455             // So if it the type check succeeds for type T in the instructionTypeSet, a type check for type T 
1456             // in the globalTypeSet would've also succeeded.
1457             // (The other direction does not hold in general).
1458
1459             RefPtr<TypeSet> typeSet = node->typeLocation()->m_instructionTypeSet;
1460             RuntimeTypeMask seenTypes = typeSet->seenTypes();
1461             if (typeSet->doesTypeConformTo(TypeAnyInt)) {
1462                 if (node->child1()->shouldSpeculateInt32()) {
1463                     fixEdge<Int32Use>(node->child1());
1464                     node->remove();
1465                     break;
1466                 }
1467
1468                 if (enableInt52()) {
1469                     fixEdge<AnyIntUse>(node->child1());
1470                     node->remove();
1471                     break;
1472                 }
1473
1474                 // Must not perform fixEdge<NumberUse> here since the type set only includes TypeAnyInt. Double values should be logged.
1475             }
1476
1477             if (typeSet->doesTypeConformTo(TypeNumber | TypeAnyInt) && ((seenTypes & TypeNumber) && (seenTypes & TypeAnyInt))) {
1478                 // NumberUse can pass TypeNumber and TypeAnyInt. Thus, this node removal is allowed only if both TypeNumber and TypeAnyInt are logged in the type set.
1479                 fixEdge<NumberUse>(node->child1());
1480                 node->remove();
1481             } else if (typeSet->doesTypeConformTo(TypeString)) {
1482                 fixEdge<StringUse>(node->child1());
1483                 node->remove();
1484             } else if (typeSet->doesTypeConformTo(TypeBoolean)) {
1485                 fixEdge<BooleanUse>(node->child1());
1486                 node->remove();
1487             } else if (typeSet->doesTypeConformTo(TypeUndefined | TypeNull) && (seenTypes & TypeUndefined) && (seenTypes & TypeNull)) {
1488                 fixEdge<OtherUse>(node->child1());
1489                 node->remove();
1490             } else if (typeSet->doesTypeConformTo(TypeObject)) {
1491                 StructureSet set;
1492                 {
1493                     ConcurrentJITLocker locker(typeSet->m_lock);
1494                     set = typeSet->structureSet(locker);
1495                 }
1496                 if (!set.isEmpty()) {
1497                     fixEdge<CellUse>(node->child1());
1498                     node->convertToCheckStructure(m_graph.addStructureSet(set));
1499                 }
1500             }
1501
1502             break;
1503         }
1504
1505         case CreateScopedArguments:
1506         case CreateActivation:
1507         case NewFunction:
1508         case NewGeneratorFunction: {
1509             fixEdge<CellUse>(node->child1());
1510             break;
1511         }
1512
1513         case SetFunctionName: {
1514             // The first child is guaranteed to be a cell because op_set_function_name is only used
1515             // on a newly instantiated function object (the first child).
1516             fixEdge<KnownCellUse>(node->child1());
1517             fixEdge<UntypedUse>(node->child2());
1518             break;
1519         }
1520
1521         case CreateRest: {
1522             watchHavingABadTime(node);
1523             fixEdge<KnownInt32Use>(node->child1());
1524             break;
1525         }
1526
1527         case ResolveScope:
1528         case GetDynamicVar:
1529         case PutDynamicVar: {
1530             fixEdge<KnownCellUse>(node->child1());
1531             break;
1532         }
1533
1534         case LogShadowChickenPrologue: {
1535             fixEdge<KnownCellUse>(node->child1());
1536             break;
1537         }
1538         case LogShadowChickenTail: {
1539             fixEdge<UntypedUse>(node->child1());
1540             fixEdge<KnownCellUse>(node->child2());
1541             break;
1542         }
1543
1544 #if !ASSERT_DISABLED
1545         // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
1546         case SetArgument:
1547         case JSConstant:
1548         case LazyJSConstant:
1549         case DoubleConstant:
1550         case GetLocal:
1551         case GetCallee:
1552         case GetArgumentCountIncludingThis:
1553         case GetRestLength:
1554         case Flush:
1555         case PhantomLocal:
1556         case GetLocalUnlinked:
1557         case GetGlobalVar:
1558         case GetGlobalLexicalVariable:
1559         case NotifyWrite:
1560         case Call:
1561         case CheckTypeInfoFlags:
1562         case TailCallInlinedCaller:
1563         case Construct:
1564         case CallVarargs:
1565         case CallEval:
1566         case TailCallVarargsInlinedCaller:
1567         case ConstructVarargs:
1568         case CallForwardVarargs:
1569         case ConstructForwardVarargs:
1570         case TailCallForwardVarargs:
1571         case TailCallForwardVarargsInlinedCaller:
1572         case LoadVarargs:
1573         case ForwardVarargs:
1574         case ProfileControlFlow:
1575         case NewObject:
1576         case NewArrayBuffer:
1577         case NewRegexp:
1578         case DeleteById:
1579         case DeleteByVal:
1580         case IsJSArray:
1581         case IsTypedArrayView:
1582         case IsEmpty:
1583         case IsUndefined:
1584         case IsBoolean:
1585         case IsNumber:
1586         case IsObjectOrNull:
1587         case IsFunction:
1588         case IsRegExpObject:
1589         case CreateDirectArguments:
1590         case CreateClonedArguments:
1591         case Jump:
1592         case Return:
1593         case TailCall:
1594         case TailCallVarargs:
1595         case Throw:
1596         case ThrowReferenceError:
1597         case CountExecution:
1598         case ForceOSRExit:
1599         case CheckBadCell:
1600         case CheckNotEmpty:
1601         case CheckWatchdogTimer:
1602         case Unreachable:
1603         case ExtractOSREntryLocal:
1604         case LoopHint:
1605         case MovHint:
1606         case ZombieHint:
1607         case ExitOK:
1608         case BottomValue:
1609         case TypeOf:
1610         case GetByIdWithThis:
1611         case PutByIdWithThis:
1612         case PutByValWithThis:
1613         case GetByValWithThis:
1614         case CompareEqPtr:
1615             break;
1616             
1617             break;
1618 #else
1619         default:
1620             break;
1621 #endif
1622         }
1623     }
1624
1625     void watchHavingABadTime(Node* node)
1626     {
1627         JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
1628
1629         // If this global object is not having a bad time, watch it. We go down this path anytime the code
1630         // does an array allocation. The types of array allocations may change if we start to have a bad
1631         // time. It's easier to reason about this if we know that whenever the types change after we start
1632         // optimizing, the code just gets thrown out. Doing this at FixupPhase is just early enough, since
1633         // prior to this point nobody should have been doing optimizations based on the indexing type of
1634         // the allocation.
1635         if (!globalObject->isHavingABadTime())
1636             m_graph.watchpoints().addLazily(globalObject->havingABadTimeWatchpoint());
1637     }
1638     
1639     template<UseKind useKind>
1640     void createToString(Node* node, Edge& edge)
1641     {
1642         edge.setNode(m_insertionSet.insertNode(
1643             m_indexInBlock, SpecString, ToString, node->origin,
1644             Edge(edge.node(), useKind)));
1645     }
1646     
1647     template<UseKind useKind>
1648     void attemptToForceStringArrayModeByToStringConversion(ArrayMode& arrayMode, Node* node)
1649     {
1650         ASSERT(arrayMode == ArrayMode(Array::Generic));
1651         
1652         if (!m_graph.canOptimizeStringObjectAccess(node->origin.semantic))
1653             return;
1654         
1655         createToString<useKind>(node, node->child1());
1656         arrayMode = ArrayMode(Array::String);
1657     }
1658     
1659     template<UseKind useKind>
1660     bool isStringObjectUse()
1661     {
1662         switch (useKind) {
1663         case StringObjectUse:
1664         case StringOrStringObjectUse:
1665             return true;
1666         default:
1667             return false;
1668         }
1669     }
1670     
1671     template<UseKind useKind>
1672     void convertStringAddUse(Node* node, Edge& edge)
1673     {
1674         if (useKind == StringUse) {
1675             observeUseKindOnNode<StringUse>(edge.node());
1676             m_insertionSet.insertNode(
1677                 m_indexInBlock, SpecNone, Check, node->origin,
1678                 Edge(edge.node(), StringUse));
1679             edge.setUseKind(KnownStringUse);
1680             return;
1681         }
1682         
1683         observeUseKindOnNode<useKind>(edge.node());
1684         createToString<useKind>(node, edge);
1685     }
1686     
1687     void convertToMakeRope(Node* node)
1688     {
1689         node->setOpAndDefaultFlags(MakeRope);
1690         fixupMakeRope(node);
1691     }
1692     
1693     void fixupMakeRope(Node* node)
1694     {
1695         for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
1696             Edge& edge = node->children.child(i);
1697             if (!edge)
1698                 break;
1699             edge.setUseKind(KnownStringUse);
1700             JSString* string = edge->dynamicCastConstant<JSString*>();
1701             if (!string)
1702                 continue;
1703             if (string->length())
1704                 continue;
1705             
1706             // Don't allow the MakeRope to have zero children.
1707             if (!i && !node->child2())
1708                 break;
1709             
1710             node->children.removeEdge(i--);
1711         }
1712         
1713         if (!node->child2()) {
1714             ASSERT(!node->child3());
1715             node->convertToIdentity();
1716         }
1717     }
1718
1719     void fixupToThis(Node* node)
1720     {
1721         ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->isStrictMode() ? StrictMode : NotStrictMode;
1722
1723         if (ecmaMode == StrictMode) {
1724             if (node->child1()->shouldSpeculateBoolean()) {
1725                 fixEdge<BooleanUse>(node->child1());
1726                 node->convertToIdentity();
1727                 return;
1728             }
1729
1730             if (node->child1()->shouldSpeculateInt32()) {
1731                 fixEdge<Int32Use>(node->child1());
1732                 node->convertToIdentity();
1733                 return;
1734             }
1735
1736             if (enableInt52() && node->child1()->shouldSpeculateAnyInt()) {
1737                 fixEdge<Int52RepUse>(node->child1());
1738                 node->convertToIdentity();
1739                 node->setResult(NodeResultInt52);
1740                 return;
1741             }
1742
1743             if (node->child1()->shouldSpeculateNumber()) {
1744                 fixEdge<DoubleRepUse>(node->child1());
1745                 node->convertToIdentity();
1746                 node->setResult(NodeResultDouble);
1747                 return;
1748             }
1749
1750             if (node->child1()->shouldSpeculateSymbol()) {
1751                 fixEdge<SymbolUse>(node->child1());
1752                 node->convertToIdentity();
1753                 return;
1754             }
1755
1756             if (node->child1()->shouldSpeculateStringIdent()) {
1757                 fixEdge<StringIdentUse>(node->child1());
1758                 node->convertToIdentity();
1759                 return;
1760             }
1761
1762             if (node->child1()->shouldSpeculateString()) {
1763                 fixEdge<StringUse>(node->child1());
1764                 node->convertToIdentity();
1765                 return;
1766             }
1767         }
1768
1769         if (node->child1()->shouldSpeculateOther()) {
1770             if (ecmaMode == StrictMode) {
1771                 fixEdge<OtherUse>(node->child1());
1772                 node->convertToIdentity();
1773                 return;
1774             }
1775
1776             m_insertionSet.insertNode(
1777                 m_indexInBlock, SpecNone, Check, node->origin,
1778                 Edge(node->child1().node(), OtherUse));
1779             observeUseKindOnNode<OtherUse>(node->child1().node());
1780             m_graph.convertToConstant(
1781                 node, m_graph.globalThisObjectFor(node->origin.semantic));
1782             return;
1783         }
1784
1785         // FIXME: This should cover other use cases but we don't have use kinds for them. It's not critical,
1786         // however, since we cover all the missing cases in constant folding.
1787         // https://bugs.webkit.org/show_bug.cgi?id=157213
1788         if (node->child1()->shouldSpeculateStringObject()) {
1789             fixEdge<StringObjectUse>(node->child1());
1790             node->convertToIdentity();
1791             return;
1792         }
1793
1794         if (isFinalObjectSpeculation(node->child1()->prediction())) {
1795             fixEdge<FinalObjectUse>(node->child1());
1796             node->convertToIdentity();
1797             return;
1798         }
1799     }
1800     
1801     void fixupToPrimitive(Node* node)
1802     {
1803         if (node->child1()->shouldSpeculateInt32()) {
1804             fixEdge<Int32Use>(node->child1());
1805             node->convertToIdentity();
1806             return;
1807         }
1808         
1809         if (node->child1()->shouldSpeculateString()) {
1810             fixEdge<StringUse>(node->child1());
1811             node->convertToIdentity();
1812             return;
1813         }
1814         
1815         if (node->child1()->shouldSpeculateStringObject()
1816             && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
1817             fixEdge<StringObjectUse>(node->child1());
1818             node->convertToToString();
1819             return;
1820         }
1821         
1822         if (node->child1()->shouldSpeculateStringOrStringObject()
1823             && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
1824             fixEdge<StringOrStringObjectUse>(node->child1());
1825             node->convertToToString();
1826             return;
1827         }
1828     }
1829
1830     void fixupToNumber(Node* node)
1831     {
1832         // If the prediction of the child is Number, we attempt to convert ToNumber to Identity.
1833         if (node->child1()->shouldSpeculateNumber()) {
1834             if (isInt32Speculation(node->getHeapPrediction())) {
1835                 // If the both predictions of this node and the child is Int32, we just convert ToNumber to Identity, that's simple.
1836                 if (node->child1()->shouldSpeculateInt32()) {
1837                     fixEdge<Int32Use>(node->child1());
1838                     node->convertToIdentity();
1839                     return;
1840                 }
1841
1842                 // 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.
1843                 // 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.
1844                 fixEdge<DoubleRepUse>(node->child1());
1845                 node->setOp(DoubleAsInt32);
1846                 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
1847                     node->setArithMode(Arith::CheckOverflow);
1848                 else
1849                     node->setArithMode(Arith::CheckOverflowAndNegativeZero);
1850                 return;
1851             }
1852
1853             fixEdge<DoubleRepUse>(node->child1());
1854             node->convertToIdentity();
1855             node->setResult(NodeResultDouble);
1856             return;
1857         }
1858
1859         fixEdge<UntypedUse>(node->child1());
1860         node->setResult(NodeResultJS);
1861     }
1862     
1863     void fixupToStringOrCallStringConstructor(Node* node)
1864     {
1865         if (node->child1()->shouldSpeculateString()) {
1866             fixEdge<StringUse>(node->child1());
1867             node->convertToIdentity();
1868             return;
1869         }
1870         
1871         if (node->child1()->shouldSpeculateStringObject()
1872             && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
1873             fixEdge<StringObjectUse>(node->child1());
1874             return;
1875         }
1876         
1877         if (node->child1()->shouldSpeculateStringOrStringObject()
1878             && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
1879             fixEdge<StringOrStringObjectUse>(node->child1());
1880             return;
1881         }
1882         
1883         if (node->child1()->shouldSpeculateCell()) {
1884             fixEdge<CellUse>(node->child1());
1885             return;
1886         }
1887     }
1888
1889     bool attemptToMakeFastStringAdd(Node* node)
1890     {
1891         bool goodToGo = true;
1892         m_graph.doToChildren(
1893             node,
1894             [&] (Edge& edge) {
1895                 if (edge->shouldSpeculateString())
1896                     return;
1897                 if (m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
1898                     if (edge->shouldSpeculateStringObject())
1899                         return;
1900                     if (edge->shouldSpeculateStringOrStringObject())
1901                         return;
1902                 }
1903                 goodToGo = false;
1904             });
1905         if (!goodToGo)
1906             return false;
1907
1908         m_graph.doToChildren(
1909             node,
1910             [&] (Edge& edge) {
1911                 if (edge->shouldSpeculateString()) {
1912                     convertStringAddUse<StringUse>(node, edge);
1913                     return;
1914                 }
1915                 ASSERT(m_graph.canOptimizeStringObjectAccess(node->origin.semantic));
1916                 if (edge->shouldSpeculateStringObject()) {
1917                     convertStringAddUse<StringObjectUse>(node, edge);
1918                     return;
1919                 }
1920                 if (edge->shouldSpeculateStringOrStringObject()) {
1921                     convertStringAddUse<StringOrStringObjectUse>(node, edge);
1922                     return;
1923                 }
1924                 RELEASE_ASSERT_NOT_REACHED();
1925             });
1926         
1927         convertToMakeRope(node);
1928         return true;
1929     }
1930
1931     void fixupGetAndSetLocalsInBlock(BasicBlock* block)
1932     {
1933         if (!block)
1934             return;
1935         ASSERT(block->isReachable);
1936         m_block = block;
1937         for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
1938             Node* node = m_currentNode = block->at(m_indexInBlock);
1939             if (node->op() != SetLocal && node->op() != GetLocal)
1940                 continue;
1941             
1942             VariableAccessData* variable = node->variableAccessData();
1943             switch (node->op()) {
1944             case GetLocal:
1945                 switch (variable->flushFormat()) {
1946                 case FlushedDouble:
1947                     node->setResult(NodeResultDouble);
1948                     break;
1949                 case FlushedInt52:
1950                     node->setResult(NodeResultInt52);
1951                     break;
1952                 default:
1953                     break;
1954                 }
1955                 break;
1956                 
1957             case SetLocal:
1958                 // NOTE: Any type checks we put here may get hoisted by fixupChecksInBlock(). So, if we
1959                 // add new type checking use kind for SetLocals, we need to modify that code as well.
1960                 
1961                 switch (variable->flushFormat()) {
1962                 case FlushedJSValue:
1963                     break;
1964                 case FlushedDouble:
1965                     fixEdge<DoubleRepUse>(node->child1());
1966                     break;
1967                 case FlushedInt32:
1968                     fixEdge<Int32Use>(node->child1());
1969                     break;
1970                 case FlushedInt52:
1971                     fixEdge<Int52RepUse>(node->child1());
1972                     break;
1973                 case FlushedCell:
1974                     fixEdge<CellUse>(node->child1());
1975                     break;
1976                 case FlushedBoolean:
1977                     fixEdge<BooleanUse>(node->child1());
1978                     break;
1979                 default:
1980                     RELEASE_ASSERT_NOT_REACHED();
1981                     break;
1982                 }
1983                 break;
1984                 
1985             default:
1986                 RELEASE_ASSERT_NOT_REACHED();
1987                 break;
1988             }
1989         }
1990         m_insertionSet.execute(block);
1991     }
1992     
1993     void addStringReplacePrimordialChecks(Node* searchRegExp)
1994     {
1995         Node* node = m_currentNode;
1996
1997         // Check that structure of searchRegExp is RegExp object
1998         m_insertionSet.insertNode(
1999             m_indexInBlock, SpecNone, Check, node->origin,
2000             Edge(searchRegExp, RegExpObjectUse));
2001
2002         auto emitPrimordialCheckFor = [&] (JSValue primordialProperty, UniquedStringImpl* propertyUID) {
2003             unsigned index = m_graph.identifiers().ensure(propertyUID);
2004
2005             Node* actualProperty = m_insertionSet.insertNode(
2006                 m_indexInBlock, SpecNone, TryGetById, node->origin,
2007                 OpInfo(index), OpInfo(SpecFunction), Edge(searchRegExp, CellUse));
2008
2009             m_insertionSet.insertNode(
2010                 m_indexInBlock, SpecNone, CheckCell, node->origin,
2011                 OpInfo(m_graph.freeze(primordialProperty)), Edge(actualProperty, CellUse));
2012         };
2013
2014         JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
2015
2016         // Check that searchRegExp.exec is the primordial RegExp.prototype.exec
2017         emitPrimordialCheckFor(globalObject->regExpProtoExecFunction(), vm().propertyNames->exec.impl());
2018         // Check that searchRegExp.global is the primordial RegExp.prototype.global
2019         emitPrimordialCheckFor(globalObject->regExpProtoGlobalGetter(), vm().propertyNames->global.impl());
2020         // Check that searchRegExp.unicode is the primordial RegExp.prototype.unicode
2021         emitPrimordialCheckFor(globalObject->regExpProtoUnicodeGetter(), vm().propertyNames->unicode.impl());
2022         // Check that searchRegExp[Symbol.match] is the primordial RegExp.prototype[Symbol.replace]
2023         emitPrimordialCheckFor(globalObject->regExpProtoSymbolReplaceFunction(), vm().propertyNames->replaceSymbol.impl());
2024     }
2025
2026     Node* checkArray(ArrayMode arrayMode, const NodeOrigin& origin, Node* array, Node* index, bool (*storageCheck)(const ArrayMode&) = canCSEStorage)
2027     {
2028         ASSERT(arrayMode.isSpecific());
2029         
2030         if (arrayMode.type() == Array::String) {
2031             m_insertionSet.insertNode(
2032                 m_indexInBlock, SpecNone, Check, origin, Edge(array, StringUse));
2033         } else {
2034             // Note that we only need to be using a structure check if we opt for SaneChain, since
2035             // that needs to protect against JSArray's __proto__ being changed.
2036             Structure* structure = arrayMode.originalArrayStructure(m_graph, origin.semantic);
2037         
2038             Edge indexEdge = index ? Edge(index, Int32Use) : Edge();
2039             
2040             if (arrayMode.doesConversion()) {
2041                 if (structure) {
2042                     m_insertionSet.insertNode(
2043                         m_indexInBlock, SpecNone, ArrayifyToStructure, origin,
2044                         OpInfo(structure), OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
2045                 } else {
2046                     m_insertionSet.insertNode(
2047                         m_indexInBlock, SpecNone, Arrayify, origin,
2048                         OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
2049                 }
2050             } else {
2051                 if (structure) {
2052                     m_insertionSet.insertNode(
2053                         m_indexInBlock, SpecNone, CheckStructure, origin,
2054                         OpInfo(m_graph.addStructureSet(structure)), Edge(array, CellUse));
2055                 } else {
2056                     m_insertionSet.insertNode(
2057                         m_indexInBlock, SpecNone, CheckArray, origin,
2058                         OpInfo(arrayMode.asWord()), Edge(array, CellUse));
2059                 }
2060             }
2061         }
2062         
2063         if (!storageCheck(arrayMode))
2064             return 0;
2065         
2066         if (arrayMode.usesButterfly()) {
2067             return m_insertionSet.insertNode(
2068                 m_indexInBlock, SpecNone, GetButterfly, origin, Edge(array, CellUse));
2069         }
2070         
2071         return m_insertionSet.insertNode(
2072             m_indexInBlock, SpecNone, GetIndexedPropertyStorage, origin,
2073             OpInfo(arrayMode.asWord()), Edge(array, KnownCellUse));
2074     }
2075     
2076     void blessArrayOperation(Edge base, Edge index, Edge& storageChild)
2077     {
2078         Node* node = m_currentNode;
2079         
2080         switch (node->arrayMode().type()) {
2081         case Array::ForceExit: {
2082             m_insertionSet.insertNode(
2083                 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
2084             return;
2085         }
2086             
2087         case Array::SelectUsingPredictions:
2088         case Array::Unprofiled:
2089             RELEASE_ASSERT_NOT_REACHED();
2090             return;
2091             
2092         case Array::Generic:
2093             return;
2094             
2095         default: {
2096             Node* storage = checkArray(node->arrayMode(), node->origin, base.node(), index.node());
2097             if (!storage)
2098                 return;
2099             
2100             storageChild = Edge(storage);
2101             return;
2102         } }
2103     }
2104     
2105     bool alwaysUnboxSimplePrimitives()
2106     {
2107 #if USE(JSVALUE64)
2108         return false;
2109 #else
2110         // Any boolean, int, or cell value is profitable to unbox on 32-bit because it
2111         // reduces traffic.
2112         return true;
2113 #endif
2114     }
2115
2116     template<UseKind useKind>
2117     void observeUseKindOnNode(Node* node)
2118     {
2119         if (useKind == UntypedUse)
2120             return;
2121         observeUseKindOnNode(node, useKind);
2122     }
2123
2124     void observeUseKindOnEdge(Edge edge)
2125     {
2126         observeUseKindOnNode(edge.node(), edge.useKind());
2127     }
2128
2129     void observeUseKindOnNode(Node* node, UseKind useKind)
2130     {
2131         if (node->op() != GetLocal)
2132             return;
2133         
2134         // FIXME: The way this uses alwaysUnboxSimplePrimitives() is suspicious.
2135         // https://bugs.webkit.org/show_bug.cgi?id=121518
2136         
2137         VariableAccessData* variable = node->variableAccessData();
2138         switch (useKind) {
2139         case Int32Use:
2140         case KnownInt32Use:
2141             if (alwaysUnboxSimplePrimitives()
2142                 || isInt32Speculation(variable->prediction()))
2143                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
2144             break;
2145         case NumberUse:
2146         case RealNumberUse:
2147         case DoubleRepUse:
2148         case DoubleRepRealUse:
2149             if (variable->doubleFormatState() == UsingDoubleFormat)
2150                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
2151             break;
2152         case BooleanUse:
2153         case KnownBooleanUse:
2154             if (alwaysUnboxSimplePrimitives()
2155                 || isBooleanSpeculation(variable->prediction()))
2156                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
2157             break;
2158         case Int52RepUse:
2159             if (isAnyIntSpeculation(variable->prediction()))
2160                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
2161             break;
2162         case CellUse:
2163         case KnownCellUse:
2164         case ObjectUse:
2165         case FunctionUse:
2166         case StringUse:
2167         case KnownStringUse:
2168         case SymbolUse:
2169         case StringObjectUse:
2170         case StringOrStringObjectUse:
2171             if (alwaysUnboxSimplePrimitives()
2172                 || isCellSpeculation(variable->prediction()))
2173                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
2174             break;
2175         default:
2176             break;
2177         }
2178     }
2179     
2180     template<UseKind useKind>
2181     void fixEdge(Edge& edge)
2182     {
2183         observeUseKindOnNode<useKind>(edge.node());
2184         edge.setUseKind(useKind);
2185     }
2186     
2187     void speculateForBarrier(Edge value)
2188     {
2189         // Currently, the DFG won't take advantage of this speculation. But, we want to do it in
2190         // the DFG anyway because if such a speculation would be wrong, we want to know before
2191         // we do an expensive compile.
2192         
2193         if (value->shouldSpeculateInt32()) {
2194             insertCheck<Int32Use>(m_indexInBlock, value.node());
2195             return;
2196         }
2197             
2198         if (value->shouldSpeculateBoolean()) {
2199             insertCheck<BooleanUse>(m_indexInBlock, value.node());
2200             return;
2201         }
2202             
2203         if (value->shouldSpeculateOther()) {
2204             insertCheck<OtherUse>(m_indexInBlock, value.node());
2205             return;
2206         }
2207             
2208         if (value->shouldSpeculateNumber()) {
2209             insertCheck<NumberUse>(m_indexInBlock, value.node());
2210             return;
2211         }
2212             
2213         if (value->shouldSpeculateNotCell()) {
2214             insertCheck<NotCellUse>(m_indexInBlock, value.node());
2215             return;
2216         }
2217     }
2218     
2219     template<UseKind useKind>
2220     void insertCheck(unsigned indexInBlock, Node* node)
2221     {
2222         observeUseKindOnNode<useKind>(node);
2223         m_insertionSet.insertNode(
2224             indexInBlock, SpecNone, Check, m_currentNode->origin, Edge(node, useKind));
2225     }
2226
2227     void fixIntConvertingEdge(Edge& edge)
2228     {
2229         Node* node = edge.node();
2230         if (node->shouldSpeculateInt32OrBoolean()) {
2231             fixIntOrBooleanEdge(edge);
2232             return;
2233         }
2234         
2235         UseKind useKind;
2236         if (node->shouldSpeculateAnyInt())
2237             useKind = Int52RepUse;
2238         else if (node->shouldSpeculateNumber())
2239             useKind = DoubleRepUse;
2240         else
2241             useKind = NotCellUse;
2242         Node* newNode = m_insertionSet.insertNode(
2243             m_indexInBlock, SpecInt32Only, ValueToInt32, m_currentNode->origin,
2244             Edge(node, useKind));
2245         observeUseKindOnNode(node, useKind);
2246         
2247         edge = Edge(newNode, KnownInt32Use);
2248     }
2249     
2250     void fixIntOrBooleanEdge(Edge& edge)
2251     {
2252         Node* node = edge.node();
2253         if (!node->sawBooleans()) {
2254             fixEdge<Int32Use>(edge);
2255             return;
2256         }
2257         
2258         UseKind useKind;
2259         if (node->shouldSpeculateBoolean())
2260             useKind = BooleanUse;
2261         else
2262             useKind = UntypedUse;
2263         Node* newNode = m_insertionSet.insertNode(
2264             m_indexInBlock, SpecInt32Only, BooleanToNumber, m_currentNode->origin,
2265             Edge(node, useKind));
2266         observeUseKindOnNode(node, useKind);
2267         
2268         edge = Edge(newNode, Int32Use);
2269     }
2270     
2271     void fixDoubleOrBooleanEdge(Edge& edge)
2272     {
2273         Node* node = edge.node();
2274         if (!node->sawBooleans()) {
2275             fixEdge<DoubleRepUse>(edge);
2276             return;
2277         }
2278         
2279         UseKind useKind;
2280         if (node->shouldSpeculateBoolean())
2281             useKind = BooleanUse;
2282         else
2283             useKind = UntypedUse;
2284         Node* newNode = m_insertionSet.insertNode(
2285             m_indexInBlock, SpecInt32Only, BooleanToNumber, m_currentNode->origin,
2286             Edge(node, useKind));
2287         observeUseKindOnNode(node, useKind);
2288         
2289         edge = Edge(newNode, DoubleRepUse);
2290     }
2291     
2292     void truncateConstantToInt32(Edge& edge)
2293     {
2294         Node* oldNode = edge.node();
2295         
2296         JSValue value = oldNode->asJSValue();
2297         if (value.isInt32())
2298             return;
2299         
2300         value = jsNumber(JSC::toInt32(value.asNumber()));
2301         ASSERT(value.isInt32());
2302         edge.setNode(m_insertionSet.insertNode(
2303             m_indexInBlock, SpecInt32Only, JSConstant, m_currentNode->origin,
2304             OpInfo(m_graph.freeze(value))));
2305     }
2306     
2307     void truncateConstantsIfNecessary(Node* node, AddSpeculationMode mode)
2308     {
2309         if (mode != SpeculateInt32AndTruncateConstants)
2310             return;
2311         
2312         ASSERT(node->child1()->hasConstant() || node->child2()->hasConstant());
2313         if (node->child1()->hasConstant())
2314             truncateConstantToInt32(node->child1());
2315         else
2316             truncateConstantToInt32(node->child2());
2317     }
2318     
2319     bool attemptToMakeIntegerAdd(Node* node)
2320     {
2321         AddSpeculationMode mode = m_graph.addSpeculationMode(node, FixupPass);
2322         if (mode != DontSpeculateInt32) {
2323             truncateConstantsIfNecessary(node, mode);
2324             fixIntOrBooleanEdge(node->child1());
2325             fixIntOrBooleanEdge(node->child2());
2326             if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
2327                 node->setArithMode(Arith::Unchecked);
2328             else
2329                 node->setArithMode(Arith::CheckOverflow);
2330             return true;
2331         }
2332         
2333         if (m_graph.addShouldSpeculateAnyInt(node)) {
2334             fixEdge<Int52RepUse>(node->child1());
2335             fixEdge<Int52RepUse>(node->child2());
2336             node->setArithMode(Arith::CheckOverflow);
2337             node->setResult(NodeResultInt52);
2338             return true;
2339         }
2340         
2341         return false;
2342     }
2343     
2344     bool attemptToMakeGetArrayLength(Node* node)
2345     {
2346         if (!isInt32Speculation(node->prediction()))
2347             return false;
2348         CodeBlock* profiledBlock = m_graph.baselineCodeBlockFor(node->origin.semantic);
2349         ArrayProfile* arrayProfile = 
2350             profiledBlock->getArrayProfile(node->origin.semantic.bytecodeIndex);
2351         ArrayMode arrayMode = ArrayMode(Array::SelectUsingPredictions);
2352         if (arrayProfile) {
2353             ConcurrentJITLocker locker(profiledBlock->m_lock);
2354             arrayProfile->computeUpdatedPrediction(locker, profiledBlock);
2355             arrayMode = ArrayMode::fromObserved(locker, arrayProfile, Array::Read, false);
2356             if (arrayMode.type() == Array::Unprofiled) {
2357                 // For normal array operations, it makes sense to treat Unprofiled
2358                 // accesses as ForceExit and get more data rather than using
2359                 // predictions and then possibly ending up with a Generic. But here,
2360                 // we treat anything that is Unprofiled as Generic and keep the
2361                 // GetById. I.e. ForceExit = Generic. So, there is no harm - and only
2362                 // profit - from treating the Unprofiled case as
2363                 // SelectUsingPredictions.
2364                 arrayMode = ArrayMode(Array::SelectUsingPredictions);
2365             }
2366         }
2367             
2368         arrayMode = arrayMode.refine(
2369             m_graph, node, node->child1()->prediction(), node->prediction());
2370             
2371         if (arrayMode.type() == Array::Generic) {
2372             // Check if the input is something that we can't get array length for, but for which we
2373             // could insert some conversions in order to transform it into something that we can do it
2374             // for.
2375             if (node->child1()->shouldSpeculateStringObject())
2376                 attemptToForceStringArrayModeByToStringConversion<StringObjectUse>(arrayMode, node);
2377             else if (node->child1()->shouldSpeculateStringOrStringObject())
2378                 attemptToForceStringArrayModeByToStringConversion<StringOrStringObjectUse>(arrayMode, node);
2379         }
2380             
2381         if (!arrayMode.supportsSelfLength())
2382             return false;
2383         
2384         convertToGetArrayLength(node, arrayMode);
2385         return true;
2386     }
2387
2388     void convertToGetArrayLength(Node* node, ArrayMode arrayMode)
2389     {
2390         node->setOp(GetArrayLength);
2391         node->clearFlags(NodeMustGenerate);
2392         fixEdge<KnownCellUse>(node->child1());
2393         node->setArrayMode(arrayMode);
2394             
2395         Node* storage = checkArray(arrayMode, node->origin, node->child1().node(), 0, lengthNeedsStorage);
2396         if (!storage)
2397             return;
2398             
2399         node->child2() = Edge(storage);
2400     }
2401     
2402     Node* prependGetArrayLength(NodeOrigin origin, Node* child, ArrayMode arrayMode)
2403     {
2404         Node* storage = checkArray(arrayMode, origin, child, 0, lengthNeedsStorage);
2405         return m_insertionSet.insertNode(
2406             m_indexInBlock, SpecInt32Only, GetArrayLength, origin,
2407             OpInfo(arrayMode.asWord()), Edge(child, KnownCellUse), Edge(storage));
2408     }
2409     
2410     void fixupChecksInBlock(BasicBlock* block)
2411     {
2412         if (!block)
2413             return;
2414         ASSERT(block->isReachable);
2415         m_block = block;
2416         unsigned indexForChecks = UINT_MAX;
2417         NodeOrigin originForChecks;
2418         for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
2419             Node* node = block->at(indexInBlock);
2420
2421             // If this is a node at which we could exit, then save its index. If nodes after this one
2422             // cannot exit, then we will hoist checks to here.
2423             if (node->origin.exitOK) {
2424                 indexForChecks = indexInBlock;
2425                 originForChecks = node->origin;
2426             }
2427
2428             originForChecks = originForChecks.withSemantic(node->origin.semantic);
2429
2430             // First, try to relax the representational demands of each node, in order to have
2431             // fewer conversions.
2432             switch (node->op()) {
2433             case MovHint:
2434             case Check:
2435                 m_graph.doToChildren(
2436                     node,
2437                     [&] (Edge& edge) {
2438                         switch (edge.useKind()) {
2439                         case DoubleRepUse:
2440                         case DoubleRepRealUse:
2441                             if (edge->hasDoubleResult())
2442                                 break;
2443             
2444                             if (edge->hasInt52Result())
2445                                 edge.setUseKind(Int52RepUse);
2446                             else if (edge.useKind() == DoubleRepUse)
2447                                 edge.setUseKind(NumberUse);
2448                             break;
2449             
2450                         case Int52RepUse:
2451                             // Nothing we can really do.
2452                             break;
2453             
2454                         case UntypedUse:
2455                         case NumberUse:
2456                             if (edge->hasDoubleResult())
2457                                 edge.setUseKind(DoubleRepUse);
2458                             else if (edge->hasInt52Result())
2459                                 edge.setUseKind(Int52RepUse);
2460                             break;
2461             
2462                         case RealNumberUse:
2463                             if (edge->hasDoubleResult())
2464                                 edge.setUseKind(DoubleRepRealUse);
2465                             else if (edge->hasInt52Result())
2466                                 edge.setUseKind(Int52RepUse);
2467                             break;
2468             
2469                         default:
2470                             break;
2471                         }
2472                     });
2473                 break;
2474                 
2475             case ValueToInt32:
2476                 if (node->child1().useKind() == DoubleRepUse
2477                     && !node->child1()->hasDoubleResult()) {
2478                     node->child1().setUseKind(NumberUse);
2479                     break;
2480                 }
2481                 break;
2482                 
2483             default:
2484                 break;
2485             }
2486
2487             // Now, insert type conversions if necessary.
2488             m_graph.doToChildren(
2489                 node,
2490                 [&] (Edge& edge) {
2491                     Node* result = nullptr;
2492
2493                     switch (edge.useKind()) {
2494                     case DoubleRepUse:
2495                     case DoubleRepRealUse:
2496                     case DoubleRepAnyIntUse: {
2497                         if (edge->hasDoubleResult())
2498                             break;
2499             
2500                         if (edge->isNumberConstant()) {
2501                             result = m_insertionSet.insertNode(
2502                                 indexForChecks, SpecBytecodeDouble, DoubleConstant, originForChecks,
2503                                 OpInfo(m_graph.freeze(jsDoubleNumber(edge->asNumber()))));
2504                         } else if (edge->hasInt52Result()) {
2505                             result = m_insertionSet.insertNode(
2506                                 indexForChecks, SpecAnyIntAsDouble, DoubleRep, originForChecks,
2507                                 Edge(edge.node(), Int52RepUse));
2508                         } else {
2509                             UseKind useKind;
2510                             if (edge->shouldSpeculateDoubleReal())
2511                                 useKind = RealNumberUse;
2512                             else if (edge->shouldSpeculateNumber())
2513                                 useKind = NumberUse;
2514                             else
2515                                 useKind = NotCellUse;
2516
2517                             result = m_insertionSet.insertNode(
2518                                 indexForChecks, SpecBytecodeDouble, DoubleRep, originForChecks,
2519                                 Edge(edge.node(), useKind));
2520                         }
2521
2522                         edge.setNode(result);
2523                         break;
2524                     }
2525             
2526                     case Int52RepUse: {
2527                         if (edge->hasInt52Result())
2528                             break;
2529             
2530                         if (edge->isAnyIntConstant()) {
2531                             result = m_insertionSet.insertNode(
2532                                 indexForChecks, SpecAnyInt, Int52Constant, originForChecks,
2533                                 OpInfo(edge->constant()));
2534                         } else if (edge->hasDoubleResult()) {
2535                             result = m_insertionSet.insertNode(
2536                                 indexForChecks, SpecAnyInt, Int52Rep, originForChecks,
2537                                 Edge(edge.node(), DoubleRepAnyIntUse));
2538                         } else if (edge->shouldSpeculateInt32ForArithmetic()) {
2539                             result = m_insertionSet.insertNode(
2540                                 indexForChecks, SpecInt32Only, Int52Rep, originForChecks,
2541                                 Edge(edge.node(), Int32Use));
2542                         } else {
2543                             result = m_insertionSet.insertNode(
2544                                 indexForChecks, SpecAnyInt, Int52Rep, originForChecks,
2545                                 Edge(edge.node(), AnyIntUse));
2546                         }
2547
2548                         edge.setNode(result);
2549                         break;
2550                     }
2551
2552                     default: {
2553                         if (!edge->hasDoubleResult() && !edge->hasInt52Result())
2554                             break;
2555             
2556                         if (edge->hasDoubleResult()) {
2557                             result = m_insertionSet.insertNode(
2558                                 indexForChecks, SpecBytecodeDouble, ValueRep, originForChecks,
2559                                 Edge(edge.node(), DoubleRepUse));
2560                         } else {
2561                             result = m_insertionSet.insertNode(
2562                                 indexForChecks, SpecInt32Only | SpecAnyIntAsDouble, ValueRep,
2563                                 originForChecks, Edge(edge.node(), Int52RepUse));
2564                         }
2565
2566                         edge.setNode(result);
2567                         break;
2568                     } }
2569
2570                     // It's remotely possible that this node cannot do type checks, but we now have a
2571                     // type check on this node. We don't have to handle the general form of this
2572                     // problem. It only arises when ByteCodeParser emits an immediate SetLocal, rather
2573                     // than a delayed one. So, we only worry about those checks that we may have put on
2574                     // a SetLocal. Note that "indexForChecks != indexInBlock" is just another way of
2575                     // saying "!node->origin.exitOK".
2576                     if (indexForChecks != indexInBlock && mayHaveTypeCheck(edge.useKind())) {
2577                         UseKind knownUseKind;
2578                         
2579                         switch (edge.useKind()) {
2580                         case Int32Use:
2581                             knownUseKind = KnownInt32Use;
2582                             break;
2583                         case CellUse:
2584                             knownUseKind = KnownCellUse;
2585                             break;
2586                         case BooleanUse:
2587                             knownUseKind = KnownBooleanUse;
2588                             break;
2589                         default:
2590                             // This can only arise if we have a Check node, and in that case, we can
2591                             // just remove the original check.
2592                             DFG_ASSERT(m_graph, node, node->op() == Check);
2593                             knownUseKind = UntypedUse;
2594                             break;
2595                         }
2596
2597                         m_insertionSet.insertNode(
2598                             indexForChecks, SpecNone, Check, originForChecks, edge);
2599
2600                         edge.setUseKind(knownUseKind);
2601                     }
2602                 });
2603         }
2604         
2605         m_insertionSet.execute(block);
2606     }
2607     
2608     BasicBlock* m_block;
2609     unsigned m_indexInBlock;
2610     Node* m_currentNode;
2611     InsertionSet m_insertionSet;
2612     bool m_profitabilityChanged;
2613 };
2614     
2615 bool performFixup(Graph& graph)
2616 {
2617     return runPhase<FixupPhase>(graph);
2618 }
2619
2620 } } // namespace JSC::DFG
2621
2622 #endif // ENABLE(DFG_JIT)
2623