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