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