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