Move back primary header includes next to config.h
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGFixupPhase.cpp
1 /*
2  * Copyright (C) 2012, 2013, 2014 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
38 namespace JSC { namespace DFG {
39
40 class FixupPhase : public Phase {
41 public:
42     FixupPhase(Graph& graph)
43         : Phase(graph, "fixup")
44         , m_insertionSet(graph)
45     {
46     }
47     
48     bool run()
49     {
50         ASSERT(m_graph.m_fixpointState == BeforeFixpoint);
51         ASSERT(m_graph.m_form == ThreadedCPS);
52         
53         m_profitabilityChanged = false;
54         for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
55             fixupBlock(m_graph.block(blockIndex));
56         
57         while (m_profitabilityChanged) {
58             m_profitabilityChanged = false;
59             
60             for (unsigned i = m_graph.m_argumentPositions.size(); i--;)
61                 m_graph.m_argumentPositions[i].mergeArgumentUnboxingAwareness();
62             
63             for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
64                 fixupSetLocalsInBlock(m_graph.block(blockIndex));
65         }
66         
67         for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
68             fixupUntypedSetLocalsInBlock(m_graph.block(blockIndex));
69         
70         return true;
71     }
72
73 private:
74     void fixupBlock(BasicBlock* block)
75     {
76         if (!block)
77             return;
78         ASSERT(block->isReachable);
79         m_block = block;
80         for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
81             m_currentNode = block->at(m_indexInBlock);
82             fixupNode(m_currentNode);
83         }
84         m_insertionSet.execute(block);
85     }
86     
87     void fixupNode(Node* node)
88     {
89         NodeType op = node->op();
90
91         switch (op) {
92         case SetLocal: {
93             // This gets handled by fixupSetLocalsInBlock().
94             return;
95         }
96             
97         case BitAnd:
98         case BitOr:
99         case BitXor:
100         case BitRShift:
101         case BitLShift:
102         case BitURShift: {
103             fixIntEdge(node->child1());
104             fixIntEdge(node->child2());
105             break;
106         }
107
108         case ArithIMul: {
109             fixIntEdge(node->child1());
110             fixIntEdge(node->child2());
111             node->setOp(ArithMul);
112             node->setArithMode(Arith::Unchecked);
113             node->child1().setUseKind(Int32Use);
114             node->child2().setUseKind(Int32Use);
115             break;
116         }
117             
118         case UInt32ToNumber: {
119             fixIntEdge(node->child1());
120             if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
121                 node->convertToIdentity();
122             else if (nodeCanSpeculateInt32(node->arithNodeFlags()))
123                 node->setArithMode(Arith::CheckOverflow);
124             else
125                 node->setArithMode(Arith::DoOverflow);
126             break;
127         }
128             
129         case ValueAdd: {
130             if (attemptToMakeIntegerAdd(node)) {
131                 node->setOp(ArithAdd);
132                 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
133                 break;
134             }
135             if (Node::shouldSpeculateNumberExpectingDefined(node->child1().node(), node->child2().node())) {
136                 fixEdge<NumberUse>(node->child1());
137                 fixEdge<NumberUse>(node->child2());
138                 node->setOp(ArithAdd);
139                 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
140                 break;
141             }
142             
143             // FIXME: Optimize for the case where one of the operands is the
144             // empty string. Also consider optimizing for the case where we don't
145             // believe either side is the emtpy string. Both of these things should
146             // be easy.
147             
148             if (node->child1()->shouldSpeculateString()
149                 && attemptToMakeFastStringAdd<StringUse>(node, node->child1(), node->child2()))
150                 break;
151             if (node->child2()->shouldSpeculateString()
152                 && attemptToMakeFastStringAdd<StringUse>(node, node->child2(), node->child1()))
153                 break;
154             if (node->child1()->shouldSpeculateStringObject()
155                 && attemptToMakeFastStringAdd<StringObjectUse>(node, node->child1(), node->child2()))
156                 break;
157             if (node->child2()->shouldSpeculateStringObject()
158                 && attemptToMakeFastStringAdd<StringObjectUse>(node, node->child2(), node->child1()))
159                 break;
160             if (node->child1()->shouldSpeculateStringOrStringObject()
161                 && attemptToMakeFastStringAdd<StringOrStringObjectUse>(node, node->child1(), node->child2()))
162                 break;
163             if (node->child2()->shouldSpeculateStringOrStringObject()
164                 && attemptToMakeFastStringAdd<StringOrStringObjectUse>(node, node->child2(), node->child1()))
165                 break;
166             break;
167         }
168             
169         case MakeRope: {
170             fixupMakeRope(node);
171             break;
172         }
173             
174         case ArithAdd:
175         case ArithSub: {
176             if (attemptToMakeIntegerAdd(node))
177                 break;
178             fixEdge<NumberUse>(node->child1());
179             fixEdge<NumberUse>(node->child2());
180             break;
181         }
182             
183         case ArithNegate: {
184             if (m_graph.negateShouldSpeculateInt32(node)) {
185                 fixEdge<Int32Use>(node->child1());
186                 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
187                     node->setArithMode(Arith::Unchecked);
188                 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
189                     node->setArithMode(Arith::CheckOverflow);
190                 else
191                     node->setArithMode(Arith::CheckOverflowAndNegativeZero);
192                 break;
193             }
194             if (m_graph.negateShouldSpeculateMachineInt(node)) {
195                 fixEdge<MachineIntUse>(node->child1());
196                 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
197                     node->setArithMode(Arith::CheckOverflow);
198                 else
199                     node->setArithMode(Arith::CheckOverflowAndNegativeZero);
200                 break;
201             }
202             fixEdge<NumberUse>(node->child1());
203             break;
204         }
205             
206         case ArithMul: {
207             if (m_graph.mulShouldSpeculateInt32(node)) {
208                 fixEdge<Int32Use>(node->child1());
209                 fixEdge<Int32Use>(node->child2());
210                 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
211                     node->setArithMode(Arith::Unchecked);
212                 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
213                     node->setArithMode(Arith::CheckOverflow);
214                 else
215                     node->setArithMode(Arith::CheckOverflowAndNegativeZero);
216                 break;
217             }
218             if (m_graph.mulShouldSpeculateMachineInt(node)) {
219                 fixEdge<MachineIntUse>(node->child1());
220                 fixEdge<MachineIntUse>(node->child2());
221                 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
222                     node->setArithMode(Arith::CheckOverflow);
223                 else
224                     node->setArithMode(Arith::CheckOverflowAndNegativeZero);
225                 break;
226             }
227             fixEdge<NumberUse>(node->child1());
228             fixEdge<NumberUse>(node->child2());
229             break;
230         }
231
232         case ArithDiv:
233         case ArithMod: {
234             if (Node::shouldSpeculateInt32ForArithmetic(node->child1().node(), node->child2().node())
235                 && node->canSpeculateInt32()) {
236                 if (optimizeForX86() || optimizeForARM64() || optimizeForARMv7s()) {
237                     fixEdge<Int32Use>(node->child1());
238                     fixEdge<Int32Use>(node->child2());
239                     if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
240                         node->setArithMode(Arith::Unchecked);
241                     else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
242                         node->setArithMode(Arith::CheckOverflow);
243                     else
244                         node->setArithMode(Arith::CheckOverflowAndNegativeZero);
245                     break;
246                 }
247                 Edge child1 = node->child1();
248                 Edge child2 = node->child2();
249                 
250                 injectInt32ToDoubleNode(node->child1());
251                 injectInt32ToDoubleNode(node->child2());
252
253                 // We don't need to do ref'ing on the children because we're stealing them from
254                 // the original division.
255                 Node* newDivision = m_insertionSet.insertNode(
256                     m_indexInBlock, SpecDouble, *node);
257                 
258                 node->setOp(DoubleAsInt32);
259                 node->children.initialize(Edge(newDivision, KnownNumberUse), Edge(), Edge());
260                 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
261                     node->setArithMode(Arith::CheckOverflow);
262                 else
263                     node->setArithMode(Arith::CheckOverflowAndNegativeZero);
264                 
265                 m_insertionSet.insertNode(m_indexInBlock + 1, SpecNone, Phantom, node->origin, child1, child2);
266                 break;
267             }
268             fixEdge<NumberUse>(node->child1());
269             fixEdge<NumberUse>(node->child2());
270             break;
271         }
272             
273         case ArithMin:
274         case ArithMax: {
275             if (Node::shouldSpeculateInt32ForArithmetic(node->child1().node(), node->child2().node())
276                 && node->canSpeculateInt32()) {
277                 fixEdge<Int32Use>(node->child1());
278                 fixEdge<Int32Use>(node->child2());
279                 break;
280             }
281             fixEdge<NumberUse>(node->child1());
282             fixEdge<NumberUse>(node->child2());
283             break;
284         }
285             
286         case ArithAbs: {
287             if (node->child1()->shouldSpeculateInt32ForArithmetic()
288                 && node->canSpeculateInt32()) {
289                 fixEdge<Int32Use>(node->child1());
290                 break;
291             }
292             fixEdge<NumberUse>(node->child1());
293             break;
294         }
295             
296         case ArithSqrt:
297         case ArithSin:
298         case ArithCos: {
299             fixEdge<NumberUse>(node->child1());
300             break;
301         }
302             
303         case LogicalNot: {
304             if (node->child1()->shouldSpeculateBoolean())
305                 fixEdge<BooleanUse>(node->child1());
306             else if (node->child1()->shouldSpeculateObjectOrOther())
307                 fixEdge<ObjectOrOtherUse>(node->child1());
308             else if (node->child1()->shouldSpeculateInt32())
309                 fixEdge<Int32Use>(node->child1());
310             else if (node->child1()->shouldSpeculateNumber())
311                 fixEdge<NumberUse>(node->child1());
312             else if (node->child1()->shouldSpeculateString())
313                 fixEdge<StringUse>(node->child1());
314             break;
315         }
316             
317         case TypeOf: {
318             if (node->child1()->shouldSpeculateString())
319                 fixEdge<StringUse>(node->child1());
320             else if (node->child1()->shouldSpeculateCell())
321                 fixEdge<CellUse>(node->child1());
322             break;
323         }
324             
325         case CompareEqConstant: {
326             break;
327         }
328
329         case CompareEq:
330         case CompareLess:
331         case CompareLessEq:
332         case CompareGreater:
333         case CompareGreaterEq: {
334             if (Node::shouldSpeculateInt32(node->child1().node(), node->child2().node())) {
335                 fixEdge<Int32Use>(node->child1());
336                 fixEdge<Int32Use>(node->child2());
337                 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
338                 break;
339             }
340             if (enableInt52()
341                 && Node::shouldSpeculateMachineInt(node->child1().node(), node->child2().node())) {
342                 fixEdge<MachineIntUse>(node->child1());
343                 fixEdge<MachineIntUse>(node->child2());
344                 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
345                 break;
346             }
347             if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
348                 fixEdge<NumberUse>(node->child1());
349                 fixEdge<NumberUse>(node->child2());
350                 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
351                 break;
352             }
353             if (node->op() != CompareEq)
354                 break;
355             if (Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
356                 fixEdge<BooleanUse>(node->child1());
357                 fixEdge<BooleanUse>(node->child2());
358                 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
359                 break;
360             }
361             if (node->child1()->shouldSpeculateStringIdent() && node->child2()->shouldSpeculateStringIdent()) {
362                 fixEdge<StringIdentUse>(node->child1());
363                 fixEdge<StringIdentUse>(node->child2());
364                 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
365                 break;
366             }
367             if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && GPRInfo::numberOfRegisters >= 7) {
368                 fixEdge<StringUse>(node->child1());
369                 fixEdge<StringUse>(node->child2());
370                 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
371                 break;
372             }
373             if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
374                 fixEdge<ObjectUse>(node->child1());
375                 fixEdge<ObjectUse>(node->child2());
376                 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
377                 break;
378             }
379             if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObjectOrOther()) {
380                 fixEdge<ObjectUse>(node->child1());
381                 fixEdge<ObjectOrOtherUse>(node->child2());
382                 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
383                 break;
384             }
385             if (node->child1()->shouldSpeculateObjectOrOther() && node->child2()->shouldSpeculateObject()) {
386                 fixEdge<ObjectOrOtherUse>(node->child1());
387                 fixEdge<ObjectUse>(node->child2());
388                 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
389                 break;
390             }
391             break;
392         }
393             
394         case CompareStrictEqConstant: {
395             break;
396         }
397             
398         case CompareStrictEq: {
399             if (Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
400                 fixEdge<BooleanUse>(node->child1());
401                 fixEdge<BooleanUse>(node->child2());
402                 break;
403             }
404             if (Node::shouldSpeculateInt32(node->child1().node(), node->child2().node())) {
405                 fixEdge<Int32Use>(node->child1());
406                 fixEdge<Int32Use>(node->child2());
407                 break;
408             }
409             if (enableInt52()
410                 && Node::shouldSpeculateMachineInt(node->child1().node(), node->child2().node())) {
411                 fixEdge<MachineIntUse>(node->child1());
412                 fixEdge<MachineIntUse>(node->child2());
413                 break;
414             }
415             if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
416                 fixEdge<NumberUse>(node->child1());
417                 fixEdge<NumberUse>(node->child2());
418                 break;
419             }
420             if (node->child1()->shouldSpeculateStringIdent() && node->child2()->shouldSpeculateStringIdent()) {
421                 fixEdge<StringIdentUse>(node->child1());
422                 fixEdge<StringIdentUse>(node->child2());
423                 break;
424             }
425             if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && GPRInfo::numberOfRegisters >= 7) {
426                 fixEdge<StringUse>(node->child1());
427                 fixEdge<StringUse>(node->child2());
428                 break;
429             }
430             if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
431                 fixEdge<ObjectUse>(node->child1());
432                 fixEdge<ObjectUse>(node->child2());
433                 break;
434             }
435             break;
436         }
437
438         case StringFromCharCode:
439             fixEdge<Int32Use>(node->child1());
440             break;
441
442         case StringCharAt:
443         case StringCharCodeAt: {
444             // Currently we have no good way of refining these.
445             ASSERT(node->arrayMode() == ArrayMode(Array::String));
446             blessArrayOperation(node->child1(), node->child2(), node->child3());
447             fixEdge<KnownCellUse>(node->child1());
448             fixEdge<Int32Use>(node->child2());
449             break;
450         }
451
452         case GetByVal: {
453             node->setArrayMode(
454                 node->arrayMode().refine(
455                     m_graph, node->origin.semantic,
456                     node->child1()->prediction(),
457                     node->child2()->prediction(),
458                     SpecNone, node->flags()));
459             
460             blessArrayOperation(node->child1(), node->child2(), node->child3());
461             
462             ArrayMode arrayMode = node->arrayMode();
463             switch (arrayMode.type()) {
464             case Array::Double:
465                 if (arrayMode.arrayClass() == Array::OriginalArray
466                     && arrayMode.speculation() == Array::InBounds
467                     && m_graph.globalObjectFor(node->origin.semantic)->arrayPrototypeChainIsSane()
468                     && !(node->flags() & NodeBytecodeUsesAsOther))
469                     node->setArrayMode(arrayMode.withSpeculation(Array::SaneChain));
470                 break;
471                 
472             case Array::String:
473                 if ((node->prediction() & ~SpecString)
474                     || m_graph.hasExitSite(node->origin.semantic, OutOfBounds))
475                     node->setArrayMode(arrayMode.withSpeculation(Array::OutOfBounds));
476                 break;
477                 
478             default:
479                 break;
480             }
481             
482             switch (node->arrayMode().type()) {
483             case Array::SelectUsingPredictions:
484             case Array::Unprofiled:
485             case Array::Undecided:
486                 RELEASE_ASSERT_NOT_REACHED();
487                 break;
488             case Array::Generic:
489 #if USE(JSVALUE32_64)
490                 fixEdge<CellUse>(node->child1()); // Speculating cell due to register pressure on 32-bit.
491 #endif
492                 break;
493             case Array::ForceExit:
494                 break;
495             default:
496                 fixEdge<KnownCellUse>(node->child1());
497                 fixEdge<Int32Use>(node->child2());
498                 break;
499             }
500             
501             break;
502         }
503
504         case PutByValDirect:
505         case PutByVal:
506         case PutByValAlias: {
507             Edge& child1 = m_graph.varArgChild(node, 0);
508             Edge& child2 = m_graph.varArgChild(node, 1);
509             Edge& child3 = m_graph.varArgChild(node, 2);
510
511             node->setArrayMode(
512                 node->arrayMode().refine(
513                     m_graph, node->origin.semantic,
514                     child1->prediction(),
515                     child2->prediction(),
516                     child3->prediction()));
517             
518             blessArrayOperation(child1, child2, m_graph.varArgChild(node, 3));
519             
520             switch (node->arrayMode().modeForPut().type()) {
521             case Array::SelectUsingPredictions:
522             case Array::Unprofiled:
523             case Array::Undecided:
524                 RELEASE_ASSERT_NOT_REACHED();
525                 break;
526             case Array::ForceExit:
527             case Array::Generic:
528 #if USE(JSVALUE32_64)
529                 // Due to register pressure on 32-bit, we speculate cell and
530                 // ignore the base-is-not-cell case entirely by letting the
531                 // baseline JIT handle it.
532                 fixEdge<CellUse>(child1);
533 #endif
534                 break;
535             case Array::Int32:
536                 fixEdge<KnownCellUse>(child1);
537                 fixEdge<Int32Use>(child2);
538                 fixEdge<Int32Use>(child3);
539                 if (child3->prediction() & SpecInt52)
540                     fixEdge<MachineIntUse>(child3);
541                 else
542                     fixEdge<Int32Use>(child3);
543                 break;
544             case Array::Double:
545                 fixEdge<KnownCellUse>(child1);
546                 fixEdge<Int32Use>(child2);
547                 fixEdge<RealNumberUse>(child3);
548                 break;
549             case Array::Int8Array:
550             case Array::Int16Array:
551             case Array::Int32Array:
552             case Array::Uint8Array:
553             case Array::Uint8ClampedArray:
554             case Array::Uint16Array:
555             case Array::Uint32Array:
556                 fixEdge<KnownCellUse>(child1);
557                 fixEdge<Int32Use>(child2);
558                 if (child3->shouldSpeculateInt32())
559                     fixEdge<Int32Use>(child3);
560                 else if (child3->shouldSpeculateMachineInt())
561                     fixEdge<MachineIntUse>(child3);
562                 else
563                     fixEdge<NumberUse>(child3);
564                 break;
565             case Array::Float32Array:
566             case Array::Float64Array:
567                 fixEdge<KnownCellUse>(child1);
568                 fixEdge<Int32Use>(child2);
569                 fixEdge<NumberUse>(child3);
570                 break;
571             case Array::Contiguous:
572             case Array::ArrayStorage:
573             case Array::SlowPutArrayStorage:
574             case Array::Arguments:
575                 fixEdge<KnownCellUse>(child1);
576                 fixEdge<Int32Use>(child2);
577                 insertStoreBarrier(m_indexInBlock, child1, child3);
578                 break;
579             default:
580                 fixEdge<KnownCellUse>(child1);
581                 fixEdge<Int32Use>(child2);
582                 break;
583             }
584             break;
585         }
586             
587         case ArrayPush: {
588             // May need to refine the array mode in case the value prediction contravenes
589             // the array prediction. For example, we may have evidence showing that the
590             // array is in Int32 mode, but the value we're storing is likely to be a double.
591             // Then we should turn this into a conversion to Double array followed by the
592             // push. On the other hand, we absolutely don't want to refine based on the
593             // base prediction. If it has non-cell garbage in it, then we want that to be
594             // ignored. That's because ArrayPush can't handle any array modes that aren't
595             // array-related - so if refine() turned this into a "Generic" ArrayPush then
596             // that would break things.
597             node->setArrayMode(
598                 node->arrayMode().refine(
599                     m_graph, node->origin.semantic,
600                     node->child1()->prediction() & SpecCell,
601                     SpecInt32,
602                     node->child2()->prediction()));
603             blessArrayOperation(node->child1(), Edge(), node->child3());
604             fixEdge<KnownCellUse>(node->child1());
605             
606             switch (node->arrayMode().type()) {
607             case Array::Int32:
608                 fixEdge<Int32Use>(node->child2());
609                 break;
610             case Array::Double:
611                 fixEdge<RealNumberUse>(node->child2());
612                 break;
613             case Array::Contiguous:
614             case Array::ArrayStorage:
615                 insertStoreBarrier(m_indexInBlock, node->child1(), node->child2());
616                 break;
617             default:
618                 break;
619             }
620             break;
621         }
622             
623         case ArrayPop: {
624             blessArrayOperation(node->child1(), Edge(), node->child2());
625             fixEdge<KnownCellUse>(node->child1());
626             break;
627         }
628             
629         case RegExpExec:
630         case RegExpTest: {
631             fixEdge<CellUse>(node->child1());
632             fixEdge<CellUse>(node->child2());
633             break;
634         }
635             
636         case Branch: {
637             if (node->child1()->shouldSpeculateBoolean())
638                 fixEdge<BooleanUse>(node->child1());
639             else if (node->child1()->shouldSpeculateObjectOrOther())
640                 fixEdge<ObjectOrOtherUse>(node->child1());
641             else if (node->child1()->shouldSpeculateInt32())
642                 fixEdge<Int32Use>(node->child1());
643             else if (node->child1()->shouldSpeculateNumber())
644                 fixEdge<NumberUse>(node->child1());
645
646             Node* logicalNot = node->child1().node();
647             if (logicalNot->op() == LogicalNot) {
648                 
649                 // Make sure that OSR exit can't observe the LogicalNot. If it can,
650                 // then we must compute it and cannot peephole around it.
651                 bool found = false;
652                 bool ok = true;
653                 for (unsigned i = m_indexInBlock; i--;) {
654                     Node* candidate = m_block->at(i);
655                     if (candidate == logicalNot) {
656                         found = true;
657                         break;
658                     }
659                     if (candidate->canExit()) {
660                         ok = false;
661                         found = true;
662                         break;
663                     }
664                 }
665                 ASSERT_UNUSED(found, found);
666                 
667                 if (ok) {
668                     Edge newChildEdge = logicalNot->child1();
669                     if (newChildEdge->hasBooleanResult()) {
670                         node->children.setChild1(newChildEdge);
671                         
672                         BasicBlock* toBeTaken = node->notTakenBlock();
673                         BasicBlock* toBeNotTaken = node->takenBlock();
674                         node->setTakenBlock(toBeTaken);
675                         node->setNotTakenBlock(toBeNotTaken);
676                     }
677                 }
678             }
679             break;
680         }
681             
682         case Switch: {
683             SwitchData* data = node->switchData();
684             switch (data->kind) {
685             case SwitchImm:
686                 if (node->child1()->shouldSpeculateInt32())
687                     fixEdge<Int32Use>(node->child1());
688                 break;
689             case SwitchChar:
690                 if (node->child1()->shouldSpeculateString())
691                     fixEdge<StringUse>(node->child1());
692                 break;
693             case SwitchString:
694                 if (node->child1()->shouldSpeculateStringIdent())
695                     fixEdge<StringIdentUse>(node->child1());
696                 else if (node->child1()->shouldSpeculateString())
697                     fixEdge<StringUse>(node->child1());
698                 break;
699             }
700             break;
701         }
702             
703         case ToPrimitive: {
704             fixupToPrimitive(node);
705             break;
706         }
707             
708         case ToString: {
709             fixupToString(node);
710             break;
711         }
712             
713         case NewStringObject: {
714             fixEdge<KnownStringUse>(node->child1());
715             break;
716         }
717             
718         case NewArray: {
719             for (unsigned i = m_graph.varArgNumChildren(node); i--;) {
720                 node->setIndexingType(
721                     leastUpperBoundOfIndexingTypeAndType(
722                         node->indexingType(), m_graph.varArgChild(node, i)->prediction()));
723             }
724             switch (node->indexingType()) {
725             case ALL_BLANK_INDEXING_TYPES:
726                 CRASH();
727                 break;
728             case ALL_UNDECIDED_INDEXING_TYPES:
729                 if (node->numChildren()) {
730                     // This will only happen if the children have no type predictions. We
731                     // would have already exited by now, but insert a forced exit just to
732                     // be safe.
733                     m_insertionSet.insertNode(
734                         m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
735                 }
736                 break;
737             case ALL_INT32_INDEXING_TYPES:
738                 for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
739                     fixEdge<Int32Use>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
740                 break;
741             case ALL_DOUBLE_INDEXING_TYPES:
742                 for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
743                     fixEdge<RealNumberUse>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
744                 break;
745             case ALL_CONTIGUOUS_INDEXING_TYPES:
746             case ALL_ARRAY_STORAGE_INDEXING_TYPES:
747                 break;
748             default:
749                 CRASH();
750                 break;
751             }
752             break;
753         }
754             
755         case NewTypedArray: {
756             if (node->child1()->shouldSpeculateInt32()) {
757                 fixEdge<Int32Use>(node->child1());
758                 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
759                 break;
760             }
761             break;
762         }
763             
764         case NewArrayWithSize: {
765             fixEdge<Int32Use>(node->child1());
766             break;
767         }
768             
769         case ToThis: {
770             ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->isStrictMode() ? StrictMode : NotStrictMode;
771
772             if (isOtherSpeculation(node->child1()->prediction())) {
773                 if (ecmaMode == StrictMode) {
774                     fixEdge<OtherUse>(node->child1());
775                     node->convertToIdentity();
776                     break;
777                 }
778
779                 m_insertionSet.insertNode(
780                     m_indexInBlock, SpecNone, Phantom, node->origin,
781                     Edge(node->child1().node(), OtherUse));
782                 observeUseKindOnNode<OtherUse>(node->child1().node());
783                 node->convertToWeakConstant(m_graph.globalThisObjectFor(node->origin.semantic));
784                 break;
785             }
786             
787             if (isFinalObjectSpeculation(node->child1()->prediction())) {
788                 fixEdge<FinalObjectUse>(node->child1());
789                 node->convertToIdentity();
790                 break;
791             }
792             
793             break;
794         }
795             
796         case GetMyArgumentByVal:
797         case GetMyArgumentByValSafe: {
798             fixEdge<Int32Use>(node->child1());
799             break;
800         }
801             
802         case PutStructure: {
803             fixEdge<KnownCellUse>(node->child1());
804             insertStoreBarrier(m_indexInBlock, node->child1());
805             break;
806         }
807
808         case PutClosureVar: {
809             fixEdge<KnownCellUse>(node->child1());
810             insertStoreBarrier(m_indexInBlock, node->child1(), node->child3());
811             break;
812         }
813
814         case GetClosureRegisters:
815         case SkipTopScope:
816         case SkipScope:
817         case GetScope: {
818             fixEdge<KnownCellUse>(node->child1());
819             break;
820         }
821             
822         case AllocatePropertyStorage:
823         case ReallocatePropertyStorage: {
824             fixEdge<KnownCellUse>(node->child1());
825             insertStoreBarrier(m_indexInBlock + 1, node->child1());
826             break;
827         }
828
829         case GetById:
830         case GetByIdFlush: {
831             if (!node->child1()->shouldSpeculateCell())
832                 break;
833             StringImpl* impl = m_graph.identifiers()[node->identifierNumber()];
834             if (impl == vm().propertyNames->length.impl()) {
835                 attemptToMakeGetArrayLength(node);
836                 break;
837             }
838             if (impl == vm().propertyNames->byteLength.impl()) {
839                 attemptToMakeGetTypedArrayByteLength(node);
840                 break;
841             }
842             if (impl == vm().propertyNames->byteOffset.impl()) {
843                 attemptToMakeGetTypedArrayByteOffset(node);
844                 break;
845             }
846             fixEdge<CellUse>(node->child1());
847             break;
848         }
849             
850         case PutById:
851         case PutByIdDirect: {
852             fixEdge<CellUse>(node->child1());
853             insertStoreBarrier(m_indexInBlock, node->child1(), node->child2());
854             break;
855         }
856
857         case CheckExecutable:
858         case CheckStructure:
859         case StructureTransitionWatchpoint:
860         case CheckFunction:
861         case CheckHasInstance:
862         case CreateThis:
863         case GetButterfly: {
864             fixEdge<CellUse>(node->child1());
865             break;
866         }
867             
868         case Arrayify:
869         case ArrayifyToStructure: {
870             fixEdge<CellUse>(node->child1());
871             if (node->child2())
872                 fixEdge<Int32Use>(node->child2());
873             break;
874         }
875             
876         case GetByOffset: {
877             if (!node->child1()->hasStorageResult())
878                 fixEdge<KnownCellUse>(node->child1());
879             fixEdge<KnownCellUse>(node->child2());
880             break;
881         }
882             
883         case MultiGetByOffset: {
884             fixEdge<CellUse>(node->child1());
885             break;
886         }
887             
888         case PutByOffset: {
889             if (!node->child1()->hasStorageResult())
890                 fixEdge<KnownCellUse>(node->child1());
891             fixEdge<KnownCellUse>(node->child2());
892             insertStoreBarrier(m_indexInBlock, node->child2(), node->child3());
893             break;
894         }
895             
896         case InstanceOf: {
897             // FIXME: This appears broken: CheckHasInstance already does an unconditional cell
898             // check. https://bugs.webkit.org/show_bug.cgi?id=107479
899             if (!(node->child1()->prediction() & ~SpecCell))
900                 fixEdge<CellUse>(node->child1());
901             fixEdge<CellUse>(node->child2());
902             break;
903         }
904             
905         case In: {
906             // FIXME: We should at some point have array profiling on op_in, in which
907             // case we would be able to turn this into a kind of GetByVal.
908             
909             fixEdge<CellUse>(node->child2());
910             break;
911         }
912
913         case Phantom:
914         case Identity:
915         case Check: {
916             switch (node->child1().useKind()) {
917             case NumberUse:
918                 if (node->child1()->shouldSpeculateInt32ForArithmetic())
919                     node->child1().setUseKind(Int32Use);
920                 break;
921             default:
922                 break;
923             }
924             observeUseKindOnEdge(node->child1());
925             break;
926         }
927
928         case GetArrayLength:
929         case Phi:
930         case Upsilon:
931         case GetArgument:
932         case PhantomPutStructure:
933         case GetIndexedPropertyStorage:
934         case GetTypedArrayByteOffset:
935         case LastNodeType:
936         case CheckTierUpInLoop:
937         case CheckTierUpAtReturn:
938         case CheckTierUpAndOSREnter:
939         case Int52ToDouble:
940         case Int52ToValue:
941         case InvalidationPoint:
942         case CheckArray:
943         case CheckInBounds:
944         case ConstantStoragePointer:
945         case DoubleAsInt32:
946         case Int32ToDouble:
947         case ValueToInt32:
948         case HardPhantom: // HardPhantom would be trivial to handle but anyway we assert that we won't see it here yet.
949             // These are just nodes that we don't currently expect to see during fixup.
950             // If we ever wanted to insert them prior to fixup, then we just have to create
951             // fixup rules for them.
952             RELEASE_ASSERT_NOT_REACHED();
953             break;
954         
955         case PutGlobalVar: {
956             Node* globalObjectNode = m_insertionSet.insertNode(
957                 m_indexInBlock, SpecNone, WeakJSConstant, node->origin, 
958                 OpInfo(m_graph.globalObjectFor(node->origin.semantic)));
959             Node* barrierNode = m_graph.addNode(
960                 SpecNone, ConditionalStoreBarrier, m_currentNode->origin, 
961                 Edge(globalObjectNode, KnownCellUse), Edge(node->child1().node(), UntypedUse));
962             m_insertionSet.insert(m_indexInBlock, barrierNode);
963             break;
964         }
965
966         case TearOffActivation: {
967             Node* barrierNode = m_graph.addNode(
968                 SpecNone, StoreBarrierWithNullCheck, m_currentNode->origin, 
969                 Edge(node->child1().node(), UntypedUse));
970             m_insertionSet.insert(m_indexInBlock, barrierNode);
971             break;
972         }
973
974         case IsString:
975             if (node->child1()->shouldSpeculateString()) {
976                 m_insertionSet.insertNode(
977                     m_indexInBlock, SpecNone, Phantom, node->origin,
978                     Edge(node->child1().node(), StringUse));
979                 m_graph.convertToConstant(node, jsBoolean(true));
980                 observeUseKindOnNode<StringUse>(node);
981             }
982             break;
983             
984 #if !ASSERT_DISABLED
985         // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
986         case SetArgument:
987         case JSConstant:
988         case WeakJSConstant:
989         case GetLocal:
990         case GetCallee:
991         case Flush:
992         case PhantomLocal:
993         case GetLocalUnlinked:
994         case GetMyScope:
995         case GetClosureVar:
996         case GetGlobalVar:
997         case NotifyWrite:
998         case VariableWatchpoint:
999         case VarInjectionWatchpoint:
1000         case AllocationProfileWatchpoint:
1001         case Call:
1002         case Construct:
1003         case NewObject:
1004         case NewArrayBuffer:
1005         case NewRegexp:
1006         case Breakpoint:
1007         case ProfileWillCall:
1008         case ProfileDidCall:
1009         case IsUndefined:
1010         case IsBoolean:
1011         case IsNumber:
1012         case IsObject:
1013         case IsFunction:
1014         case CreateActivation:
1015         case CreateArguments:
1016         case PhantomArguments:
1017         case TearOffArguments:
1018         case GetMyArgumentsLength:
1019         case GetMyArgumentsLengthSafe:
1020         case CheckArgumentsNotCreated:
1021         case NewFunction:
1022         case NewFunctionNoCheck:
1023         case NewFunctionExpression:
1024         case Jump:
1025         case Return:
1026         case Throw:
1027         case ThrowReferenceError:
1028         case CountExecution:
1029         case ForceOSRExit:
1030         case CheckWatchdogTimer:
1031         case Unreachable:
1032         case ExtractOSREntryLocal:
1033         case LoopHint:
1034         case StoreBarrier:
1035         case ConditionalStoreBarrier:
1036         case StoreBarrierWithNullCheck:
1037         case FunctionReentryWatchpoint:
1038         case TypedArrayWatchpoint:
1039         case MovHint:
1040         case ZombieHint:
1041             break;
1042 #else
1043         default:
1044             break;
1045 #endif
1046         }
1047         
1048         if (!node->containsMovHint())
1049             DFG_NODE_DO_TO_CHILDREN(m_graph, node, observeUntypedEdge);
1050         
1051         if (node->isTerminal()) {
1052             // Terminal nodes don't need post-phantoms, and inserting them would violate
1053             // the current requirement that a terminal is the last thing in a block. We
1054             // should eventually change that requirement but even if we did, this would
1055             // still be a valid optimization. All terminals accept just one input, and
1056             // if that input is a conversion node then no further speculations will be
1057             // performed.
1058             // FIXME: Get rid of this by allowing Phantoms after terminals.
1059             // https://bugs.webkit.org/show_bug.cgi?id=126778
1060             m_requiredPhantoms.resize(0);
1061         // Since StoreBarriers are recursively fixed up so that their children look 
1062         // identical to that of the node they're barrier-ing, we need to avoid adding
1063         // any Phantoms when processing them because this would invalidate the 
1064         // InsertionSet's invariant of inserting things in a monotonically increasing
1065         // order. This should be okay anyways because StoreBarriers can't exit. 
1066         } else
1067             addPhantomsIfNecessary();
1068     }
1069     
1070     void observeUntypedEdge(Node*, Edge& edge)
1071     {
1072         if (edge.useKind() != UntypedUse)
1073             return;
1074         fixEdge<UntypedUse>(edge);
1075     }
1076     
1077     template<UseKind useKind>
1078     void createToString(Node* node, Edge& edge)
1079     {
1080         edge.setNode(m_insertionSet.insertNode(
1081             m_indexInBlock, SpecString, ToString, node->origin,
1082             Edge(edge.node(), useKind)));
1083     }
1084     
1085     template<UseKind useKind>
1086     void attemptToForceStringArrayModeByToStringConversion(ArrayMode& arrayMode, Node* node)
1087     {
1088         ASSERT(arrayMode == ArrayMode(Array::Generic));
1089         
1090         if (!canOptimizeStringObjectAccess(node->origin.semantic))
1091             return;
1092         
1093         createToString<useKind>(node, node->child1());
1094         arrayMode = ArrayMode(Array::String);
1095     }
1096     
1097     template<UseKind useKind>
1098     bool isStringObjectUse()
1099     {
1100         switch (useKind) {
1101         case StringObjectUse:
1102         case StringOrStringObjectUse:
1103             return true;
1104         default:
1105             return false;
1106         }
1107     }
1108     
1109     template<UseKind useKind>
1110     void convertStringAddUse(Node* node, Edge& edge)
1111     {
1112         if (useKind == StringUse) {
1113             // This preserves the binaryUseKind() invariant ot ValueAdd: ValueAdd's
1114             // two edges will always have identical use kinds, which makes the
1115             // decision process much easier.
1116             observeUseKindOnNode<StringUse>(edge.node());
1117             m_insertionSet.insertNode(
1118                 m_indexInBlock, SpecNone, Phantom, node->origin,
1119                 Edge(edge.node(), StringUse));
1120             edge.setUseKind(KnownStringUse);
1121             return;
1122         }
1123         
1124         // FIXME: We ought to be able to have a ToPrimitiveToString node.
1125         
1126         observeUseKindOnNode<useKind>(edge.node());
1127         createToString<useKind>(node, edge);
1128     }
1129     
1130     void convertToMakeRope(Node* node)
1131     {
1132         node->setOpAndDefaultFlags(MakeRope);
1133         fixupMakeRope(node);
1134     }
1135     
1136     void fixupMakeRope(Node* node)
1137     {
1138         for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
1139             Edge& edge = node->children.child(i);
1140             if (!edge)
1141                 break;
1142             edge.setUseKind(KnownStringUse);
1143             if (!m_graph.isConstant(edge.node()))
1144                 continue;
1145             JSString* string = jsCast<JSString*>(m_graph.valueOfJSConstant(edge.node()).asCell());
1146             if (string->length())
1147                 continue;
1148             
1149             // Don't allow the MakeRope to have zero children.
1150             if (!i && !node->child2())
1151                 break;
1152             
1153             node->children.removeEdge(i--);
1154         }
1155         
1156         if (!node->child2()) {
1157             ASSERT(!node->child3());
1158             node->convertToIdentity();
1159         }
1160     }
1161     
1162     void fixupToPrimitive(Node* node)
1163     {
1164         if (node->child1()->shouldSpeculateInt32()) {
1165             fixEdge<Int32Use>(node->child1());
1166             node->convertToIdentity();
1167             return;
1168         }
1169         
1170         if (node->child1()->shouldSpeculateString()) {
1171             fixEdge<StringUse>(node->child1());
1172             node->convertToIdentity();
1173             return;
1174         }
1175         
1176         if (node->child1()->shouldSpeculateStringObject()
1177             && canOptimizeStringObjectAccess(node->origin.semantic)) {
1178             fixEdge<StringObjectUse>(node->child1());
1179             node->convertToToString();
1180             return;
1181         }
1182         
1183         if (node->child1()->shouldSpeculateStringOrStringObject()
1184             && canOptimizeStringObjectAccess(node->origin.semantic)) {
1185             fixEdge<StringOrStringObjectUse>(node->child1());
1186             node->convertToToString();
1187             return;
1188         }
1189     }
1190     
1191     void fixupToString(Node* node)
1192     {
1193         if (node->child1()->shouldSpeculateString()) {
1194             fixEdge<StringUse>(node->child1());
1195             node->convertToIdentity();
1196             return;
1197         }
1198         
1199         if (node->child1()->shouldSpeculateStringObject()
1200             && canOptimizeStringObjectAccess(node->origin.semantic)) {
1201             fixEdge<StringObjectUse>(node->child1());
1202             return;
1203         }
1204         
1205         if (node->child1()->shouldSpeculateStringOrStringObject()
1206             && canOptimizeStringObjectAccess(node->origin.semantic)) {
1207             fixEdge<StringOrStringObjectUse>(node->child1());
1208             return;
1209         }
1210         
1211         if (node->child1()->shouldSpeculateCell()) {
1212             fixEdge<CellUse>(node->child1());
1213             return;
1214         }
1215     }
1216     
1217     template<UseKind leftUseKind>
1218     bool attemptToMakeFastStringAdd(Node* node, Edge& left, Edge& right)
1219     {
1220         Node* originalLeft = left.node();
1221         Node* originalRight = right.node();
1222         
1223         ASSERT(leftUseKind == StringUse || leftUseKind == StringObjectUse || leftUseKind == StringOrStringObjectUse);
1224         
1225         if (isStringObjectUse<leftUseKind>() && !canOptimizeStringObjectAccess(node->origin.semantic))
1226             return false;
1227         
1228         convertStringAddUse<leftUseKind>(node, left);
1229         
1230         if (right->shouldSpeculateString())
1231             convertStringAddUse<StringUse>(node, right);
1232         else if (right->shouldSpeculateStringObject() && canOptimizeStringObjectAccess(node->origin.semantic))
1233             convertStringAddUse<StringObjectUse>(node, right);
1234         else if (right->shouldSpeculateStringOrStringObject() && canOptimizeStringObjectAccess(node->origin.semantic))
1235             convertStringAddUse<StringOrStringObjectUse>(node, right);
1236         else {
1237             // At this point we know that the other operand is something weird. The semantically correct
1238             // way of dealing with this is:
1239             //
1240             // MakeRope(@left, ToString(ToPrimitive(@right)))
1241             //
1242             // So that's what we emit. NB, we need to do all relevant type checks on @left before we do
1243             // anything to @right, since ToPrimitive may be effectful.
1244             
1245             Node* toPrimitive = m_insertionSet.insertNode(
1246                 m_indexInBlock, resultOfToPrimitive(right->prediction()), ToPrimitive,
1247                 node->origin, Edge(right.node()));
1248             Node* toString = m_insertionSet.insertNode(
1249                 m_indexInBlock, SpecString, ToString, node->origin, Edge(toPrimitive));
1250             
1251             fixupToPrimitive(toPrimitive);
1252             fixupToString(toString);
1253             
1254             right.setNode(toString);
1255         }
1256         
1257         // We're doing checks up there, so we need to make sure that the
1258         // *original* inputs to the addition are live up to here.
1259         m_insertionSet.insertNode(
1260             m_indexInBlock, SpecNone, Phantom, node->origin,
1261             Edge(originalLeft), Edge(originalRight));
1262         
1263         convertToMakeRope(node);
1264         return true;
1265     }
1266     
1267     bool isStringPrototypeMethodSane(Structure* stringPrototypeStructure, StringImpl* uid)
1268     {
1269         unsigned attributesUnused;
1270         JSCell* specificValue;
1271         PropertyOffset offset = stringPrototypeStructure->getConcurrently(
1272             vm(), uid, attributesUnused, specificValue);
1273         if (!isValidOffset(offset))
1274             return false;
1275         
1276         if (!specificValue)
1277             return false;
1278         
1279         if (!specificValue->inherits(JSFunction::info()))
1280             return false;
1281         
1282         JSFunction* function = jsCast<JSFunction*>(specificValue);
1283         if (function->executable()->intrinsicFor(CodeForCall) != StringPrototypeValueOfIntrinsic)
1284             return false;
1285         
1286         return true;
1287     }
1288     
1289     bool canOptimizeStringObjectAccess(const CodeOrigin& codeOrigin)
1290     {
1291         if (m_graph.hasExitSite(codeOrigin, NotStringObject))
1292             return false;
1293         
1294         Structure* stringObjectStructure = m_graph.globalObjectFor(codeOrigin)->stringObjectStructure();
1295         ASSERT(stringObjectStructure->storedPrototype().isObject());
1296         ASSERT(stringObjectStructure->storedPrototype().asCell()->classInfo() == StringPrototype::info());
1297         
1298         JSObject* stringPrototypeObject = asObject(stringObjectStructure->storedPrototype());
1299         Structure* stringPrototypeStructure = stringPrototypeObject->structure();
1300         if (!m_graph.watchpoints().isStillValid(stringPrototypeStructure->transitionWatchpointSet()))
1301             return false;
1302         
1303         if (stringPrototypeStructure->isDictionary())
1304             return false;
1305         
1306         // We're being conservative here. We want DFG's ToString on StringObject to be
1307         // used in both numeric contexts (that would call valueOf()) and string contexts
1308         // (that would call toString()). We don't want the DFG to have to distinguish
1309         // between the two, just because that seems like it would get confusing. So we
1310         // just require both methods to be sane.
1311         if (!isStringPrototypeMethodSane(stringPrototypeStructure, vm().propertyNames->valueOf.impl()))
1312             return false;
1313         if (!isStringPrototypeMethodSane(stringPrototypeStructure, vm().propertyNames->toString.impl()))
1314             return false;
1315         
1316         return true;
1317     }
1318     
1319     void fixupSetLocalsInBlock(BasicBlock* block)
1320     {
1321         if (!block)
1322             return;
1323         ASSERT(block->isReachable);
1324         m_block = block;
1325         for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
1326             Node* node = m_currentNode = block->at(m_indexInBlock);
1327             if (node->op() != SetLocal)
1328                 continue;
1329             
1330             VariableAccessData* variable = node->variableAccessData();
1331             switch (variable->flushFormat()) {
1332             case FlushedJSValue:
1333                 break;
1334             case FlushedDouble:
1335                 fixEdge<NumberUse>(node->child1());
1336                 break;
1337             case FlushedInt32:
1338                 fixEdge<Int32Use>(node->child1());
1339                 break;
1340             case FlushedInt52:
1341                 fixEdge<MachineIntUse>(node->child1());
1342                 break;
1343             case FlushedCell:
1344                 fixEdge<CellUse>(node->child1());
1345                 break;
1346             case FlushedBoolean:
1347                 fixEdge<BooleanUse>(node->child1());
1348                 break;
1349             default:
1350                 RELEASE_ASSERT_NOT_REACHED();
1351                 break;
1352             }
1353             addPhantomsIfNecessary();
1354         }
1355         m_insertionSet.execute(block);
1356     }
1357     
1358     void fixupUntypedSetLocalsInBlock(BasicBlock* block)
1359     {
1360         if (!block)
1361             return;
1362         ASSERT(block->isReachable);
1363         m_block = block;
1364         for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
1365             Node* node = m_currentNode = block->at(m_indexInBlock);
1366             if (node->op() != SetLocal)
1367                 continue;
1368             
1369             if (node->child1().useKind() == UntypedUse) {
1370                 fixEdge<UntypedUse>(node->child1());
1371                 addPhantomsIfNecessary();
1372             }
1373         }
1374         m_insertionSet.execute(block);
1375     }
1376     
1377     Node* checkArray(ArrayMode arrayMode, const NodeOrigin& origin, Node* array, Node* index, bool (*storageCheck)(const ArrayMode&) = canCSEStorage)
1378     {
1379         ASSERT(arrayMode.isSpecific());
1380         
1381         if (arrayMode.type() == Array::String) {
1382             m_insertionSet.insertNode(
1383                 m_indexInBlock, SpecNone, Phantom, origin, Edge(array, StringUse));
1384         } else {
1385             Structure* structure = arrayMode.originalArrayStructure(m_graph, origin.semantic);
1386         
1387             Edge indexEdge = index ? Edge(index, Int32Use) : Edge();
1388         
1389             if (arrayMode.doesConversion()) {
1390                 if (structure) {
1391                     m_insertionSet.insertNode(
1392                         m_indexInBlock, SpecNone, ArrayifyToStructure, origin,
1393                         OpInfo(structure), OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
1394                 } else {
1395                     m_insertionSet.insertNode(
1396                         m_indexInBlock, SpecNone, Arrayify, origin,
1397                         OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
1398                 }
1399             } else {
1400                 if (structure) {
1401                     m_insertionSet.insertNode(
1402                         m_indexInBlock, SpecNone, CheckStructure, origin,
1403                         OpInfo(m_graph.addStructureSet(structure)), Edge(array, CellUse));
1404                 } else {
1405                     m_insertionSet.insertNode(
1406                         m_indexInBlock, SpecNone, CheckArray, origin,
1407                         OpInfo(arrayMode.asWord()), Edge(array, CellUse));
1408                 }
1409             }
1410         }
1411         
1412         if (!storageCheck(arrayMode))
1413             return 0;
1414         
1415         if (arrayMode.usesButterfly()) {
1416             return m_insertionSet.insertNode(
1417                 m_indexInBlock, SpecNone, GetButterfly, origin, Edge(array, CellUse));
1418         }
1419         
1420         return m_insertionSet.insertNode(
1421             m_indexInBlock, SpecNone, GetIndexedPropertyStorage, origin,
1422             OpInfo(arrayMode.asWord()), Edge(array, KnownCellUse));
1423     }
1424     
1425     void blessArrayOperation(Edge base, Edge index, Edge& storageChild)
1426     {
1427         Node* node = m_currentNode;
1428         
1429         switch (node->arrayMode().type()) {
1430         case Array::ForceExit: {
1431             m_insertionSet.insertNode(
1432                 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
1433             return;
1434         }
1435             
1436         case Array::SelectUsingPredictions:
1437         case Array::Unprofiled:
1438             RELEASE_ASSERT_NOT_REACHED();
1439             return;
1440             
1441         case Array::Generic:
1442             return;
1443             
1444         default: {
1445             Node* storage = checkArray(node->arrayMode(), node->origin, base.node(), index.node());
1446             if (!storage)
1447                 return;
1448             
1449             storageChild = Edge(storage);
1450             return;
1451         } }
1452     }
1453     
1454     bool alwaysUnboxSimplePrimitives()
1455     {
1456 #if USE(JSVALUE64)
1457         return false;
1458 #else
1459         // Any boolean, int, or cell value is profitable to unbox on 32-bit because it
1460         // reduces traffic.
1461         return true;
1462 #endif
1463     }
1464
1465     template<UseKind useKind>
1466     void observeUseKindOnNode(Node* node)
1467     {
1468         if (useKind == UntypedUse)
1469             return;
1470         observeUseKindOnNode(node, useKind);
1471     }
1472
1473     void observeUseKindOnEdge(Edge edge)
1474     {
1475         observeUseKindOnNode(edge.node(), edge.useKind());
1476     }
1477
1478     void observeUseKindOnNode(Node* node, UseKind useKind)
1479     {
1480         if (node->op() != GetLocal)
1481             return;
1482         
1483         // FIXME: The way this uses alwaysUnboxSimplePrimitives() is suspicious.
1484         // https://bugs.webkit.org/show_bug.cgi?id=121518
1485         
1486         VariableAccessData* variable = node->variableAccessData();
1487         switch (useKind) {
1488         case Int32Use:
1489             if (alwaysUnboxSimplePrimitives()
1490                 || isInt32Speculation(variable->prediction()))
1491                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1492             break;
1493         case NumberUse:
1494         case RealNumberUse:
1495             if (variable->doubleFormatState() == UsingDoubleFormat)
1496                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1497             break;
1498         case BooleanUse:
1499             if (alwaysUnboxSimplePrimitives()
1500                 || isBooleanSpeculation(variable->prediction()))
1501                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1502             break;
1503         case MachineIntUse:
1504             if (isMachineIntSpeculation(variable->prediction()))
1505                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1506             break;
1507         case CellUse:
1508         case KnownCellUse:
1509         case ObjectUse:
1510         case StringUse:
1511         case KnownStringUse:
1512         case StringObjectUse:
1513         case StringOrStringObjectUse:
1514             if (alwaysUnboxSimplePrimitives()
1515                 || isCellSpeculation(variable->prediction()))
1516                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
1517             break;
1518         default:
1519             break;
1520         }
1521     }
1522     
1523     // Set the use kind of the edge and perform any actions that need to be done for
1524     // that use kind, like inserting intermediate conversion nodes. Never call this
1525     // with useKind = UntypedUse explicitly; edges have UntypedUse implicitly and any
1526     // edge that survives fixup and still has UntypedUse will have this method called
1527     // from observeUntypedEdge(). Also, make sure that if you do change the type of an
1528     // edge, you either call fixEdge() or perform the equivalent functionality
1529     // yourself. Obviously, you should have a really good reason if you do the latter.
1530     template<UseKind useKind>
1531     void fixEdge(Edge& edge)
1532     {
1533         if (isDouble(useKind)) {
1534             if (edge->shouldSpeculateInt32ForArithmetic()) {
1535                 injectInt32ToDoubleNode(edge, useKind);
1536                 return;
1537             }
1538             
1539             if (enableInt52() && edge->shouldSpeculateMachineInt()) {
1540                 // Make all double uses of int52 values have an intermediate Int52ToDouble.
1541                 // This is for the same reason as Int52ToValue (see below) except that
1542                 // Int8ToDouble will convert int52's that fit in an int32 into a double
1543                 // rather than trying to create a boxed int32 like Int52ToValue does.
1544                 
1545                 m_requiredPhantoms.append(edge.node());
1546                 Node* result = m_insertionSet.insertNode(
1547                     m_indexInBlock, SpecInt52AsDouble, Int52ToDouble,
1548                     m_currentNode->origin, Edge(edge.node(), NumberUse));
1549                 edge = Edge(result, useKind);
1550                 return;
1551             }
1552         }
1553         
1554         if (enableInt52() && useKind != MachineIntUse
1555             && edge->shouldSpeculateMachineInt() && !edge->shouldSpeculateInt32()) {
1556             // We make all non-int52 uses of int52 values have an intermediate Int52ToValue
1557             // node to ensure that we handle this properly:
1558             //
1559             // a: SomeInt52
1560             // b: ArithAdd(@a, ...)
1561             // c: Call(..., @a)
1562             // d: ArithAdd(@a, ...)
1563             //
1564             // Without an intermediate node and just labeling the uses, we will get:
1565             //
1566             // a: SomeInt52
1567             // b: ArithAdd(Int52:@a, ...)
1568             // c: Call(..., Untyped:@a)
1569             // d: ArithAdd(Int52:@a, ...)
1570             //
1571             // And now the c->Untyped:@a edge will box the value of @a into a double. This
1572             // is bad, because now the d->Int52:@a edge will either have to do double-to-int
1573             // conversions, or will have to OSR exit unconditionally. Alternatively we could
1574             // have the c->Untyped:@a edge box the value by copying rather than in-place.
1575             // But these boxings are also costly so this wouldn't be great.
1576             //
1577             // The solution we use is to always have non-Int52 uses of predicted Int52's use
1578             // an intervening Int52ToValue node:
1579             //
1580             // a: SomeInt52
1581             // b: ArithAdd(Int52:@a, ...)
1582             // x: Int52ToValue(Int52:@a)
1583             // c: Call(..., Untyped:@x)
1584             // d: ArithAdd(Int52:@a, ...)
1585             //
1586             // Note that even if we had multiple non-int52 uses of @a, the multiple
1587             // Int52ToValue's would get CSE'd together. So the boxing would only happen once.
1588             // At the same time, @a would continue to be represented as a native int52.
1589             //
1590             // An alternative would have been to insert ToNativeInt52 nodes on int52 uses of
1591             // int52's. This would have handled the above example but would fall over for:
1592             //
1593             // a: SomeInt52
1594             // b: Call(..., @a)
1595             // c: ArithAdd(@a, ...)
1596             //
1597             // But the solution we use handles the above gracefully.
1598             
1599             m_requiredPhantoms.append(edge.node());
1600             Node* result = m_insertionSet.insertNode(
1601                 m_indexInBlock, SpecInt52, Int52ToValue,
1602                 m_currentNode->origin, Edge(edge.node(), UntypedUse));
1603             edge = Edge(result, useKind);
1604             return;
1605         }
1606         
1607         observeUseKindOnNode<useKind>(edge.node());
1608         
1609         edge.setUseKind(useKind);
1610     }
1611     
1612     void insertStoreBarrier(unsigned indexInBlock, Edge child1, Edge child2 = Edge())
1613     {
1614         Node* barrierNode;
1615         if (!child2)
1616             barrierNode = m_graph.addNode(SpecNone, StoreBarrier, m_currentNode->origin, Edge(child1.node(), child1.useKind()));
1617         else {
1618             barrierNode = m_graph.addNode(SpecNone, ConditionalStoreBarrier, m_currentNode->origin, 
1619                 Edge(child1.node(), child1.useKind()), Edge(child2.node(), child2.useKind()));
1620         }
1621         m_insertionSet.insert(indexInBlock, barrierNode);
1622     }
1623
1624     void fixIntEdge(Edge& edge)
1625     {
1626         Node* node = edge.node();
1627         if (node->shouldSpeculateInt32()) {
1628             fixEdge<Int32Use>(edge);
1629             return;
1630         }
1631         
1632         UseKind useKind;
1633         if (node->shouldSpeculateMachineInt())
1634             useKind = MachineIntUse;
1635         else if (node->shouldSpeculateNumber())
1636             useKind = NumberUse;
1637         else if (node->shouldSpeculateBoolean())
1638             useKind = BooleanUse;
1639         else
1640             useKind = NotCellUse;
1641         Node* newNode = m_insertionSet.insertNode(
1642             m_indexInBlock, SpecInt32, ValueToInt32, m_currentNode->origin,
1643             Edge(node, useKind));
1644         observeUseKindOnNode(node, useKind);
1645         
1646         edge = Edge(newNode, KnownInt32Use);
1647         m_requiredPhantoms.append(node);
1648     }
1649     
1650     void injectInt32ToDoubleNode(Edge& edge, UseKind useKind = NumberUse)
1651     {
1652         m_requiredPhantoms.append(edge.node());
1653         
1654         Node* result = m_insertionSet.insertNode(
1655             m_indexInBlock, SpecInt52AsDouble, Int32ToDouble,
1656             m_currentNode->origin, Edge(edge.node(), NumberUse));
1657         
1658         edge = Edge(result, useKind);
1659     }
1660     
1661     void truncateConstantToInt32(Edge& edge)
1662     {
1663         Node* oldNode = edge.node();
1664         
1665         ASSERT(oldNode->hasConstant());
1666         JSValue value = m_graph.valueOfJSConstant(oldNode);
1667         if (value.isInt32())
1668             return;
1669         
1670         value = jsNumber(JSC::toInt32(value.asNumber()));
1671         ASSERT(value.isInt32());
1672         unsigned constantRegister;
1673         if (!codeBlock()->findConstant(value, constantRegister)) {
1674             constantRegister = codeBlock()->addConstantLazily();
1675             initializeLazyWriteBarrierForConstant(
1676                 m_graph.m_plan.writeBarriers,
1677                 codeBlock()->constants()[constantRegister],
1678                 codeBlock(),
1679                 constantRegister,
1680                 codeBlock()->ownerExecutable(),
1681                 value);
1682         }
1683         edge.setNode(m_insertionSet.insertNode(
1684             m_indexInBlock, SpecInt32, JSConstant, m_currentNode->origin,
1685             OpInfo(constantRegister)));
1686     }
1687     
1688     void truncateConstantsIfNecessary(Node* node, AddSpeculationMode mode)
1689     {
1690         if (mode != SpeculateInt32AndTruncateConstants)
1691             return;
1692         
1693         ASSERT(node->child1()->hasConstant() || node->child2()->hasConstant());
1694         if (node->child1()->hasConstant())
1695             truncateConstantToInt32(node->child1());
1696         else
1697             truncateConstantToInt32(node->child2());
1698     }
1699     
1700     bool attemptToMakeIntegerAdd(Node* node)
1701     {
1702         AddSpeculationMode mode = m_graph.addSpeculationMode(node);
1703         if (mode != DontSpeculateInt32) {
1704             truncateConstantsIfNecessary(node, mode);
1705             fixEdge<Int32Use>(node->child1());
1706             fixEdge<Int32Use>(node->child2());
1707             if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
1708                 node->setArithMode(Arith::Unchecked);
1709             else
1710                 node->setArithMode(Arith::CheckOverflow);
1711             return true;
1712         }
1713         
1714         if (m_graph.addShouldSpeculateMachineInt(node)) {
1715             fixEdge<MachineIntUse>(node->child1());
1716             fixEdge<MachineIntUse>(node->child2());
1717             node->setArithMode(Arith::CheckOverflow);
1718             return true;
1719         }
1720         
1721         return false;
1722     }
1723     
1724     bool attemptToMakeGetArrayLength(Node* node)
1725     {
1726         if (!isInt32Speculation(node->prediction()))
1727             return false;
1728         CodeBlock* profiledBlock = m_graph.baselineCodeBlockFor(node->origin.semantic);
1729         ArrayProfile* arrayProfile = 
1730             profiledBlock->getArrayProfile(node->origin.semantic.bytecodeIndex);
1731         ArrayMode arrayMode = ArrayMode(Array::SelectUsingPredictions);
1732         if (arrayProfile) {
1733             ConcurrentJITLocker locker(profiledBlock->m_lock);
1734             arrayProfile->computeUpdatedPrediction(locker, profiledBlock);
1735             arrayMode = ArrayMode::fromObserved(locker, arrayProfile, Array::Read, false);
1736             if (arrayMode.type() == Array::Unprofiled) {
1737                 // For normal array operations, it makes sense to treat Unprofiled
1738                 // accesses as ForceExit and get more data rather than using
1739                 // predictions and then possibly ending up with a Generic. But here,
1740                 // we treat anything that is Unprofiled as Generic and keep the
1741                 // GetById. I.e. ForceExit = Generic. So, there is no harm - and only
1742                 // profit - from treating the Unprofiled case as
1743                 // SelectUsingPredictions.
1744                 arrayMode = ArrayMode(Array::SelectUsingPredictions);
1745             }
1746         }
1747             
1748         arrayMode = arrayMode.refine(
1749             m_graph, node->origin.semantic, node->child1()->prediction(), node->prediction());
1750             
1751         if (arrayMode.type() == Array::Generic) {
1752             // Check if the input is something that we can't get array length for, but for which we
1753             // could insert some conversions in order to transform it into something that we can do it
1754             // for.
1755             if (node->child1()->shouldSpeculateStringObject())
1756                 attemptToForceStringArrayModeByToStringConversion<StringObjectUse>(arrayMode, node);
1757             else if (node->child1()->shouldSpeculateStringOrStringObject())
1758                 attemptToForceStringArrayModeByToStringConversion<StringOrStringObjectUse>(arrayMode, node);
1759         }
1760             
1761         if (!arrayMode.supportsLength())
1762             return false;
1763         
1764         convertToGetArrayLength(node, arrayMode);
1765         return true;
1766     }
1767     
1768     bool attemptToMakeGetTypedArrayByteLength(Node* node)
1769     {
1770         if (!isInt32Speculation(node->prediction()))
1771             return false;
1772         
1773         TypedArrayType type = typedArrayTypeFromSpeculation(node->child1()->prediction());
1774         if (!isTypedView(type))
1775             return false;
1776         
1777         if (elementSize(type) == 1) {
1778             convertToGetArrayLength(node, ArrayMode(toArrayType(type)));
1779             return true;
1780         }
1781         
1782         Node* length = prependGetArrayLength(
1783             node->origin, node->child1().node(), ArrayMode(toArrayType(type)));
1784         
1785         Node* shiftAmount = m_insertionSet.insertNode(
1786             m_indexInBlock, SpecInt32, JSConstant, node->origin,
1787             OpInfo(m_graph.constantRegisterForConstant(jsNumber(logElementSize(type)))));
1788         
1789         // We can use a BitLShift here because typed arrays will never have a byteLength
1790         // that overflows int32.
1791         node->setOp(BitLShift);
1792         node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
1793         observeUseKindOnNode(length, Int32Use);
1794         observeUseKindOnNode(shiftAmount, Int32Use);
1795         node->child1() = Edge(length, Int32Use);
1796         node->child2() = Edge(shiftAmount, Int32Use);
1797         return true;
1798     }
1799     
1800     void convertToGetArrayLength(Node* node, ArrayMode arrayMode)
1801     {
1802         node->setOp(GetArrayLength);
1803         node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
1804         fixEdge<KnownCellUse>(node->child1());
1805         node->setArrayMode(arrayMode);
1806             
1807         Node* storage = checkArray(arrayMode, node->origin, node->child1().node(), 0, lengthNeedsStorage);
1808         if (!storage)
1809             return;
1810             
1811         node->child2() = Edge(storage);
1812     }
1813     
1814     Node* prependGetArrayLength(NodeOrigin origin, Node* child, ArrayMode arrayMode)
1815     {
1816         Node* storage = checkArray(arrayMode, origin, child, 0, lengthNeedsStorage);
1817         return m_insertionSet.insertNode(
1818             m_indexInBlock, SpecInt32, GetArrayLength, origin,
1819             OpInfo(arrayMode.asWord()), Edge(child, KnownCellUse), Edge(storage));
1820     }
1821     
1822     bool attemptToMakeGetTypedArrayByteOffset(Node* node)
1823     {
1824         if (!isInt32Speculation(node->prediction()))
1825             return false;
1826         
1827         TypedArrayType type = typedArrayTypeFromSpeculation(node->child1()->prediction());
1828         if (!isTypedView(type))
1829             return false;
1830         
1831         checkArray(
1832             ArrayMode(toArrayType(type)), node->origin, node->child1().node(),
1833             0, neverNeedsStorage);
1834         
1835         node->setOp(GetTypedArrayByteOffset);
1836         node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
1837         fixEdge<KnownCellUse>(node->child1());
1838         return true;
1839     }
1840     
1841     void addPhantomsIfNecessary()
1842     {
1843         if (m_requiredPhantoms.isEmpty())
1844             return;
1845         
1846         for (unsigned i = m_requiredPhantoms.size(); i--;) {
1847             m_insertionSet.insertNode(
1848                 m_indexInBlock + 1, SpecNone, Phantom, m_currentNode->origin,
1849                 Edge(m_requiredPhantoms[i], UntypedUse));
1850         }
1851         
1852         m_requiredPhantoms.resize(0);
1853     }
1854
1855     BasicBlock* m_block;
1856     unsigned m_indexInBlock;
1857     Node* m_currentNode;
1858     InsertionSet m_insertionSet;
1859     bool m_profitabilityChanged;
1860     Vector<Node*, 3> m_requiredPhantoms;
1861 };
1862     
1863 bool performFixup(Graph& graph)
1864 {
1865     SamplingRegion samplingRegion("DFG Fixup Phase");
1866     return runPhase<FixupPhase>(graph);
1867 }
1868
1869 } } // namespace JSC::DFG
1870
1871 #endif // ENABLE(DFG_JIT)
1872