491fbc1cc9300c8618a2fa7bfd6b15256e2cfa5d
[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 (!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             && canOptimizeStringObjectAccess(node->origin.semantic)) {
1533             fixEdge<StringObjectUse>(node->child1());
1534             node->convertToToString();
1535             return;
1536         }
1537         
1538         if (node->child1()->shouldSpeculateStringOrStringObject()
1539             && 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             && canOptimizeStringObjectAccess(node->origin.semantic)) {
1556             fixEdge<StringObjectUse>(node->child1());
1557             return;
1558         }
1559         
1560         if (node->child1()->shouldSpeculateStringOrStringObject()
1561             && 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 (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(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     bool isStringPrototypeMethodSane(
1615         JSObject* stringPrototype, Structure* stringPrototypeStructure, UniquedStringImpl* uid)
1616     {
1617         unsigned attributesUnused;
1618         PropertyOffset offset =
1619             stringPrototypeStructure->getConcurrently(uid, attributesUnused);
1620         if (!isValidOffset(offset))
1621             return false;
1622         
1623         JSValue value = m_graph.tryGetConstantProperty(
1624             stringPrototype, stringPrototypeStructure, offset);
1625         if (!value)
1626             return false;
1627         
1628         JSFunction* function = jsDynamicCast<JSFunction*>(value);
1629         if (!function)
1630             return false;
1631         
1632         if (function->executable()->intrinsicFor(CodeForCall) != StringPrototypeValueOfIntrinsic)
1633             return false;
1634         
1635         return true;
1636     }
1637     
1638     bool canOptimizeStringObjectAccess(const CodeOrigin& codeOrigin)
1639     {
1640         if (m_graph.hasExitSite(codeOrigin, NotStringObject))
1641             return false;
1642         
1643         Structure* stringObjectStructure = m_graph.globalObjectFor(codeOrigin)->stringObjectStructure();
1644         m_graph.registerStructure(stringObjectStructure);
1645         ASSERT(stringObjectStructure->storedPrototype().isObject());
1646         ASSERT(stringObjectStructure->storedPrototype().asCell()->classInfo() == StringPrototype::info());
1647
1648         FrozenValue* stringPrototypeObjectValue =
1649             m_graph.freeze(stringObjectStructure->storedPrototype());
1650         StringPrototype* stringPrototypeObject =
1651             stringPrototypeObjectValue->dynamicCast<StringPrototype*>();
1652         Structure* stringPrototypeStructure = stringPrototypeObjectValue->structure();
1653         if (m_graph.registerStructure(stringPrototypeStructure) != StructureRegisteredAndWatched)
1654             return false;
1655         
1656         if (stringPrototypeStructure->isDictionary())
1657             return false;
1658         
1659         // We're being conservative here. We want DFG's ToString on StringObject to be
1660         // used in both numeric contexts (that would call valueOf()) and string contexts
1661         // (that would call toString()). We don't want the DFG to have to distinguish
1662         // between the two, just because that seems like it would get confusing. So we
1663         // just require both methods to be sane.
1664         if (!isStringPrototypeMethodSane(stringPrototypeObject, stringPrototypeStructure, vm().propertyNames->valueOf.impl()))
1665             return false;
1666         if (!isStringPrototypeMethodSane(stringPrototypeObject, stringPrototypeStructure, vm().propertyNames->toString.impl()))
1667             return false;
1668         
1669         return true;
1670     }
1671     
1672     void fixupGetAndSetLocalsInBlock(BasicBlock* block)
1673     {
1674         if (!block)
1675             return;
1676         ASSERT(block->isReachable);
1677         m_block = block;
1678         for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
1679             Node* node = m_currentNode = block->at(m_indexInBlock);
1680             if (node->op() != SetLocal && node->op() != GetLocal)
1681                 continue;
1682             
1683             VariableAccessData* variable = node->variableAccessData();
1684             switch (node->op()) {
1685             case GetLocal:
1686                 switch (variable->flushFormat()) {
1687                 case FlushedDouble:
1688                     node->setResult(NodeResultDouble);
1689                     break;
1690                 case FlushedInt52:
1691                     node->setResult(NodeResultInt52);
1692                     break;
1693                 default:
1694                     break;
1695                 }
1696                 break;
1697                 
1698             case SetLocal:
1699                 // NOTE: Any type checks we put here may get hoisted by fixupChecksInBlock(). So, if we
1700                 // add new type checking use kind for SetLocals, we need to modify that code as well.
1701                 
1702                 switch (variable->flushFormat()) {
1703                 case FlushedJSValue:
1704                     break;
1705                 case FlushedDouble:
1706                     fixEdge<DoubleRepUse>(node->child1());
1707                     break;
1708                 case FlushedInt32:
1709                     fixEdge<Int32Use>(node->child1());
1710                     break;
1711                 case FlushedInt52:
1712                     fixEdge<Int52RepUse>(node->child1());
1713                     break;
1714                 case FlushedCell:
1715                     fixEdge<CellUse>(node->child1());
1716                     break;
1717                 case FlushedBoolean:
1718                     fixEdge<BooleanUse>(node->child1());
1719                     break;
1720                 default:
1721                     RELEASE_ASSERT_NOT_REACHED();
1722                     break;
1723                 }
1724                 break;
1725                 
1726             default:
1727                 RELEASE_ASSERT_NOT_REACHED();
1728                 break;
1729             }
1730         }
1731         m_insertionSet.execute(block);
1732     }
1733     
1734     Node* checkArray(ArrayMode arrayMode, const NodeOrigin& origin, Node* array, Node* index, bool (*storageCheck)(const ArrayMode&) = canCSEStorage)
1735     {
1736         ASSERT(arrayMode.isSpecific());
1737         
1738         if (arrayMode.type() == Array::String) {
1739             m_insertionSet.insertNode(
1740                 m_indexInBlock, SpecNone, Check, origin, Edge(array, StringUse));
1741         } else {
1742             // Note that we only need to be using a structure check if we opt for SaneChain, since
1743             // that needs to protect against JSArray's __proto__ being changed.
1744             Structure* structure = arrayMode.originalArrayStructure(m_graph, origin.semantic);
1745         
1746             Edge indexEdge = index ? Edge(index, Int32Use) : Edge();
1747             
1748             if (arrayMode.doesConversion()) {
1749                 if (structure) {
1750                     m_insertionSet.insertNode(
1751                         m_indexInBlock, SpecNone, ArrayifyToStructure, origin,
1752                         OpInfo(structure), OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
1753                 } else {
1754                     m_insertionSet.insertNode(
1755                         m_indexInBlock, SpecNone, Arrayify, origin,
1756                         OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
1757                 }
1758             } else {
1759                 if (structure) {
1760                     m_insertionSet.insertNode(
1761                         m_indexInBlock, SpecNone, CheckStructure, origin,
1762                         OpInfo(m_graph.addStructureSet(structure)), Edge(array, CellUse));
1763                 } else {
1764                     m_insertionSet.insertNode(
1765                         m_indexInBlock, SpecNone, CheckArray, origin,
1766                         OpInfo(arrayMode.asWord()), Edge(array, CellUse));
1767                 }
1768             }
1769         }
1770         
1771         if (!storageCheck(arrayMode))
1772             return 0;
1773         
1774         if (arrayMode.usesButterfly()) {
1775             return m_insertionSet.insertNode(
1776                 m_indexInBlock, SpecNone, GetButterfly, origin, Edge(array, CellUse));
1777         }
1778         
1779         return m_insertionSet.insertNode(
1780             m_indexInBlock, SpecNone, GetIndexedPropertyStorage, origin,
1781             OpInfo(arrayMode.asWord()), Edge(array, KnownCellUse));
1782     }
1783     
1784     void blessArrayOperation(Edge base, Edge index, Edge& storageChild)
1785     {
1786         Node* node = m_currentNode;
1787         
1788         switch (node->arrayMode().type()) {
1789         case Array::ForceExit: {
1790             m_insertionSet.insertNode(
1791                 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
1792             return;
1793         }
1794             
1795         case Array::SelectUsingPredictions:
1796         case Array::Unprofiled:
1797             RELEASE_ASSERT_NOT_REACHED();
1798             return;
1799             
1800         case Array::Generic:
1801             return;
1802             
1803         default: {
1804             Node* storage = checkArray(node->arrayMode(), node->origin, base.node(), index.node());
1805             if (!storage)
1806                 return;
1807             
1808             storageChild = Edge(storage);
1809             return;
1810         } }
1811     }
1812     
1813     bool alwaysUnboxSimplePrimitives()
1814     {
1815 #if USE(JSVALUE64)
1816         return false;
1817 #else
1818         // Any boolean, int, or cell value is profitable to unbox on 32-bit because it
1819         // reduces traffic.
1820         return true;
1821 #endif
1822     }
1823
1824     template<UseKind useKind>
1825     void observeUseKindOnNode(Node* node)
1826     {
1827         if (useKind == UntypedUse)
1828             return;
1829         observeUseKindOnNode(node, useKind);
1830     }
1831
1832     void observeUseKindOnEdge(Edge edge)
1833     {
1834         observeUseKindOnNode(edge.node(), edge.useKind());
1835     }
1836
1837     void observeUseKindOnNode(Node* node, UseKind useKind)
1838     {
1839         if (node->op() != GetLocal)
1840             return;
1841         
1842         // FIXME: The way this uses alwaysUnboxSimplePrimitives() is suspicious.
1843         // https://bugs.webkit.org/show_bug.cgi?id=121518
1844         
1845         VariableAccessData* variable = node->variableAccessData();
1846         switch (useKind) {
1847         case Int32Use:
1848         case KnownInt32Use:
1849             if (alwaysUnboxSimplePrimitives()
1850                 || isInt32Speculation(variable->prediction()))
1851                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1852             break;
1853         case NumberUse:
1854         case RealNumberUse:
1855         case DoubleRepUse:
1856         case DoubleRepRealUse:
1857             if (variable->doubleFormatState() == UsingDoubleFormat)
1858                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1859             break;
1860         case BooleanUse:
1861         case KnownBooleanUse:
1862             if (alwaysUnboxSimplePrimitives()
1863                 || isBooleanSpeculation(variable->prediction()))
1864                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1865             break;
1866         case Int52RepUse:
1867             if (isMachineIntSpeculation(variable->prediction()))
1868                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1869             break;
1870         case CellUse:
1871         case KnownCellUse:
1872         case ObjectUse:
1873         case FunctionUse:
1874         case StringUse:
1875         case KnownStringUse:
1876         case SymbolUse:
1877         case StringObjectUse:
1878         case StringOrStringObjectUse:
1879             if (alwaysUnboxSimplePrimitives()
1880                 || isCellSpeculation(variable->prediction()))
1881                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1882             break;
1883         default:
1884             break;
1885         }
1886     }
1887     
1888     template<UseKind useKind>
1889     void fixEdge(Edge& edge)
1890     {
1891         observeUseKindOnNode<useKind>(edge.node());
1892         edge.setUseKind(useKind);
1893     }
1894     
1895     void speculateForBarrier(Edge value)
1896     {
1897         // Currently, the DFG won't take advantage of this speculation. But, we want to do it in
1898         // the DFG anyway because if such a speculation would be wrong, we want to know before
1899         // we do an expensive compile.
1900         
1901         if (value->shouldSpeculateInt32()) {
1902             insertCheck<Int32Use>(m_indexInBlock, value.node());
1903             return;
1904         }
1905             
1906         if (value->shouldSpeculateBoolean()) {
1907             insertCheck<BooleanUse>(m_indexInBlock, value.node());
1908             return;
1909         }
1910             
1911         if (value->shouldSpeculateOther()) {
1912             insertCheck<OtherUse>(m_indexInBlock, value.node());
1913             return;
1914         }
1915             
1916         if (value->shouldSpeculateNumber()) {
1917             insertCheck<NumberUse>(m_indexInBlock, value.node());
1918             return;
1919         }
1920             
1921         if (value->shouldSpeculateNotCell()) {
1922             insertCheck<NotCellUse>(m_indexInBlock, value.node());
1923             return;
1924         }
1925     }
1926     
1927     template<UseKind useKind>
1928     void insertCheck(unsigned indexInBlock, Node* node)
1929     {
1930         observeUseKindOnNode<useKind>(node);
1931         m_insertionSet.insertNode(
1932             indexInBlock, SpecNone, Check, m_currentNode->origin, Edge(node, useKind));
1933     }
1934
1935     void fixIntConvertingEdge(Edge& edge)
1936     {
1937         Node* node = edge.node();
1938         if (node->shouldSpeculateInt32OrBoolean()) {
1939             fixIntOrBooleanEdge(edge);
1940             return;
1941         }
1942         
1943         UseKind useKind;
1944         if (node->shouldSpeculateMachineInt())
1945             useKind = Int52RepUse;
1946         else if (node->shouldSpeculateNumber())
1947             useKind = DoubleRepUse;
1948         else
1949             useKind = NotCellUse;
1950         Node* newNode = m_insertionSet.insertNode(
1951             m_indexInBlock, SpecInt32, ValueToInt32, m_currentNode->origin,
1952             Edge(node, useKind));
1953         observeUseKindOnNode(node, useKind);
1954         
1955         edge = Edge(newNode, KnownInt32Use);
1956     }
1957     
1958     void fixIntOrBooleanEdge(Edge& edge)
1959     {
1960         Node* node = edge.node();
1961         if (!node->sawBooleans()) {
1962             fixEdge<Int32Use>(edge);
1963             return;
1964         }
1965         
1966         UseKind useKind;
1967         if (node->shouldSpeculateBoolean())
1968             useKind = BooleanUse;
1969         else
1970             useKind = UntypedUse;
1971         Node* newNode = m_insertionSet.insertNode(
1972             m_indexInBlock, SpecInt32, BooleanToNumber, m_currentNode->origin,
1973             Edge(node, useKind));
1974         observeUseKindOnNode(node, useKind);
1975         
1976         edge = Edge(newNode, Int32Use);
1977     }
1978     
1979     void fixDoubleOrBooleanEdge(Edge& edge)
1980     {
1981         Node* node = edge.node();
1982         if (!node->sawBooleans()) {
1983             fixEdge<DoubleRepUse>(edge);
1984             return;
1985         }
1986         
1987         UseKind useKind;
1988         if (node->shouldSpeculateBoolean())
1989             useKind = BooleanUse;
1990         else
1991             useKind = UntypedUse;
1992         Node* newNode = m_insertionSet.insertNode(
1993             m_indexInBlock, SpecInt32, BooleanToNumber, m_currentNode->origin,
1994             Edge(node, useKind));
1995         observeUseKindOnNode(node, useKind);
1996         
1997         edge = Edge(newNode, DoubleRepUse);
1998     }
1999     
2000     void truncateConstantToInt32(Edge& edge)
2001     {
2002         Node* oldNode = edge.node();
2003         
2004         JSValue value = oldNode->asJSValue();
2005         if (value.isInt32())
2006             return;
2007         
2008         value = jsNumber(JSC::toInt32(value.asNumber()));
2009         ASSERT(value.isInt32());
2010         edge.setNode(m_insertionSet.insertNode(
2011             m_indexInBlock, SpecInt32, JSConstant, m_currentNode->origin,
2012             OpInfo(m_graph.freeze(value))));
2013     }
2014     
2015     void truncateConstantsIfNecessary(Node* node, AddSpeculationMode mode)
2016     {
2017         if (mode != SpeculateInt32AndTruncateConstants)
2018             return;
2019         
2020         ASSERT(node->child1()->hasConstant() || node->child2()->hasConstant());
2021         if (node->child1()->hasConstant())
2022             truncateConstantToInt32(node->child1());
2023         else
2024             truncateConstantToInt32(node->child2());
2025     }
2026     
2027     bool attemptToMakeIntegerAdd(Node* node)
2028     {
2029         AddSpeculationMode mode = m_graph.addSpeculationMode(node, FixupPass);
2030         if (mode != DontSpeculateInt32) {
2031             truncateConstantsIfNecessary(node, mode);
2032             fixIntOrBooleanEdge(node->child1());
2033             fixIntOrBooleanEdge(node->child2());
2034             if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
2035                 node->setArithMode(Arith::Unchecked);
2036             else
2037                 node->setArithMode(Arith::CheckOverflow);
2038             return true;
2039         }
2040         
2041         if (m_graph.addShouldSpeculateMachineInt(node)) {
2042             fixEdge<Int52RepUse>(node->child1());
2043             fixEdge<Int52RepUse>(node->child2());
2044             node->setArithMode(Arith::CheckOverflow);
2045             node->setResult(NodeResultInt52);
2046             return true;
2047         }
2048         
2049         return false;
2050     }
2051     
2052     bool attemptToMakeGetArrayLength(Node* node)
2053     {
2054         if (!isInt32Speculation(node->prediction()))
2055             return false;
2056         CodeBlock* profiledBlock = m_graph.baselineCodeBlockFor(node->origin.semantic);
2057         ArrayProfile* arrayProfile = 
2058             profiledBlock->getArrayProfile(node->origin.semantic.bytecodeIndex);
2059         ArrayMode arrayMode = ArrayMode(Array::SelectUsingPredictions);
2060         if (arrayProfile) {
2061             ConcurrentJITLocker locker(profiledBlock->m_lock);
2062             arrayProfile->computeUpdatedPrediction(locker, profiledBlock);
2063             arrayMode = ArrayMode::fromObserved(locker, arrayProfile, Array::Read, false);
2064             if (arrayMode.type() == Array::Unprofiled) {
2065                 // For normal array operations, it makes sense to treat Unprofiled
2066                 // accesses as ForceExit and get more data rather than using
2067                 // predictions and then possibly ending up with a Generic. But here,
2068                 // we treat anything that is Unprofiled as Generic and keep the
2069                 // GetById. I.e. ForceExit = Generic. So, there is no harm - and only
2070                 // profit - from treating the Unprofiled case as
2071                 // SelectUsingPredictions.
2072                 arrayMode = ArrayMode(Array::SelectUsingPredictions);
2073             }
2074         }
2075             
2076         arrayMode = arrayMode.refine(
2077             m_graph, node, node->child1()->prediction(), node->prediction());
2078             
2079         if (arrayMode.type() == Array::Generic) {
2080             // Check if the input is something that we can't get array length for, but for which we
2081             // could insert some conversions in order to transform it into something that we can do it
2082             // for.
2083             if (node->child1()->shouldSpeculateStringObject())
2084                 attemptToForceStringArrayModeByToStringConversion<StringObjectUse>(arrayMode, node);
2085             else if (node->child1()->shouldSpeculateStringOrStringObject())
2086                 attemptToForceStringArrayModeByToStringConversion<StringOrStringObjectUse>(arrayMode, node);
2087         }
2088             
2089         if (!arrayMode.supportsLength())
2090             return false;
2091         
2092         convertToGetArrayLength(node, arrayMode);
2093         return true;
2094     }
2095
2096     void convertToGetArrayLength(Node* node, ArrayMode arrayMode)
2097     {
2098         node->setOp(GetArrayLength);
2099         node->clearFlags(NodeMustGenerate);
2100         fixEdge<KnownCellUse>(node->child1());
2101         node->setArrayMode(arrayMode);
2102             
2103         Node* storage = checkArray(arrayMode, node->origin, node->child1().node(), 0, lengthNeedsStorage);
2104         if (!storage)
2105             return;
2106             
2107         node->child2() = Edge(storage);
2108     }
2109     
2110     Node* prependGetArrayLength(NodeOrigin origin, Node* child, ArrayMode arrayMode)
2111     {
2112         Node* storage = checkArray(arrayMode, origin, child, 0, lengthNeedsStorage);
2113         return m_insertionSet.insertNode(
2114             m_indexInBlock, SpecInt32, GetArrayLength, origin,
2115             OpInfo(arrayMode.asWord()), Edge(child, KnownCellUse), Edge(storage));
2116     }
2117     
2118     void fixupChecksInBlock(BasicBlock* block)
2119     {
2120         if (!block)
2121             return;
2122         ASSERT(block->isReachable);
2123         m_block = block;
2124         unsigned indexForChecks = UINT_MAX;
2125         NodeOrigin originForChecks;
2126         for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
2127             Node* node = block->at(indexInBlock);
2128
2129             // If this is a node at which we could exit, then save its index. If nodes after this one
2130             // cannot exit, then we will hoist checks to here.
2131             if (node->origin.exitOK) {
2132                 indexForChecks = indexInBlock;
2133                 originForChecks = node->origin;
2134             }
2135
2136             originForChecks = originForChecks.withSemantic(node->origin.semantic);
2137
2138             // First, try to relax the representational demands of each node, in order to have
2139             // fewer conversions.
2140             switch (node->op()) {
2141             case MovHint:
2142             case Check:
2143                 m_graph.doToChildren(
2144                     node,
2145                     [&] (Edge& edge) {
2146                         switch (edge.useKind()) {
2147                         case DoubleRepUse:
2148                         case DoubleRepRealUse:
2149                             if (edge->hasDoubleResult())
2150                                 break;
2151             
2152                             if (edge->hasInt52Result())
2153                                 edge.setUseKind(Int52RepUse);
2154                             else if (edge.useKind() == DoubleRepUse)
2155                                 edge.setUseKind(NumberUse);
2156                             break;
2157             
2158                         case Int52RepUse:
2159                             // Nothing we can really do.
2160                             break;
2161             
2162                         case UntypedUse:
2163                         case NumberUse:
2164                             if (edge->hasDoubleResult())
2165                                 edge.setUseKind(DoubleRepUse);
2166                             else if (edge->hasInt52Result())
2167                                 edge.setUseKind(Int52RepUse);
2168                             break;
2169             
2170                         case RealNumberUse:
2171                             if (edge->hasDoubleResult())
2172                                 edge.setUseKind(DoubleRepRealUse);
2173                             else if (edge->hasInt52Result())
2174                                 edge.setUseKind(Int52RepUse);
2175                             break;
2176             
2177                         default:
2178                             break;
2179                         }
2180                     });
2181                 break;
2182                 
2183             case ValueToInt32:
2184                 if (node->child1().useKind() == DoubleRepUse
2185                     && !node->child1()->hasDoubleResult()) {
2186                     node->child1().setUseKind(NumberUse);
2187                     break;
2188                 }
2189                 break;
2190                 
2191             default:
2192                 break;
2193             }
2194
2195             // Now, insert type conversions if necessary.
2196             m_graph.doToChildren(
2197                 node,
2198                 [&] (Edge& edge) {
2199                     Node* result = nullptr;
2200
2201                     switch (edge.useKind()) {
2202                     case DoubleRepUse:
2203                     case DoubleRepRealUse:
2204                     case DoubleRepMachineIntUse: {
2205                         if (edge->hasDoubleResult())
2206                             break;
2207             
2208                         if (edge->isNumberConstant()) {
2209                             result = m_insertionSet.insertNode(
2210                                 indexForChecks, SpecBytecodeDouble, DoubleConstant, originForChecks,
2211                                 OpInfo(m_graph.freeze(jsDoubleNumber(edge->asNumber()))));
2212                         } else if (edge->hasInt52Result()) {
2213                             result = m_insertionSet.insertNode(
2214                                 indexForChecks, SpecInt52AsDouble, DoubleRep, originForChecks,
2215                                 Edge(edge.node(), Int52RepUse));
2216                         } else {
2217                             UseKind useKind;
2218                             if (edge->shouldSpeculateDoubleReal())
2219                                 useKind = RealNumberUse;
2220                             else if (edge->shouldSpeculateNumber())
2221                                 useKind = NumberUse;
2222                             else
2223                                 useKind = NotCellUse;
2224
2225                             result = m_insertionSet.insertNode(
2226                                 indexForChecks, SpecBytecodeDouble, DoubleRep, originForChecks,
2227                                 Edge(edge.node(), useKind));
2228                         }
2229
2230                         edge.setNode(result);
2231                         break;
2232                     }
2233             
2234                     case Int52RepUse: {
2235                         if (edge->hasInt52Result())
2236                             break;
2237             
2238                         if (edge->isMachineIntConstant()) {
2239                             result = m_insertionSet.insertNode(
2240                                 indexForChecks, SpecMachineInt, Int52Constant, originForChecks,
2241                                 OpInfo(edge->constant()));
2242                         } else if (edge->hasDoubleResult()) {
2243                             result = m_insertionSet.insertNode(
2244                                 indexForChecks, SpecMachineInt, Int52Rep, originForChecks,
2245                                 Edge(edge.node(), DoubleRepMachineIntUse));
2246                         } else if (edge->shouldSpeculateInt32ForArithmetic()) {
2247                             result = m_insertionSet.insertNode(
2248                                 indexForChecks, SpecInt32, Int52Rep, originForChecks,
2249                                 Edge(edge.node(), Int32Use));
2250                         } else {
2251                             result = m_insertionSet.insertNode(
2252                                 indexForChecks, SpecMachineInt, Int52Rep, originForChecks,
2253                                 Edge(edge.node(), MachineIntUse));
2254                         }
2255
2256                         edge.setNode(result);
2257                         break;
2258                     }
2259
2260                     default: {
2261                         if (!edge->hasDoubleResult() && !edge->hasInt52Result())
2262                             break;
2263             
2264                         if (edge->hasDoubleResult()) {
2265                             result = m_insertionSet.insertNode(
2266                                 indexForChecks, SpecBytecodeDouble, ValueRep, originForChecks,
2267                                 Edge(edge.node(), DoubleRepUse));
2268                         } else {
2269                             result = m_insertionSet.insertNode(
2270                                 indexForChecks, SpecInt32 | SpecInt52AsDouble, ValueRep,
2271                                 originForChecks, Edge(edge.node(), Int52RepUse));
2272                         }
2273
2274                         edge.setNode(result);
2275                         break;
2276                     } }
2277
2278                     // It's remotely possible that this node cannot do type checks, but we now have a
2279                     // type check on this node. We don't have to handle the general form of this
2280                     // problem. It only arises when ByteCodeParser emits an immediate SetLocal, rather
2281                     // than a delayed one. So, we only worry about those checks that we may have put on
2282                     // a SetLocal. Note that "indexForChecks != indexInBlock" is just another way of
2283                     // saying "!node->origin.exitOK".
2284                     if (indexForChecks != indexInBlock && mayHaveTypeCheck(edge.useKind())) {
2285                         UseKind knownUseKind;
2286                         
2287                         switch (edge.useKind()) {
2288                         case Int32Use:
2289                             knownUseKind = KnownInt32Use;
2290                             break;
2291                         case CellUse:
2292                             knownUseKind = KnownCellUse;
2293                             break;
2294                         case BooleanUse:
2295                             knownUseKind = KnownBooleanUse;
2296                             break;
2297                         default:
2298                             // This can only arise if we have a Check node, and in that case, we can
2299                             // just remove the original check.
2300                             DFG_ASSERT(m_graph, node, node->op() == Check);
2301                             knownUseKind = UntypedUse;
2302                             break;
2303                         }
2304
2305                         m_insertionSet.insertNode(
2306                             indexForChecks, SpecNone, Check, originForChecks, edge);
2307
2308                         edge.setUseKind(knownUseKind);
2309                     }
2310                 });
2311         }
2312         
2313         m_insertionSet.execute(block);
2314     }
2315     
2316     BasicBlock* m_block;
2317     unsigned m_indexInBlock;
2318     Node* m_currentNode;
2319     InsertionSet m_insertionSet;
2320     bool m_profitabilityChanged;
2321 };
2322     
2323 bool performFixup(Graph& graph)
2324 {
2325     SamplingRegion samplingRegion("DFG Fixup Phase");
2326     return runPhase<FixupPhase>(graph);
2327 }
2328
2329 } } // namespace JSC::DFG
2330
2331 #endif // ENABLE(DFG_JIT)
2332