1/*
2 * Copyright (C) 2012-2019 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 "DFGInsertionSet.h"
34#include "DFGPhase.h"
35#include "DFGPredictionPropagationPhase.h"
36#include "DFGVariableAccessDataDump.h"
37#include "JSCInlines.h"
38#include "TypeLocation.h"
39
40namespace JSC { namespace DFG {
41
42class FixupPhase : public Phase {
43public:
44 FixupPhase(Graph& graph)
45 : Phase(graph, "fixup")
46 , m_insertionSet(graph)
47 {
48 }
49
50 bool run()
51 {
52 ASSERT(m_graph.m_fixpointState == BeforeFixpoint);
53 ASSERT(m_graph.m_form == ThreadedCPS);
54
55 m_profitabilityChanged = false;
56 for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
57 fixupBlock(m_graph.block(blockIndex));
58
59 while (m_profitabilityChanged) {
60 m_profitabilityChanged = false;
61
62 for (unsigned i = m_graph.m_argumentPositions.size(); i--;)
63 m_graph.m_argumentPositions[i].mergeArgumentUnboxingAwareness();
64
65 for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
66 fixupGetAndSetLocalsInBlock(m_graph.block(blockIndex));
67 }
68
69 for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
70 fixupChecksInBlock(m_graph.block(blockIndex));
71
72 m_graph.m_planStage = PlanStage::AfterFixup;
73
74 return true;
75 }
76
77private:
78
79 void fixupArithDivInt32(Node* node, Edge& leftChild, Edge& rightChild)
80 {
81 if (optimizeForX86() || optimizeForARM64() || optimizeForARMv7IDIVSupported()) {
82 fixIntOrBooleanEdge(leftChild);
83 fixIntOrBooleanEdge(rightChild);
84 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
85 node->setArithMode(Arith::Unchecked);
86 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
87 node->setArithMode(Arith::CheckOverflow);
88 else
89 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
90 return;
91 }
92
93 // This will cause conversion nodes to be inserted later.
94 fixDoubleOrBooleanEdge(leftChild);
95 fixDoubleOrBooleanEdge(rightChild);
96
97 // We don't need to do ref'ing on the children because we're stealing them from
98 // the original division.
99 Node* newDivision = m_insertionSet.insertNode(m_indexInBlock, SpecBytecodeDouble, *node);
100 newDivision->setResult(NodeResultDouble);
101
102 node->setOp(DoubleAsInt32);
103 node->children.initialize(Edge(newDivision, DoubleRepUse), Edge(), Edge());
104 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
105 node->setArithMode(Arith::CheckOverflow);
106 else
107 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
108
109 }
110
111 void fixupArithDiv(Node* node, Edge& leftChild, Edge& rightChild)
112 {
113 if (m_graph.binaryArithShouldSpeculateInt32(node, FixupPass)) {
114 fixupArithDivInt32(node, leftChild, rightChild);
115 return;
116 }
117
118 fixDoubleOrBooleanEdge(leftChild);
119 fixDoubleOrBooleanEdge(rightChild);
120 node->setResult(NodeResultDouble);
121 }
122
123 void fixupArithMul(Node* node, Edge& leftChild, Edge& rightChild)
124 {
125 if (m_graph.binaryArithShouldSpeculateInt32(node, FixupPass)) {
126 fixIntOrBooleanEdge(leftChild);
127 fixIntOrBooleanEdge(rightChild);
128 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
129 node->setArithMode(Arith::Unchecked);
130 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()) || leftChild.node() == rightChild.node())
131 node->setArithMode(Arith::CheckOverflow);
132 else
133 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
134 return;
135 }
136 if (m_graph.binaryArithShouldSpeculateInt52(node, FixupPass)) {
137 fixEdge<Int52RepUse>(leftChild);
138 fixEdge<Int52RepUse>(rightChild);
139 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()) || leftChild.node() == rightChild.node())
140 node->setArithMode(Arith::CheckOverflow);
141 else
142 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
143 node->setResult(NodeResultInt52);
144 return;
145 }
146
147 fixDoubleOrBooleanEdge(leftChild);
148 fixDoubleOrBooleanEdge(rightChild);
149 node->setResult(NodeResultDouble);
150 }
151
152 void fixupBlock(BasicBlock* block)
153 {
154 if (!block)
155 return;
156 ASSERT(block->isReachable);
157 m_block = block;
158 for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
159 m_currentNode = block->at(m_indexInBlock);
160 fixupNode(m_currentNode);
161 }
162 m_insertionSet.execute(block);
163 }
164
165 void fixupNode(Node* node)
166 {
167 NodeType op = node->op();
168
169 switch (op) {
170 case SetLocal: {
171 // This gets handled by fixupGetAndSetLocalsInBlock().
172 return;
173 }
174
175 case ValueSub: {
176 Edge& child1 = node->child1();
177 Edge& child2 = node->child2();
178
179 if (Node::shouldSpeculateBigInt(child1.node(), child2.node())) {
180 fixEdge<BigIntUse>(child1);
181 fixEdge<BigIntUse>(child2);
182 break;
183 }
184
185 if (Node::shouldSpeculateUntypedForArithmetic(node->child1().node(), node->child2().node())) {
186 fixEdge<UntypedUse>(child1);
187 fixEdge<UntypedUse>(child2);
188 break;
189 }
190
191 if (attemptToMakeIntegerAdd(node)) {
192 // FIXME: Clear ArithSub's NodeMustGenerate when ArithMode is unchecked
193 // https://bugs.webkit.org/show_bug.cgi?id=190607
194 node->setOp(ArithSub);
195 break;
196 }
197
198 fixDoubleOrBooleanEdge(node->child1());
199 fixDoubleOrBooleanEdge(node->child2());
200 node->setOp(ArithSub);
201 node->setResult(NodeResultDouble);
202
203 break;
204 }
205
206 case ValueBitXor:
207 case ValueBitOr:
208 case ValueBitAnd: {
209 if (Node::shouldSpeculateBigInt(node->child1().node(), node->child2().node())) {
210 fixEdge<BigIntUse>(node->child1());
211 fixEdge<BigIntUse>(node->child2());
212 break;
213 }
214
215 if (Node::shouldSpeculateUntypedForBitOps(node->child1().node(), node->child2().node())) {
216 fixEdge<UntypedUse>(node->child1());
217 fixEdge<UntypedUse>(node->child2());
218 break;
219 }
220
221 // In such case, we need to fallback to ArithBitOp
222 switch (op) {
223 case ValueBitXor:
224 node->setOp(ArithBitXor);
225 break;
226 case ValueBitOr:
227 node->setOp(ArithBitOr);
228 break;
229 case ValueBitAnd:
230 node->setOp(ArithBitAnd);
231 break;
232 default:
233 DFG_CRASH(m_graph, node, "Unexpected node during ValueBit operation fixup");
234 break;
235 }
236
237 node->clearFlags(NodeMustGenerate);
238 node->setResult(NodeResultInt32);
239 fixIntConvertingEdge(node->child1());
240 fixIntConvertingEdge(node->child2());
241 break;
242 }
243
244 case ValueBitNot: {
245 Edge& operandEdge = node->child1();
246
247 if (operandEdge.node()->shouldSpeculateBigInt()) {
248 node->clearFlags(NodeMustGenerate);
249 fixEdge<BigIntUse>(operandEdge);
250 } else if (operandEdge.node()->shouldSpeculateUntypedForBitOps())
251 fixEdge<UntypedUse>(operandEdge);
252 else {
253 node->setOp(ArithBitNot);
254 node->setResult(NodeResultInt32);
255 node->clearFlags(NodeMustGenerate);
256 fixIntConvertingEdge(operandEdge);
257 }
258 break;
259 }
260
261 case ArithBitNot: {
262 Edge& operandEdge = node->child1();
263
264 fixIntConvertingEdge(operandEdge);
265 break;
266 }
267
268 case ArithBitXor:
269 case ArithBitOr:
270 case ArithBitAnd: {
271 fixIntConvertingEdge(node->child1());
272 fixIntConvertingEdge(node->child2());
273 break;
274 }
275
276 case BitRShift:
277 case BitLShift:
278 case BitURShift: {
279 if (Node::shouldSpeculateUntypedForBitOps(node->child1().node(), node->child2().node())) {
280 fixEdge<UntypedUse>(node->child1());
281 fixEdge<UntypedUse>(node->child2());
282 break;
283 }
284 fixIntConvertingEdge(node->child1());
285 fixIntConvertingEdge(node->child2());
286 break;
287 }
288
289 case ArithIMul: {
290 fixIntConvertingEdge(node->child1());
291 fixIntConvertingEdge(node->child2());
292 node->setOp(ArithMul);
293 node->setArithMode(Arith::Unchecked);
294 node->child1().setUseKind(Int32Use);
295 node->child2().setUseKind(Int32Use);
296 break;
297 }
298
299 case ArithClz32: {
300 if (node->child1()->shouldSpeculateNotCell()) {
301 fixIntConvertingEdge(node->child1());
302 node->clearFlags(NodeMustGenerate);
303 } else
304 fixEdge<UntypedUse>(node->child1());
305 break;
306 }
307
308 case UInt32ToNumber: {
309 fixIntConvertingEdge(node->child1());
310 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
311 node->convertToIdentity();
312 else if (node->canSpeculateInt32(FixupPass))
313 node->setArithMode(Arith::CheckOverflow);
314 else {
315 node->setArithMode(Arith::DoOverflow);
316 node->setResult(enableInt52() ? NodeResultInt52 : NodeResultDouble);
317 }
318 break;
319 }
320
321 case ValueNegate: {
322 if (node->child1()->shouldSpeculateInt32OrBoolean() && node->canSpeculateInt32(FixupPass)) {
323 node->setOp(ArithNegate);
324 fixIntOrBooleanEdge(node->child1());
325 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
326 node->setArithMode(Arith::Unchecked);
327 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
328 node->setArithMode(Arith::CheckOverflow);
329 else
330 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
331 node->setResult(NodeResultInt32);
332 node->clearFlags(NodeMustGenerate);
333 break;
334 }
335
336 if (m_graph.unaryArithShouldSpeculateInt52(node, FixupPass)) {
337 node->setOp(ArithNegate);
338 fixEdge<Int52RepUse>(node->child1());
339 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
340 node->setArithMode(Arith::CheckOverflow);
341 else
342 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
343 node->setResult(NodeResultInt52);
344 node->clearFlags(NodeMustGenerate);
345 break;
346 }
347 if (node->child1()->shouldSpeculateNotCell()) {
348 node->setOp(ArithNegate);
349 fixDoubleOrBooleanEdge(node->child1());
350 node->setResult(NodeResultDouble);
351 node->clearFlags(NodeMustGenerate);
352 } else {
353 fixEdge<UntypedUse>(node->child1());
354 node->setResult(NodeResultJS);
355 }
356 break;
357 }
358
359 case ValueAdd: {
360 if (attemptToMakeIntegerAdd(node)) {
361 node->setOp(ArithAdd);
362 break;
363 }
364 if (Node::shouldSpeculateNumberOrBooleanExpectingDefined(node->child1().node(), node->child2().node())) {
365 fixDoubleOrBooleanEdge(node->child1());
366 fixDoubleOrBooleanEdge(node->child2());
367 node->setOp(ArithAdd);
368 node->setResult(NodeResultDouble);
369 break;
370 }
371
372 if (attemptToMakeFastStringAdd(node))
373 break;
374
375 Edge& child1 = node->child1();
376 Edge& child2 = node->child2();
377 if (child1->shouldSpeculateString() || child2->shouldSpeculateString()) {
378 if (child1->shouldSpeculateInt32() || child2->shouldSpeculateInt32()) {
379 auto convertString = [&](Node* node, Edge& edge) {
380 if (edge->shouldSpeculateInt32())
381 convertStringAddUse<Int32Use>(node, edge);
382 else {
383 ASSERT(edge->shouldSpeculateString());
384 convertStringAddUse<StringUse>(node, edge);
385 }
386 };
387 convertString(node, child1);
388 convertString(node, child2);
389 convertToMakeRope(node);
390 break;
391 }
392 }
393
394 if (Node::shouldSpeculateBigInt(child1.node(), child2.node())) {
395 fixEdge<BigIntUse>(child1);
396 fixEdge<BigIntUse>(child2);
397 } else {
398 fixEdge<UntypedUse>(child1);
399 fixEdge<UntypedUse>(child2);
400 }
401
402 node->setResult(NodeResultJS);
403 break;
404 }
405
406 case StrCat: {
407 if (attemptToMakeFastStringAdd(node))
408 break;
409
410 // FIXME: Remove empty string arguments and possibly turn this into a ToString operation. That
411 // would require a form of ToString that takes a KnownPrimitiveUse. This is necessary because
412 // the implementation of StrCat doesn't dynamically optimize for empty strings.
413 // https://bugs.webkit.org/show_bug.cgi?id=148540
414 m_graph.doToChildren(
415 node,
416 [&] (Edge& edge) {
417 fixEdge<KnownPrimitiveUse>(edge);
418 // StrCat automatically coerces the values into strings before concatenating them.
419 // The ECMA spec says that we're not allowed to automatically coerce a Symbol into
420 // a string. If a Symbol is encountered, a TypeError will be thrown. As a result,
421 // our runtime functions for this slow path expect that they will never be passed
422 // Symbols.
423 m_insertionSet.insertNode(
424 m_indexInBlock, SpecNone, Check, node->origin,
425 Edge(edge.node(), NotSymbolUse));
426 });
427 break;
428 }
429
430 case MakeRope: {
431 fixupMakeRope(node);
432 break;
433 }
434
435 case ArithAdd:
436 case ArithSub: {
437 // FIXME: Clear ArithSub's NodeMustGenerate when ArithMode is unchecked
438 // https://bugs.webkit.org/show_bug.cgi?id=190607
439 if (attemptToMakeIntegerAdd(node))
440 break;
441 fixDoubleOrBooleanEdge(node->child1());
442 fixDoubleOrBooleanEdge(node->child2());
443 node->setResult(NodeResultDouble);
444 break;
445 }
446
447 case ArithNegate: {
448 if (node->child1()->shouldSpeculateInt32OrBoolean() && node->canSpeculateInt32(FixupPass)) {
449 fixIntOrBooleanEdge(node->child1());
450 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
451 node->setArithMode(Arith::Unchecked);
452 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
453 node->setArithMode(Arith::CheckOverflow);
454 else
455 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
456 node->setResult(NodeResultInt32);
457 node->clearFlags(NodeMustGenerate);
458 break;
459 }
460 if (m_graph.unaryArithShouldSpeculateInt52(node, FixupPass)) {
461 fixEdge<Int52RepUse>(node->child1());
462 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
463 node->setArithMode(Arith::CheckOverflow);
464 else
465 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
466 node->setResult(NodeResultInt52);
467 node->clearFlags(NodeMustGenerate);
468 break;
469 }
470
471 fixDoubleOrBooleanEdge(node->child1());
472 node->setResult(NodeResultDouble);
473 node->clearFlags(NodeMustGenerate);
474 break;
475 }
476
477 case ValueMul: {
478 Edge& leftChild = node->child1();
479 Edge& rightChild = node->child2();
480
481 if (Node::shouldSpeculateBigInt(leftChild.node(), rightChild.node())) {
482 fixEdge<BigIntUse>(node->child1());
483 fixEdge<BigIntUse>(node->child2());
484 node->clearFlags(NodeMustGenerate);
485 break;
486 }
487
488 // There are cases where we can have BigInt + Int32 operands reaching ValueMul.
489 // Imagine the scenario where ValueMul was never executed, but we can predict types
490 // reaching the node:
491 //
492 // 63: GetLocal(Check:Untyped:@72, JS|MustGen, NonBoolInt32, ...) predicting NonBoolInt32
493 // 64: GetLocal(Check:Untyped:@71, JS|MustGen, BigInt, ...) predicting BigInt
494 // 65: ValueMul(Check:Untyped:@63, Check:Untyped:@64, BigInt|BoolInt32|NonBoolInt32, ...)
495 //
496 // In such scenario, we need to emit ValueMul(Untyped, Untyped), so the runtime can throw
497 // an exception whenever it gets excuted.
498 if (Node::shouldSpeculateUntypedForArithmetic(leftChild.node(), rightChild.node())) {
499 fixEdge<UntypedUse>(leftChild);
500 fixEdge<UntypedUse>(rightChild);
501 break;
502 }
503
504 // At this point, all other possible specializations are only handled by ArithMul.
505 node->setOp(ArithMul);
506 node->setResult(NodeResultNumber);
507 fixupArithMul(node, leftChild, rightChild);
508 break;
509 }
510
511 case ArithMul: {
512 Edge& leftChild = node->child1();
513 Edge& rightChild = node->child2();
514
515 fixupArithMul(node, leftChild, rightChild);
516 break;
517 }
518
519 case ValueMod:
520 case ValueDiv: {
521 Edge& leftChild = node->child1();
522 Edge& rightChild = node->child2();
523
524 if (Node::shouldSpeculateBigInt(leftChild.node(), rightChild.node())) {
525 fixEdge<BigIntUse>(leftChild);
526 fixEdge<BigIntUse>(rightChild);
527 node->clearFlags(NodeMustGenerate);
528 break;
529 }
530
531 if (Node::shouldSpeculateUntypedForArithmetic(leftChild.node(), rightChild.node())) {
532 fixEdge<UntypedUse>(leftChild);
533 fixEdge<UntypedUse>(rightChild);
534 break;
535 }
536
537 if (op == ValueDiv)
538 node->setOp(ArithDiv);
539 else
540 node->setOp(ArithMod);
541
542 node->setResult(NodeResultNumber);
543 fixupArithDiv(node, leftChild, rightChild);
544 break;
545
546 }
547
548 case ArithDiv:
549 case ArithMod: {
550 Edge& leftChild = node->child1();
551 Edge& rightChild = node->child2();
552
553 fixupArithDiv(node, leftChild, rightChild);
554 break;
555 }
556
557 case ArithMin:
558 case ArithMax: {
559 if (m_graph.binaryArithShouldSpeculateInt32(node, FixupPass)) {
560 fixIntOrBooleanEdge(node->child1());
561 fixIntOrBooleanEdge(node->child2());
562 break;
563 }
564 fixDoubleOrBooleanEdge(node->child1());
565 fixDoubleOrBooleanEdge(node->child2());
566 node->setResult(NodeResultDouble);
567 break;
568 }
569
570 case ArithAbs: {
571 if (node->child1()->shouldSpeculateInt32OrBoolean()
572 && node->canSpeculateInt32(FixupPass)) {
573 fixIntOrBooleanEdge(node->child1());
574 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
575 node->setArithMode(Arith::Unchecked);
576 else
577 node->setArithMode(Arith::CheckOverflow);
578 node->clearFlags(NodeMustGenerate);
579 node->setResult(NodeResultInt32);
580 break;
581 }
582
583 if (node->child1()->shouldSpeculateNotCell()) {
584 fixDoubleOrBooleanEdge(node->child1());
585 node->clearFlags(NodeMustGenerate);
586 } else
587 fixEdge<UntypedUse>(node->child1());
588 node->setResult(NodeResultDouble);
589 break;
590 }
591
592 case ArithPow: {
593 if (node->child2()->shouldSpeculateInt32OrBooleanForArithmetic()) {
594 fixDoubleOrBooleanEdge(node->child1());
595 fixIntOrBooleanEdge(node->child2());
596 break;
597 }
598
599 fixDoubleOrBooleanEdge(node->child1());
600 fixDoubleOrBooleanEdge(node->child2());
601 break;
602 }
603
604 case ArithRandom: {
605 node->setResult(NodeResultDouble);
606 break;
607 }
608
609 case ArithRound:
610 case ArithFloor:
611 case ArithCeil:
612 case ArithTrunc: {
613 if (node->child1()->shouldSpeculateInt32OrBoolean() && m_graph.roundShouldSpeculateInt32(node, FixupPass)) {
614 fixIntOrBooleanEdge(node->child1());
615 insertCheck<Int32Use>(node->child1().node());
616 node->convertToIdentity();
617 break;
618 }
619 if (node->child1()->shouldSpeculateNotCell()) {
620 fixDoubleOrBooleanEdge(node->child1());
621
622 if (isInt32OrBooleanSpeculation(node->getHeapPrediction()) && m_graph.roundShouldSpeculateInt32(node, FixupPass)) {
623 node->setResult(NodeResultInt32);
624 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
625 node->setArithRoundingMode(Arith::RoundingMode::Int32);
626 else
627 node->setArithRoundingMode(Arith::RoundingMode::Int32WithNegativeZeroCheck);
628 } else {
629 node->setResult(NodeResultDouble);
630 node->setArithRoundingMode(Arith::RoundingMode::Double);
631 }
632 node->clearFlags(NodeMustGenerate);
633 } else
634 fixEdge<UntypedUse>(node->child1());
635 break;
636 }
637
638 case ArithFRound:
639 case ArithSqrt:
640 case ArithUnary: {
641 Edge& child1 = node->child1();
642 if (child1->shouldSpeculateNotCell()) {
643 fixDoubleOrBooleanEdge(child1);
644 node->clearFlags(NodeMustGenerate);
645 } else
646 fixEdge<UntypedUse>(child1);
647 break;
648 }
649
650 case LogicalNot: {
651 if (node->child1()->shouldSpeculateBoolean()) {
652 if (node->child1()->result() == NodeResultBoolean) {
653 // This is necessary in case we have a bytecode instruction implemented by:
654 //
655 // a: CompareEq(...)
656 // b: LogicalNot(@a)
657 //
658 // In that case, CompareEq might have a side-effect. Then, we need to make
659 // sure that we know that Branch does not exit.
660 fixEdge<KnownBooleanUse>(node->child1());
661 } else
662 fixEdge<BooleanUse>(node->child1());
663 } else if (node->child1()->shouldSpeculateObjectOrOther())
664 fixEdge<ObjectOrOtherUse>(node->child1());
665 else if (node->child1()->shouldSpeculateInt32OrBoolean())
666 fixIntOrBooleanEdge(node->child1());
667 else if (node->child1()->shouldSpeculateNumber())
668 fixEdge<DoubleRepUse>(node->child1());
669 else if (node->child1()->shouldSpeculateString())
670 fixEdge<StringUse>(node->child1());
671 else if (node->child1()->shouldSpeculateStringOrOther())
672 fixEdge<StringOrOtherUse>(node->child1());
673 else {
674 WatchpointSet* masqueradesAsUndefinedWatchpoint = m_graph.globalObjectFor(node->origin.semantic)->masqueradesAsUndefinedWatchpoint();
675 if (masqueradesAsUndefinedWatchpoint->isStillValid())
676 m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
677 }
678 break;
679 }
680
681 case CompareEq:
682 case CompareLess:
683 case CompareLessEq:
684 case CompareGreater:
685 case CompareGreaterEq: {
686 if (node->op() == CompareEq
687 && Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
688 fixEdge<BooleanUse>(node->child1());
689 fixEdge<BooleanUse>(node->child2());
690 node->clearFlags(NodeMustGenerate);
691 break;
692 }
693 if (Node::shouldSpeculateInt32OrBoolean(node->child1().node(), node->child2().node())) {
694 fixIntOrBooleanEdge(node->child1());
695 fixIntOrBooleanEdge(node->child2());
696 node->clearFlags(NodeMustGenerate);
697 break;
698 }
699 if (Node::shouldSpeculateInt52(node->child1().node(), node->child2().node())) {
700 fixEdge<Int52RepUse>(node->child1());
701 fixEdge<Int52RepUse>(node->child2());
702 node->clearFlags(NodeMustGenerate);
703 break;
704 }
705 if (Node::shouldSpeculateNumberOrBoolean(node->child1().node(), node->child2().node())) {
706 fixDoubleOrBooleanEdge(node->child1());
707 fixDoubleOrBooleanEdge(node->child2());
708 }
709 if (node->op() != CompareEq
710 && node->child1()->shouldSpeculateNotCell()
711 && node->child2()->shouldSpeculateNotCell()) {
712 if (node->child1()->shouldSpeculateNumberOrBoolean())
713 fixDoubleOrBooleanEdge(node->child1());
714 else
715 fixEdge<DoubleRepUse>(node->child1());
716 if (node->child2()->shouldSpeculateNumberOrBoolean())
717 fixDoubleOrBooleanEdge(node->child2());
718 else
719 fixEdge<DoubleRepUse>(node->child2());
720 node->clearFlags(NodeMustGenerate);
721 break;
722 }
723 if (node->child1()->shouldSpeculateStringIdent() && node->child2()->shouldSpeculateStringIdent()) {
724 fixEdge<StringIdentUse>(node->child1());
725 fixEdge<StringIdentUse>(node->child2());
726 node->clearFlags(NodeMustGenerate);
727 break;
728 }
729 if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && GPRInfo::numberOfRegisters >= 7) {
730 fixEdge<StringUse>(node->child1());
731 fixEdge<StringUse>(node->child2());
732 node->clearFlags(NodeMustGenerate);
733 break;
734 }
735
736 if (node->op() != CompareEq)
737 break;
738 if (Node::shouldSpeculateSymbol(node->child1().node(), node->child2().node())) {
739 fixEdge<SymbolUse>(node->child1());
740 fixEdge<SymbolUse>(node->child2());
741 node->clearFlags(NodeMustGenerate);
742 break;
743 }
744 if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
745 fixEdge<ObjectUse>(node->child1());
746 fixEdge<ObjectUse>(node->child2());
747 node->clearFlags(NodeMustGenerate);
748 break;
749 }
750
751 // If either child can be proved to be Null or Undefined, comparing them is greatly simplified.
752 bool oneArgumentIsUsedAsSpecOther = false;
753 if (node->child1()->isUndefinedOrNullConstant()) {
754 fixEdge<KnownOtherUse>(node->child1());
755 oneArgumentIsUsedAsSpecOther = true;
756 } else if (node->child1()->shouldSpeculateOther()) {
757 m_insertionSet.insertNode(m_indexInBlock, SpecNone, Check, node->origin,
758 Edge(node->child1().node(), OtherUse));
759 fixEdge<KnownOtherUse>(node->child1());
760 oneArgumentIsUsedAsSpecOther = true;
761 }
762 if (node->child2()->isUndefinedOrNullConstant()) {
763 fixEdge<KnownOtherUse>(node->child2());
764 oneArgumentIsUsedAsSpecOther = true;
765 } else if (node->child2()->shouldSpeculateOther()) {
766 m_insertionSet.insertNode(m_indexInBlock, SpecNone, Check, node->origin,
767 Edge(node->child2().node(), OtherUse));
768 fixEdge<KnownOtherUse>(node->child2());
769 oneArgumentIsUsedAsSpecOther = true;
770 }
771 if (oneArgumentIsUsedAsSpecOther) {
772 node->clearFlags(NodeMustGenerate);
773 break;
774 }
775
776 if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObjectOrOther()) {
777 fixEdge<ObjectUse>(node->child1());
778 fixEdge<ObjectOrOtherUse>(node->child2());
779 node->clearFlags(NodeMustGenerate);
780 break;
781 }
782 if (node->child1()->shouldSpeculateObjectOrOther() && node->child2()->shouldSpeculateObject()) {
783 fixEdge<ObjectOrOtherUse>(node->child1());
784 fixEdge<ObjectUse>(node->child2());
785 node->clearFlags(NodeMustGenerate);
786 break;
787 }
788
789 break;
790 }
791
792 case CompareStrictEq:
793 case SameValue: {
794 fixupCompareStrictEqAndSameValue(node);
795 break;
796 }
797
798 case StringFromCharCode:
799 if (node->child1()->shouldSpeculateInt32()) {
800 fixEdge<Int32Use>(node->child1());
801 node->clearFlags(NodeMustGenerate);
802 } else
803 fixEdge<UntypedUse>(node->child1());
804 break;
805
806 case StringCharAt:
807 case StringCharCodeAt: {
808 // Currently we have no good way of refining these.
809 ASSERT(node->arrayMode() == ArrayMode(Array::String, Array::Read));
810 blessArrayOperation(node->child1(), node->child2(), node->child3());
811 fixEdge<KnownStringUse>(node->child1());
812 fixEdge<Int32Use>(node->child2());
813 break;
814 }
815
816 case GetByVal: {
817 if (!node->prediction()) {
818 m_insertionSet.insertNode(
819 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
820 }
821
822 node->setArrayMode(
823 node->arrayMode().refine(
824 m_graph, node,
825 m_graph.varArgChild(node, 0)->prediction(),
826 m_graph.varArgChild(node, 1)->prediction(),
827 SpecNone));
828
829 blessArrayOperation(m_graph.varArgChild(node, 0), m_graph.varArgChild(node, 1), m_graph.varArgChild(node, 2));
830
831 ArrayMode arrayMode = node->arrayMode();
832 switch (arrayMode.type()) {
833 case Array::Contiguous:
834 case Array::Double:
835 if (arrayMode.isJSArrayWithOriginalStructure() && arrayMode.speculation() == Array::InBounds) {
836 // Check if SaneChain will work on a per-type basis. Note that:
837 //
838 // 1) We don't want double arrays to sometimes return undefined, since
839 // that would require a change to the return type and it would pessimise
840 // things a lot. So, we'd only want to do that if we actually had
841 // evidence that we could read from a hole. That's pretty annoying.
842 // Likely the best way to handle that case is with an equivalent of
843 // SaneChain for OutOfBounds. For now we just detect when Undefined and
844 // NaN are indistinguishable according to backwards propagation, and just
845 // use SaneChain in that case. This happens to catch a lot of cases.
846 //
847 // 2) We don't want int32 array loads to have to do a hole check just to
848 // coerce to Undefined, since that would mean twice the checks.
849 //
850 // This has two implications. First, we have to do more checks than we'd
851 // like. It's unfortunate that we have to do the hole check. Second,
852 // some accesses that hit a hole will now need to take the full-blown
853 // out-of-bounds slow path. We can fix that with:
854 // https://bugs.webkit.org/show_bug.cgi?id=144668
855
856 bool canDoSaneChain = false;
857 switch (arrayMode.type()) {
858 case Array::Contiguous:
859 // This is happens to be entirely natural. We already would have
860 // returned any JSValue, and now we'll return Undefined. We still do
861 // the check but it doesn't require taking any kind of slow path.
862 canDoSaneChain = true;
863 break;
864
865 case Array::Double:
866 if (!(node->flags() & NodeBytecodeUsesAsOther)) {
867 // Holes look like NaN already, so if the user doesn't care
868 // about the difference between Undefined and NaN then we can
869 // do this.
870 canDoSaneChain = true;
871 }
872 break;
873
874 default:
875 break;
876 }
877
878 if (canDoSaneChain) {
879 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
880 Structure* arrayPrototypeStructure = globalObject->arrayPrototype()->structure(vm());
881 Structure* objectPrototypeStructure = globalObject->objectPrototype()->structure(vm());
882 if (arrayPrototypeStructure->transitionWatchpointSetIsStillValid()
883 && objectPrototypeStructure->transitionWatchpointSetIsStillValid()
884 && globalObject->arrayPrototypeChainIsSane()) {
885 m_graph.registerAndWatchStructureTransition(arrayPrototypeStructure);
886 m_graph.registerAndWatchStructureTransition(objectPrototypeStructure);
887 node->setArrayMode(arrayMode.withSpeculation(Array::SaneChain));
888 }
889 }
890 }
891 break;
892
893 case Array::String:
894 if ((node->prediction() & ~SpecString)
895 || m_graph.hasExitSite(node->origin.semantic, OutOfBounds))
896 node->setArrayMode(arrayMode.withSpeculation(Array::OutOfBounds));
897 break;
898
899 default:
900 break;
901 }
902
903 arrayMode = node->arrayMode();
904 switch (arrayMode.type()) {
905 case Array::SelectUsingPredictions:
906 case Array::Unprofiled:
907 RELEASE_ASSERT_NOT_REACHED();
908 break;
909 case Array::Generic:
910 if (m_graph.varArgChild(node, 0)->shouldSpeculateObject()) {
911 if (m_graph.varArgChild(node, 1)->shouldSpeculateString()) {
912 fixEdge<ObjectUse>(m_graph.varArgChild(node, 0));
913 fixEdge<StringUse>(m_graph.varArgChild(node, 1));
914 break;
915 }
916
917 if (m_graph.varArgChild(node, 1)->shouldSpeculateSymbol()) {
918 fixEdge<ObjectUse>(m_graph.varArgChild(node, 0));
919 fixEdge<SymbolUse>(m_graph.varArgChild(node, 1));
920 break;
921 }
922 }
923#if USE(JSVALUE32_64)
924 fixEdge<CellUse>(m_graph.varArgChild(node, 0)); // Speculating cell due to register pressure on 32-bit.
925#endif
926 break;
927 case Array::ForceExit:
928 break;
929 case Array::String:
930 fixEdge<KnownStringUse>(m_graph.varArgChild(node, 0));
931 fixEdge<Int32Use>(m_graph.varArgChild(node, 1));
932 break;
933 default:
934 fixEdge<KnownCellUse>(m_graph.varArgChild(node, 0));
935 fixEdge<Int32Use>(m_graph.varArgChild(node, 1));
936 break;
937 }
938
939 switch (arrayMode.type()) {
940 case Array::Double:
941 if (!arrayMode.isOutOfBounds())
942 node->setResult(NodeResultDouble);
943 break;
944
945 case Array::Float32Array:
946 case Array::Float64Array:
947 node->setResult(NodeResultDouble);
948 break;
949
950 case Array::Uint32Array:
951 if (node->shouldSpeculateInt32())
952 break;
953 if (node->shouldSpeculateInt52())
954 node->setResult(NodeResultInt52);
955 else
956 node->setResult(NodeResultDouble);
957 break;
958
959 default:
960 break;
961 }
962
963 break;
964 }
965
966 case PutByValDirect:
967 case PutByVal:
968 case PutByValAlias: {
969 Edge& child1 = m_graph.varArgChild(node, 0);
970 Edge& child2 = m_graph.varArgChild(node, 1);
971 Edge& child3 = m_graph.varArgChild(node, 2);
972
973 node->setArrayMode(
974 node->arrayMode().refine(
975 m_graph, node,
976 child1->prediction(),
977 child2->prediction(),
978 child3->prediction()));
979
980 blessArrayOperation(child1, child2, m_graph.varArgChild(node, 3));
981
982 switch (node->arrayMode().modeForPut().type()) {
983 case Array::SelectUsingPredictions:
984 case Array::SelectUsingArguments:
985 case Array::Unprofiled:
986 case Array::Undecided:
987 RELEASE_ASSERT_NOT_REACHED();
988 break;
989 case Array::ForceExit:
990 case Array::Generic:
991 if (child1->shouldSpeculateCell()) {
992 if (child2->shouldSpeculateString()) {
993 fixEdge<CellUse>(child1);
994 fixEdge<StringUse>(child2);
995 break;
996 }
997
998 if (child2->shouldSpeculateSymbol()) {
999 fixEdge<CellUse>(child1);
1000 fixEdge<SymbolUse>(child2);
1001 break;
1002 }
1003 }
1004#if USE(JSVALUE32_64)
1005 // Due to register pressure on 32-bit, we speculate cell and
1006 // ignore the base-is-not-cell case entirely by letting the
1007 // baseline JIT handle it.
1008 fixEdge<CellUse>(child1);
1009#endif
1010 break;
1011 case Array::Int32:
1012 fixEdge<KnownCellUse>(child1);
1013 fixEdge<Int32Use>(child2);
1014 fixEdge<Int32Use>(child3);
1015 break;
1016 case Array::Double:
1017 fixEdge<KnownCellUse>(child1);
1018 fixEdge<Int32Use>(child2);
1019 fixEdge<DoubleRepRealUse>(child3);
1020 break;
1021 case Array::Int8Array:
1022 case Array::Int16Array:
1023 case Array::Int32Array:
1024 case Array::Uint8Array:
1025 case Array::Uint8ClampedArray:
1026 case Array::Uint16Array:
1027 case Array::Uint32Array:
1028 fixEdge<KnownCellUse>(child1);
1029 fixEdge<Int32Use>(child2);
1030 if (child3->shouldSpeculateInt32())
1031 fixIntOrBooleanEdge(child3);
1032 else if (child3->shouldSpeculateInt52())
1033 fixEdge<Int52RepUse>(child3);
1034 else
1035 fixDoubleOrBooleanEdge(child3);
1036 break;
1037 case Array::Float32Array:
1038 case Array::Float64Array:
1039 fixEdge<KnownCellUse>(child1);
1040 fixEdge<Int32Use>(child2);
1041 fixDoubleOrBooleanEdge(child3);
1042 break;
1043 case Array::Contiguous:
1044 case Array::ArrayStorage:
1045 case Array::SlowPutArrayStorage:
1046 fixEdge<KnownCellUse>(child1);
1047 fixEdge<Int32Use>(child2);
1048 speculateForBarrier(child3);
1049 break;
1050 default:
1051 fixEdge<KnownCellUse>(child1);
1052 fixEdge<Int32Use>(child2);
1053 break;
1054 }
1055 break;
1056 }
1057
1058 case AtomicsAdd:
1059 case AtomicsAnd:
1060 case AtomicsCompareExchange:
1061 case AtomicsExchange:
1062 case AtomicsLoad:
1063 case AtomicsOr:
1064 case AtomicsStore:
1065 case AtomicsSub:
1066 case AtomicsXor: {
1067 Edge& base = m_graph.child(node, 0);
1068 Edge& index = m_graph.child(node, 1);
1069
1070 bool badNews = false;
1071 for (unsigned i = numExtraAtomicsArgs(node->op()); i--;) {
1072 Edge& child = m_graph.child(node, 2 + i);
1073 // NOTE: DFG is not smart enough to handle double->int conversions in atomics. So, we
1074 // just call the function when that happens. But the FTL is totally cool with those
1075 // conversions.
1076 if (!child->shouldSpeculateInt32()
1077 && !child->shouldSpeculateInt52()
1078 && !(child->shouldSpeculateNumberOrBoolean() && m_graph.m_plan.isFTL()))
1079 badNews = true;
1080 }
1081
1082 if (badNews) {
1083 node->setArrayMode(ArrayMode(Array::Generic, node->arrayMode().action()));
1084 break;
1085 }
1086
1087 node->setArrayMode(
1088 node->arrayMode().refine(
1089 m_graph, node, base->prediction(), index->prediction()));
1090
1091 if (node->arrayMode().type() == Array::Generic)
1092 break;
1093
1094 for (unsigned i = numExtraAtomicsArgs(node->op()); i--;) {
1095 Edge& child = m_graph.child(node, 2 + i);
1096 if (child->shouldSpeculateInt32())
1097 fixIntOrBooleanEdge(child);
1098 else if (child->shouldSpeculateInt52())
1099 fixEdge<Int52RepUse>(child);
1100 else {
1101 RELEASE_ASSERT(child->shouldSpeculateNumberOrBoolean() && m_graph.m_plan.isFTL());
1102 fixDoubleOrBooleanEdge(child);
1103 }
1104 }
1105
1106 blessArrayOperation(base, index, m_graph.child(node, 2 + numExtraAtomicsArgs(node->op())));
1107 fixEdge<CellUse>(base);
1108 fixEdge<Int32Use>(index);
1109
1110 if (node->arrayMode().type() == Array::Uint32Array) {
1111 // NOTE: This means basically always doing Int52.
1112 if (node->shouldSpeculateInt52())
1113 node->setResult(NodeResultInt52);
1114 else
1115 node->setResult(NodeResultDouble);
1116 }
1117 break;
1118 }
1119
1120 case AtomicsIsLockFree:
1121 if (node->child1()->shouldSpeculateInt32())
1122 fixIntOrBooleanEdge(node->child1());
1123 break;
1124
1125 case ArrayPush: {
1126 // May need to refine the array mode in case the value prediction contravenes
1127 // the array prediction. For example, we may have evidence showing that the
1128 // array is in Int32 mode, but the value we're storing is likely to be a double.
1129 // Then we should turn this into a conversion to Double array followed by the
1130 // push. On the other hand, we absolutely don't want to refine based on the
1131 // base prediction. If it has non-cell garbage in it, then we want that to be
1132 // ignored. That's because ArrayPush can't handle any array modes that aren't
1133 // array-related - so if refine() turned this into a "Generic" ArrayPush then
1134 // that would break things.
1135 Edge& storageEdge = m_graph.varArgChild(node, 0);
1136 Edge& arrayEdge = m_graph.varArgChild(node, 1);
1137 unsigned elementOffset = 2;
1138 unsigned elementCount = node->numChildren() - elementOffset;
1139 for (unsigned i = 0; i < elementCount; ++i) {
1140 Edge& element = m_graph.varArgChild(node, i + elementOffset);
1141 node->setArrayMode(
1142 node->arrayMode().refine(
1143 m_graph, node,
1144 arrayEdge->prediction() & SpecCell,
1145 SpecInt32Only,
1146 element->prediction()));
1147 }
1148 blessArrayOperation(arrayEdge, Edge(), storageEdge);
1149 fixEdge<KnownCellUse>(arrayEdge);
1150
1151 // Convert `array.push()` to GetArrayLength.
1152 if (!elementCount && node->arrayMode().supportsSelfLength()) {
1153 node->setOpAndDefaultFlags(GetArrayLength);
1154 node->child1() = arrayEdge;
1155 node->child2() = storageEdge;
1156 fixEdge<KnownCellUse>(node->child1());
1157 break;
1158 }
1159
1160 // We do not want to perform osr exit and retry for ArrayPush. We insert Check with appropriate type,
1161 // and ArrayPush uses the edge as known typed edge. Therefore, ArrayPush do not need to perform type checks.
1162 for (unsigned i = 0; i < elementCount; ++i) {
1163 Edge& element = m_graph.varArgChild(node, i + elementOffset);
1164 switch (node->arrayMode().type()) {
1165 case Array::Int32:
1166 fixEdge<Int32Use>(element);
1167 break;
1168 case Array::Double:
1169 fixEdge<DoubleRepRealUse>(element);
1170 break;
1171 case Array::Contiguous:
1172 case Array::ArrayStorage:
1173 speculateForBarrier(element);
1174 break;
1175 default:
1176 break;
1177 }
1178 }
1179 break;
1180 }
1181
1182 case ArrayPop: {
1183 blessArrayOperation(node->child1(), Edge(), node->child2());
1184 fixEdge<KnownCellUse>(node->child1());
1185 break;
1186 }
1187
1188 case ArraySlice: {
1189 fixEdge<KnownCellUse>(m_graph.varArgChild(node, 0));
1190 if (node->numChildren() >= 3) {
1191 fixEdge<Int32Use>(m_graph.varArgChild(node, 1));
1192 if (node->numChildren() == 4)
1193 fixEdge<Int32Use>(m_graph.varArgChild(node, 2));
1194 }
1195 break;
1196 }
1197
1198 case ArrayIndexOf:
1199 fixupArrayIndexOf(node);
1200 break;
1201
1202 case RegExpExec:
1203 case RegExpTest: {
1204 fixEdge<KnownCellUse>(node->child1());
1205
1206 if (node->child2()->shouldSpeculateRegExpObject()) {
1207 fixEdge<RegExpObjectUse>(node->child2());
1208
1209 if (node->child3()->shouldSpeculateString())
1210 fixEdge<StringUse>(node->child3());
1211 }
1212 break;
1213 }
1214
1215 case RegExpMatchFast: {
1216 fixEdge<KnownCellUse>(node->child1());
1217 fixEdge<RegExpObjectUse>(node->child2());
1218 fixEdge<StringUse>(node->child3());
1219 break;
1220 }
1221
1222 case StringReplace:
1223 case StringReplaceRegExp: {
1224 if (node->child2()->shouldSpeculateString()) {
1225 m_insertionSet.insertNode(
1226 m_indexInBlock, SpecNone, Check, node->origin,
1227 Edge(node->child2().node(), StringUse));
1228 fixEdge<StringUse>(node->child2());
1229 } else if (op == StringReplace) {
1230 if (node->child2()->shouldSpeculateRegExpObject())
1231 addStringReplacePrimordialChecks(node->child2().node());
1232 else
1233 m_insertionSet.insertNode(
1234 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
1235 }
1236
1237 if (node->child1()->shouldSpeculateString()
1238 && node->child2()->shouldSpeculateRegExpObject()
1239 && node->child3()->shouldSpeculateString()) {
1240
1241 fixEdge<StringUse>(node->child1());
1242 fixEdge<RegExpObjectUse>(node->child2());
1243 fixEdge<StringUse>(node->child3());
1244 break;
1245 }
1246 break;
1247 }
1248
1249 case Branch: {
1250 if (node->child1()->shouldSpeculateBoolean()) {
1251 if (node->child1()->result() == NodeResultBoolean) {
1252 // This is necessary in case we have a bytecode instruction implemented by:
1253 //
1254 // a: CompareEq(...)
1255 // b: Branch(@a)
1256 //
1257 // In that case, CompareEq might have a side-effect. Then, we need to make
1258 // sure that we know that Branch does not exit.
1259 fixEdge<KnownBooleanUse>(node->child1());
1260 } else
1261 fixEdge<BooleanUse>(node->child1());
1262 } else if (node->child1()->shouldSpeculateObjectOrOther())
1263 fixEdge<ObjectOrOtherUse>(node->child1());
1264 else if (node->child1()->shouldSpeculateInt32OrBoolean())
1265 fixIntOrBooleanEdge(node->child1());
1266 else if (node->child1()->shouldSpeculateNumber())
1267 fixEdge<DoubleRepUse>(node->child1());
1268 else if (node->child1()->shouldSpeculateString())
1269 fixEdge<StringUse>(node->child1());
1270 else if (node->child1()->shouldSpeculateStringOrOther())
1271 fixEdge<StringOrOtherUse>(node->child1());
1272 else {
1273 WatchpointSet* masqueradesAsUndefinedWatchpoint = m_graph.globalObjectFor(node->origin.semantic)->masqueradesAsUndefinedWatchpoint();
1274 if (masqueradesAsUndefinedWatchpoint->isStillValid())
1275 m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
1276 }
1277 break;
1278 }
1279
1280 case Switch: {
1281 SwitchData* data = node->switchData();
1282 switch (data->kind) {
1283 case SwitchImm:
1284 if (node->child1()->shouldSpeculateInt32())
1285 fixEdge<Int32Use>(node->child1());
1286 break;
1287 case SwitchChar:
1288 if (node->child1()->shouldSpeculateString())
1289 fixEdge<StringUse>(node->child1());
1290 break;
1291 case SwitchString:
1292 if (node->child1()->shouldSpeculateStringIdent())
1293 fixEdge<StringIdentUse>(node->child1());
1294 else if (node->child1()->shouldSpeculateString())
1295 fixEdge<StringUse>(node->child1());
1296 break;
1297 case SwitchCell:
1298 if (node->child1()->shouldSpeculateCell())
1299 fixEdge<CellUse>(node->child1());
1300 // else it's fine for this to have UntypedUse; we will handle this by just making
1301 // non-cells take the default case.
1302 break;
1303 }
1304 break;
1305 }
1306
1307 case ToPrimitive: {
1308 fixupToPrimitive(node);
1309 break;
1310 }
1311
1312 case ToNumber: {
1313 fixupToNumber(node);
1314 break;
1315 }
1316
1317 case ToString:
1318 case CallStringConstructor: {
1319 fixupToStringOrCallStringConstructor(node);
1320 break;
1321 }
1322
1323 case NewStringObject: {
1324 fixEdge<KnownStringUse>(node->child1());
1325 break;
1326 }
1327
1328 case NewSymbol: {
1329 if (node->child1())
1330 fixEdge<KnownStringUse>(node->child1());
1331 break;
1332 }
1333
1334 case NewArrayWithSpread: {
1335 watchHavingABadTime(node);
1336
1337 BitVector* bitVector = node->bitVector();
1338 for (unsigned i = node->numChildren(); i--;) {
1339 if (bitVector->get(i))
1340 fixEdge<KnownCellUse>(m_graph.m_varArgChildren[node->firstChild() + i]);
1341 else
1342 fixEdge<UntypedUse>(m_graph.m_varArgChildren[node->firstChild() + i]);
1343 }
1344
1345 break;
1346 }
1347
1348 case Spread: {
1349 // Note: We care about performing the protocol on our child's global object, not necessarily ours.
1350
1351 watchHavingABadTime(node->child1().node());
1352
1353 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->child1()->origin.semantic);
1354 // When we go down the fast path, we don't consult the prototype chain, so we must prove
1355 // that it doesn't contain any indexed properties, and that any holes will result in
1356 // jsUndefined().
1357 Structure* arrayPrototypeStructure = globalObject->arrayPrototype()->structure(vm());
1358 Structure* objectPrototypeStructure = globalObject->objectPrototype()->structure(vm());
1359 if (node->child1()->shouldSpeculateArray()
1360 && arrayPrototypeStructure->transitionWatchpointSetIsStillValid()
1361 && objectPrototypeStructure->transitionWatchpointSetIsStillValid()
1362 && globalObject->arrayPrototypeChainIsSane()
1363 && m_graph.isWatchingArrayIteratorProtocolWatchpoint(node->child1().node())
1364 && m_graph.isWatchingHavingABadTimeWatchpoint(node->child1().node())) {
1365 m_graph.registerAndWatchStructureTransition(objectPrototypeStructure);
1366 m_graph.registerAndWatchStructureTransition(arrayPrototypeStructure);
1367 fixEdge<ArrayUse>(node->child1());
1368 } else
1369 fixEdge<CellUse>(node->child1());
1370 break;
1371 }
1372
1373 case NewArray: {
1374 watchHavingABadTime(node);
1375
1376 for (unsigned i = m_graph.varArgNumChildren(node); i--;) {
1377 node->setIndexingType(
1378 leastUpperBoundOfIndexingTypeAndType(
1379 node->indexingType(), m_graph.varArgChild(node, i)->prediction()));
1380 }
1381 switch (node->indexingType()) {
1382 case ALL_BLANK_INDEXING_TYPES:
1383 CRASH();
1384 break;
1385 case ALL_UNDECIDED_INDEXING_TYPES:
1386 if (node->numChildren()) {
1387 // This will only happen if the children have no type predictions. We
1388 // would have already exited by now, but insert a forced exit just to
1389 // be safe.
1390 m_insertionSet.insertNode(
1391 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
1392 }
1393 break;
1394 case ALL_INT32_INDEXING_TYPES:
1395 for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
1396 fixEdge<Int32Use>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
1397 break;
1398 case ALL_DOUBLE_INDEXING_TYPES:
1399 for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
1400 fixEdge<DoubleRepRealUse>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
1401 break;
1402 case ALL_CONTIGUOUS_INDEXING_TYPES:
1403 case ALL_ARRAY_STORAGE_INDEXING_TYPES:
1404 break;
1405 default:
1406 CRASH();
1407 break;
1408 }
1409 break;
1410 }
1411
1412 case NewTypedArray: {
1413 watchHavingABadTime(node);
1414
1415 if (node->child1()->shouldSpeculateInt32()) {
1416 fixEdge<Int32Use>(node->child1());
1417 node->clearFlags(NodeMustGenerate);
1418 break;
1419 }
1420 break;
1421 }
1422
1423 case NewArrayWithSize: {
1424 watchHavingABadTime(node);
1425 fixEdge<Int32Use>(node->child1());
1426 break;
1427 }
1428
1429 case NewArrayBuffer: {
1430 watchHavingABadTime(node);
1431 break;
1432 }
1433
1434 case ToObject: {
1435 fixupToObject(node);
1436 break;
1437 }
1438
1439 case CallObjectConstructor: {
1440 fixupCallObjectConstructor(node);
1441 break;
1442 }
1443
1444 case ToThis: {
1445 fixupToThis(node);
1446 break;
1447 }
1448
1449 case PutStructure: {
1450 fixEdge<KnownCellUse>(node->child1());
1451 break;
1452 }
1453
1454 case GetClosureVar:
1455 case GetFromArguments: {
1456 fixEdge<KnownCellUse>(node->child1());
1457 break;
1458 }
1459
1460 case PutClosureVar:
1461 case PutToArguments: {
1462 fixEdge<KnownCellUse>(node->child1());
1463 speculateForBarrier(node->child2());
1464 break;
1465 }
1466
1467 case SkipScope:
1468 case GetScope:
1469 case GetGetter:
1470 case GetSetter:
1471 case GetGlobalObject: {
1472 fixEdge<KnownCellUse>(node->child1());
1473 break;
1474 }
1475
1476 case AllocatePropertyStorage:
1477 case ReallocatePropertyStorage: {
1478 fixEdge<KnownCellUse>(node->child1());
1479 break;
1480 }
1481
1482 case NukeStructureAndSetButterfly: {
1483 fixEdge<KnownCellUse>(node->child1());
1484 break;
1485 }
1486
1487 case TryGetById: {
1488 if (node->child1()->shouldSpeculateCell())
1489 fixEdge<CellUse>(node->child1());
1490 break;
1491 }
1492
1493 case GetByIdDirect:
1494 case GetByIdDirectFlush: {
1495 if (node->child1()->shouldSpeculateCell())
1496 fixEdge<CellUse>(node->child1());
1497 break;
1498 }
1499
1500 case GetById:
1501 case GetByIdFlush: {
1502 // FIXME: This should be done in the ByteCodeParser based on reading the
1503 // PolymorphicAccess, which will surely tell us that this is a AccessCase::ArrayLength.
1504 // https://bugs.webkit.org/show_bug.cgi?id=154990
1505 auto uid = m_graph.identifiers()[node->identifierNumber()];
1506 if (node->child1()->shouldSpeculateCellOrOther()
1507 && !m_graph.hasExitSite(node->origin.semantic, BadType)
1508 && !m_graph.hasExitSite(node->origin.semantic, BadCache)
1509 && !m_graph.hasExitSite(node->origin.semantic, BadIndexingType)
1510 && !m_graph.hasExitSite(node->origin.semantic, ExoticObjectMode)) {
1511
1512 if (uid == vm().propertyNames->length.impl()) {
1513 attemptToMakeGetArrayLength(node);
1514 break;
1515 }
1516
1517 if (uid == vm().propertyNames->lastIndex.impl()
1518 && node->child1()->shouldSpeculateRegExpObject()) {
1519 node->setOp(GetRegExpObjectLastIndex);
1520 node->clearFlags(NodeMustGenerate);
1521 fixEdge<RegExpObjectUse>(node->child1());
1522 break;
1523 }
1524 }
1525
1526 if (node->child1()->shouldSpeculateNumber()) {
1527 if (uid == vm().propertyNames->toString.impl()) {
1528 if (m_graph.isWatchingNumberToStringWatchpoint(node)) {
1529 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
1530 if (node->child1()->shouldSpeculateInt32()) {
1531 insertCheck<Int32Use>(node->child1().node());
1532 m_graph.convertToConstant(node, m_graph.freeze(globalObject->numberProtoToStringFunction()));
1533 break;
1534 }
1535
1536 if (node->child1()->shouldSpeculateInt52()) {
1537 insertCheck<Int52RepUse>(node->child1().node());
1538 m_graph.convertToConstant(node, m_graph.freeze(globalObject->numberProtoToStringFunction()));
1539 break;
1540 }
1541
1542 ASSERT(node->child1()->shouldSpeculateNumber());
1543 insertCheck<DoubleRepUse>(node->child1().node());
1544 m_graph.convertToConstant(node, m_graph.freeze(globalObject->numberProtoToStringFunction()));
1545 break;
1546 }
1547 }
1548 }
1549
1550 if (node->child1()->shouldSpeculateCell())
1551 fixEdge<CellUse>(node->child1());
1552 break;
1553 }
1554
1555 case GetByIdWithThis: {
1556 if (node->child1()->shouldSpeculateCell() && node->child2()->shouldSpeculateCell()) {
1557 fixEdge<CellUse>(node->child1());
1558 fixEdge<CellUse>(node->child2());
1559 }
1560 break;
1561 }
1562
1563 case PutById:
1564 case PutByIdFlush:
1565 case PutByIdDirect: {
1566 if (node->child1()->shouldSpeculateCellOrOther()
1567 && !m_graph.hasExitSite(node->origin.semantic, BadType)
1568 && !m_graph.hasExitSite(node->origin.semantic, BadCache)
1569 && !m_graph.hasExitSite(node->origin.semantic, BadIndexingType)
1570 && !m_graph.hasExitSite(node->origin.semantic, ExoticObjectMode)) {
1571
1572 auto uid = m_graph.identifiers()[node->identifierNumber()];
1573
1574 if (uid == vm().propertyNames->lastIndex.impl()
1575 && node->child1()->shouldSpeculateRegExpObject()) {
1576 node->convertToSetRegExpObjectLastIndex();
1577 fixEdge<RegExpObjectUse>(node->child1());
1578 speculateForBarrier(node->child2());
1579 break;
1580 }
1581 }
1582
1583 fixEdge<CellUse>(node->child1());
1584 break;
1585 }
1586
1587 case PutGetterById:
1588 case PutSetterById: {
1589 fixEdge<KnownCellUse>(node->child1());
1590 fixEdge<KnownCellUse>(node->child2());
1591 break;
1592 }
1593
1594 case PutGetterSetterById: {
1595 fixEdge<KnownCellUse>(node->child1());
1596 break;
1597 }
1598
1599 case PutGetterByVal:
1600 case PutSetterByVal: {
1601 fixEdge<KnownCellUse>(node->child1());
1602 fixEdge<KnownCellUse>(node->child3());
1603 break;
1604 }
1605
1606 case GetExecutable: {
1607 fixEdge<FunctionUse>(node->child1());
1608 break;
1609 }
1610
1611 case OverridesHasInstance:
1612 case CheckStructure:
1613 case CheckCell:
1614 case CreateThis:
1615 case GetButterfly: {
1616 fixEdge<CellUse>(node->child1());
1617 break;
1618 }
1619
1620 case ObjectCreate: {
1621 if (node->child1()->shouldSpeculateObject()) {
1622 fixEdge<ObjectUse>(node->child1());
1623 node->clearFlags(NodeMustGenerate);
1624 break;
1625 }
1626 break;
1627 }
1628
1629 case ObjectKeys: {
1630 if (node->child1()->shouldSpeculateObject()) {
1631 watchHavingABadTime(node);
1632 fixEdge<ObjectUse>(node->child1());
1633 }
1634 break;
1635 }
1636
1637 case CheckStringIdent: {
1638 fixEdge<StringIdentUse>(node->child1());
1639 break;
1640 }
1641
1642 case Arrayify:
1643 case ArrayifyToStructure: {
1644 fixEdge<CellUse>(node->child1());
1645 if (node->child2())
1646 fixEdge<Int32Use>(node->child2());
1647 break;
1648 }
1649
1650 case GetByOffset:
1651 case GetGetterSetterByOffset: {
1652 if (!node->child1()->hasStorageResult())
1653 fixEdge<KnownCellUse>(node->child1());
1654 fixEdge<KnownCellUse>(node->child2());
1655 break;
1656 }
1657
1658 case MultiGetByOffset: {
1659 fixEdge<CellUse>(node->child1());
1660 break;
1661 }
1662
1663 case PutByOffset: {
1664 if (!node->child1()->hasStorageResult())
1665 fixEdge<KnownCellUse>(node->child1());
1666 fixEdge<KnownCellUse>(node->child2());
1667 speculateForBarrier(node->child3());
1668 break;
1669 }
1670
1671 case MultiPutByOffset: {
1672 fixEdge<CellUse>(node->child1());
1673 break;
1674 }
1675
1676 case MatchStructure: {
1677 // FIXME: Introduce a variant of MatchStructure that doesn't do a cell check.
1678 // https://bugs.webkit.org/show_bug.cgi?id=185784
1679 fixEdge<CellUse>(node->child1());
1680 break;
1681 }
1682
1683 case InstanceOf: {
1684 if (node->child1()->shouldSpeculateCell()
1685 && node->child2()->shouldSpeculateCell()
1686 && is64Bit()) {
1687 fixEdge<CellUse>(node->child1());
1688 fixEdge<CellUse>(node->child2());
1689 break;
1690 }
1691 break;
1692 }
1693
1694 case InstanceOfCustom:
1695 fixEdge<CellUse>(node->child2());
1696 break;
1697
1698 case InById: {
1699 fixEdge<CellUse>(node->child1());
1700 break;
1701 }
1702
1703 case InByVal: {
1704 if (node->child2()->shouldSpeculateInt32()) {
1705 convertToHasIndexedProperty(node);
1706 break;
1707 }
1708
1709 fixEdge<CellUse>(node->child1());
1710 break;
1711 }
1712
1713 case HasOwnProperty: {
1714 fixEdge<ObjectUse>(node->child1());
1715#if CPU(X86)
1716 // We don't have enough registers to do anything interesting on x86 and mips.
1717 fixEdge<UntypedUse>(node->child2());
1718#else
1719 if (node->child2()->shouldSpeculateString())
1720 fixEdge<StringUse>(node->child2());
1721 else if (node->child2()->shouldSpeculateSymbol())
1722 fixEdge<SymbolUse>(node->child2());
1723 else
1724 fixEdge<UntypedUse>(node->child2());
1725#endif
1726 break;
1727 }
1728
1729 case CheckVarargs:
1730 case Check: {
1731 m_graph.doToChildren(
1732 node,
1733 [&] (Edge& edge) {
1734 switch (edge.useKind()) {
1735 case NumberUse:
1736 if (edge->shouldSpeculateInt32ForArithmetic())
1737 edge.setUseKind(Int32Use);
1738 break;
1739 default:
1740 break;
1741 }
1742 observeUseKindOnEdge(edge);
1743 });
1744 break;
1745 }
1746
1747 case Phantom:
1748 // Phantoms are meaningless past Fixup. We recreate them on-demand in the backend.
1749 node->remove(m_graph);
1750 break;
1751
1752 case FiatInt52: {
1753 RELEASE_ASSERT(enableInt52());
1754 node->convertToIdentity();
1755 fixEdge<Int52RepUse>(node->child1());
1756 node->setResult(NodeResultInt52);
1757 break;
1758 }
1759
1760 case GetArrayLength: {
1761 fixEdge<KnownCellUse>(node->child1());
1762 break;
1763 }
1764
1765 case GetTypedArrayByteOffset: {
1766 fixEdge<KnownCellUse>(node->child1());
1767 break;
1768 }
1769
1770 case CompareBelow:
1771 case CompareBelowEq: {
1772 fixEdge<Int32Use>(node->child1());
1773 fixEdge<Int32Use>(node->child2());
1774 break;
1775 }
1776
1777 case GetPrototypeOf: {
1778 fixupGetPrototypeOf(node);
1779 break;
1780 }
1781
1782 case Phi:
1783 case Upsilon:
1784 case EntrySwitch:
1785 case GetIndexedPropertyStorage:
1786 case LastNodeType:
1787 case CheckTierUpInLoop:
1788 case CheckTierUpAtReturn:
1789 case CheckTierUpAndOSREnter:
1790 case CheckArray:
1791 case CheckInBounds:
1792 case ConstantStoragePointer:
1793 case DoubleAsInt32:
1794 case ValueToInt32:
1795 case DoubleRep:
1796 case ValueRep:
1797 case Int52Rep:
1798 case Int52Constant:
1799 case Identity: // This should have been cleaned up.
1800 case BooleanToNumber:
1801 case PhantomNewObject:
1802 case PhantomNewFunction:
1803 case PhantomNewGeneratorFunction:
1804 case PhantomNewAsyncGeneratorFunction:
1805 case PhantomNewAsyncFunction:
1806 case PhantomCreateActivation:
1807 case PhantomDirectArguments:
1808 case PhantomCreateRest:
1809 case PhantomSpread:
1810 case PhantomNewArrayWithSpread:
1811 case PhantomNewArrayBuffer:
1812 case PhantomClonedArguments:
1813 case PhantomNewRegexp:
1814 case GetMyArgumentByVal:
1815 case GetMyArgumentByValOutOfBounds:
1816 case GetVectorLength:
1817 case PutHint:
1818 case CheckStructureImmediate:
1819 case CheckStructureOrEmpty:
1820 case MaterializeNewObject:
1821 case MaterializeCreateActivation:
1822 case PutStack:
1823 case KillStack:
1824 case GetStack:
1825 case StoreBarrier:
1826 case FencedStoreBarrier:
1827 case GetRegExpObjectLastIndex:
1828 case SetRegExpObjectLastIndex:
1829 case RecordRegExpCachedResult:
1830 case RegExpExecNonGlobalOrSticky:
1831 case RegExpMatchFastGlobal:
1832 // These are just nodes that we don't currently expect to see during fixup.
1833 // If we ever wanted to insert them prior to fixup, then we just have to create
1834 // fixup rules for them.
1835 DFG_CRASH(m_graph, node, "Unexpected node during fixup");
1836 break;
1837
1838 case PutGlobalVariable: {
1839 fixEdge<CellUse>(node->child1());
1840 speculateForBarrier(node->child2());
1841 break;
1842 }
1843
1844 case IsObject:
1845 if (node->child1()->shouldSpeculateObject()) {
1846 m_insertionSet.insertNode(
1847 m_indexInBlock, SpecNone, Check, node->origin,
1848 Edge(node->child1().node(), ObjectUse));
1849 m_graph.convertToConstant(node, jsBoolean(true));
1850 observeUseKindOnNode<ObjectUse>(node);
1851 }
1852 break;
1853
1854 case IsCellWithType: {
1855 fixupIsCellWithType(node);
1856 break;
1857 }
1858
1859 case GetEnumerableLength: {
1860 fixEdge<CellUse>(node->child1());
1861 break;
1862 }
1863 case HasGenericProperty: {
1864 fixEdge<CellUse>(node->child2());
1865 break;
1866 }
1867 case HasStructureProperty: {
1868 fixEdge<StringUse>(node->child2());
1869 fixEdge<KnownCellUse>(node->child3());
1870 break;
1871 }
1872 case HasIndexedProperty: {
1873 node->setArrayMode(
1874 node->arrayMode().refine(
1875 m_graph, node,
1876 m_graph.varArgChild(node, 0)->prediction(),
1877 m_graph.varArgChild(node, 1)->prediction(),
1878 SpecNone));
1879
1880 blessArrayOperation(m_graph.varArgChild(node, 0), m_graph.varArgChild(node, 1), m_graph.varArgChild(node, 2));
1881 fixEdge<CellUse>(m_graph.varArgChild(node, 0));
1882 fixEdge<Int32Use>(m_graph.varArgChild(node, 1));
1883 break;
1884 }
1885 case GetDirectPname: {
1886 Edge& base = m_graph.varArgChild(node, 0);
1887 Edge& property = m_graph.varArgChild(node, 1);
1888 Edge& index = m_graph.varArgChild(node, 2);
1889 Edge& enumerator = m_graph.varArgChild(node, 3);
1890 fixEdge<CellUse>(base);
1891 fixEdge<KnownCellUse>(property);
1892 fixEdge<Int32Use>(index);
1893 fixEdge<KnownCellUse>(enumerator);
1894 break;
1895 }
1896 case GetPropertyEnumerator: {
1897 if (node->child1()->shouldSpeculateCell())
1898 fixEdge<CellUse>(node->child1());
1899 break;
1900 }
1901 case GetEnumeratorStructurePname: {
1902 fixEdge<KnownCellUse>(node->child1());
1903 fixEdge<Int32Use>(node->child2());
1904 break;
1905 }
1906 case GetEnumeratorGenericPname: {
1907 fixEdge<KnownCellUse>(node->child1());
1908 fixEdge<Int32Use>(node->child2());
1909 break;
1910 }
1911 case ToIndexString: {
1912 fixEdge<Int32Use>(node->child1());
1913 break;
1914 }
1915 case ProfileType: {
1916 // We want to insert type checks based on the instructionTypeSet of the TypeLocation, not the globalTypeSet.
1917 // Because the instructionTypeSet is contained in globalTypeSet, if we produce a type check for
1918 // type T for the instructionTypeSet, the global type set must also have information for type T.
1919 // So if it the type check succeeds for type T in the instructionTypeSet, a type check for type T
1920 // in the globalTypeSet would've also succeeded.
1921 // (The other direction does not hold in general).
1922
1923 RefPtr<TypeSet> typeSet = node->typeLocation()->m_instructionTypeSet;
1924 RuntimeTypeMask seenTypes = typeSet->seenTypes();
1925 if (typeSet->doesTypeConformTo(TypeAnyInt)) {
1926 if (node->child1()->shouldSpeculateInt32()) {
1927 fixEdge<Int32Use>(node->child1());
1928 node->remove(m_graph);
1929 break;
1930 }
1931
1932 if (enableInt52()) {
1933 fixEdge<AnyIntUse>(node->child1());
1934 node->remove(m_graph);
1935 break;
1936 }
1937
1938 // Must not perform fixEdge<NumberUse> here since the type set only includes TypeAnyInt. Double values should be logged.
1939 }
1940
1941 if (typeSet->doesTypeConformTo(TypeNumber | TypeAnyInt)) {
1942 fixEdge<NumberUse>(node->child1());
1943 node->remove(m_graph);
1944 } else if (typeSet->doesTypeConformTo(TypeString)) {
1945 fixEdge<StringUse>(node->child1());
1946 node->remove(m_graph);
1947 } else if (typeSet->doesTypeConformTo(TypeBoolean)) {
1948 fixEdge<BooleanUse>(node->child1());
1949 node->remove(m_graph);
1950 } else if (typeSet->doesTypeConformTo(TypeUndefined | TypeNull) && (seenTypes & TypeUndefined) && (seenTypes & TypeNull)) {
1951 fixEdge<OtherUse>(node->child1());
1952 node->remove(m_graph);
1953 } else if (typeSet->doesTypeConformTo(TypeObject)) {
1954 StructureSet set;
1955 {
1956 ConcurrentJSLocker locker(typeSet->m_lock);
1957 set = typeSet->structureSet(locker);
1958 }
1959 if (!set.isEmpty()) {
1960 fixEdge<CellUse>(node->child1());
1961 node->convertToCheckStructureOrEmpty(m_graph.addStructureSet(set));
1962 }
1963 }
1964
1965 break;
1966 }
1967
1968 case CreateClonedArguments: {
1969 watchHavingABadTime(node);
1970 break;
1971 }
1972
1973 case CreateScopedArguments:
1974 case CreateActivation:
1975 case NewFunction:
1976 case NewGeneratorFunction:
1977 case NewAsyncGeneratorFunction:
1978 case NewAsyncFunction: {
1979 // Child 1 is always the current scope, which is guaranteed to be an object
1980 // FIXME: should be KnownObjectUse once that exists (https://bugs.webkit.org/show_bug.cgi?id=175689)
1981 fixEdge<KnownCellUse>(node->child1());
1982 break;
1983 }
1984
1985 case PushWithScope: {
1986 // Child 1 is always the current scope, which is guaranteed to be an object
1987 // FIXME: should be KnownObjectUse once that exists (https://bugs.webkit.org/show_bug.cgi?id=175689)
1988 fixEdge<KnownCellUse>(node->child1());
1989 if (node->child2()->shouldSpeculateObject())
1990 fixEdge<ObjectUse>(node->child2());
1991 break;
1992 }
1993
1994 case SetFunctionName: {
1995 // The first child is guaranteed to be a cell because op_set_function_name is only used
1996 // on a newly instantiated function object (the first child).
1997 fixEdge<KnownCellUse>(node->child1());
1998 fixEdge<UntypedUse>(node->child2());
1999 break;
2000 }
2001
2002 case CreateRest: {
2003 watchHavingABadTime(node);
2004 fixEdge<Int32Use>(node->child1());
2005 break;
2006 }
2007
2008 case ResolveScopeForHoistingFuncDeclInEval: {
2009 fixEdge<KnownCellUse>(node->child1());
2010 break;
2011 }
2012 case ResolveScope:
2013 case GetDynamicVar:
2014 case PutDynamicVar: {
2015 fixEdge<KnownCellUse>(node->child1());
2016 break;
2017 }
2018
2019 case LogShadowChickenPrologue: {
2020 fixEdge<KnownCellUse>(node->child1());
2021 break;
2022 }
2023 case LogShadowChickenTail: {
2024 fixEdge<UntypedUse>(node->child1());
2025 fixEdge<KnownCellUse>(node->child2());
2026 break;
2027 }
2028
2029 case GetMapBucket:
2030 if (node->child1().useKind() == MapObjectUse)
2031 fixEdge<MapObjectUse>(node->child1());
2032 else if (node->child1().useKind() == SetObjectUse)
2033 fixEdge<SetObjectUse>(node->child1());
2034 else
2035 RELEASE_ASSERT_NOT_REACHED();
2036
2037#if USE(JSVALUE64)
2038 if (node->child2()->shouldSpeculateBoolean())
2039 fixEdge<BooleanUse>(node->child2());
2040 else if (node->child2()->shouldSpeculateInt32())
2041 fixEdge<Int32Use>(node->child2());
2042 else if (node->child2()->shouldSpeculateSymbol())
2043 fixEdge<SymbolUse>(node->child2());
2044 else if (node->child2()->shouldSpeculateObject())
2045 fixEdge<ObjectUse>(node->child2());
2046 else if (node->child2()->shouldSpeculateString())
2047 fixEdge<StringUse>(node->child2());
2048 else if (node->child2()->shouldSpeculateCell())
2049 fixEdge<CellUse>(node->child2());
2050 else
2051 fixEdge<UntypedUse>(node->child2());
2052#else
2053 fixEdge<UntypedUse>(node->child2());
2054#endif // USE(JSVALUE64)
2055
2056 fixEdge<Int32Use>(node->child3());
2057 break;
2058
2059 case GetMapBucketHead:
2060 if (node->child1().useKind() == MapObjectUse)
2061 fixEdge<MapObjectUse>(node->child1());
2062 else if (node->child1().useKind() == SetObjectUse)
2063 fixEdge<SetObjectUse>(node->child1());
2064 else
2065 RELEASE_ASSERT_NOT_REACHED();
2066 break;
2067
2068 case GetMapBucketNext:
2069 case LoadKeyFromMapBucket:
2070 case LoadValueFromMapBucket:
2071 fixEdge<CellUse>(node->child1());
2072 break;
2073
2074 case MapHash: {
2075#if USE(JSVALUE64)
2076 if (node->child1()->shouldSpeculateBoolean()) {
2077 fixEdge<BooleanUse>(node->child1());
2078 break;
2079 }
2080
2081 if (node->child1()->shouldSpeculateInt32()) {
2082 fixEdge<Int32Use>(node->child1());
2083 break;
2084 }
2085
2086 if (node->child1()->shouldSpeculateSymbol()) {
2087 fixEdge<SymbolUse>(node->child1());
2088 break;
2089 }
2090
2091 if (node->child1()->shouldSpeculateObject()) {
2092 fixEdge<ObjectUse>(node->child1());
2093 break;
2094 }
2095
2096 if (node->child1()->shouldSpeculateString()) {
2097 fixEdge<StringUse>(node->child1());
2098 break;
2099 }
2100
2101 if (node->child1()->shouldSpeculateCell()) {
2102 fixEdge<CellUse>(node->child1());
2103 break;
2104 }
2105
2106 fixEdge<UntypedUse>(node->child1());
2107#else
2108 fixEdge<UntypedUse>(node->child1());
2109#endif // USE(JSVALUE64)
2110 break;
2111 }
2112
2113 case NormalizeMapKey: {
2114 fixupNormalizeMapKey(node);
2115 break;
2116 }
2117
2118 case WeakMapGet: {
2119 if (node->child1().useKind() == WeakMapObjectUse)
2120 fixEdge<WeakMapObjectUse>(node->child1());
2121 else if (node->child1().useKind() == WeakSetObjectUse)
2122 fixEdge<WeakSetObjectUse>(node->child1());
2123 else
2124 RELEASE_ASSERT_NOT_REACHED();
2125 fixEdge<ObjectUse>(node->child2());
2126 fixEdge<Int32Use>(node->child3());
2127 break;
2128 }
2129
2130 case SetAdd: {
2131 fixEdge<SetObjectUse>(node->child1());
2132 fixEdge<Int32Use>(node->child3());
2133 break;
2134 }
2135
2136 case MapSet: {
2137 fixEdge<MapObjectUse>(m_graph.varArgChild(node, 0));
2138 fixEdge<Int32Use>(m_graph.varArgChild(node, 3));
2139 break;
2140 }
2141
2142 case WeakSetAdd: {
2143 fixEdge<WeakSetObjectUse>(node->child1());
2144 fixEdge<ObjectUse>(node->child2());
2145 fixEdge<Int32Use>(node->child3());
2146 break;
2147 }
2148
2149 case WeakMapSet: {
2150 fixEdge<WeakMapObjectUse>(m_graph.varArgChild(node, 0));
2151 fixEdge<ObjectUse>(m_graph.varArgChild(node, 1));
2152 fixEdge<Int32Use>(m_graph.varArgChild(node, 3));
2153 break;
2154 }
2155
2156 case DefineDataProperty: {
2157 fixEdge<CellUse>(m_graph.varArgChild(node, 0));
2158 Edge& propertyEdge = m_graph.varArgChild(node, 1);
2159 if (propertyEdge->shouldSpeculateSymbol())
2160 fixEdge<SymbolUse>(propertyEdge);
2161 else if (propertyEdge->shouldSpeculateStringIdent())
2162 fixEdge<StringIdentUse>(propertyEdge);
2163 else if (propertyEdge->shouldSpeculateString())
2164 fixEdge<StringUse>(propertyEdge);
2165 else
2166 fixEdge<UntypedUse>(propertyEdge);
2167 fixEdge<UntypedUse>(m_graph.varArgChild(node, 2));
2168 fixEdge<Int32Use>(m_graph.varArgChild(node, 3));
2169 break;
2170 }
2171
2172 case StringValueOf: {
2173 fixupStringValueOf(node);
2174 break;
2175 }
2176
2177 case StringSlice: {
2178 fixEdge<StringUse>(node->child1());
2179 fixEdge<Int32Use>(node->child2());
2180 if (node->child3())
2181 fixEdge<Int32Use>(node->child3());
2182 break;
2183 }
2184
2185 case ToLowerCase: {
2186 // We currently only support StringUse since that will ensure that
2187 // ToLowerCase is a pure operation. If we decide to update this with
2188 // more types in the future, we need to ensure that the clobberize rules
2189 // are correct.
2190 fixEdge<StringUse>(node->child1());
2191 break;
2192 }
2193
2194 case NumberToStringWithRadix: {
2195 if (node->child1()->shouldSpeculateInt32())
2196 fixEdge<Int32Use>(node->child1());
2197 else if (node->child1()->shouldSpeculateInt52())
2198 fixEdge<Int52RepUse>(node->child1());
2199 else
2200 fixEdge<DoubleRepUse>(node->child1());
2201 fixEdge<Int32Use>(node->child2());
2202 break;
2203 }
2204
2205 case DefineAccessorProperty: {
2206 fixEdge<CellUse>(m_graph.varArgChild(node, 0));
2207 Edge& propertyEdge = m_graph.varArgChild(node, 1);
2208 if (propertyEdge->shouldSpeculateSymbol())
2209 fixEdge<SymbolUse>(propertyEdge);
2210 else if (propertyEdge->shouldSpeculateStringIdent())
2211 fixEdge<StringIdentUse>(propertyEdge);
2212 else if (propertyEdge->shouldSpeculateString())
2213 fixEdge<StringUse>(propertyEdge);
2214 else
2215 fixEdge<UntypedUse>(propertyEdge);
2216 fixEdge<CellUse>(m_graph.varArgChild(node, 2));
2217 fixEdge<CellUse>(m_graph.varArgChild(node, 3));
2218 fixEdge<Int32Use>(m_graph.varArgChild(node, 4));
2219 break;
2220 }
2221
2222 case CheckSubClass: {
2223 fixupCheckSubClass(node);
2224 break;
2225 }
2226
2227 case CallDOMGetter: {
2228 DOMJIT::CallDOMGetterSnippet* snippet = node->callDOMGetterData()->snippet;
2229 fixEdge<CellUse>(node->child1()); // DOM.
2230 if (snippet && snippet->requireGlobalObject)
2231 fixEdge<KnownCellUse>(node->child2()); // GlobalObject.
2232 break;
2233 }
2234
2235 case CallDOM: {
2236 fixupCallDOM(node);
2237 break;
2238 }
2239
2240 case Call: {
2241 attemptToMakeCallDOM(node);
2242 break;
2243 }
2244
2245 case ParseInt: {
2246 if (node->child1()->shouldSpeculateInt32() && !node->child2()) {
2247 fixEdge<Int32Use>(node->child1());
2248 node->convertToIdentity();
2249 break;
2250 }
2251
2252 if (node->child1()->shouldSpeculateString()) {
2253 fixEdge<StringUse>(node->child1());
2254 node->clearFlags(NodeMustGenerate);
2255 }
2256
2257 if (node->child2())
2258 fixEdge<Int32Use>(node->child2());
2259
2260 break;
2261 }
2262
2263 case IdentityWithProfile: {
2264 node->clearFlags(NodeMustGenerate);
2265 break;
2266 }
2267
2268 case ThrowStaticError:
2269 fixEdge<StringUse>(node->child1());
2270 break;
2271
2272 case NumberIsInteger:
2273 if (node->child1()->shouldSpeculateInt32()) {
2274 m_insertionSet.insertNode(
2275 m_indexInBlock, SpecNone, Check, node->origin,
2276 Edge(node->child1().node(), Int32Use));
2277 m_graph.convertToConstant(node, jsBoolean(true));
2278 break;
2279 }
2280 break;
2281
2282 case SetCallee:
2283 fixEdge<CellUse>(node->child1());
2284 break;
2285
2286 case DataViewGetInt:
2287 case DataViewGetFloat: {
2288 fixEdge<DataViewObjectUse>(node->child1());
2289 fixEdge<Int32Use>(node->child2());
2290 if (node->child3())
2291 fixEdge<BooleanUse>(node->child3());
2292
2293 if (node->op() == DataViewGetInt) {
2294 DataViewData data = node->dataViewData();
2295 switch (data.byteSize) {
2296 case 1:
2297 case 2:
2298 node->setResult(NodeResultInt32);
2299 break;
2300 case 4:
2301 if (data.isSigned)
2302 node->setResult(NodeResultInt32);
2303 else
2304 node->setResult(NodeResultInt52);
2305 break;
2306 default:
2307 RELEASE_ASSERT_NOT_REACHED();
2308 }
2309 }
2310 break;
2311 }
2312
2313 case DataViewSet: {
2314 fixEdge<DataViewObjectUse>(m_graph.varArgChild(node, 0));
2315 fixEdge<Int32Use>(m_graph.varArgChild(node, 1));
2316 if (m_graph.varArgChild(node, 3))
2317 fixEdge<BooleanUse>(m_graph.varArgChild(node, 3));
2318
2319 DataViewData data = node->dataViewData();
2320 Edge& valueToStore = m_graph.varArgChild(node, 2);
2321 if (data.isFloatingPoint)
2322 fixEdge<DoubleRepUse>(valueToStore);
2323 else {
2324 switch (data.byteSize) {
2325 case 1:
2326 case 2:
2327 fixEdge<Int32Use>(valueToStore);
2328 break;
2329 case 4:
2330 if (data.isSigned)
2331 fixEdge<Int32Use>(valueToStore);
2332 else
2333 fixEdge<Int52RepUse>(valueToStore);
2334 break;
2335 }
2336 }
2337 break;
2338 }
2339
2340#if !ASSERT_DISABLED
2341 // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
2342 case SetArgumentDefinitely:
2343 case SetArgumentMaybe:
2344 case JSConstant:
2345 case LazyJSConstant:
2346 case DoubleConstant:
2347 case GetLocal:
2348 case GetCallee:
2349 case GetArgumentCountIncludingThis:
2350 case SetArgumentCountIncludingThis:
2351 case GetRestLength:
2352 case GetArgument:
2353 case Flush:
2354 case PhantomLocal:
2355 case GetGlobalVar:
2356 case GetGlobalLexicalVariable:
2357 case NotifyWrite:
2358 case DirectCall:
2359 case CheckTypeInfoFlags:
2360 case TailCallInlinedCaller:
2361 case DirectTailCallInlinedCaller:
2362 case Construct:
2363 case DirectConstruct:
2364 case CallVarargs:
2365 case CallEval:
2366 case TailCallVarargsInlinedCaller:
2367 case ConstructVarargs:
2368 case CallForwardVarargs:
2369 case ConstructForwardVarargs:
2370 case TailCallForwardVarargs:
2371 case TailCallForwardVarargsInlinedCaller:
2372 case LoadVarargs:
2373 case ForwardVarargs:
2374 case ProfileControlFlow:
2375 case NewObject:
2376 case NewRegexp:
2377 case DeleteById:
2378 case DeleteByVal:
2379 case IsTypedArrayView:
2380 case IsEmpty:
2381 case IsUndefined:
2382 case IsUndefinedOrNull:
2383 case IsBoolean:
2384 case IsNumber:
2385 case IsObjectOrNull:
2386 case IsFunction:
2387 case CreateDirectArguments:
2388 case Jump:
2389 case Return:
2390 case TailCall:
2391 case DirectTailCall:
2392 case TailCallVarargs:
2393 case Throw:
2394 case CountExecution:
2395 case SuperSamplerBegin:
2396 case SuperSamplerEnd:
2397 case ForceOSRExit:
2398 case CheckBadCell:
2399 case CheckNotEmpty:
2400 case AssertNotEmpty:
2401 case CheckTraps:
2402 case Unreachable:
2403 case ExtractOSREntryLocal:
2404 case ExtractCatchLocal:
2405 case ClearCatchLocals:
2406 case LoopHint:
2407 case MovHint:
2408 case InitializeEntrypointArguments:
2409 case ZombieHint:
2410 case ExitOK:
2411 case BottomValue:
2412 case TypeOf:
2413 case PutByIdWithThis:
2414 case PutByValWithThis:
2415 case GetByValWithThis:
2416 case CompareEqPtr:
2417 case NumberToStringWithValidRadixConstant:
2418 case GetGlobalThis:
2419 case ExtractValueFromWeakMapGet:
2420 case CPUIntrinsic:
2421 case FilterCallLinkStatus:
2422 case FilterGetByIdStatus:
2423 case FilterPutByIdStatus:
2424 case FilterInByIdStatus:
2425 case InvalidationPoint:
2426 break;
2427#else
2428 default:
2429 break;
2430#endif
2431 }
2432 }
2433
2434 void watchHavingABadTime(Node* node)
2435 {
2436 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
2437
2438 // If this global object is not having a bad time, watch it. We go down this path anytime the code
2439 // does an array allocation. The types of array allocations may change if we start to have a bad
2440 // time. It's easier to reason about this if we know that whenever the types change after we start
2441 // optimizing, the code just gets thrown out. Doing this at FixupPhase is just early enough, since
2442 // prior to this point nobody should have been doing optimizations based on the indexing type of
2443 // the allocation.
2444 if (!globalObject->isHavingABadTime()) {
2445 m_graph.watchpoints().addLazily(globalObject->havingABadTimeWatchpoint());
2446 m_graph.freeze(globalObject);
2447 }
2448 }
2449
2450 template<UseKind useKind>
2451 void createToString(Node* node, Edge& edge)
2452 {
2453 Node* toString = m_insertionSet.insertNode(
2454 m_indexInBlock, SpecString, ToString, node->origin,
2455 Edge(edge.node(), useKind));
2456 switch (useKind) {
2457 case Int32Use:
2458 case Int52RepUse:
2459 case DoubleRepUse:
2460 case NotCellUse:
2461 toString->clearFlags(NodeMustGenerate);
2462 break;
2463 default:
2464 break;
2465 }
2466 edge.setNode(toString);
2467 }
2468
2469 template<UseKind useKind>
2470 void attemptToForceStringArrayModeByToStringConversion(ArrayMode& arrayMode, Node* node)
2471 {
2472 ASSERT(arrayMode == ArrayMode(Array::Generic, Array::Read) || arrayMode == ArrayMode(Array::Generic, Array::OriginalNonArray, Array::Read));
2473
2474 if (!m_graph.canOptimizeStringObjectAccess(node->origin.semantic))
2475 return;
2476
2477 addCheckStructureForOriginalStringObjectUse(useKind, node->origin, node->child1().node());
2478 createToString<useKind>(node, node->child1());
2479 arrayMode = ArrayMode(Array::String, Array::Read);
2480 }
2481
2482 void addCheckStructureForOriginalStringObjectUse(UseKind useKind, const NodeOrigin& origin, Node* node)
2483 {
2484 RELEASE_ASSERT(useKind == StringObjectUse || useKind == StringOrStringObjectUse);
2485
2486 StructureSet set;
2487 set.add(m_graph.globalObjectFor(node->origin.semantic)->stringObjectStructure());
2488 if (useKind == StringOrStringObjectUse)
2489 set.add(vm().stringStructure.get());
2490
2491 m_insertionSet.insertNode(
2492 m_indexInBlock, SpecNone, CheckStructure, origin,
2493 OpInfo(m_graph.addStructureSet(set)), Edge(node, CellUse));
2494 }
2495
2496 template<UseKind useKind>
2497 void convertStringAddUse(Node* node, Edge& edge)
2498 {
2499 if (useKind == StringUse) {
2500 observeUseKindOnNode<StringUse>(edge.node());
2501 m_insertionSet.insertNode(
2502 m_indexInBlock, SpecNone, Check, node->origin,
2503 Edge(edge.node(), StringUse));
2504 edge.setUseKind(KnownStringUse);
2505 return;
2506 }
2507
2508 observeUseKindOnNode<useKind>(edge.node());
2509 createToString<useKind>(node, edge);
2510 }
2511
2512 void convertToMakeRope(Node* node)
2513 {
2514 node->setOpAndDefaultFlags(MakeRope);
2515 fixupMakeRope(node);
2516 }
2517
2518 void fixupMakeRope(Node* node)
2519 {
2520 for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
2521 Edge& edge = node->children.child(i);
2522 if (!edge)
2523 break;
2524 edge.setUseKind(KnownStringUse);
2525 JSString* string = edge->dynamicCastConstant<JSString*>(vm());
2526 if (!string)
2527 continue;
2528 if (string->length())
2529 continue;
2530
2531 // Don't allow the MakeRope to have zero children.
2532 if (!i && !node->child2())
2533 break;
2534
2535 node->children.removeEdge(i--);
2536 }
2537
2538 if (!node->child2()) {
2539 ASSERT(!node->child3());
2540 node->convertToIdentity();
2541 }
2542 }
2543
2544 void fixupIsCellWithType(Node* node)
2545 {
2546 switch (node->speculatedTypeForQuery()) {
2547 case SpecString:
2548 if (node->child1()->shouldSpeculateString()) {
2549 m_insertionSet.insertNode(
2550 m_indexInBlock, SpecNone, Check, node->origin,
2551 Edge(node->child1().node(), StringUse));
2552 m_graph.convertToConstant(node, jsBoolean(true));
2553 observeUseKindOnNode<StringUse>(node);
2554 return;
2555 }
2556 break;
2557
2558 case SpecProxyObject:
2559 if (node->child1()->shouldSpeculateProxyObject()) {
2560 m_insertionSet.insertNode(
2561 m_indexInBlock, SpecNone, Check, node->origin,
2562 Edge(node->child1().node(), ProxyObjectUse));
2563 m_graph.convertToConstant(node, jsBoolean(true));
2564 observeUseKindOnNode<ProxyObjectUse>(node);
2565 return;
2566 }
2567 break;
2568
2569 case SpecRegExpObject:
2570 if (node->child1()->shouldSpeculateRegExpObject()) {
2571 m_insertionSet.insertNode(
2572 m_indexInBlock, SpecNone, Check, node->origin,
2573 Edge(node->child1().node(), RegExpObjectUse));
2574 m_graph.convertToConstant(node, jsBoolean(true));
2575 observeUseKindOnNode<RegExpObjectUse>(node);
2576 return;
2577 }
2578 break;
2579
2580 case SpecArray:
2581 if (node->child1()->shouldSpeculateArray()) {
2582 m_insertionSet.insertNode(
2583 m_indexInBlock, SpecNone, Check, node->origin,
2584 Edge(node->child1().node(), ArrayUse));
2585 m_graph.convertToConstant(node, jsBoolean(true));
2586 observeUseKindOnNode<ArrayUse>(node);
2587 return;
2588 }
2589 break;
2590
2591 case SpecDerivedArray:
2592 if (node->child1()->shouldSpeculateDerivedArray()) {
2593 m_insertionSet.insertNode(
2594 m_indexInBlock, SpecNone, Check, node->origin,
2595 Edge(node->child1().node(), DerivedArrayUse));
2596 m_graph.convertToConstant(node, jsBoolean(true));
2597 observeUseKindOnNode<DerivedArrayUse>(node);
2598 return;
2599 }
2600 break;
2601 }
2602
2603 if (node->child1()->shouldSpeculateCell()) {
2604 fixEdge<CellUse>(node->child1());
2605 return;
2606 }
2607
2608 if (node->child1()->shouldSpeculateNotCell()) {
2609 m_insertionSet.insertNode(
2610 m_indexInBlock, SpecNone, Check, node->origin,
2611 Edge(node->child1().node(), NotCellUse));
2612 m_graph.convertToConstant(node, jsBoolean(false));
2613 observeUseKindOnNode<NotCellUse>(node);
2614 return;
2615 }
2616 }
2617
2618 void fixupGetPrototypeOf(Node* node)
2619 {
2620 // Reflect.getPrototypeOf only accepts Objects. For Reflect.getPrototypeOf, ByteCodeParser attaches ObjectUse edge filter before fixup phase.
2621 if (node->child1().useKind() != ObjectUse) {
2622 if (node->child1()->shouldSpeculateString()) {
2623 insertCheck<StringUse>(node->child1().node());
2624 m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->stringPrototype()));
2625 return;
2626 }
2627 if (node->child1()->shouldSpeculateInt32()) {
2628 insertCheck<Int32Use>(node->child1().node());
2629 m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->numberPrototype()));
2630 return;
2631 }
2632 if (node->child1()->shouldSpeculateInt52()) {
2633 insertCheck<Int52RepUse>(node->child1().node());
2634 m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->numberPrototype()));
2635 return;
2636 }
2637 if (node->child1()->shouldSpeculateNumber()) {
2638 insertCheck<NumberUse>(node->child1().node());
2639 m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->numberPrototype()));
2640 return;
2641 }
2642 if (node->child1()->shouldSpeculateSymbol()) {
2643 insertCheck<SymbolUse>(node->child1().node());
2644 m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->symbolPrototype()));
2645 return;
2646 }
2647 if (node->child1()->shouldSpeculateBoolean()) {
2648 insertCheck<BooleanUse>(node->child1().node());
2649 m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->booleanPrototype()));
2650 return;
2651 }
2652 }
2653
2654 if (node->child1()->shouldSpeculateFinalObject()) {
2655 fixEdge<FinalObjectUse>(node->child1());
2656 node->clearFlags(NodeMustGenerate);
2657 return;
2658 }
2659 if (node->child1()->shouldSpeculateArray()) {
2660 fixEdge<ArrayUse>(node->child1());
2661 node->clearFlags(NodeMustGenerate);
2662 return;
2663 }
2664 if (node->child1()->shouldSpeculateFunction()) {
2665 fixEdge<FunctionUse>(node->child1());
2666 node->clearFlags(NodeMustGenerate);
2667 return;
2668 }
2669 }
2670
2671 void fixupToThis(Node* node)
2672 {
2673 bool isStrictMode = m_graph.isStrictModeFor(node->origin.semantic);
2674
2675 if (isStrictMode) {
2676 if (node->child1()->shouldSpeculateBoolean()) {
2677 fixEdge<BooleanUse>(node->child1());
2678 node->convertToIdentity();
2679 return;
2680 }
2681
2682 if (node->child1()->shouldSpeculateInt32()) {
2683 fixEdge<Int32Use>(node->child1());
2684 node->convertToIdentity();
2685 return;
2686 }
2687
2688 if (node->child1()->shouldSpeculateInt52()) {
2689 fixEdge<Int52RepUse>(node->child1());
2690 node->convertToIdentity();
2691 node->setResult(NodeResultInt52);
2692 return;
2693 }
2694
2695 if (node->child1()->shouldSpeculateNumber()) {
2696 fixEdge<DoubleRepUse>(node->child1());
2697 node->convertToIdentity();
2698 node->setResult(NodeResultDouble);
2699 return;
2700 }
2701
2702 if (node->child1()->shouldSpeculateSymbol()) {
2703 fixEdge<SymbolUse>(node->child1());
2704 node->convertToIdentity();
2705 return;
2706 }
2707
2708 if (node->child1()->shouldSpeculateStringIdent()) {
2709 fixEdge<StringIdentUse>(node->child1());
2710 node->convertToIdentity();
2711 return;
2712 }
2713
2714 if (node->child1()->shouldSpeculateString()) {
2715 fixEdge<StringUse>(node->child1());
2716 node->convertToIdentity();
2717 return;
2718 }
2719
2720 if (node->child1()->shouldSpeculateBigInt()) {
2721 fixEdge<BigIntUse>(node->child1());
2722 node->convertToIdentity();
2723 return;
2724 }
2725 }
2726
2727 if (node->child1()->shouldSpeculateOther()) {
2728 if (isStrictMode) {
2729 fixEdge<OtherUse>(node->child1());
2730 node->convertToIdentity();
2731 return;
2732 }
2733
2734 m_insertionSet.insertNode(
2735 m_indexInBlock, SpecNone, Check, node->origin,
2736 Edge(node->child1().node(), OtherUse));
2737 observeUseKindOnNode<OtherUse>(node->child1().node());
2738 m_graph.convertToConstant(
2739 node, m_graph.globalThisObjectFor(node->origin.semantic));
2740 return;
2741 }
2742
2743 // FIXME: This should cover other use cases but we don't have use kinds for them. It's not critical,
2744 // however, since we cover all the missing cases in constant folding.
2745 // https://bugs.webkit.org/show_bug.cgi?id=157213
2746 if (node->child1()->shouldSpeculateStringObject()) {
2747 fixEdge<StringObjectUse>(node->child1());
2748 node->convertToIdentity();
2749 return;
2750 }
2751
2752 if (isFinalObjectSpeculation(node->child1()->prediction())) {
2753 fixEdge<FinalObjectUse>(node->child1());
2754 node->convertToIdentity();
2755 return;
2756 }
2757 }
2758
2759 void fixupToPrimitive(Node* node)
2760 {
2761 if (node->child1()->shouldSpeculateInt32()) {
2762 fixEdge<Int32Use>(node->child1());
2763 node->convertToIdentity();
2764 return;
2765 }
2766
2767 if (node->child1()->shouldSpeculateString()) {
2768 fixEdge<StringUse>(node->child1());
2769 node->convertToIdentity();
2770 return;
2771 }
2772
2773 if (node->child1()->shouldSpeculateStringObject()
2774 && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
2775 addCheckStructureForOriginalStringObjectUse(StringObjectUse, node->origin, node->child1().node());
2776 fixEdge<StringObjectUse>(node->child1());
2777 node->convertToToString();
2778 return;
2779 }
2780
2781 if (node->child1()->shouldSpeculateStringOrStringObject()
2782 && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
2783 addCheckStructureForOriginalStringObjectUse(StringOrStringObjectUse, node->origin, node->child1().node());
2784 fixEdge<StringOrStringObjectUse>(node->child1());
2785 node->convertToToString();
2786 return;
2787 }
2788 }
2789
2790 void fixupToNumber(Node* node)
2791 {
2792 // If the prediction of the child is Number, we attempt to convert ToNumber to Identity.
2793 if (node->child1()->shouldSpeculateNumber()) {
2794 if (isInt32Speculation(node->getHeapPrediction())) {
2795 // If the both predictions of this node and the child is Int32, we just convert ToNumber to Identity, that's simple.
2796 if (node->child1()->shouldSpeculateInt32()) {
2797 fixEdge<Int32Use>(node->child1());
2798 node->convertToIdentity();
2799 return;
2800 }
2801
2802 // The another case is that the predicted type of the child is Int32, but the heap prediction tell the users that this will produce non Int32 values.
2803 // In that case, let's receive the child value as a Double value and convert it to Int32. This case happens in misc-bugs-847389-jpeg2000.
2804 fixEdge<DoubleRepUse>(node->child1());
2805 node->setOp(DoubleAsInt32);
2806 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
2807 node->setArithMode(Arith::CheckOverflow);
2808 else
2809 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
2810 return;
2811 }
2812
2813 fixEdge<DoubleRepUse>(node->child1());
2814 node->convertToIdentity();
2815 node->setResult(NodeResultDouble);
2816 return;
2817 }
2818
2819 fixEdge<UntypedUse>(node->child1());
2820 node->setResult(NodeResultJS);
2821 }
2822
2823 void fixupToObject(Node* node)
2824 {
2825 if (node->child1()->shouldSpeculateObject()) {
2826 fixEdge<ObjectUse>(node->child1());
2827 node->convertToIdentity();
2828 return;
2829 }
2830
2831 // ToObject(Null/Undefined) can throw an error. We can emit filters to convert ToObject to CallObjectConstructor.
2832
2833 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
2834
2835 if (node->child1()->shouldSpeculateString()) {
2836 insertCheck<StringUse>(node->child1().node());
2837 fixEdge<KnownStringUse>(node->child1());
2838 node->convertToNewStringObject(m_graph.registerStructure(globalObject->stringObjectStructure()));
2839 return;
2840 }
2841
2842 if (node->child1()->shouldSpeculateSymbol()) {
2843 insertCheck<SymbolUse>(node->child1().node());
2844 node->convertToCallObjectConstructor(m_graph.freeze(globalObject));
2845 return;
2846 }
2847
2848 if (node->child1()->shouldSpeculateNumber()) {
2849 insertCheck<NumberUse>(node->child1().node());
2850 node->convertToCallObjectConstructor(m_graph.freeze(globalObject));
2851 return;
2852 }
2853
2854 if (node->child1()->shouldSpeculateBoolean()) {
2855 insertCheck<BooleanUse>(node->child1().node());
2856 node->convertToCallObjectConstructor(m_graph.freeze(globalObject));
2857 return;
2858 }
2859
2860 fixEdge<UntypedUse>(node->child1());
2861 }
2862
2863 void fixupCallObjectConstructor(Node* node)
2864 {
2865 if (node->child1()->shouldSpeculateObject()) {
2866 fixEdge<ObjectUse>(node->child1());
2867 node->convertToIdentity();
2868 return;
2869 }
2870
2871 if (node->child1()->shouldSpeculateString()) {
2872 auto* globalObject = jsCast<JSGlobalObject*>(node->cellOperand()->cell());
2873 insertCheck<StringUse>(node->child1().node());
2874 fixEdge<KnownStringUse>(node->child1());
2875 node->convertToNewStringObject(m_graph.registerStructure(globalObject->stringObjectStructure()));
2876 return;
2877 }
2878
2879 // While ToObject(Null/Undefined) throws an error, CallObjectConstructor(Null/Undefined) generates a new empty object.
2880 if (node->child1()->shouldSpeculateOther()) {
2881 insertCheck<OtherUse>(node->child1().node());
2882 node->convertToNewObject(m_graph.registerStructure(jsCast<JSGlobalObject*>(node->cellOperand()->cell())->objectStructureForObjectConstructor()));
2883 return;
2884 }
2885
2886 fixEdge<UntypedUse>(node->child1());
2887 }
2888
2889 void fixupToStringOrCallStringConstructor(Node* node)
2890 {
2891 if (node->child1()->shouldSpeculateString()) {
2892 fixEdge<StringUse>(node->child1());
2893 node->convertToIdentity();
2894 return;
2895 }
2896
2897 if (node->child1()->shouldSpeculateStringObject()
2898 && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
2899 addCheckStructureForOriginalStringObjectUse(StringObjectUse, node->origin, node->child1().node());
2900 fixEdge<StringObjectUse>(node->child1());
2901 return;
2902 }
2903
2904 if (node->child1()->shouldSpeculateStringOrStringObject()
2905 && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
2906 addCheckStructureForOriginalStringObjectUse(StringOrStringObjectUse, node->origin, node->child1().node());
2907 fixEdge<StringOrStringObjectUse>(node->child1());
2908 return;
2909 }
2910
2911 if (node->child1()->shouldSpeculateCell()) {
2912 fixEdge<CellUse>(node->child1());
2913 return;
2914 }
2915
2916 if (node->child1()->shouldSpeculateInt32()) {
2917 fixEdge<Int32Use>(node->child1());
2918 node->clearFlags(NodeMustGenerate);
2919 return;
2920 }
2921
2922 if (node->child1()->shouldSpeculateInt52()) {
2923 fixEdge<Int52RepUse>(node->child1());
2924 node->clearFlags(NodeMustGenerate);
2925 return;
2926 }
2927
2928 if (node->child1()->shouldSpeculateNumber()) {
2929 fixEdge<DoubleRepUse>(node->child1());
2930 node->clearFlags(NodeMustGenerate);
2931 return;
2932 }
2933
2934 // ToString(Symbol) throws an error. So if the child1 can include Symbols,
2935 // we need to care about it in the clobberize. In the following case,
2936 // since NotCellUse edge filter is used and this edge filters Symbols,
2937 // we can say that ToString never throws an error!
2938 if (node->child1()->shouldSpeculateNotCell()) {
2939 fixEdge<NotCellUse>(node->child1());
2940 node->clearFlags(NodeMustGenerate);
2941 return;
2942 }
2943 }
2944
2945 void fixupStringValueOf(Node* node)
2946 {
2947 if (node->child1()->shouldSpeculateString()) {
2948 fixEdge<StringUse>(node->child1());
2949 node->convertToIdentity();
2950 return;
2951 }
2952
2953 if (node->child1()->shouldSpeculateStringObject()) {
2954 fixEdge<StringObjectUse>(node->child1());
2955 node->convertToToString();
2956 // It does not need to look up a toString property for the StringObject case. So we can clear NodeMustGenerate.
2957 node->clearFlags(NodeMustGenerate);
2958 return;
2959 }
2960
2961 if (node->child1()->shouldSpeculateStringOrStringObject()) {
2962 fixEdge<StringOrStringObjectUse>(node->child1());
2963 node->convertToToString();
2964 // It does not need to look up a toString property for the StringObject case. So we can clear NodeMustGenerate.
2965 node->clearFlags(NodeMustGenerate);
2966 return;
2967 }
2968 }
2969
2970 bool attemptToMakeFastStringAdd(Node* node)
2971 {
2972 bool goodToGo = true;
2973 m_graph.doToChildren(
2974 node,
2975 [&] (Edge& edge) {
2976 if (edge->shouldSpeculateString())
2977 return;
2978 if (m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
2979 if (edge->shouldSpeculateStringObject())
2980 return;
2981 if (edge->shouldSpeculateStringOrStringObject())
2982 return;
2983 }
2984 goodToGo = false;
2985 });
2986 if (!goodToGo)
2987 return false;
2988
2989 m_graph.doToChildren(
2990 node,
2991 [&] (Edge& edge) {
2992 if (edge->shouldSpeculateString()) {
2993 convertStringAddUse<StringUse>(node, edge);
2994 return;
2995 }
2996 if (!Options::useConcurrentJIT())
2997 ASSERT(m_graph.canOptimizeStringObjectAccess(node->origin.semantic));
2998 if (edge->shouldSpeculateStringObject()) {
2999 addCheckStructureForOriginalStringObjectUse(StringObjectUse, node->origin, edge.node());
3000 convertStringAddUse<StringObjectUse>(node, edge);
3001 return;
3002 }
3003 if (edge->shouldSpeculateStringOrStringObject()) {
3004 addCheckStructureForOriginalStringObjectUse(StringOrStringObjectUse, node->origin, edge.node());
3005 convertStringAddUse<StringOrStringObjectUse>(node, edge);
3006 return;
3007 }
3008 RELEASE_ASSERT_NOT_REACHED();
3009 });
3010
3011 convertToMakeRope(node);
3012 return true;
3013 }
3014
3015 void fixupGetAndSetLocalsInBlock(BasicBlock* block)
3016 {
3017 if (!block)
3018 return;
3019 ASSERT(block->isReachable);
3020 m_block = block;
3021 for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
3022 Node* node = m_currentNode = block->at(m_indexInBlock);
3023 if (node->op() != SetLocal && node->op() != GetLocal)
3024 continue;
3025
3026 VariableAccessData* variable = node->variableAccessData();
3027 switch (node->op()) {
3028 case GetLocal:
3029 switch (variable->flushFormat()) {
3030 case FlushedDouble:
3031 node->setResult(NodeResultDouble);
3032 break;
3033 case FlushedInt52:
3034 node->setResult(NodeResultInt52);
3035 break;
3036 default:
3037 break;
3038 }
3039 break;
3040
3041 case SetLocal:
3042 // NOTE: Any type checks we put here may get hoisted by fixupChecksInBlock(). So, if we
3043 // add new type checking use kind for SetLocals, we need to modify that code as well.
3044
3045 switch (variable->flushFormat()) {
3046 case FlushedJSValue:
3047 break;
3048 case FlushedDouble:
3049 fixEdge<DoubleRepUse>(node->child1());
3050 break;
3051 case FlushedInt32:
3052 fixEdge<Int32Use>(node->child1());
3053 break;
3054 case FlushedInt52:
3055 fixEdge<Int52RepUse>(node->child1());
3056 break;
3057 case FlushedCell:
3058 fixEdge<CellUse>(node->child1());
3059 break;
3060 case FlushedBoolean:
3061 fixEdge<BooleanUse>(node->child1());
3062 break;
3063 default:
3064 RELEASE_ASSERT_NOT_REACHED();
3065 break;
3066 }
3067 break;
3068
3069 default:
3070 RELEASE_ASSERT_NOT_REACHED();
3071 break;
3072 }
3073 }
3074 m_insertionSet.execute(block);
3075 }
3076
3077 void addStringReplacePrimordialChecks(Node* searchRegExp)
3078 {
3079 Node* node = m_currentNode;
3080
3081 // Check that structure of searchRegExp is RegExp object
3082 m_insertionSet.insertNode(
3083 m_indexInBlock, SpecNone, Check, node->origin,
3084 Edge(searchRegExp, RegExpObjectUse));
3085
3086 auto emitPrimordialCheckFor = [&] (JSValue primordialProperty, UniquedStringImpl* propertyUID) {
3087 unsigned index = m_graph.identifiers().ensure(propertyUID);
3088
3089 Node* actualProperty = m_insertionSet.insertNode(
3090 m_indexInBlock, SpecNone, TryGetById, node->origin,
3091 OpInfo(index), OpInfo(SpecFunction), Edge(searchRegExp, CellUse));
3092
3093 m_insertionSet.insertNode(
3094 m_indexInBlock, SpecNone, CheckCell, node->origin,
3095 OpInfo(m_graph.freeze(primordialProperty)), Edge(actualProperty, CellUse));
3096 };
3097
3098 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
3099
3100 // Check that searchRegExp.exec is the primordial RegExp.prototype.exec
3101 emitPrimordialCheckFor(globalObject->regExpProtoExecFunction(), vm().propertyNames->exec.impl());
3102 // Check that searchRegExp.global is the primordial RegExp.prototype.global
3103 emitPrimordialCheckFor(globalObject->regExpProtoGlobalGetter(), vm().propertyNames->global.impl());
3104 // Check that searchRegExp.unicode is the primordial RegExp.prototype.unicode
3105 emitPrimordialCheckFor(globalObject->regExpProtoUnicodeGetter(), vm().propertyNames->unicode.impl());
3106 // Check that searchRegExp[Symbol.match] is the primordial RegExp.prototype[Symbol.replace]
3107 emitPrimordialCheckFor(globalObject->regExpProtoSymbolReplaceFunction(), vm().propertyNames->replaceSymbol.impl());
3108 }
3109
3110 Node* checkArray(ArrayMode arrayMode, const NodeOrigin& origin, Node* array, Node* index, bool (*storageCheck)(const ArrayMode&) = canCSEStorage)
3111 {
3112 ASSERT(arrayMode.isSpecific());
3113
3114 if (arrayMode.type() == Array::String) {
3115 m_insertionSet.insertNode(
3116 m_indexInBlock, SpecNone, Check, origin, Edge(array, StringUse));
3117 } else {
3118 // Note that we only need to be using a structure check if we opt for SaneChain, since
3119 // that needs to protect against JSArray's __proto__ being changed.
3120 Structure* structure = arrayMode.originalArrayStructure(m_graph, origin.semantic);
3121
3122 Edge indexEdge = index ? Edge(index, Int32Use) : Edge();
3123
3124 if (arrayMode.doesConversion()) {
3125 if (structure) {
3126 m_insertionSet.insertNode(
3127 m_indexInBlock, SpecNone, ArrayifyToStructure, origin,
3128 OpInfo(m_graph.registerStructure(structure)), OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
3129 } else {
3130 m_insertionSet.insertNode(
3131 m_indexInBlock, SpecNone, Arrayify, origin,
3132 OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
3133 }
3134 } else {
3135 if (structure) {
3136 m_insertionSet.insertNode(
3137 m_indexInBlock, SpecNone, CheckStructure, origin,
3138 OpInfo(m_graph.addStructureSet(structure)), Edge(array, CellUse));
3139 } else {
3140 m_insertionSet.insertNode(
3141 m_indexInBlock, SpecNone, CheckArray, origin,
3142 OpInfo(arrayMode.asWord()), Edge(array, CellUse));
3143 }
3144 }
3145 }
3146
3147 if (!storageCheck(arrayMode))
3148 return nullptr;
3149
3150 if (arrayMode.usesButterfly()) {
3151 return m_insertionSet.insertNode(
3152 m_indexInBlock, SpecNone, GetButterfly, origin, Edge(array, CellUse));
3153 }
3154
3155 return m_insertionSet.insertNode(
3156 m_indexInBlock, SpecNone, GetIndexedPropertyStorage, origin,
3157 OpInfo(arrayMode.asWord()), Edge(array, KnownCellUse));
3158 }
3159
3160 void blessArrayOperation(Edge base, Edge index, Edge& storageChild)
3161 {
3162 Node* node = m_currentNode;
3163
3164 switch (node->arrayMode().type()) {
3165 case Array::ForceExit: {
3166 m_insertionSet.insertNode(
3167 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
3168 return;
3169 }
3170
3171 case Array::SelectUsingPredictions:
3172 case Array::Unprofiled:
3173 RELEASE_ASSERT_NOT_REACHED();
3174 return;
3175
3176 case Array::Generic:
3177 return;
3178
3179 default: {
3180 Node* storage = checkArray(node->arrayMode(), node->origin, base.node(), index.node());
3181 if (!storage)
3182 return;
3183
3184 storageChild = Edge(storage);
3185 return;
3186 } }
3187 }
3188
3189 bool alwaysUnboxSimplePrimitives()
3190 {
3191#if USE(JSVALUE64)
3192 return false;
3193#else
3194 // Any boolean, int, or cell value is profitable to unbox on 32-bit because it
3195 // reduces traffic.
3196 return true;
3197#endif
3198 }
3199
3200 template<UseKind useKind>
3201 void observeUseKindOnNode(Node* node)
3202 {
3203 if (useKind == UntypedUse)
3204 return;
3205 observeUseKindOnNode(node, useKind);
3206 }
3207
3208 void observeUseKindOnEdge(Edge edge)
3209 {
3210 observeUseKindOnNode(edge.node(), edge.useKind());
3211 }
3212
3213 void observeUseKindOnNode(Node* node, UseKind useKind)
3214 {
3215 if (node->op() != GetLocal)
3216 return;
3217
3218 // FIXME: The way this uses alwaysUnboxSimplePrimitives() is suspicious.
3219 // https://bugs.webkit.org/show_bug.cgi?id=121518
3220
3221 VariableAccessData* variable = node->variableAccessData();
3222 switch (useKind) {
3223 case Int32Use:
3224 case KnownInt32Use:
3225 if (alwaysUnboxSimplePrimitives()
3226 || isInt32Speculation(variable->prediction()))
3227 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
3228 break;
3229 case NumberUse:
3230 case RealNumberUse:
3231 case DoubleRepUse:
3232 case DoubleRepRealUse:
3233 if (variable->doubleFormatState() == UsingDoubleFormat)
3234 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
3235 break;
3236 case BooleanUse:
3237 case KnownBooleanUse:
3238 if (alwaysUnboxSimplePrimitives()
3239 || isBooleanSpeculation(variable->prediction()))
3240 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
3241 break;
3242 case Int52RepUse:
3243 if (!isInt32Speculation(variable->prediction()) && isInt32OrInt52Speculation(variable->prediction()))
3244 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
3245 break;
3246 case CellUse:
3247 case KnownCellUse:
3248 case ObjectUse:
3249 case FunctionUse:
3250 case StringUse:
3251 case KnownStringUse:
3252 case SymbolUse:
3253 case BigIntUse:
3254 case StringObjectUse:
3255 case StringOrStringObjectUse:
3256 if (alwaysUnboxSimplePrimitives()
3257 || isCellSpeculation(variable->prediction()))
3258 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
3259 break;
3260 default:
3261 break;
3262 }
3263 }
3264
3265 template<UseKind useKind>
3266 void fixEdge(Edge& edge)
3267 {
3268 observeUseKindOnNode<useKind>(edge.node());
3269 edge.setUseKind(useKind);
3270 }
3271
3272 unsigned indexForChecks()
3273 {
3274 unsigned index = m_indexInBlock;
3275 while (!m_block->at(index)->origin.exitOK)
3276 index--;
3277 return index;
3278 }
3279
3280 NodeOrigin originForCheck(unsigned index)
3281 {
3282 return m_block->at(index)->origin.withSemantic(m_currentNode->origin.semantic);
3283 }
3284
3285 void speculateForBarrier(Edge value)
3286 {
3287 // Currently, the DFG won't take advantage of this speculation. But, we want to do it in
3288 // the DFG anyway because if such a speculation would be wrong, we want to know before
3289 // we do an expensive compile.
3290
3291 if (value->shouldSpeculateInt32()) {
3292 insertCheck<Int32Use>(value.node());
3293 return;
3294 }
3295
3296 if (value->shouldSpeculateBoolean()) {
3297 insertCheck<BooleanUse>(value.node());
3298 return;
3299 }
3300
3301 if (value->shouldSpeculateOther()) {
3302 insertCheck<OtherUse>(value.node());
3303 return;
3304 }
3305
3306 if (value->shouldSpeculateNumber()) {
3307 insertCheck<NumberUse>(value.node());
3308 return;
3309 }
3310
3311 if (value->shouldSpeculateNotCell()) {
3312 insertCheck<NotCellUse>(value.node());
3313 return;
3314 }
3315 }
3316
3317 template<UseKind useKind>
3318 void insertCheck(Node* node)
3319 {
3320 observeUseKindOnNode<useKind>(node);
3321 unsigned index = indexForChecks();
3322 m_insertionSet.insertNode(index, SpecNone, Check, originForCheck(index), Edge(node, useKind));
3323 }
3324
3325 void fixIntConvertingEdge(Edge& edge)
3326 {
3327 Node* node = edge.node();
3328 if (node->shouldSpeculateInt32OrBoolean()) {
3329 fixIntOrBooleanEdge(edge);
3330 return;
3331 }
3332
3333 UseKind useKind;
3334 if (node->shouldSpeculateInt52())
3335 useKind = Int52RepUse;
3336 else if (node->shouldSpeculateNumber())
3337 useKind = DoubleRepUse;
3338 else
3339 useKind = NotCellUse;
3340 Node* newNode = m_insertionSet.insertNode(
3341 m_indexInBlock, SpecInt32Only, ValueToInt32, m_currentNode->origin,
3342 Edge(node, useKind));
3343 observeUseKindOnNode(node, useKind);
3344
3345 edge = Edge(newNode, KnownInt32Use);
3346 }
3347
3348 void fixIntOrBooleanEdge(Edge& edge)
3349 {
3350 Node* node = edge.node();
3351 if (!node->sawBooleans()) {
3352 fixEdge<Int32Use>(edge);
3353 return;
3354 }
3355
3356 UseKind useKind;
3357 if (node->shouldSpeculateBoolean())
3358 useKind = BooleanUse;
3359 else
3360 useKind = UntypedUse;
3361 Node* newNode = m_insertionSet.insertNode(
3362 m_indexInBlock, SpecInt32Only, BooleanToNumber, m_currentNode->origin,
3363 Edge(node, useKind));
3364 observeUseKindOnNode(node, useKind);
3365
3366 edge = Edge(newNode, Int32Use);
3367 }
3368
3369 void fixDoubleOrBooleanEdge(Edge& edge)
3370 {
3371 Node* node = edge.node();
3372 if (!node->sawBooleans()) {
3373 fixEdge<DoubleRepUse>(edge);
3374 return;
3375 }
3376
3377 UseKind useKind;
3378 if (node->shouldSpeculateBoolean())
3379 useKind = BooleanUse;
3380 else
3381 useKind = UntypedUse;
3382 Node* newNode = m_insertionSet.insertNode(
3383 m_indexInBlock, SpecInt32Only, BooleanToNumber, m_currentNode->origin,
3384 Edge(node, useKind));
3385 observeUseKindOnNode(node, useKind);
3386
3387 edge = Edge(newNode, DoubleRepUse);
3388 }
3389
3390 void truncateConstantToInt32(Edge& edge)
3391 {
3392 Node* oldNode = edge.node();
3393
3394 JSValue value = oldNode->asJSValue();
3395 if (value.isInt32())
3396 return;
3397
3398 value = jsNumber(JSC::toInt32(value.asNumber()));
3399 ASSERT(value.isInt32());
3400 edge.setNode(m_insertionSet.insertNode(
3401 m_indexInBlock, SpecInt32Only, JSConstant, m_currentNode->origin,
3402 OpInfo(m_graph.freeze(value))));
3403 }
3404
3405 void truncateConstantsIfNecessary(Node* node, AddSpeculationMode mode)
3406 {
3407 if (mode != SpeculateInt32AndTruncateConstants)
3408 return;
3409
3410 ASSERT(node->child1()->hasConstant() || node->child2()->hasConstant());
3411 if (node->child1()->hasConstant())
3412 truncateConstantToInt32(node->child1());
3413 else
3414 truncateConstantToInt32(node->child2());
3415 }
3416
3417 bool attemptToMakeIntegerAdd(Node* node)
3418 {
3419 AddSpeculationMode mode = m_graph.addSpeculationMode(node, FixupPass);
3420 if (mode != DontSpeculateInt32) {
3421 truncateConstantsIfNecessary(node, mode);
3422 fixIntOrBooleanEdge(node->child1());
3423 fixIntOrBooleanEdge(node->child2());
3424 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
3425 node->setArithMode(Arith::Unchecked);
3426 else
3427 node->setArithMode(Arith::CheckOverflow);
3428 return true;
3429 }
3430
3431 if (m_graph.addShouldSpeculateInt52(node)) {
3432 fixEdge<Int52RepUse>(node->child1());
3433 fixEdge<Int52RepUse>(node->child2());
3434 node->setArithMode(Arith::CheckOverflow);
3435 node->setResult(NodeResultInt52);
3436 return true;
3437 }
3438
3439 return false;
3440 }
3441
3442 bool attemptToMakeGetArrayLength(Node* node)
3443 {
3444 if (!isInt32Speculation(node->prediction()))
3445 return false;
3446 CodeBlock* profiledBlock = m_graph.baselineCodeBlockFor(node->origin.semantic);
3447 ArrayProfile* arrayProfile =
3448 profiledBlock->getArrayProfile(node->origin.semantic.bytecodeIndex());
3449 ArrayMode arrayMode = ArrayMode(Array::SelectUsingPredictions, Array::Read);
3450 if (arrayProfile) {
3451 ConcurrentJSLocker locker(profiledBlock->m_lock);
3452 arrayProfile->computeUpdatedPrediction(locker, profiledBlock);
3453 arrayMode = ArrayMode::fromObserved(locker, arrayProfile, Array::Read, false);
3454 if (arrayMode.type() == Array::Unprofiled) {
3455 // For normal array operations, it makes sense to treat Unprofiled
3456 // accesses as ForceExit and get more data rather than using
3457 // predictions and then possibly ending up with a Generic. But here,
3458 // we treat anything that is Unprofiled as Generic and keep the
3459 // GetById. I.e. ForceExit = Generic. So, there is no harm - and only
3460 // profit - from treating the Unprofiled case as
3461 // SelectUsingPredictions.
3462 arrayMode = ArrayMode(Array::SelectUsingPredictions, Array::Read);
3463 }
3464 }
3465
3466 arrayMode = arrayMode.refine(
3467 m_graph, node, node->child1()->prediction(), node->prediction());
3468
3469 if (arrayMode.type() == Array::Generic) {
3470 // Check if the input is something that we can't get array length for, but for which we
3471 // could insert some conversions in order to transform it into something that we can do it
3472 // for.
3473 if (node->child1()->shouldSpeculateStringObject())
3474 attemptToForceStringArrayModeByToStringConversion<StringObjectUse>(arrayMode, node);
3475 else if (node->child1()->shouldSpeculateStringOrStringObject())
3476 attemptToForceStringArrayModeByToStringConversion<StringOrStringObjectUse>(arrayMode, node);
3477 }
3478
3479 if (!arrayMode.supportsSelfLength())
3480 return false;
3481
3482 convertToGetArrayLength(node, arrayMode);
3483 return true;
3484 }
3485
3486 void convertToGetArrayLength(Node* node, ArrayMode arrayMode)
3487 {
3488 node->setOp(GetArrayLength);
3489 node->clearFlags(NodeMustGenerate);
3490 fixEdge<KnownCellUse>(node->child1());
3491 node->setArrayMode(arrayMode);
3492
3493 Node* storage = checkArray(arrayMode, node->origin, node->child1().node(), 0, lengthNeedsStorage);
3494 if (!storage)
3495 return;
3496
3497 node->child2() = Edge(storage);
3498 }
3499
3500 Node* prependGetArrayLength(NodeOrigin origin, Node* child, ArrayMode arrayMode)
3501 {
3502 Node* storage = checkArray(arrayMode, origin, child, 0, lengthNeedsStorage);
3503 return m_insertionSet.insertNode(
3504 m_indexInBlock, SpecInt32Only, GetArrayLength, origin,
3505 OpInfo(arrayMode.asWord()), Edge(child, KnownCellUse), Edge(storage));
3506 }
3507
3508 void convertToHasIndexedProperty(Node* node)
3509 {
3510 node->setOp(HasIndexedProperty);
3511 node->clearFlags(NodeMustGenerate);
3512
3513 {
3514 unsigned firstChild = m_graph.m_varArgChildren.size();
3515 unsigned numChildren = 3;
3516 m_graph.m_varArgChildren.append(node->child1());
3517 m_graph.m_varArgChildren.append(node->child2());
3518 m_graph.m_varArgChildren.append(Edge());
3519 node->mergeFlags(NodeHasVarArgs);
3520 node->children = AdjacencyList(AdjacencyList::Variable, firstChild, numChildren);
3521 }
3522
3523 node->setArrayMode(
3524 node->arrayMode().refine(
3525 m_graph, node,
3526 m_graph.varArgChild(node, 0)->prediction(),
3527 m_graph.varArgChild(node, 1)->prediction(),
3528 SpecNone));
3529 node->setInternalMethodType(PropertySlot::InternalMethodType::HasProperty);
3530
3531 blessArrayOperation(m_graph.varArgChild(node, 0), m_graph.varArgChild(node, 1), m_graph.varArgChild(node, 2));
3532
3533 fixEdge<CellUse>(m_graph.varArgChild(node, 0));
3534 fixEdge<Int32Use>(m_graph.varArgChild(node, 1));
3535 }
3536
3537 void fixupNormalizeMapKey(Node* node)
3538 {
3539 if (node->child1()->shouldSpeculateBoolean()) {
3540 fixEdge<BooleanUse>(node->child1());
3541 node->convertToIdentity();
3542 return;
3543 }
3544
3545 if (node->child1()->shouldSpeculateInt32()) {
3546 fixEdge<Int32Use>(node->child1());
3547 node->convertToIdentity();
3548 return;
3549 }
3550
3551 if (node->child1()->shouldSpeculateSymbol()) {
3552 fixEdge<SymbolUse>(node->child1());
3553 node->convertToIdentity();
3554 return;
3555 }
3556
3557 if (node->child1()->shouldSpeculateObject()) {
3558 fixEdge<ObjectUse>(node->child1());
3559 node->convertToIdentity();
3560 return;
3561 }
3562
3563 if (node->child1()->shouldSpeculateString()) {
3564 fixEdge<StringUse>(node->child1());
3565 node->convertToIdentity();
3566 return;
3567 }
3568
3569 if (node->child1()->shouldSpeculateCell()) {
3570 fixEdge<CellUse>(node->child1());
3571 node->convertToIdentity();
3572 return;
3573 }
3574
3575 fixEdge<UntypedUse>(node->child1());
3576 }
3577
3578 bool attemptToMakeCallDOM(Node* node)
3579 {
3580 if (m_graph.hasExitSite(node->origin.semantic, BadType))
3581 return false;
3582
3583 const DOMJIT::Signature* signature = node->signature();
3584 if (!signature)
3585 return false;
3586
3587 {
3588 unsigned index = 0;
3589 bool shouldConvertToCallDOM = true;
3590 m_graph.doToChildren(node, [&](Edge& edge) {
3591 // Callee. Ignore this. DFGByteCodeParser already emit appropriate checks.
3592 if (!index)
3593 return;
3594
3595 if (index == 1) {
3596 // DOM node case.
3597 if (edge->shouldSpeculateNotCell())
3598 shouldConvertToCallDOM = false;
3599 } else {
3600 switch (signature->arguments[index - 2]) {
3601 case SpecString:
3602 if (edge->shouldSpeculateNotString())
3603 shouldConvertToCallDOM = false;
3604 break;
3605 case SpecInt32Only:
3606 if (edge->shouldSpeculateNotInt32())
3607 shouldConvertToCallDOM = false;
3608 break;
3609 case SpecBoolean:
3610 if (edge->shouldSpeculateNotBoolean())
3611 shouldConvertToCallDOM = false;
3612 break;
3613 default:
3614 RELEASE_ASSERT_NOT_REACHED();
3615 break;
3616 }
3617 }
3618 ++index;
3619 });
3620 if (!shouldConvertToCallDOM)
3621 return false;
3622 }
3623
3624 Node* thisNode = m_graph.varArgChild(node, 1).node();
3625 Node* checkSubClass = m_insertionSet.insertNode(m_indexInBlock, SpecNone, CheckSubClass, node->origin, OpInfo(signature->classInfo), Edge(thisNode));
3626 node->convertToCallDOM(m_graph);
3627 fixupCheckSubClass(checkSubClass);
3628 fixupCallDOM(node);
3629 return true;
3630 }
3631
3632 void fixupCheckSubClass(Node* node)
3633 {
3634 fixEdge<CellUse>(node->child1());
3635 }
3636
3637 void fixupCallDOM(Node* node)
3638 {
3639 const DOMJIT::Signature* signature = node->signature();
3640 auto fixup = [&](Edge& edge, unsigned argumentIndex) {
3641 if (!edge)
3642 return;
3643 switch (signature->arguments[argumentIndex]) {
3644 case SpecString:
3645 fixEdge<StringUse>(edge);
3646 break;
3647 case SpecInt32Only:
3648 fixEdge<Int32Use>(edge);
3649 break;
3650 case SpecBoolean:
3651 fixEdge<BooleanUse>(edge);
3652 break;
3653 default:
3654 RELEASE_ASSERT_NOT_REACHED();
3655 break;
3656 }
3657 };
3658 fixEdge<CellUse>(node->child1()); // DOM.
3659 fixup(node->child2(), 0);
3660 fixup(node->child3(), 1);
3661 }
3662
3663 void fixupArrayIndexOf(Node* node)
3664 {
3665 Edge& array = m_graph.varArgChild(node, 0);
3666 Edge& storage = m_graph.varArgChild(node, node->numChildren() == 3 ? 2 : 3);
3667 blessArrayOperation(array, Edge(), storage);
3668 ASSERT_WITH_MESSAGE(storage.node(), "blessArrayOperation for ArrayIndexOf must set Butterfly for storage edge.");
3669
3670 Edge& searchElement = m_graph.varArgChild(node, 1);
3671
3672 // Constant folding.
3673 switch (node->arrayMode().type()) {
3674 case Array::Double:
3675 case Array::Int32: {
3676 if (searchElement->shouldSpeculateCell()) {
3677 m_insertionSet.insertNode(m_indexInBlock, SpecNone, Check, node->origin, Edge(searchElement.node(), CellUse));
3678 m_graph.convertToConstant(node, jsNumber(-1));
3679 observeUseKindOnNode<CellUse>(searchElement.node());
3680 return;
3681 }
3682
3683 if (searchElement->shouldSpeculateOther()) {
3684 m_insertionSet.insertNode(m_indexInBlock, SpecNone, Check, node->origin, Edge(searchElement.node(), OtherUse));
3685 m_graph.convertToConstant(node, jsNumber(-1));
3686 observeUseKindOnNode<OtherUse>(searchElement.node());
3687 return;
3688 }
3689
3690 if (searchElement->shouldSpeculateBoolean()) {
3691 m_insertionSet.insertNode(m_indexInBlock, SpecNone, Check, node->origin, Edge(searchElement.node(), BooleanUse));
3692 m_graph.convertToConstant(node, jsNumber(-1));
3693 observeUseKindOnNode<BooleanUse>(searchElement.node());
3694 return;
3695 }
3696 break;
3697 }
3698 default:
3699 break;
3700 }
3701
3702 fixEdge<KnownCellUse>(array);
3703 if (node->numChildren() == 4)
3704 fixEdge<Int32Use>(m_graph.varArgChild(node, 2));
3705
3706 switch (node->arrayMode().type()) {
3707 case Array::Double: {
3708 if (searchElement->shouldSpeculateNumber())
3709 fixEdge<DoubleRepUse>(searchElement);
3710 return;
3711 }
3712 case Array::Int32: {
3713 if (searchElement->shouldSpeculateInt32())
3714 fixEdge<Int32Use>(searchElement);
3715 return;
3716 }
3717 case Array::Contiguous: {
3718 if (searchElement->shouldSpeculateString())
3719 fixEdge<StringUse>(searchElement);
3720 else if (searchElement->shouldSpeculateSymbol())
3721 fixEdge<SymbolUse>(searchElement);
3722 else if (searchElement->shouldSpeculateOther())
3723 fixEdge<OtherUse>(searchElement);
3724 else if (searchElement->shouldSpeculateObject())
3725 fixEdge<ObjectUse>(searchElement);
3726 return;
3727 }
3728 default:
3729 RELEASE_ASSERT_NOT_REACHED();
3730 return;
3731 }
3732 }
3733
3734 void fixupCompareStrictEqAndSameValue(Node* node)
3735 {
3736 ASSERT(node->op() == SameValue || node->op() == CompareStrictEq);
3737
3738 if (Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
3739 fixEdge<BooleanUse>(node->child1());
3740 fixEdge<BooleanUse>(node->child2());
3741 node->setOpAndDefaultFlags(CompareStrictEq);
3742 return;
3743 }
3744 if (Node::shouldSpeculateInt32(node->child1().node(), node->child2().node())) {
3745 fixEdge<Int32Use>(node->child1());
3746 fixEdge<Int32Use>(node->child2());
3747 node->setOpAndDefaultFlags(CompareStrictEq);
3748 return;
3749 }
3750 if (Node::shouldSpeculateInt52(node->child1().node(), node->child2().node())) {
3751 fixEdge<Int52RepUse>(node->child1());
3752 fixEdge<Int52RepUse>(node->child2());
3753 node->setOpAndDefaultFlags(CompareStrictEq);
3754 return;
3755 }
3756 if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
3757 fixEdge<DoubleRepUse>(node->child1());
3758 fixEdge<DoubleRepUse>(node->child2());
3759 // Do not convert SameValue to CompareStrictEq in this case since SameValue(NaN, NaN) and SameValue(-0, +0)
3760 // are not the same to CompareStrictEq(NaN, NaN) and CompareStrictEq(-0, +0).
3761 return;
3762 }
3763 if (Node::shouldSpeculateSymbol(node->child1().node(), node->child2().node())) {
3764 fixEdge<SymbolUse>(node->child1());
3765 fixEdge<SymbolUse>(node->child2());
3766 node->setOpAndDefaultFlags(CompareStrictEq);
3767 return;
3768 }
3769 if (Node::shouldSpeculateBigInt(node->child1().node(), node->child2().node())) {
3770 fixEdge<BigIntUse>(node->child1());
3771 fixEdge<BigIntUse>(node->child2());
3772 node->setOpAndDefaultFlags(CompareStrictEq);
3773 return;
3774 }
3775 if (node->child1()->shouldSpeculateStringIdent() && node->child2()->shouldSpeculateStringIdent()) {
3776 fixEdge<StringIdentUse>(node->child1());
3777 fixEdge<StringIdentUse>(node->child2());
3778 node->setOpAndDefaultFlags(CompareStrictEq);
3779 return;
3780 }
3781 if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 7) || m_graph.m_plan.isFTL())) {
3782 fixEdge<StringUse>(node->child1());
3783 fixEdge<StringUse>(node->child2());
3784 node->setOpAndDefaultFlags(CompareStrictEq);
3785 return;
3786 }
3787
3788 if (node->op() == SameValue) {
3789 if (node->child1()->shouldSpeculateObject()) {
3790 fixEdge<ObjectUse>(node->child1());
3791 node->setOpAndDefaultFlags(CompareStrictEq);
3792 return;
3793 }
3794 if (node->child2()->shouldSpeculateObject()) {
3795 fixEdge<ObjectUse>(node->child2());
3796 node->setOpAndDefaultFlags(CompareStrictEq);
3797 return;
3798 }
3799 } else {
3800 WatchpointSet* masqueradesAsUndefinedWatchpoint = m_graph.globalObjectFor(node->origin.semantic)->masqueradesAsUndefinedWatchpoint();
3801 if (masqueradesAsUndefinedWatchpoint->isStillValid()) {
3802 if (node->child1()->shouldSpeculateObject()) {
3803 m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
3804 fixEdge<ObjectUse>(node->child1());
3805 return;
3806 }
3807 if (node->child2()->shouldSpeculateObject()) {
3808 m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
3809 fixEdge<ObjectUse>(node->child2());
3810 return;
3811 }
3812 } else if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
3813 fixEdge<ObjectUse>(node->child1());
3814 fixEdge<ObjectUse>(node->child2());
3815 return;
3816 }
3817 }
3818
3819 if (node->child1()->shouldSpeculateSymbol()) {
3820 fixEdge<SymbolUse>(node->child1());
3821 node->setOpAndDefaultFlags(CompareStrictEq);
3822 return;
3823 }
3824 if (node->child2()->shouldSpeculateSymbol()) {
3825 fixEdge<SymbolUse>(node->child2());
3826 node->setOpAndDefaultFlags(CompareStrictEq);
3827 return;
3828 }
3829 if (node->child1()->shouldSpeculateMisc()) {
3830 fixEdge<MiscUse>(node->child1());
3831 node->setOpAndDefaultFlags(CompareStrictEq);
3832 return;
3833 }
3834 if (node->child2()->shouldSpeculateMisc()) {
3835 fixEdge<MiscUse>(node->child2());
3836 node->setOpAndDefaultFlags(CompareStrictEq);
3837 return;
3838 }
3839 if (node->child1()->shouldSpeculateStringIdent()
3840 && node->child2()->shouldSpeculateNotStringVar()) {
3841 fixEdge<StringIdentUse>(node->child1());
3842 fixEdge<NotStringVarUse>(node->child2());
3843 node->setOpAndDefaultFlags(CompareStrictEq);
3844 return;
3845 }
3846 if (node->child2()->shouldSpeculateStringIdent()
3847 && node->child1()->shouldSpeculateNotStringVar()) {
3848 fixEdge<StringIdentUse>(node->child2());
3849 fixEdge<NotStringVarUse>(node->child1());
3850 node->setOpAndDefaultFlags(CompareStrictEq);
3851 return;
3852 }
3853 if (node->child1()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 8) || m_graph.m_plan.isFTL())) {
3854 fixEdge<StringUse>(node->child1());
3855 node->setOpAndDefaultFlags(CompareStrictEq);
3856 return;
3857 }
3858 if (node->child2()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 8) || m_graph.m_plan.isFTL())) {
3859 fixEdge<StringUse>(node->child2());
3860 node->setOpAndDefaultFlags(CompareStrictEq);
3861 return;
3862 }
3863 }
3864
3865 void fixupChecksInBlock(BasicBlock* block)
3866 {
3867 if (!block)
3868 return;
3869 ASSERT(block->isReachable);
3870 m_block = block;
3871 unsigned indexForChecks = UINT_MAX;
3872 NodeOrigin originForChecks;
3873 for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
3874 Node* node = block->at(indexInBlock);
3875
3876 // If this is a node at which we could exit, then save its index. If nodes after this one
3877 // cannot exit, then we will hoist checks to here.
3878 if (node->origin.exitOK) {
3879 indexForChecks = indexInBlock;
3880 originForChecks = node->origin;
3881 }
3882
3883 originForChecks = originForChecks.withSemantic(node->origin.semantic);
3884
3885 // First, try to relax the representational demands of each node, in order to have
3886 // fewer conversions.
3887 switch (node->op()) {
3888 case MovHint:
3889 case Check:
3890 case CheckVarargs:
3891 m_graph.doToChildren(
3892 node,
3893 [&] (Edge& edge) {
3894 switch (edge.useKind()) {
3895 case DoubleRepUse:
3896 case DoubleRepRealUse:
3897 if (edge->hasDoubleResult())
3898 break;
3899
3900 if (edge->hasInt52Result())
3901 edge.setUseKind(Int52RepUse);
3902 else if (edge.useKind() == DoubleRepUse)
3903 edge.setUseKind(NumberUse);
3904 break;
3905
3906 case Int52RepUse:
3907 // Nothing we can really do.
3908 break;
3909
3910 case UntypedUse:
3911 case NumberUse:
3912 if (edge->hasDoubleResult())
3913 edge.setUseKind(DoubleRepUse);
3914 else if (edge->hasInt52Result())
3915 edge.setUseKind(Int52RepUse);
3916 break;
3917
3918 case RealNumberUse:
3919 if (edge->hasDoubleResult())
3920 edge.setUseKind(DoubleRepRealUse);
3921 else if (edge->hasInt52Result())
3922 edge.setUseKind(Int52RepUse);
3923 break;
3924
3925 default:
3926 break;
3927 }
3928 });
3929 break;
3930
3931 case ValueToInt32:
3932 if (node->child1().useKind() == DoubleRepUse
3933 && !node->child1()->hasDoubleResult()) {
3934 node->child1().setUseKind(NumberUse);
3935 break;
3936 }
3937 break;
3938
3939 default:
3940 break;
3941 }
3942
3943 // Now, insert type conversions if necessary.
3944 m_graph.doToChildren(
3945 node,
3946 [&] (Edge& edge) {
3947 Node* result = nullptr;
3948
3949 switch (edge.useKind()) {
3950 case DoubleRepUse:
3951 case DoubleRepRealUse:
3952 case DoubleRepAnyIntUse: {
3953 if (edge->hasDoubleResult())
3954 break;
3955
3956 ASSERT(indexForChecks != UINT_MAX);
3957 if (edge->isNumberConstant()) {
3958 result = m_insertionSet.insertNode(
3959 indexForChecks, SpecBytecodeDouble, DoubleConstant, originForChecks,
3960 OpInfo(m_graph.freeze(jsDoubleNumber(edge->asNumber()))));
3961 } else if (edge->hasInt52Result()) {
3962 result = m_insertionSet.insertNode(
3963 indexForChecks, SpecAnyIntAsDouble, DoubleRep, originForChecks,
3964 Edge(edge.node(), Int52RepUse));
3965 } else {
3966 UseKind useKind;
3967 if (edge->shouldSpeculateDoubleReal())
3968 useKind = RealNumberUse;
3969 else if (edge->shouldSpeculateNumber())
3970 useKind = NumberUse;
3971 else
3972 useKind = NotCellUse;
3973
3974 result = m_insertionSet.insertNode(
3975 indexForChecks, SpecBytecodeDouble, DoubleRep, originForChecks,
3976 Edge(edge.node(), useKind));
3977 }
3978
3979 edge.setNode(result);
3980 break;
3981 }
3982
3983 case Int52RepUse: {
3984 if (edge->hasInt52Result())
3985 break;
3986
3987 ASSERT(indexForChecks != UINT_MAX);
3988 if (edge->isAnyIntConstant()) {
3989 result = m_insertionSet.insertNode(
3990 indexForChecks, SpecInt52Any, Int52Constant, originForChecks,
3991 OpInfo(edge->constant()));
3992 } else if (edge->hasDoubleResult()) {
3993 result = m_insertionSet.insertNode(
3994 indexForChecks, SpecInt52Any, Int52Rep, originForChecks,
3995 Edge(edge.node(), DoubleRepAnyIntUse));
3996 } else if (edge->shouldSpeculateInt32ForArithmetic()) {
3997 result = m_insertionSet.insertNode(
3998 indexForChecks, SpecInt32Only, Int52Rep, originForChecks,
3999 Edge(edge.node(), Int32Use));
4000 } else {
4001 result = m_insertionSet.insertNode(
4002 indexForChecks, SpecInt52Any, Int52Rep, originForChecks,
4003 Edge(edge.node(), AnyIntUse));
4004 }
4005
4006 edge.setNode(result);
4007 break;
4008 }
4009
4010 default: {
4011 if (!edge->hasDoubleResult() && !edge->hasInt52Result())
4012 break;
4013
4014 ASSERT(indexForChecks != UINT_MAX);
4015 if (edge->hasDoubleResult()) {
4016 result = m_insertionSet.insertNode(
4017 indexForChecks, SpecBytecodeDouble, ValueRep, originForChecks,
4018 Edge(edge.node(), DoubleRepUse));
4019 } else {
4020 result = m_insertionSet.insertNode(
4021 indexForChecks, SpecInt32Only | SpecAnyIntAsDouble, ValueRep,
4022 originForChecks, Edge(edge.node(), Int52RepUse));
4023 }
4024
4025 edge.setNode(result);
4026 break;
4027 } }
4028
4029 // It's remotely possible that this node cannot do type checks, but we now have a
4030 // type check on this node. We don't have to handle the general form of this
4031 // problem. It only arises when ByteCodeParser emits an immediate SetLocal, rather
4032 // than a delayed one. So, we only worry about those checks that we may have put on
4033 // a SetLocal. Note that "indexForChecks != indexInBlock" is just another way of
4034 // saying "!node->origin.exitOK".
4035 if (indexForChecks != indexInBlock && mayHaveTypeCheck(edge.useKind())) {
4036 UseKind knownUseKind;
4037
4038 switch (edge.useKind()) {
4039 case Int32Use:
4040 knownUseKind = KnownInt32Use;
4041 break;
4042 case CellUse:
4043 knownUseKind = KnownCellUse;
4044 break;
4045 case BooleanUse:
4046 knownUseKind = KnownBooleanUse;
4047 break;
4048 default:
4049 // This can only arise if we have a Check node, and in that case, we can
4050 // just remove the original check.
4051 DFG_ASSERT(m_graph, node, node->op() == Check, node->op(), edge.useKind());
4052 knownUseKind = UntypedUse;
4053 break;
4054 }
4055
4056 ASSERT(indexForChecks != UINT_MAX);
4057 m_insertionSet.insertNode(
4058 indexForChecks, SpecNone, Check, originForChecks, edge);
4059
4060 edge.setUseKind(knownUseKind);
4061 }
4062 });
4063 }
4064
4065 m_insertionSet.execute(block);
4066 }
4067
4068 BasicBlock* m_block;
4069 unsigned m_indexInBlock;
4070 Node* m_currentNode;
4071 InsertionSet m_insertionSet;
4072 bool m_profitabilityChanged;
4073};
4074
4075bool performFixup(Graph& graph)
4076{
4077 return runPhase<FixupPhase>(graph);
4078}
4079
4080} } // namespace JSC::DFG
4081
4082#endif // ENABLE(DFG_JIT)
4083
4084