af86a463866f2a02b8ec47d109028252c9c86d38
[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             fixEdge<CellUse>(node->child1());
883             fixEdge<CellUse>(node->child2());
884             break;
885         }
886
887         case StringReplace: {
888             if (node->child1()->shouldSpeculateString()
889                 && node->child2()->shouldSpeculateRegExpObject()
890                 && node->child3()->shouldSpeculateString()) {
891                 fixEdge<StringUse>(node->child1());
892                 fixEdge<RegExpObjectUse>(node->child2());
893                 fixEdge<StringUse>(node->child3());
894                 break;
895             }
896             break;
897         }
898             
899         case Branch: {
900             if (node->child1()->shouldSpeculateBoolean()) {
901                 if (node->child1()->result() == NodeResultBoolean) {
902                     // This is necessary in case we have a bytecode instruction implemented by:
903                     //
904                     // a: CompareEq(...)
905                     // b: Branch(@a)
906                     //
907                     // In that case, CompareEq might have a side-effect. Then, we need to make
908                     // sure that we know that Branch does not exit.
909                     fixEdge<KnownBooleanUse>(node->child1());
910                 } else
911                     fixEdge<BooleanUse>(node->child1());
912             } else if (node->child1()->shouldSpeculateObjectOrOther())
913                 fixEdge<ObjectOrOtherUse>(node->child1());
914             else if (node->child1()->shouldSpeculateInt32OrBoolean())
915                 fixIntOrBooleanEdge(node->child1());
916             else if (node->child1()->shouldSpeculateNumber())
917                 fixEdge<DoubleRepUse>(node->child1());
918             else if (node->child1()->shouldSpeculateString())
919                 fixEdge<StringUse>(node->child1());
920             break;
921         }
922             
923         case Switch: {
924             SwitchData* data = node->switchData();
925             switch (data->kind) {
926             case SwitchImm:
927                 if (node->child1()->shouldSpeculateInt32())
928                     fixEdge<Int32Use>(node->child1());
929                 break;
930             case SwitchChar:
931                 if (node->child1()->shouldSpeculateString())
932                     fixEdge<StringUse>(node->child1());
933                 break;
934             case SwitchString:
935                 if (node->child1()->shouldSpeculateStringIdent())
936                     fixEdge<StringIdentUse>(node->child1());
937                 else if (node->child1()->shouldSpeculateString())
938                     fixEdge<StringUse>(node->child1());
939                 break;
940             case SwitchCell:
941                 if (node->child1()->shouldSpeculateCell())
942                     fixEdge<CellUse>(node->child1());
943                 // else it's fine for this to have UntypedUse; we will handle this by just making
944                 // non-cells take the default case.
945                 break;
946             }
947             break;
948         }
949             
950         case ToPrimitive: {
951             fixupToPrimitive(node);
952             break;
953         }
954             
955         case ToString:
956         case CallStringConstructor: {
957             fixupToStringOrCallStringConstructor(node);
958             break;
959         }
960             
961         case NewStringObject: {
962             fixEdge<KnownStringUse>(node->child1());
963             break;
964         }
965             
966         case NewArray: {
967             watchHavingABadTime(node);
968             
969             for (unsigned i = m_graph.varArgNumChildren(node); i--;) {
970                 node->setIndexingType(
971                     leastUpperBoundOfIndexingTypeAndType(
972                         node->indexingType(), m_graph.varArgChild(node, i)->prediction()));
973             }
974             switch (node->indexingType()) {
975             case ALL_BLANK_INDEXING_TYPES:
976                 CRASH();
977                 break;
978             case ALL_UNDECIDED_INDEXING_TYPES:
979                 if (node->numChildren()) {
980                     // This will only happen if the children have no type predictions. We
981                     // would have already exited by now, but insert a forced exit just to
982                     // be safe.
983                     m_insertionSet.insertNode(
984                         m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
985                 }
986                 break;
987             case ALL_INT32_INDEXING_TYPES:
988                 for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
989                     fixEdge<Int32Use>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
990                 break;
991             case ALL_DOUBLE_INDEXING_TYPES:
992                 for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
993                     fixEdge<DoubleRepRealUse>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
994                 break;
995             case ALL_CONTIGUOUS_INDEXING_TYPES:
996             case ALL_ARRAY_STORAGE_INDEXING_TYPES:
997                 break;
998             default:
999                 CRASH();
1000                 break;
1001             }
1002             break;
1003         }
1004             
1005         case NewTypedArray: {
1006             watchHavingABadTime(node);
1007             
1008             if (node->child1()->shouldSpeculateInt32()) {
1009                 fixEdge<Int32Use>(node->child1());
1010                 node->clearFlags(NodeMustGenerate);
1011                 break;
1012             }
1013             break;
1014         }
1015             
1016         case NewArrayWithSize: {
1017             watchHavingABadTime(node);
1018             fixEdge<Int32Use>(node->child1());
1019             break;
1020         }
1021             
1022         case ToThis: {
1023             fixupToThis(node);
1024             break;
1025         }
1026             
1027         case PutStructure: {
1028             fixEdge<KnownCellUse>(node->child1());
1029             break;
1030         }
1031             
1032         case GetClosureVar:
1033         case GetFromArguments: {
1034             fixEdge<KnownCellUse>(node->child1());
1035             break;
1036         }
1037
1038         case PutClosureVar:
1039         case PutToArguments: {
1040             fixEdge<KnownCellUse>(node->child1());
1041             speculateForBarrier(node->child2());
1042             break;
1043         }
1044
1045         case SkipScope:
1046         case GetScope:
1047         case GetGetter:
1048         case GetSetter: {
1049             fixEdge<KnownCellUse>(node->child1());
1050             break;
1051         }
1052             
1053         case AllocatePropertyStorage:
1054         case ReallocatePropertyStorage: {
1055             fixEdge<KnownCellUse>(node->child1());
1056             break;
1057         }
1058
1059         case GetById:
1060         case GetByIdFlush: {
1061             if (!node->child1()->shouldSpeculateCell())
1062                 break;
1063
1064             // If we hadn't exited because of BadCache, BadIndexingType, or ExoticObjectMode, then
1065             // leave this as a GetById.
1066             if (!m_graph.hasExitSite(node->origin.semantic, BadCache)
1067                 && !m_graph.hasExitSite(node->origin.semantic, BadIndexingType)
1068                 && !m_graph.hasExitSite(node->origin.semantic, ExoticObjectMode)) {
1069                 auto uid = m_graph.identifiers()[node->identifierNumber()];
1070                 if (uid == vm().propertyNames->length.impl()) {
1071                     attemptToMakeGetArrayLength(node);
1072                     break;
1073                 }
1074             }
1075             fixEdge<CellUse>(node->child1());
1076             break;
1077         }
1078             
1079         case PutById:
1080         case PutByIdFlush:
1081         case PutByIdDirect: {
1082             fixEdge<CellUse>(node->child1());
1083             break;
1084         }
1085
1086         case PutGetterById:
1087         case PutSetterById: {
1088             fixEdge<KnownCellUse>(node->child1());
1089             fixEdge<KnownCellUse>(node->child2());
1090             break;
1091         }
1092
1093         case PutGetterSetterById: {
1094             fixEdge<KnownCellUse>(node->child1());
1095             break;
1096         }
1097
1098         case PutGetterByVal:
1099         case PutSetterByVal: {
1100             fixEdge<KnownCellUse>(node->child1());
1101             fixEdge<KnownCellUse>(node->child3());
1102             break;
1103         }
1104
1105         case GetExecutable: {
1106             fixEdge<FunctionUse>(node->child1());
1107             break;
1108         }
1109
1110         case OverridesHasInstance:
1111         case CheckStructure:
1112         case CheckCell:
1113         case CreateThis:
1114         case GetButterfly:
1115         case GetButterflyReadOnly: {
1116             fixEdge<CellUse>(node->child1());
1117             break;
1118         }
1119
1120         case CheckIdent: {
1121             UniquedStringImpl* uid = node->uidOperand();
1122             if (uid->isSymbol())
1123                 fixEdge<SymbolUse>(node->child1());
1124             else
1125                 fixEdge<StringIdentUse>(node->child1());
1126             break;
1127         }
1128             
1129         case Arrayify:
1130         case ArrayifyToStructure: {
1131             fixEdge<CellUse>(node->child1());
1132             if (node->child2())
1133                 fixEdge<Int32Use>(node->child2());
1134             break;
1135         }
1136             
1137         case GetByOffset:
1138         case GetGetterSetterByOffset: {
1139             if (!node->child1()->hasStorageResult())
1140                 fixEdge<KnownCellUse>(node->child1());
1141             fixEdge<KnownCellUse>(node->child2());
1142             break;
1143         }
1144             
1145         case MultiGetByOffset: {
1146             fixEdge<CellUse>(node->child1());
1147             break;
1148         }
1149             
1150         case PutByOffset: {
1151             if (!node->child1()->hasStorageResult())
1152                 fixEdge<KnownCellUse>(node->child1());
1153             fixEdge<KnownCellUse>(node->child2());
1154             insertInferredTypeCheck(
1155                 m_insertionSet, m_indexInBlock, node->origin, node->child3().node(),
1156                 node->storageAccessData().inferredType);
1157             speculateForBarrier(node->child3());
1158             break;
1159         }
1160             
1161         case MultiPutByOffset: {
1162             fixEdge<CellUse>(node->child1());
1163             speculateForBarrier(node->child2());
1164             break;
1165         }
1166             
1167         case InstanceOf: {
1168             if (!(node->child1()->prediction() & ~SpecCell))
1169                 fixEdge<CellUse>(node->child1());
1170             fixEdge<CellUse>(node->child2());
1171             break;
1172         }
1173
1174         case InstanceOfCustom:
1175             fixEdge<CellUse>(node->child2());
1176             break;
1177
1178         case In: {
1179             // FIXME: We should at some point have array profiling on op_in, in which
1180             // case we would be able to turn this into a kind of GetByVal.
1181             
1182             fixEdge<CellUse>(node->child2());
1183             break;
1184         }
1185
1186         case Check: {
1187             m_graph.doToChildren(
1188                 node,
1189                 [&] (Edge& edge) {
1190                     switch (edge.useKind()) {
1191                     case NumberUse:
1192                         if (edge->shouldSpeculateInt32ForArithmetic())
1193                             edge.setUseKind(Int32Use);
1194                         break;
1195                     default:
1196                         break;
1197                     }
1198                     observeUseKindOnEdge(edge);
1199                 });
1200             break;
1201         }
1202
1203         case Phantom:
1204             // Phantoms are meaningless past Fixup. We recreate them on-demand in the backend.
1205             node->remove();
1206             break;
1207
1208         case FiatInt52: {
1209             RELEASE_ASSERT(enableInt52());
1210             node->convertToIdentity();
1211             fixEdge<Int52RepUse>(node->child1());
1212             node->setResult(NodeResultInt52);
1213             break;
1214         }
1215
1216         case GetArrayLength: {
1217             fixEdge<KnownCellUse>(node->child1());
1218             break;
1219         }
1220
1221         case GetTypedArrayByteOffset: {
1222             fixEdge<KnownCellUse>(node->child1());
1223             break;
1224         }
1225
1226         case Phi:
1227         case Upsilon:
1228         case GetIndexedPropertyStorage:
1229         case LastNodeType:
1230         case CheckTierUpInLoop:
1231         case CheckTierUpAtReturn:
1232         case CheckTierUpAndOSREnter:
1233         case CheckTierUpWithNestedTriggerAndOSREnter:
1234         case InvalidationPoint:
1235         case CheckArray:
1236         case CheckInBounds:
1237         case ConstantStoragePointer:
1238         case DoubleAsInt32:
1239         case ValueToInt32:
1240         case DoubleRep:
1241         case ValueRep:
1242         case Int52Rep:
1243         case Int52Constant:
1244         case Identity: // This should have been cleaned up.
1245         case BooleanToNumber:
1246         case PhantomNewObject:
1247         case PhantomNewFunction:
1248         case PhantomNewGeneratorFunction:
1249         case PhantomCreateActivation:
1250         case PhantomDirectArguments:
1251         case PhantomClonedArguments:
1252         case ForwardVarargs:
1253         case GetMyArgumentByVal:
1254         case PutHint:
1255         case CheckStructureImmediate:
1256         case MaterializeNewObject:
1257         case MaterializeCreateActivation:
1258         case PutStack:
1259         case KillStack:
1260         case GetStack:
1261         case StoreBarrier:
1262             // These are just nodes that we don't currently expect to see during fixup.
1263             // If we ever wanted to insert them prior to fixup, then we just have to create
1264             // fixup rules for them.
1265             DFG_CRASH(m_graph, node, "Unexpected node during fixup");
1266             break;
1267         
1268         case PutGlobalVariable: {
1269             fixEdge<CellUse>(node->child1());
1270             speculateForBarrier(node->child2());
1271             break;
1272         }
1273
1274         case IsString:
1275             if (node->child1()->shouldSpeculateString()) {
1276                 m_insertionSet.insertNode(
1277                     m_indexInBlock, SpecNone, Check, node->origin,
1278                     Edge(node->child1().node(), StringUse));
1279                 m_graph.convertToConstant(node, jsBoolean(true));
1280                 observeUseKindOnNode<StringUse>(node);
1281             }
1282             break;
1283
1284         case IsObject:
1285             if (node->child1()->shouldSpeculateObject()) {
1286                 m_insertionSet.insertNode(
1287                     m_indexInBlock, SpecNone, Check, node->origin,
1288                     Edge(node->child1().node(), ObjectUse));
1289                 m_graph.convertToConstant(node, jsBoolean(true));
1290                 observeUseKindOnNode<ObjectUse>(node);
1291             }
1292             break;
1293
1294         case GetEnumerableLength: {
1295             fixEdge<CellUse>(node->child1());
1296             break;
1297         }
1298         case HasGenericProperty: {
1299             fixEdge<CellUse>(node->child2());
1300             break;
1301         }
1302         case HasStructureProperty: {
1303             fixEdge<StringUse>(node->child2());
1304             fixEdge<KnownCellUse>(node->child3());
1305             break;
1306         }
1307         case HasIndexedProperty: {
1308             node->setArrayMode(
1309                 node->arrayMode().refine(
1310                     m_graph, node,
1311                     node->child1()->prediction(),
1312                     node->child2()->prediction(),
1313                     SpecNone));
1314             
1315             blessArrayOperation(node->child1(), node->child2(), node->child3());
1316             fixEdge<CellUse>(node->child1());
1317             fixEdge<KnownInt32Use>(node->child2());
1318             break;
1319         }
1320         case GetDirectPname: {
1321             Edge& base = m_graph.varArgChild(node, 0);
1322             Edge& property = m_graph.varArgChild(node, 1);
1323             Edge& index = m_graph.varArgChild(node, 2);
1324             Edge& enumerator = m_graph.varArgChild(node, 3);
1325             fixEdge<CellUse>(base);
1326             fixEdge<KnownCellUse>(property);
1327             fixEdge<KnownInt32Use>(index);
1328             fixEdge<KnownCellUse>(enumerator);
1329             break;
1330         }
1331         case GetPropertyEnumerator: {
1332             fixEdge<CellUse>(node->child1());
1333             break;
1334         }
1335         case GetEnumeratorStructurePname: {
1336             fixEdge<KnownCellUse>(node->child1());
1337             fixEdge<KnownInt32Use>(node->child2());
1338             break;
1339         }
1340         case GetEnumeratorGenericPname: {
1341             fixEdge<KnownCellUse>(node->child1());
1342             fixEdge<KnownInt32Use>(node->child2());
1343             break;
1344         }
1345         case ToIndexString: {
1346             fixEdge<KnownInt32Use>(node->child1());
1347             break;
1348         }
1349         case ProfileType: {
1350             // We want to insert type checks based on the instructionTypeSet of the TypeLocation, not the globalTypeSet.
1351             // Because the instructionTypeSet is contained in globalTypeSet, if we produce a type check for
1352             // type T for the instructionTypeSet, the global type set must also have information for type T.
1353             // So if it the type check succeeds for type T in the instructionTypeSet, a type check for type T 
1354             // in the globalTypeSet would've also succeeded.
1355             // (The other direction does not hold in general).
1356
1357             RefPtr<TypeSet> typeSet = node->typeLocation()->m_instructionTypeSet;
1358             RuntimeTypeMask seenTypes = typeSet->seenTypes();
1359             if (typeSet->doesTypeConformTo(TypeMachineInt)) {
1360                 if (node->child1()->shouldSpeculateInt32())
1361                     fixEdge<Int32Use>(node->child1());
1362                 else
1363                     fixEdge<MachineIntUse>(node->child1());
1364                 node->remove();
1365             } else if (typeSet->doesTypeConformTo(TypeNumber | TypeMachineInt)) {
1366                 fixEdge<NumberUse>(node->child1());
1367                 node->remove();
1368             } else if (typeSet->doesTypeConformTo(TypeString)) {
1369                 fixEdge<StringUse>(node->child1());
1370                 node->remove();
1371             } else if (typeSet->doesTypeConformTo(TypeBoolean)) {
1372                 fixEdge<BooleanUse>(node->child1());
1373                 node->remove();
1374             } else if (typeSet->doesTypeConformTo(TypeUndefined | TypeNull) && (seenTypes & TypeUndefined) && (seenTypes & TypeNull)) {
1375                 fixEdge<OtherUse>(node->child1());
1376                 node->remove();
1377             } else if (typeSet->doesTypeConformTo(TypeObject)) {
1378                 StructureSet set = typeSet->structureSet();
1379                 if (!set.isEmpty()) {
1380                     fixEdge<CellUse>(node->child1());
1381                     node->convertToCheckStructure(m_graph.addStructureSet(set));
1382                 }
1383             }
1384
1385             break;
1386         }
1387
1388         case CreateScopedArguments:
1389         case CreateActivation:
1390         case NewFunction:
1391         case NewGeneratorFunction: {
1392             fixEdge<CellUse>(node->child1());
1393             break;
1394         }
1395
1396         case NewArrowFunction: {
1397             fixEdge<CellUse>(node->child1());
1398             fixEdge<CellUse>(node->child2());
1399             break;
1400         }
1401
1402         case CopyRest: {
1403             fixEdge<KnownCellUse>(node->child1());
1404             fixEdge<KnownInt32Use>(node->child2());
1405             break;
1406         }
1407
1408 #if !ASSERT_DISABLED
1409         // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
1410         case SetArgument:
1411         case JSConstant:
1412         case DoubleConstant:
1413         case GetLocal:
1414         case GetCallee:
1415         case GetArgumentCount:
1416         case GetRestLength:
1417         case Flush:
1418         case PhantomLocal:
1419         case GetLocalUnlinked:
1420         case GetGlobalVar:
1421         case GetGlobalLexicalVariable:
1422         case NotifyWrite:
1423         case VarInjectionWatchpoint:
1424         case Call:
1425         case CheckTypeInfoFlags:
1426         case TailCallInlinedCaller:
1427         case Construct:
1428         case CallVarargs:
1429         case TailCallVarargsInlinedCaller:
1430         case ConstructVarargs:
1431         case CallForwardVarargs:
1432         case ConstructForwardVarargs:
1433         case TailCallForwardVarargs:
1434         case TailCallForwardVarargsInlinedCaller:
1435         case LoadVarargs:
1436         case ProfileControlFlow:
1437         case NewObject:
1438         case NewArrayBuffer:
1439         case NewRegexp:
1440         case Breakpoint:
1441         case ProfileWillCall:
1442         case ProfileDidCall:
1443         case IsUndefined:
1444         case IsBoolean:
1445         case IsNumber:
1446         case IsObjectOrNull:
1447         case IsFunction:
1448         case CreateDirectArguments:
1449         case CreateClonedArguments:
1450         case Jump:
1451         case Return:
1452         case TailCall:
1453         case TailCallVarargs:
1454         case Throw:
1455         case ThrowReferenceError:
1456         case CountExecution:
1457         case ForceOSRExit:
1458         case CheckBadCell:
1459         case CheckNotEmpty:
1460         case CheckWatchdogTimer:
1461         case Unreachable:
1462         case ExtractOSREntryLocal:
1463         case LoopHint:
1464         case MovHint:
1465         case ZombieHint:
1466         case ExitOK:
1467         case BottomValue:
1468         case TypeOf:
1469             break;
1470 #else
1471         default:
1472             break;
1473 #endif
1474         }
1475     }
1476
1477     void watchHavingABadTime(Node* node)
1478     {
1479         JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
1480
1481         // If this global object is not having a bad time, watch it. We go down this path anytime the code
1482         // does an array allocation. The types of array allocations may change if we start to have a bad
1483         // time. It's easier to reason about this if we know that whenever the types change after we start
1484         // optimizing, the code just gets thrown out. Doing this at FixupPhase is just early enough, since
1485         // prior to this point nobody should have been doing optimizations based on the indexing type of
1486         // the allocation.
1487         if (!globalObject->isHavingABadTime())
1488             m_graph.watchpoints().addLazily(globalObject->havingABadTimeWatchpoint());
1489     }
1490     
1491     template<UseKind useKind>
1492     void createToString(Node* node, Edge& edge)
1493     {
1494         edge.setNode(m_insertionSet.insertNode(
1495             m_indexInBlock, SpecString, ToString, node->origin,
1496             Edge(edge.node(), useKind)));
1497     }
1498     
1499     template<UseKind useKind>
1500     void attemptToForceStringArrayModeByToStringConversion(ArrayMode& arrayMode, Node* node)
1501     {
1502         ASSERT(arrayMode == ArrayMode(Array::Generic));
1503         
1504         if (!m_graph.canOptimizeStringObjectAccess(node->origin.semantic))
1505             return;
1506         
1507         createToString<useKind>(node, node->child1());
1508         arrayMode = ArrayMode(Array::String);
1509     }
1510     
1511     template<UseKind useKind>
1512     bool isStringObjectUse()
1513     {
1514         switch (useKind) {
1515         case StringObjectUse:
1516         case StringOrStringObjectUse:
1517             return true;
1518         default:
1519             return false;
1520         }
1521     }
1522     
1523     template<UseKind useKind>
1524     void convertStringAddUse(Node* node, Edge& edge)
1525     {
1526         if (useKind == StringUse) {
1527             observeUseKindOnNode<StringUse>(edge.node());
1528             m_insertionSet.insertNode(
1529                 m_indexInBlock, SpecNone, Check, node->origin,
1530                 Edge(edge.node(), StringUse));
1531             edge.setUseKind(KnownStringUse);
1532             return;
1533         }
1534         
1535         observeUseKindOnNode<useKind>(edge.node());
1536         createToString<useKind>(node, edge);
1537     }
1538     
1539     void convertToMakeRope(Node* node)
1540     {
1541         node->setOpAndDefaultFlags(MakeRope);
1542         fixupMakeRope(node);
1543     }
1544     
1545     void fixupMakeRope(Node* node)
1546     {
1547         for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
1548             Edge& edge = node->children.child(i);
1549             if (!edge)
1550                 break;
1551             edge.setUseKind(KnownStringUse);
1552             JSString* string = edge->dynamicCastConstant<JSString*>();
1553             if (!string)
1554                 continue;
1555             if (string->length())
1556                 continue;
1557             
1558             // Don't allow the MakeRope to have zero children.
1559             if (!i && !node->child2())
1560                 break;
1561             
1562             node->children.removeEdge(i--);
1563         }
1564         
1565         if (!node->child2()) {
1566             ASSERT(!node->child3());
1567             node->convertToIdentity();
1568         }
1569     }
1570
1571     void fixupToThis(Node* node)
1572     {
1573         ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->isStrictMode() ? StrictMode : NotStrictMode;
1574
1575         if (ecmaMode == StrictMode) {
1576             if (node->child1()->shouldSpeculateBoolean()) {
1577                 fixEdge<BooleanUse>(node->child1());
1578                 node->convertToIdentity();
1579                 return;
1580             }
1581
1582             if (node->child1()->shouldSpeculateInt32()) {
1583                 fixEdge<Int32Use>(node->child1());
1584                 node->convertToIdentity();
1585                 return;
1586             }
1587
1588             if (enableInt52() && node->child1()->shouldSpeculateMachineInt()) {
1589                 fixEdge<Int52RepUse>(node->child1());
1590                 node->convertToIdentity();
1591                 node->setResult(NodeResultInt52);
1592                 return;
1593             }
1594
1595             if (node->child1()->shouldSpeculateNumber()) {
1596                 fixEdge<DoubleRepUse>(node->child1());
1597                 node->convertToIdentity();
1598                 node->setResult(NodeResultDouble);
1599                 return;
1600             }
1601
1602             if (node->child1()->shouldSpeculateSymbol()) {
1603                 fixEdge<SymbolUse>(node->child1());
1604                 node->convertToIdentity();
1605                 return;
1606             }
1607
1608             if (node->child1()->shouldSpeculateStringIdent()) {
1609                 fixEdge<StringIdentUse>(node->child1());
1610                 node->convertToIdentity();
1611                 return;
1612             }
1613
1614             if (node->child1()->shouldSpeculateString()) {
1615                 fixEdge<StringUse>(node->child1());
1616                 node->convertToIdentity();
1617                 return;
1618             }
1619         }
1620
1621         if (node->child1()->shouldSpeculateOther()) {
1622             if (ecmaMode == StrictMode) {
1623                 fixEdge<OtherUse>(node->child1());
1624                 node->convertToIdentity();
1625                 return;
1626             }
1627
1628             m_insertionSet.insertNode(
1629                 m_indexInBlock, SpecNone, Check, node->origin,
1630                 Edge(node->child1().node(), OtherUse));
1631             observeUseKindOnNode<OtherUse>(node->child1().node());
1632             m_graph.convertToConstant(
1633                 node, m_graph.globalThisObjectFor(node->origin.semantic));
1634             return;
1635         }
1636
1637         if (node->child1()->shouldSpeculateStringObject()) {
1638             fixEdge<StringObjectUse>(node->child1());
1639             node->convertToIdentity();
1640             return;
1641         }
1642
1643         if (isFinalObjectSpeculation(node->child1()->prediction())) {
1644             fixEdge<FinalObjectUse>(node->child1());
1645             node->convertToIdentity();
1646             return;
1647         }
1648     }
1649     
1650     void fixupToPrimitive(Node* node)
1651     {
1652         if (node->child1()->shouldSpeculateInt32()) {
1653             fixEdge<Int32Use>(node->child1());
1654             node->convertToIdentity();
1655             return;
1656         }
1657         
1658         if (node->child1()->shouldSpeculateString()) {
1659             fixEdge<StringUse>(node->child1());
1660             node->convertToIdentity();
1661             return;
1662         }
1663         
1664         if (node->child1()->shouldSpeculateStringObject()
1665             && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
1666             fixEdge<StringObjectUse>(node->child1());
1667             node->convertToToString();
1668             return;
1669         }
1670         
1671         if (node->child1()->shouldSpeculateStringOrStringObject()
1672             && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
1673             fixEdge<StringOrStringObjectUse>(node->child1());
1674             node->convertToToString();
1675             return;
1676         }
1677     }
1678     
1679     void fixupToStringOrCallStringConstructor(Node* node)
1680     {
1681         if (node->child1()->shouldSpeculateString()) {
1682             fixEdge<StringUse>(node->child1());
1683             node->convertToIdentity();
1684             return;
1685         }
1686         
1687         if (node->child1()->shouldSpeculateStringObject()
1688             && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
1689             fixEdge<StringObjectUse>(node->child1());
1690             return;
1691         }
1692         
1693         if (node->child1()->shouldSpeculateStringOrStringObject()
1694             && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
1695             fixEdge<StringOrStringObjectUse>(node->child1());
1696             return;
1697         }
1698         
1699         if (node->child1()->shouldSpeculateCell()) {
1700             fixEdge<CellUse>(node->child1());
1701             return;
1702         }
1703     }
1704
1705     bool attemptToMakeFastStringAdd(Node* node)
1706     {
1707         bool goodToGo = true;
1708         m_graph.doToChildren(
1709             node,
1710             [&] (Edge& edge) {
1711                 if (edge->shouldSpeculateString())
1712                     return;
1713                 if (m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
1714                     if (edge->shouldSpeculateStringObject())
1715                         return;
1716                     if (edge->shouldSpeculateStringOrStringObject())
1717                         return;
1718                 }
1719                 goodToGo = false;
1720             });
1721         if (!goodToGo)
1722             return false;
1723
1724         m_graph.doToChildren(
1725             node,
1726             [&] (Edge& edge) {
1727                 if (edge->shouldSpeculateString()) {
1728                     convertStringAddUse<StringUse>(node, edge);
1729                     return;
1730                 }
1731                 ASSERT(m_graph.canOptimizeStringObjectAccess(node->origin.semantic));
1732                 if (edge->shouldSpeculateStringObject()) {
1733                     convertStringAddUse<StringObjectUse>(node, edge);
1734                     return;
1735                 }
1736                 if (edge->shouldSpeculateStringOrStringObject()) {
1737                     convertStringAddUse<StringOrStringObjectUse>(node, edge);
1738                     return;
1739                 }
1740                 RELEASE_ASSERT_NOT_REACHED();
1741             });
1742         
1743         convertToMakeRope(node);
1744         return true;
1745     }
1746
1747     void fixupGetAndSetLocalsInBlock(BasicBlock* block)
1748     {
1749         if (!block)
1750             return;
1751         ASSERT(block->isReachable);
1752         m_block = block;
1753         for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
1754             Node* node = m_currentNode = block->at(m_indexInBlock);
1755             if (node->op() != SetLocal && node->op() != GetLocal)
1756                 continue;
1757             
1758             VariableAccessData* variable = node->variableAccessData();
1759             switch (node->op()) {
1760             case GetLocal:
1761                 switch (variable->flushFormat()) {
1762                 case FlushedDouble:
1763                     node->setResult(NodeResultDouble);
1764                     break;
1765                 case FlushedInt52:
1766                     node->setResult(NodeResultInt52);
1767                     break;
1768                 default:
1769                     break;
1770                 }
1771                 break;
1772                 
1773             case SetLocal:
1774                 // NOTE: Any type checks we put here may get hoisted by fixupChecksInBlock(). So, if we
1775                 // add new type checking use kind for SetLocals, we need to modify that code as well.
1776                 
1777                 switch (variable->flushFormat()) {
1778                 case FlushedJSValue:
1779                     break;
1780                 case FlushedDouble:
1781                     fixEdge<DoubleRepUse>(node->child1());
1782                     break;
1783                 case FlushedInt32:
1784                     fixEdge<Int32Use>(node->child1());
1785                     break;
1786                 case FlushedInt52:
1787                     fixEdge<Int52RepUse>(node->child1());
1788                     break;
1789                 case FlushedCell:
1790                     fixEdge<CellUse>(node->child1());
1791                     break;
1792                 case FlushedBoolean:
1793                     fixEdge<BooleanUse>(node->child1());
1794                     break;
1795                 default:
1796                     RELEASE_ASSERT_NOT_REACHED();
1797                     break;
1798                 }
1799                 break;
1800                 
1801             default:
1802                 RELEASE_ASSERT_NOT_REACHED();
1803                 break;
1804             }
1805         }
1806         m_insertionSet.execute(block);
1807     }
1808     
1809     Node* checkArray(ArrayMode arrayMode, const NodeOrigin& origin, Node* array, Node* index, bool (*storageCheck)(const ArrayMode&) = canCSEStorage)
1810     {
1811         ASSERT(arrayMode.isSpecific());
1812         
1813         if (arrayMode.type() == Array::String) {
1814             m_insertionSet.insertNode(
1815                 m_indexInBlock, SpecNone, Check, origin, Edge(array, StringUse));
1816         } else {
1817             // Note that we only need to be using a structure check if we opt for SaneChain, since
1818             // that needs to protect against JSArray's __proto__ being changed.
1819             Structure* structure = arrayMode.originalArrayStructure(m_graph, origin.semantic);
1820         
1821             Edge indexEdge = index ? Edge(index, Int32Use) : Edge();
1822             
1823             if (arrayMode.doesConversion()) {
1824                 if (structure) {
1825                     m_insertionSet.insertNode(
1826                         m_indexInBlock, SpecNone, ArrayifyToStructure, origin,
1827                         OpInfo(structure), OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
1828                 } else {
1829                     m_insertionSet.insertNode(
1830                         m_indexInBlock, SpecNone, Arrayify, origin,
1831                         OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
1832                 }
1833             } else {
1834                 if (structure) {
1835                     m_insertionSet.insertNode(
1836                         m_indexInBlock, SpecNone, CheckStructure, origin,
1837                         OpInfo(m_graph.addStructureSet(structure)), Edge(array, CellUse));
1838                 } else {
1839                     m_insertionSet.insertNode(
1840                         m_indexInBlock, SpecNone, CheckArray, origin,
1841                         OpInfo(arrayMode.asWord()), Edge(array, CellUse));
1842                 }
1843             }
1844         }
1845         
1846         if (!storageCheck(arrayMode))
1847             return 0;
1848         
1849         if (arrayMode.usesButterfly()) {
1850             return m_insertionSet.insertNode(
1851                 m_indexInBlock, SpecNone, GetButterfly, origin, Edge(array, CellUse));
1852         }
1853         
1854         return m_insertionSet.insertNode(
1855             m_indexInBlock, SpecNone, GetIndexedPropertyStorage, origin,
1856             OpInfo(arrayMode.asWord()), Edge(array, KnownCellUse));
1857     }
1858     
1859     void blessArrayOperation(Edge base, Edge index, Edge& storageChild)
1860     {
1861         Node* node = m_currentNode;
1862         
1863         switch (node->arrayMode().type()) {
1864         case Array::ForceExit: {
1865             m_insertionSet.insertNode(
1866                 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
1867             return;
1868         }
1869             
1870         case Array::SelectUsingPredictions:
1871         case Array::Unprofiled:
1872             RELEASE_ASSERT_NOT_REACHED();
1873             return;
1874             
1875         case Array::Generic:
1876             return;
1877             
1878         default: {
1879             Node* storage = checkArray(node->arrayMode(), node->origin, base.node(), index.node());
1880             if (!storage)
1881                 return;
1882             
1883             storageChild = Edge(storage);
1884             return;
1885         } }
1886     }
1887     
1888     bool alwaysUnboxSimplePrimitives()
1889     {
1890 #if USE(JSVALUE64)
1891         return false;
1892 #else
1893         // Any boolean, int, or cell value is profitable to unbox on 32-bit because it
1894         // reduces traffic.
1895         return true;
1896 #endif
1897     }
1898
1899     template<UseKind useKind>
1900     void observeUseKindOnNode(Node* node)
1901     {
1902         if (useKind == UntypedUse)
1903             return;
1904         observeUseKindOnNode(node, useKind);
1905     }
1906
1907     void observeUseKindOnEdge(Edge edge)
1908     {
1909         observeUseKindOnNode(edge.node(), edge.useKind());
1910     }
1911
1912     void observeUseKindOnNode(Node* node, UseKind useKind)
1913     {
1914         if (node->op() != GetLocal)
1915             return;
1916         
1917         // FIXME: The way this uses alwaysUnboxSimplePrimitives() is suspicious.
1918         // https://bugs.webkit.org/show_bug.cgi?id=121518
1919         
1920         VariableAccessData* variable = node->variableAccessData();
1921         switch (useKind) {
1922         case Int32Use:
1923         case KnownInt32Use:
1924             if (alwaysUnboxSimplePrimitives()
1925                 || isInt32Speculation(variable->prediction()))
1926                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1927             break;
1928         case NumberUse:
1929         case RealNumberUse:
1930         case DoubleRepUse:
1931         case DoubleRepRealUse:
1932             if (variable->doubleFormatState() == UsingDoubleFormat)
1933                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1934             break;
1935         case BooleanUse:
1936         case KnownBooleanUse:
1937             if (alwaysUnboxSimplePrimitives()
1938                 || isBooleanSpeculation(variable->prediction()))
1939                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1940             break;
1941         case Int52RepUse:
1942             if (isMachineIntSpeculation(variable->prediction()))
1943                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1944             break;
1945         case CellUse:
1946         case KnownCellUse:
1947         case ObjectUse:
1948         case FunctionUse:
1949         case StringUse:
1950         case KnownStringUse:
1951         case SymbolUse:
1952         case StringObjectUse:
1953         case StringOrStringObjectUse:
1954             if (alwaysUnboxSimplePrimitives()
1955                 || isCellSpeculation(variable->prediction()))
1956                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1957             break;
1958         default:
1959             break;
1960         }
1961     }
1962     
1963     template<UseKind useKind>
1964     void fixEdge(Edge& edge)
1965     {
1966         observeUseKindOnNode<useKind>(edge.node());
1967         edge.setUseKind(useKind);
1968     }
1969     
1970     void speculateForBarrier(Edge value)
1971     {
1972         // Currently, the DFG won't take advantage of this speculation. But, we want to do it in
1973         // the DFG anyway because if such a speculation would be wrong, we want to know before
1974         // we do an expensive compile.
1975         
1976         if (value->shouldSpeculateInt32()) {
1977             insertCheck<Int32Use>(m_indexInBlock, value.node());
1978             return;
1979         }
1980             
1981         if (value->shouldSpeculateBoolean()) {
1982             insertCheck<BooleanUse>(m_indexInBlock, value.node());
1983             return;
1984         }
1985             
1986         if (value->shouldSpeculateOther()) {
1987             insertCheck<OtherUse>(m_indexInBlock, value.node());
1988             return;
1989         }
1990             
1991         if (value->shouldSpeculateNumber()) {
1992             insertCheck<NumberUse>(m_indexInBlock, value.node());
1993             return;
1994         }
1995             
1996         if (value->shouldSpeculateNotCell()) {
1997             insertCheck<NotCellUse>(m_indexInBlock, value.node());
1998             return;
1999         }
2000     }
2001     
2002     template<UseKind useKind>
2003     void insertCheck(unsigned indexInBlock, Node* node)
2004     {
2005         observeUseKindOnNode<useKind>(node);
2006         m_insertionSet.insertNode(
2007             indexInBlock, SpecNone, Check, m_currentNode->origin, Edge(node, useKind));
2008     }
2009
2010     void fixIntConvertingEdge(Edge& edge)
2011     {
2012         Node* node = edge.node();
2013         if (node->shouldSpeculateInt32OrBoolean()) {
2014             fixIntOrBooleanEdge(edge);
2015             return;
2016         }
2017         
2018         UseKind useKind;
2019         if (node->shouldSpeculateMachineInt())
2020             useKind = Int52RepUse;
2021         else if (node->shouldSpeculateNumber())
2022             useKind = DoubleRepUse;
2023         else
2024             useKind = NotCellUse;
2025         Node* newNode = m_insertionSet.insertNode(
2026             m_indexInBlock, SpecInt32, ValueToInt32, m_currentNode->origin,
2027             Edge(node, useKind));
2028         observeUseKindOnNode(node, useKind);
2029         
2030         edge = Edge(newNode, KnownInt32Use);
2031     }
2032     
2033     void fixIntOrBooleanEdge(Edge& edge)
2034     {
2035         Node* node = edge.node();
2036         if (!node->sawBooleans()) {
2037             fixEdge<Int32Use>(edge);
2038             return;
2039         }
2040         
2041         UseKind useKind;
2042         if (node->shouldSpeculateBoolean())
2043             useKind = BooleanUse;
2044         else
2045             useKind = UntypedUse;
2046         Node* newNode = m_insertionSet.insertNode(
2047             m_indexInBlock, SpecInt32, BooleanToNumber, m_currentNode->origin,
2048             Edge(node, useKind));
2049         observeUseKindOnNode(node, useKind);
2050         
2051         edge = Edge(newNode, Int32Use);
2052     }
2053     
2054     void fixDoubleOrBooleanEdge(Edge& edge)
2055     {
2056         Node* node = edge.node();
2057         if (!node->sawBooleans()) {
2058             fixEdge<DoubleRepUse>(edge);
2059             return;
2060         }
2061         
2062         UseKind useKind;
2063         if (node->shouldSpeculateBoolean())
2064             useKind = BooleanUse;
2065         else
2066             useKind = UntypedUse;
2067         Node* newNode = m_insertionSet.insertNode(
2068             m_indexInBlock, SpecInt32, BooleanToNumber, m_currentNode->origin,
2069             Edge(node, useKind));
2070         observeUseKindOnNode(node, useKind);
2071         
2072         edge = Edge(newNode, DoubleRepUse);
2073     }
2074     
2075     void truncateConstantToInt32(Edge& edge)
2076     {
2077         Node* oldNode = edge.node();
2078         
2079         JSValue value = oldNode->asJSValue();
2080         if (value.isInt32())
2081             return;
2082         
2083         value = jsNumber(JSC::toInt32(value.asNumber()));
2084         ASSERT(value.isInt32());
2085         edge.setNode(m_insertionSet.insertNode(
2086             m_indexInBlock, SpecInt32, JSConstant, m_currentNode->origin,
2087             OpInfo(m_graph.freeze(value))));
2088     }
2089     
2090     void truncateConstantsIfNecessary(Node* node, AddSpeculationMode mode)
2091     {
2092         if (mode != SpeculateInt32AndTruncateConstants)
2093             return;
2094         
2095         ASSERT(node->child1()->hasConstant() || node->child2()->hasConstant());
2096         if (node->child1()->hasConstant())
2097             truncateConstantToInt32(node->child1());
2098         else
2099             truncateConstantToInt32(node->child2());
2100     }
2101     
2102     bool attemptToMakeIntegerAdd(Node* node)
2103     {
2104         AddSpeculationMode mode = m_graph.addSpeculationMode(node, FixupPass);
2105         if (mode != DontSpeculateInt32) {
2106             truncateConstantsIfNecessary(node, mode);
2107             fixIntOrBooleanEdge(node->child1());
2108             fixIntOrBooleanEdge(node->child2());
2109             if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
2110                 node->setArithMode(Arith::Unchecked);
2111             else
2112                 node->setArithMode(Arith::CheckOverflow);
2113             return true;
2114         }
2115         
2116         if (m_graph.addShouldSpeculateMachineInt(node)) {
2117             fixEdge<Int52RepUse>(node->child1());
2118             fixEdge<Int52RepUse>(node->child2());
2119             node->setArithMode(Arith::CheckOverflow);
2120             node->setResult(NodeResultInt52);
2121             return true;
2122         }
2123         
2124         return false;
2125     }
2126     
2127     bool attemptToMakeGetArrayLength(Node* node)
2128     {
2129         if (!isInt32Speculation(node->prediction()))
2130             return false;
2131         CodeBlock* profiledBlock = m_graph.baselineCodeBlockFor(node->origin.semantic);
2132         ArrayProfile* arrayProfile = 
2133             profiledBlock->getArrayProfile(node->origin.semantic.bytecodeIndex);
2134         ArrayMode arrayMode = ArrayMode(Array::SelectUsingPredictions);
2135         if (arrayProfile) {
2136             ConcurrentJITLocker locker(profiledBlock->m_lock);
2137             arrayProfile->computeUpdatedPrediction(locker, profiledBlock);
2138             arrayMode = ArrayMode::fromObserved(locker, arrayProfile, Array::Read, false);
2139             if (arrayMode.type() == Array::Unprofiled) {
2140                 // For normal array operations, it makes sense to treat Unprofiled
2141                 // accesses as ForceExit and get more data rather than using
2142                 // predictions and then possibly ending up with a Generic. But here,
2143                 // we treat anything that is Unprofiled as Generic and keep the
2144                 // GetById. I.e. ForceExit = Generic. So, there is no harm - and only
2145                 // profit - from treating the Unprofiled case as
2146                 // SelectUsingPredictions.
2147                 arrayMode = ArrayMode(Array::SelectUsingPredictions);
2148             }
2149         }
2150             
2151         arrayMode = arrayMode.refine(
2152             m_graph, node, node->child1()->prediction(), node->prediction());
2153             
2154         if (arrayMode.type() == Array::Generic) {
2155             // Check if the input is something that we can't get array length for, but for which we
2156             // could insert some conversions in order to transform it into something that we can do it
2157             // for.
2158             if (node->child1()->shouldSpeculateStringObject())
2159                 attemptToForceStringArrayModeByToStringConversion<StringObjectUse>(arrayMode, node);
2160             else if (node->child1()->shouldSpeculateStringOrStringObject())
2161                 attemptToForceStringArrayModeByToStringConversion<StringOrStringObjectUse>(arrayMode, node);
2162         }
2163             
2164         if (!arrayMode.supportsLength())
2165             return false;
2166         
2167         convertToGetArrayLength(node, arrayMode);
2168         return true;
2169     }
2170
2171     void convertToGetArrayLength(Node* node, ArrayMode arrayMode)
2172     {
2173         node->setOp(GetArrayLength);
2174         node->clearFlags(NodeMustGenerate);
2175         fixEdge<KnownCellUse>(node->child1());
2176         node->setArrayMode(arrayMode);
2177             
2178         Node* storage = checkArray(arrayMode, node->origin, node->child1().node(), 0, lengthNeedsStorage);
2179         if (!storage)
2180             return;
2181             
2182         node->child2() = Edge(storage);
2183     }
2184     
2185     Node* prependGetArrayLength(NodeOrigin origin, Node* child, ArrayMode arrayMode)
2186     {
2187         Node* storage = checkArray(arrayMode, origin, child, 0, lengthNeedsStorage);
2188         return m_insertionSet.insertNode(
2189             m_indexInBlock, SpecInt32, GetArrayLength, origin,
2190             OpInfo(arrayMode.asWord()), Edge(child, KnownCellUse), Edge(storage));
2191     }
2192     
2193     void fixupChecksInBlock(BasicBlock* block)
2194     {
2195         if (!block)
2196             return;
2197         ASSERT(block->isReachable);
2198         m_block = block;
2199         unsigned indexForChecks = UINT_MAX;
2200         NodeOrigin originForChecks;
2201         for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
2202             Node* node = block->at(indexInBlock);
2203
2204             // If this is a node at which we could exit, then save its index. If nodes after this one
2205             // cannot exit, then we will hoist checks to here.
2206             if (node->origin.exitOK) {
2207                 indexForChecks = indexInBlock;
2208                 originForChecks = node->origin;
2209             }
2210
2211             originForChecks = originForChecks.withSemantic(node->origin.semantic);
2212
2213             // First, try to relax the representational demands of each node, in order to have
2214             // fewer conversions.
2215             switch (node->op()) {
2216             case MovHint:
2217             case Check:
2218                 m_graph.doToChildren(
2219                     node,
2220                     [&] (Edge& edge) {
2221                         switch (edge.useKind()) {
2222                         case DoubleRepUse:
2223                         case DoubleRepRealUse:
2224                             if (edge->hasDoubleResult())
2225                                 break;
2226             
2227                             if (edge->hasInt52Result())
2228                                 edge.setUseKind(Int52RepUse);
2229                             else if (edge.useKind() == DoubleRepUse)
2230                                 edge.setUseKind(NumberUse);
2231                             break;
2232             
2233                         case Int52RepUse:
2234                             // Nothing we can really do.
2235                             break;
2236             
2237                         case UntypedUse:
2238                         case NumberUse:
2239                             if (edge->hasDoubleResult())
2240                                 edge.setUseKind(DoubleRepUse);
2241                             else if (edge->hasInt52Result())
2242                                 edge.setUseKind(Int52RepUse);
2243                             break;
2244             
2245                         case RealNumberUse:
2246                             if (edge->hasDoubleResult())
2247                                 edge.setUseKind(DoubleRepRealUse);
2248                             else if (edge->hasInt52Result())
2249                                 edge.setUseKind(Int52RepUse);
2250                             break;
2251             
2252                         default:
2253                             break;
2254                         }
2255                     });
2256                 break;
2257                 
2258             case ValueToInt32:
2259                 if (node->child1().useKind() == DoubleRepUse
2260                     && !node->child1()->hasDoubleResult()) {
2261                     node->child1().setUseKind(NumberUse);
2262                     break;
2263                 }
2264                 break;
2265                 
2266             default:
2267                 break;
2268             }
2269
2270             // Now, insert type conversions if necessary.
2271             m_graph.doToChildren(
2272                 node,
2273                 [&] (Edge& edge) {
2274                     Node* result = nullptr;
2275
2276                     switch (edge.useKind()) {
2277                     case DoubleRepUse:
2278                     case DoubleRepRealUse:
2279                     case DoubleRepMachineIntUse: {
2280                         if (edge->hasDoubleResult())
2281                             break;
2282             
2283                         if (edge->isNumberConstant()) {
2284                             result = m_insertionSet.insertNode(
2285                                 indexForChecks, SpecBytecodeDouble, DoubleConstant, originForChecks,
2286                                 OpInfo(m_graph.freeze(jsDoubleNumber(edge->asNumber()))));
2287                         } else if (edge->hasInt52Result()) {
2288                             result = m_insertionSet.insertNode(
2289                                 indexForChecks, SpecInt52AsDouble, DoubleRep, originForChecks,
2290                                 Edge(edge.node(), Int52RepUse));
2291                         } else {
2292                             UseKind useKind;
2293                             if (edge->shouldSpeculateDoubleReal())
2294                                 useKind = RealNumberUse;
2295                             else if (edge->shouldSpeculateNumber())
2296                                 useKind = NumberUse;
2297                             else
2298                                 useKind = NotCellUse;
2299
2300                             result = m_insertionSet.insertNode(
2301                                 indexForChecks, SpecBytecodeDouble, DoubleRep, originForChecks,
2302                                 Edge(edge.node(), useKind));
2303                         }
2304
2305                         edge.setNode(result);
2306                         break;
2307                     }
2308             
2309                     case Int52RepUse: {
2310                         if (edge->hasInt52Result())
2311                             break;
2312             
2313                         if (edge->isMachineIntConstant()) {
2314                             result = m_insertionSet.insertNode(
2315                                 indexForChecks, SpecMachineInt, Int52Constant, originForChecks,
2316                                 OpInfo(edge->constant()));
2317                         } else if (edge->hasDoubleResult()) {
2318                             result = m_insertionSet.insertNode(
2319                                 indexForChecks, SpecMachineInt, Int52Rep, originForChecks,
2320                                 Edge(edge.node(), DoubleRepMachineIntUse));
2321                         } else if (edge->shouldSpeculateInt32ForArithmetic()) {
2322                             result = m_insertionSet.insertNode(
2323                                 indexForChecks, SpecInt32, Int52Rep, originForChecks,
2324                                 Edge(edge.node(), Int32Use));
2325                         } else {
2326                             result = m_insertionSet.insertNode(
2327                                 indexForChecks, SpecMachineInt, Int52Rep, originForChecks,
2328                                 Edge(edge.node(), MachineIntUse));
2329                         }
2330
2331                         edge.setNode(result);
2332                         break;
2333                     }
2334
2335                     default: {
2336                         if (!edge->hasDoubleResult() && !edge->hasInt52Result())
2337                             break;
2338             
2339                         if (edge->hasDoubleResult()) {
2340                             result = m_insertionSet.insertNode(
2341                                 indexForChecks, SpecBytecodeDouble, ValueRep, originForChecks,
2342                                 Edge(edge.node(), DoubleRepUse));
2343                         } else {
2344                             result = m_insertionSet.insertNode(
2345                                 indexForChecks, SpecInt32 | SpecInt52AsDouble, ValueRep,
2346                                 originForChecks, Edge(edge.node(), Int52RepUse));
2347                         }
2348
2349                         edge.setNode(result);
2350                         break;
2351                     } }
2352
2353                     // It's remotely possible that this node cannot do type checks, but we now have a
2354                     // type check on this node. We don't have to handle the general form of this
2355                     // problem. It only arises when ByteCodeParser emits an immediate SetLocal, rather
2356                     // than a delayed one. So, we only worry about those checks that we may have put on
2357                     // a SetLocal. Note that "indexForChecks != indexInBlock" is just another way of
2358                     // saying "!node->origin.exitOK".
2359                     if (indexForChecks != indexInBlock && mayHaveTypeCheck(edge.useKind())) {
2360                         UseKind knownUseKind;
2361                         
2362                         switch (edge.useKind()) {
2363                         case Int32Use:
2364                             knownUseKind = KnownInt32Use;
2365                             break;
2366                         case CellUse:
2367                             knownUseKind = KnownCellUse;
2368                             break;
2369                         case BooleanUse:
2370                             knownUseKind = KnownBooleanUse;
2371                             break;
2372                         default:
2373                             // This can only arise if we have a Check node, and in that case, we can
2374                             // just remove the original check.
2375                             DFG_ASSERT(m_graph, node, node->op() == Check);
2376                             knownUseKind = UntypedUse;
2377                             break;
2378                         }
2379
2380                         m_insertionSet.insertNode(
2381                             indexForChecks, SpecNone, Check, originForChecks, edge);
2382
2383                         edge.setUseKind(knownUseKind);
2384                     }
2385                 });
2386         }
2387         
2388         m_insertionSet.execute(block);
2389     }
2390     
2391     BasicBlock* m_block;
2392     unsigned m_indexInBlock;
2393     Node* m_currentNode;
2394     InsertionSet m_insertionSet;
2395     bool m_profitabilityChanged;
2396 };
2397     
2398 bool performFixup(Graph& graph)
2399 {
2400     SamplingRegion samplingRegion("DFG Fixup Phase");
2401     return runPhase<FixupPhase>(graph);
2402 }
2403
2404 } } // namespace JSC::DFG
2405
2406 #endif // ENABLE(DFG_JIT)
2407