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