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