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