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