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