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