2 * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "DFGFixupPhase.h"
31 #include "ArrayPrototype.h"
33 #include "DFGInferredTypeCheck.h"
34 #include "DFGInsertionSet.h"
36 #include "DFGPredictionPropagationPhase.h"
37 #include "DFGVariableAccessDataDump.h"
38 #include "JSCInlines.h"
39 #include "TypeLocation.h"
41 namespace JSC { namespace DFG {
43 class FixupPhase : public Phase {
45 FixupPhase(Graph& graph)
46 : Phase(graph, "fixup")
47 , m_insertionSet(graph)
53 ASSERT(m_graph.m_fixpointState == BeforeFixpoint);
54 ASSERT(m_graph.m_form == ThreadedCPS);
56 m_profitabilityChanged = false;
57 for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
58 fixupBlock(m_graph.block(blockIndex));
60 while (m_profitabilityChanged) {
61 m_profitabilityChanged = false;
63 for (unsigned i = m_graph.m_argumentPositions.size(); i--;)
64 m_graph.m_argumentPositions[i].mergeArgumentUnboxingAwareness();
66 for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
67 fixupGetAndSetLocalsInBlock(m_graph.block(blockIndex));
70 for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
71 fixupChecksInBlock(m_graph.block(blockIndex));
73 m_graph.m_planStage = PlanStage::AfterFixup;
79 void fixupBlock(BasicBlock* block)
83 ASSERT(block->isReachable);
85 for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
86 m_currentNode = block->at(m_indexInBlock);
87 fixupNode(m_currentNode);
89 m_insertionSet.execute(block);
92 void fixupNode(Node* node)
94 NodeType op = node->op();
98 // This gets handled by fixupGetAndSetLocalsInBlock().
108 if (Node::shouldSpeculateUntypedForBitOps(node->child1().node(), node->child2().node())) {
109 fixEdge<UntypedUse>(node->child1());
110 fixEdge<UntypedUse>(node->child2());
113 fixIntConvertingEdge(node->child1());
114 fixIntConvertingEdge(node->child2());
119 fixIntConvertingEdge(node->child1());
120 fixIntConvertingEdge(node->child2());
121 node->setOp(ArithMul);
122 node->setArithMode(Arith::Unchecked);
123 node->child1().setUseKind(Int32Use);
124 node->child2().setUseKind(Int32Use);
129 if (node->child1()->shouldSpeculateNotCell()) {
130 fixIntConvertingEdge(node->child1());
131 node->clearFlags(NodeMustGenerate);
133 fixEdge<UntypedUse>(node->child1());
137 case UInt32ToNumber: {
138 fixIntConvertingEdge(node->child1());
139 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
140 node->convertToIdentity();
141 else if (node->canSpeculateInt32(FixupPass))
142 node->setArithMode(Arith::CheckOverflow);
144 node->setArithMode(Arith::DoOverflow);
145 node->setResult(enableInt52() ? NodeResultInt52 : NodeResultDouble);
151 if (attemptToMakeIntegerAdd(node)) {
152 node->setOp(ArithAdd);
155 if (Node::shouldSpeculateNumberOrBooleanExpectingDefined(node->child1().node(), node->child2().node())) {
156 fixDoubleOrBooleanEdge(node->child1());
157 fixDoubleOrBooleanEdge(node->child2());
158 node->setOp(ArithAdd);
159 node->setResult(NodeResultDouble);
163 if (attemptToMakeFastStringAdd(node))
166 Edge& child1 = node->child1();
167 Edge& child2 = node->child2();
168 if (child1->shouldSpeculateString() || child2->shouldSpeculateString()) {
169 if (child1->shouldSpeculateInt32() || child2->shouldSpeculateInt32()) {
170 auto convertString = [&](Node* node, Edge& edge) {
171 if (edge->shouldSpeculateInt32())
172 convertStringAddUse<Int32Use>(node, edge);
174 ASSERT(edge->shouldSpeculateString());
175 convertStringAddUse<StringUse>(node, edge);
178 convertString(node, child1);
179 convertString(node, child2);
180 convertToMakeRope(node);
185 fixEdge<UntypedUse>(child1);
186 fixEdge<UntypedUse>(child2);
187 node->setResult(NodeResultJS);
192 if (attemptToMakeFastStringAdd(node))
195 // FIXME: Remove empty string arguments and possibly turn this into a ToString operation. That
196 // would require a form of ToString that takes a KnownPrimitiveUse. This is necessary because
197 // the implementation of StrCat doesn't dynamically optimize for empty strings.
198 // https://bugs.webkit.org/show_bug.cgi?id=148540
199 m_graph.doToChildren(
202 fixEdge<KnownPrimitiveUse>(edge);
203 // StrCat automatically coerces the values into strings before concatenating them.
204 // The ECMA spec says that we're not allowed to automatically coerce a Symbol into
205 // a string. If a Symbol is encountered, a TypeError will be thrown. As a result,
206 // our runtime functions for this slow path expect that they will never be passed
208 m_insertionSet.insertNode(
209 m_indexInBlock, SpecNone, Check, node->origin,
210 Edge(edge.node(), NotSymbolUse));
223 && Node::shouldSpeculateUntypedForArithmetic(node->child1().node(), node->child2().node())) {
224 fixEdge<UntypedUse>(node->child1());
225 fixEdge<UntypedUse>(node->child2());
226 node->setResult(NodeResultJS);
229 if (attemptToMakeIntegerAdd(node))
231 fixDoubleOrBooleanEdge(node->child1());
232 fixDoubleOrBooleanEdge(node->child2());
233 node->setResult(NodeResultDouble);
238 if (node->child1()->shouldSpeculateInt32OrBoolean() && node->canSpeculateInt32(FixupPass)) {
239 fixIntOrBooleanEdge(node->child1());
240 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
241 node->setArithMode(Arith::Unchecked);
242 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
243 node->setArithMode(Arith::CheckOverflow);
245 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
246 node->setResult(NodeResultInt32);
247 node->clearFlags(NodeMustGenerate);
250 if (m_graph.unaryArithShouldSpeculateAnyInt(node, FixupPass)) {
251 fixEdge<Int52RepUse>(node->child1());
252 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
253 node->setArithMode(Arith::CheckOverflow);
255 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
256 node->setResult(NodeResultInt52);
257 node->clearFlags(NodeMustGenerate);
260 if (node->child1()->shouldSpeculateNotCell()) {
261 fixDoubleOrBooleanEdge(node->child1());
262 node->setResult(NodeResultDouble);
263 node->clearFlags(NodeMustGenerate);
265 fixEdge<UntypedUse>(node->child1());
270 Edge& leftChild = node->child1();
271 Edge& rightChild = node->child2();
272 if (Node::shouldSpeculateUntypedForArithmetic(leftChild.node(), rightChild.node())) {
273 fixEdge<UntypedUse>(leftChild);
274 fixEdge<UntypedUse>(rightChild);
275 node->setResult(NodeResultJS);
278 if (m_graph.binaryArithShouldSpeculateInt32(node, FixupPass)) {
279 fixIntOrBooleanEdge(leftChild);
280 fixIntOrBooleanEdge(rightChild);
281 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
282 node->setArithMode(Arith::Unchecked);
283 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())
284 || leftChild.node() == rightChild.node())
285 node->setArithMode(Arith::CheckOverflow);
287 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
290 if (m_graph.binaryArithShouldSpeculateAnyInt(node, FixupPass)) {
291 fixEdge<Int52RepUse>(leftChild);
292 fixEdge<Int52RepUse>(rightChild);
293 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())
294 || leftChild.node() == rightChild.node())
295 node->setArithMode(Arith::CheckOverflow);
297 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
298 node->setResult(NodeResultInt52);
301 fixDoubleOrBooleanEdge(leftChild);
302 fixDoubleOrBooleanEdge(rightChild);
303 node->setResult(NodeResultDouble);
309 Edge& leftChild = node->child1();
310 Edge& rightChild = node->child2();
312 && Node::shouldSpeculateUntypedForArithmetic(leftChild.node(), rightChild.node())
313 && m_graph.hasExitSite(node->origin.semantic, BadType)) {
314 fixEdge<UntypedUse>(leftChild);
315 fixEdge<UntypedUse>(rightChild);
316 node->setResult(NodeResultJS);
319 if (m_graph.binaryArithShouldSpeculateInt32(node, FixupPass)) {
320 if (optimizeForX86() || optimizeForARM64() || optimizeForARMv7IDIVSupported()) {
321 fixIntOrBooleanEdge(leftChild);
322 fixIntOrBooleanEdge(rightChild);
323 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
324 node->setArithMode(Arith::Unchecked);
325 else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
326 node->setArithMode(Arith::CheckOverflow);
328 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
332 // This will cause conversion nodes to be inserted later.
333 fixDoubleOrBooleanEdge(leftChild);
334 fixDoubleOrBooleanEdge(rightChild);
336 // We don't need to do ref'ing on the children because we're stealing them from
337 // the original division.
338 Node* newDivision = m_insertionSet.insertNode(
339 m_indexInBlock, SpecBytecodeDouble, *node);
340 newDivision->setResult(NodeResultDouble);
342 node->setOp(DoubleAsInt32);
343 node->children.initialize(Edge(newDivision, DoubleRepUse), Edge(), Edge());
344 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
345 node->setArithMode(Arith::CheckOverflow);
347 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
350 fixDoubleOrBooleanEdge(leftChild);
351 fixDoubleOrBooleanEdge(rightChild);
352 node->setResult(NodeResultDouble);
358 if (m_graph.binaryArithShouldSpeculateInt32(node, FixupPass)) {
359 fixIntOrBooleanEdge(node->child1());
360 fixIntOrBooleanEdge(node->child2());
363 fixDoubleOrBooleanEdge(node->child1());
364 fixDoubleOrBooleanEdge(node->child2());
365 node->setResult(NodeResultDouble);
370 if (node->child1()->shouldSpeculateInt32OrBoolean()
371 && node->canSpeculateInt32(FixupPass)) {
372 fixIntOrBooleanEdge(node->child1());
373 if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
374 node->setArithMode(Arith::Unchecked);
376 node->setArithMode(Arith::CheckOverflow);
377 node->clearFlags(NodeMustGenerate);
378 node->setResult(NodeResultInt32);
382 if (node->child1()->shouldSpeculateNotCell()) {
383 fixDoubleOrBooleanEdge(node->child1());
384 node->clearFlags(NodeMustGenerate);
386 fixEdge<UntypedUse>(node->child1());
387 node->setResult(NodeResultDouble);
392 if (node->child2()->shouldSpeculateInt32OrBooleanForArithmetic()) {
393 fixDoubleOrBooleanEdge(node->child1());
394 fixIntOrBooleanEdge(node->child2());
398 fixDoubleOrBooleanEdge(node->child1());
399 fixDoubleOrBooleanEdge(node->child2());
404 node->setResult(NodeResultDouble);
412 if (node->child1()->shouldSpeculateInt32OrBoolean() && m_graph.roundShouldSpeculateInt32(node, FixupPass)) {
413 fixIntOrBooleanEdge(node->child1());
414 insertCheck<Int32Use>(node->child1().node());
415 node->convertToIdentity();
418 if (node->child1()->shouldSpeculateNotCell()) {
419 fixDoubleOrBooleanEdge(node->child1());
421 if (isInt32OrBooleanSpeculation(node->getHeapPrediction()) && m_graph.roundShouldSpeculateInt32(node, FixupPass)) {
422 node->setResult(NodeResultInt32);
423 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
424 node->setArithRoundingMode(Arith::RoundingMode::Int32);
426 node->setArithRoundingMode(Arith::RoundingMode::Int32WithNegativeZeroCheck);
428 node->setResult(NodeResultDouble);
429 node->setArithRoundingMode(Arith::RoundingMode::Double);
431 node->clearFlags(NodeMustGenerate);
433 fixEdge<UntypedUse>(node->child1());
440 Edge& child1 = node->child1();
441 if (child1->shouldSpeculateNotCell()) {
442 fixDoubleOrBooleanEdge(child1);
443 node->clearFlags(NodeMustGenerate);
445 fixEdge<UntypedUse>(child1);
450 if (node->child1()->shouldSpeculateBoolean()) {
451 if (node->child1()->result() == NodeResultBoolean) {
452 // This is necessary in case we have a bytecode instruction implemented by:
457 // In that case, CompareEq might have a side-effect. Then, we need to make
458 // sure that we know that Branch does not exit.
459 fixEdge<KnownBooleanUse>(node->child1());
461 fixEdge<BooleanUse>(node->child1());
462 } else if (node->child1()->shouldSpeculateObjectOrOther())
463 fixEdge<ObjectOrOtherUse>(node->child1());
464 else if (node->child1()->shouldSpeculateInt32OrBoolean())
465 fixIntOrBooleanEdge(node->child1());
466 else if (node->child1()->shouldSpeculateNumber())
467 fixEdge<DoubleRepUse>(node->child1());
468 else if (node->child1()->shouldSpeculateString())
469 fixEdge<StringUse>(node->child1());
470 else if (node->child1()->shouldSpeculateStringOrOther())
471 fixEdge<StringOrOtherUse>(node->child1());
473 WatchpointSet* masqueradesAsUndefinedWatchpoint = m_graph.globalObjectFor(node->origin.semantic)->masqueradesAsUndefinedWatchpoint();
474 if (masqueradesAsUndefinedWatchpoint->isStillValid())
475 m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
484 case CompareGreaterEq: {
485 if (node->op() == CompareEq
486 && Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
487 fixEdge<BooleanUse>(node->child1());
488 fixEdge<BooleanUse>(node->child2());
489 node->clearFlags(NodeMustGenerate);
492 if (Node::shouldSpeculateInt32OrBoolean(node->child1().node(), node->child2().node())) {
493 fixIntOrBooleanEdge(node->child1());
494 fixIntOrBooleanEdge(node->child2());
495 node->clearFlags(NodeMustGenerate);
499 && Node::shouldSpeculateAnyInt(node->child1().node(), node->child2().node())) {
500 fixEdge<Int52RepUse>(node->child1());
501 fixEdge<Int52RepUse>(node->child2());
502 node->clearFlags(NodeMustGenerate);
505 if (Node::shouldSpeculateNumberOrBoolean(node->child1().node(), node->child2().node())) {
506 fixDoubleOrBooleanEdge(node->child1());
507 fixDoubleOrBooleanEdge(node->child2());
509 if (node->op() != CompareEq
510 && node->child1()->shouldSpeculateNotCell()
511 && node->child2()->shouldSpeculateNotCell()) {
512 if (node->child1()->shouldSpeculateNumberOrBoolean())
513 fixDoubleOrBooleanEdge(node->child1());
515 fixEdge<DoubleRepUse>(node->child1());
516 if (node->child2()->shouldSpeculateNumberOrBoolean())
517 fixDoubleOrBooleanEdge(node->child2());
519 fixEdge<DoubleRepUse>(node->child2());
520 node->clearFlags(NodeMustGenerate);
523 if (node->child1()->shouldSpeculateStringIdent() && node->child2()->shouldSpeculateStringIdent()) {
524 fixEdge<StringIdentUse>(node->child1());
525 fixEdge<StringIdentUse>(node->child2());
526 node->clearFlags(NodeMustGenerate);
529 if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && GPRInfo::numberOfRegisters >= 7) {
530 fixEdge<StringUse>(node->child1());
531 fixEdge<StringUse>(node->child2());
532 node->clearFlags(NodeMustGenerate);
536 if (node->op() != CompareEq)
538 if (Node::shouldSpeculateSymbol(node->child1().node(), node->child2().node())) {
539 fixEdge<SymbolUse>(node->child1());
540 fixEdge<SymbolUse>(node->child2());
541 node->clearFlags(NodeMustGenerate);
544 if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
545 fixEdge<ObjectUse>(node->child1());
546 fixEdge<ObjectUse>(node->child2());
547 node->clearFlags(NodeMustGenerate);
551 // If either child can be proved to be Null or Undefined, comparing them is greatly simplified.
552 bool oneArgumentIsUsedAsSpecOther = false;
553 if (node->child1()->isUndefinedOrNullConstant()) {
554 fixEdge<OtherUse>(node->child1());
555 oneArgumentIsUsedAsSpecOther = true;
556 } else if (node->child1()->shouldSpeculateOther()) {
557 m_insertionSet.insertNode(m_indexInBlock, SpecNone, Check, node->origin,
558 Edge(node->child1().node(), OtherUse));
559 fixEdge<OtherUse>(node->child1());
560 oneArgumentIsUsedAsSpecOther = true;
562 if (node->child2()->isUndefinedOrNullConstant()) {
563 fixEdge<OtherUse>(node->child2());
564 oneArgumentIsUsedAsSpecOther = true;
565 } else if (node->child2()->shouldSpeculateOther()) {
566 m_insertionSet.insertNode(m_indexInBlock, SpecNone, Check, node->origin,
567 Edge(node->child2().node(), OtherUse));
568 fixEdge<OtherUse>(node->child2());
569 oneArgumentIsUsedAsSpecOther = true;
571 if (oneArgumentIsUsedAsSpecOther) {
572 node->clearFlags(NodeMustGenerate);
576 if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObjectOrOther()) {
577 fixEdge<ObjectUse>(node->child1());
578 fixEdge<ObjectOrOtherUse>(node->child2());
579 node->clearFlags(NodeMustGenerate);
582 if (node->child1()->shouldSpeculateObjectOrOther() && node->child2()->shouldSpeculateObject()) {
583 fixEdge<ObjectOrOtherUse>(node->child1());
584 fixEdge<ObjectUse>(node->child2());
585 node->clearFlags(NodeMustGenerate);
592 case CompareStrictEq: {
593 if (Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
594 fixEdge<BooleanUse>(node->child1());
595 fixEdge<BooleanUse>(node->child2());
598 if (Node::shouldSpeculateInt32(node->child1().node(), node->child2().node())) {
599 fixEdge<Int32Use>(node->child1());
600 fixEdge<Int32Use>(node->child2());
604 && Node::shouldSpeculateAnyInt(node->child1().node(), node->child2().node())) {
605 fixEdge<Int52RepUse>(node->child1());
606 fixEdge<Int52RepUse>(node->child2());
609 if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
610 fixEdge<DoubleRepUse>(node->child1());
611 fixEdge<DoubleRepUse>(node->child2());
614 if (Node::shouldSpeculateSymbol(node->child1().node(), node->child2().node())) {
615 fixEdge<SymbolUse>(node->child1());
616 fixEdge<SymbolUse>(node->child2());
619 if (node->child1()->shouldSpeculateStringIdent() && node->child2()->shouldSpeculateStringIdent()) {
620 fixEdge<StringIdentUse>(node->child1());
621 fixEdge<StringIdentUse>(node->child2());
624 if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 7) || isFTL(m_graph.m_plan.mode))) {
625 fixEdge<StringUse>(node->child1());
626 fixEdge<StringUse>(node->child2());
629 WatchpointSet* masqueradesAsUndefinedWatchpoint = m_graph.globalObjectFor(node->origin.semantic)->masqueradesAsUndefinedWatchpoint();
630 if (masqueradesAsUndefinedWatchpoint->isStillValid()) {
632 if (node->child1()->shouldSpeculateObject()) {
633 m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
634 fixEdge<ObjectUse>(node->child1());
637 if (node->child2()->shouldSpeculateObject()) {
638 m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
639 fixEdge<ObjectUse>(node->child2());
643 } else if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
644 fixEdge<ObjectUse>(node->child1());
645 fixEdge<ObjectUse>(node->child2());
648 if (node->child1()->shouldSpeculateSymbol()) {
649 fixEdge<SymbolUse>(node->child1());
652 if (node->child2()->shouldSpeculateSymbol()) {
653 fixEdge<SymbolUse>(node->child2());
656 if (node->child1()->shouldSpeculateMisc()) {
657 fixEdge<MiscUse>(node->child1());
660 if (node->child2()->shouldSpeculateMisc()) {
661 fixEdge<MiscUse>(node->child2());
664 if (node->child1()->shouldSpeculateStringIdent()
665 && node->child2()->shouldSpeculateNotStringVar()) {
666 fixEdge<StringIdentUse>(node->child1());
667 fixEdge<NotStringVarUse>(node->child2());
670 if (node->child2()->shouldSpeculateStringIdent()
671 && node->child1()->shouldSpeculateNotStringVar()) {
672 fixEdge<StringIdentUse>(node->child2());
673 fixEdge<NotStringVarUse>(node->child1());
676 if (node->child1()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 8) || isFTL(m_graph.m_plan.mode))) {
677 fixEdge<StringUse>(node->child1());
680 if (node->child2()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 8) || isFTL(m_graph.m_plan.mode))) {
681 fixEdge<StringUse>(node->child2());
687 case StringFromCharCode:
688 if (node->child1()->shouldSpeculateInt32())
689 fixEdge<Int32Use>(node->child1());
691 fixEdge<UntypedUse>(node->child1());
695 case StringCharCodeAt: {
696 // Currently we have no good way of refining these.
697 ASSERT(node->arrayMode() == ArrayMode(Array::String));
698 blessArrayOperation(node->child1(), node->child2(), node->child3());
699 fixEdge<KnownCellUse>(node->child1());
700 fixEdge<Int32Use>(node->child2());
705 if (!node->prediction()) {
706 m_insertionSet.insertNode(
707 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
711 node->arrayMode().refine(
713 node->child1()->prediction(),
714 node->child2()->prediction(),
717 blessArrayOperation(node->child1(), node->child2(), node->child3());
719 ArrayMode arrayMode = node->arrayMode();
720 switch (arrayMode.type()) {
721 case Array::Contiguous:
723 if (arrayMode.arrayClass() == Array::OriginalArray
724 && arrayMode.speculation() == Array::InBounds) {
725 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
726 if (globalObject->arrayPrototypeChainIsSane()) {
727 // Check if SaneChain will work on a per-type basis. Note that:
729 // 1) We don't want double arrays to sometimes return undefined, since
730 // that would require a change to the return type and it would pessimise
731 // things a lot. So, we'd only want to do that if we actually had
732 // evidence that we could read from a hole. That's pretty annoying.
733 // Likely the best way to handle that case is with an equivalent of
734 // SaneChain for OutOfBounds. For now we just detect when Undefined and
735 // NaN are indistinguishable according to backwards propagation, and just
736 // use SaneChain in that case. This happens to catch a lot of cases.
738 // 2) We don't want int32 array loads to have to do a hole check just to
739 // coerce to Undefined, since that would mean twice the checks.
741 // This has two implications. First, we have to do more checks than we'd
742 // like. It's unfortunate that we have to do the hole check. Second,
743 // some accesses that hit a hole will now need to take the full-blown
744 // out-of-bounds slow path. We can fix that with:
745 // https://bugs.webkit.org/show_bug.cgi?id=144668
747 bool canDoSaneChain = false;
748 switch (arrayMode.type()) {
749 case Array::Contiguous:
750 // This is happens to be entirely natural. We already would have
751 // returned any JSValue, and now we'll return Undefined. We still do
752 // the check but it doesn't require taking any kind of slow path.
753 canDoSaneChain = true;
757 if (!(node->flags() & NodeBytecodeUsesAsOther)) {
758 // Holes look like NaN already, so if the user doesn't care
759 // about the difference between Undefined and NaN then we can
761 canDoSaneChain = true;
769 if (canDoSaneChain) {
770 m_graph.registerAndWatchStructureTransition(globalObject->arrayPrototype()->structure());
771 m_graph.registerAndWatchStructureTransition(globalObject->objectPrototype()->structure());
772 if (globalObject->arrayPrototypeChainIsSane())
773 node->setArrayMode(arrayMode.withSpeculation(Array::SaneChain));
780 if ((node->prediction() & ~SpecString)
781 || m_graph.hasExitSite(node->origin.semantic, OutOfBounds))
782 node->setArrayMode(arrayMode.withSpeculation(Array::OutOfBounds));
789 arrayMode = node->arrayMode();
790 switch (arrayMode.type()) {
791 case Array::SelectUsingPredictions:
792 case Array::Unprofiled:
793 RELEASE_ASSERT_NOT_REACHED();
796 if (node->child1()->shouldSpeculateObject()) {
797 if (node->child2()->shouldSpeculateString()) {
798 fixEdge<ObjectUse>(node->child1());
799 fixEdge<StringUse>(node->child2());
803 if (node->child2()->shouldSpeculateSymbol()) {
804 fixEdge<ObjectUse>(node->child1());
805 fixEdge<SymbolUse>(node->child2());
809 #if USE(JSVALUE32_64)
810 fixEdge<CellUse>(node->child1()); // Speculating cell due to register pressure on 32-bit.
813 case Array::ForceExit:
816 fixEdge<KnownCellUse>(node->child1());
817 fixEdge<Int32Use>(node->child2());
821 switch (arrayMode.type()) {
823 if (!arrayMode.isOutOfBounds())
824 node->setResult(NodeResultDouble);
827 case Array::Float32Array:
828 case Array::Float64Array:
829 node->setResult(NodeResultDouble);
832 case Array::Uint32Array:
833 if (node->shouldSpeculateInt32())
835 if (node->shouldSpeculateAnyInt() && enableInt52())
836 node->setResult(NodeResultInt52);
838 node->setResult(NodeResultDouble);
850 case PutByValAlias: {
851 Edge& child1 = m_graph.varArgChild(node, 0);
852 Edge& child2 = m_graph.varArgChild(node, 1);
853 Edge& child3 = m_graph.varArgChild(node, 2);
856 node->arrayMode().refine(
858 child1->prediction(),
859 child2->prediction(),
860 child3->prediction()));
862 blessArrayOperation(child1, child2, m_graph.varArgChild(node, 3));
864 switch (node->arrayMode().modeForPut().type()) {
865 case Array::SelectUsingPredictions:
866 case Array::SelectUsingArguments:
867 case Array::Unprofiled:
868 case Array::Undecided:
869 RELEASE_ASSERT_NOT_REACHED();
871 case Array::ForceExit:
873 if (child1->shouldSpeculateCell()) {
874 if (child2->shouldSpeculateString()) {
875 fixEdge<CellUse>(child1);
876 fixEdge<StringUse>(child2);
880 if (child2->shouldSpeculateSymbol()) {
881 fixEdge<CellUse>(child1);
882 fixEdge<SymbolUse>(child2);
886 #if USE(JSVALUE32_64)
887 // Due to register pressure on 32-bit, we speculate cell and
888 // ignore the base-is-not-cell case entirely by letting the
889 // baseline JIT handle it.
890 fixEdge<CellUse>(child1);
894 fixEdge<KnownCellUse>(child1);
895 fixEdge<Int32Use>(child2);
896 fixEdge<Int32Use>(child3);
899 fixEdge<KnownCellUse>(child1);
900 fixEdge<Int32Use>(child2);
901 fixEdge<DoubleRepRealUse>(child3);
903 case Array::Int8Array:
904 case Array::Int16Array:
905 case Array::Int32Array:
906 case Array::Uint8Array:
907 case Array::Uint8ClampedArray:
908 case Array::Uint16Array:
909 case Array::Uint32Array:
910 fixEdge<KnownCellUse>(child1);
911 fixEdge<Int32Use>(child2);
912 if (child3->shouldSpeculateInt32())
913 fixIntOrBooleanEdge(child3);
914 else if (child3->shouldSpeculateAnyInt())
915 fixEdge<Int52RepUse>(child3);
917 fixDoubleOrBooleanEdge(child3);
919 case Array::Float32Array:
920 case Array::Float64Array:
921 fixEdge<KnownCellUse>(child1);
922 fixEdge<Int32Use>(child2);
923 fixDoubleOrBooleanEdge(child3);
925 case Array::Contiguous:
926 case Array::ArrayStorage:
927 case Array::SlowPutArrayStorage:
928 fixEdge<KnownCellUse>(child1);
929 fixEdge<Int32Use>(child2);
930 speculateForBarrier(child3);
933 fixEdge<KnownCellUse>(child1);
934 fixEdge<Int32Use>(child2);
942 case AtomicsCompareExchange:
943 case AtomicsExchange:
949 Edge& base = m_graph.child(node, 0);
950 Edge& index = m_graph.child(node, 1);
952 bool badNews = false;
953 for (unsigned i = numExtraAtomicsArgs(node->op()); i--;) {
954 Edge& child = m_graph.child(node, 2 + i);
955 // NOTE: DFG is not smart enough to handle double->int conversions in atomics. So, we
956 // just call the function when that happens. But the FTL is totally cool with those
958 if (!child->shouldSpeculateInt32()
959 && !child->shouldSpeculateAnyInt()
960 && !(child->shouldSpeculateNumberOrBoolean() && isFTL(m_graph.m_plan.mode)))
965 node->setArrayMode(ArrayMode(Array::Generic));
970 node->arrayMode().refine(
971 m_graph, node, base->prediction(), index->prediction()));
973 if (node->arrayMode().type() == Array::Generic)
976 for (unsigned i = numExtraAtomicsArgs(node->op()); i--;) {
977 Edge& child = m_graph.child(node, 2 + i);
978 if (child->shouldSpeculateInt32())
979 fixIntOrBooleanEdge(child);
980 else if (child->shouldSpeculateAnyInt())
981 fixEdge<Int52RepUse>(child);
983 RELEASE_ASSERT(child->shouldSpeculateNumberOrBoolean() && isFTL(m_graph.m_plan.mode));
984 fixDoubleOrBooleanEdge(child);
988 blessArrayOperation(base, index, m_graph.child(node, 2 + numExtraAtomicsArgs(node->op())));
989 fixEdge<CellUse>(base);
990 fixEdge<Int32Use>(index);
992 if (node->arrayMode().type() == Array::Uint32Array) {
993 // NOTE: This means basically always doing Int52.
994 if (node->shouldSpeculateAnyInt() && enableInt52())
995 node->setResult(NodeResultInt52);
997 node->setResult(NodeResultDouble);
1002 case AtomicsIsLockFree:
1003 if (node->child1()->shouldSpeculateInt32())
1004 fixIntOrBooleanEdge(node->child1());
1008 // May need to refine the array mode in case the value prediction contravenes
1009 // the array prediction. For example, we may have evidence showing that the
1010 // array is in Int32 mode, but the value we're storing is likely to be a double.
1011 // Then we should turn this into a conversion to Double array followed by the
1012 // push. On the other hand, we absolutely don't want to refine based on the
1013 // base prediction. If it has non-cell garbage in it, then we want that to be
1014 // ignored. That's because ArrayPush can't handle any array modes that aren't
1015 // array-related - so if refine() turned this into a "Generic" ArrayPush then
1016 // that would break things.
1017 Edge& storageEdge = m_graph.varArgChild(node, 0);
1018 Edge& arrayEdge = m_graph.varArgChild(node, 1);
1019 unsigned elementOffset = 2;
1020 unsigned elementCount = node->numChildren() - elementOffset;
1021 for (unsigned i = 0; i < elementCount; ++i) {
1022 Edge& element = m_graph.varArgChild(node, i + elementOffset);
1024 node->arrayMode().refine(
1026 arrayEdge->prediction() & SpecCell,
1028 element->prediction()));
1030 blessArrayOperation(arrayEdge, Edge(), storageEdge);
1031 fixEdge<KnownCellUse>(arrayEdge);
1033 // Convert `array.push()` to GetArrayLength.
1034 if (!elementCount && node->arrayMode().supportsSelfLength()) {
1035 node->setOpAndDefaultFlags(GetArrayLength);
1036 node->child1() = arrayEdge;
1037 node->child2() = storageEdge;
1038 fixEdge<KnownCellUse>(node->child1());
1042 // We do not want to perform osr exit and retry for ArrayPush. We insert Check with appropriate type,
1043 // and ArrayPush uses the edge as known typed edge. Therefore, ArrayPush do not need to perform type checks.
1044 for (unsigned i = 0; i < elementCount; ++i) {
1045 Edge& element = m_graph.varArgChild(node, i + elementOffset);
1046 switch (node->arrayMode().type()) {
1048 insertCheck<Int32Use>(element.node());
1049 fixEdge<KnownInt32Use>(element);
1052 insertCheck<DoubleRepRealUse>(element.node());
1053 fixEdge<DoubleRepUse>(element);
1055 case Array::Contiguous:
1056 case Array::ArrayStorage:
1057 speculateForBarrier(element);
1062 ASSERT(shouldNotHaveTypeCheck(element.useKind()));
1068 blessArrayOperation(node->child1(), Edge(), node->child2());
1069 fixEdge<KnownCellUse>(node->child1());
1074 fixEdge<KnownCellUse>(m_graph.varArgChild(node, 0));
1075 fixEdge<Int32Use>(m_graph.varArgChild(node, 1));
1076 if (node->numChildren() == 4)
1077 fixEdge<Int32Use>(m_graph.varArgChild(node, 2));
1082 fixupArrayIndexOf(node);
1087 fixEdge<KnownCellUse>(node->child1());
1089 if (node->child2()->shouldSpeculateRegExpObject()) {
1090 fixEdge<RegExpObjectUse>(node->child2());
1092 if (node->child3()->shouldSpeculateString())
1093 fixEdge<StringUse>(node->child3());
1099 case StringReplaceRegExp: {
1100 if (node->child2()->shouldSpeculateString()) {
1101 m_insertionSet.insertNode(
1102 m_indexInBlock, SpecNone, Check, node->origin,
1103 Edge(node->child2().node(), StringUse));
1104 fixEdge<StringUse>(node->child2());
1105 } else if (op == StringReplace) {
1106 if (node->child2()->shouldSpeculateRegExpObject())
1107 addStringReplacePrimordialChecks(node->child2().node());
1109 m_insertionSet.insertNode(
1110 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
1113 if (node->child1()->shouldSpeculateString()
1114 && node->child2()->shouldSpeculateRegExpObject()
1115 && node->child3()->shouldSpeculateString()) {
1117 fixEdge<StringUse>(node->child1());
1118 fixEdge<RegExpObjectUse>(node->child2());
1119 fixEdge<StringUse>(node->child3());
1126 if (node->child1()->shouldSpeculateBoolean()) {
1127 if (node->child1()->result() == NodeResultBoolean) {
1128 // This is necessary in case we have a bytecode instruction implemented by:
1130 // a: CompareEq(...)
1133 // In that case, CompareEq might have a side-effect. Then, we need to make
1134 // sure that we know that Branch does not exit.
1135 fixEdge<KnownBooleanUse>(node->child1());
1137 fixEdge<BooleanUse>(node->child1());
1138 } else if (node->child1()->shouldSpeculateObjectOrOther())
1139 fixEdge<ObjectOrOtherUse>(node->child1());
1140 else if (node->child1()->shouldSpeculateInt32OrBoolean())
1141 fixIntOrBooleanEdge(node->child1());
1142 else if (node->child1()->shouldSpeculateNumber())
1143 fixEdge<DoubleRepUse>(node->child1());
1144 else if (node->child1()->shouldSpeculateString())
1145 fixEdge<StringUse>(node->child1());
1146 else if (node->child1()->shouldSpeculateStringOrOther())
1147 fixEdge<StringOrOtherUse>(node->child1());
1149 WatchpointSet* masqueradesAsUndefinedWatchpoint = m_graph.globalObjectFor(node->origin.semantic)->masqueradesAsUndefinedWatchpoint();
1150 if (masqueradesAsUndefinedWatchpoint->isStillValid())
1151 m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
1157 SwitchData* data = node->switchData();
1158 switch (data->kind) {
1160 if (node->child1()->shouldSpeculateInt32())
1161 fixEdge<Int32Use>(node->child1());
1164 if (node->child1()->shouldSpeculateString())
1165 fixEdge<StringUse>(node->child1());
1168 if (node->child1()->shouldSpeculateStringIdent())
1169 fixEdge<StringIdentUse>(node->child1());
1170 else if (node->child1()->shouldSpeculateString())
1171 fixEdge<StringUse>(node->child1());
1174 if (node->child1()->shouldSpeculateCell())
1175 fixEdge<CellUse>(node->child1());
1176 // else it's fine for this to have UntypedUse; we will handle this by just making
1177 // non-cells take the default case.
1184 fixupToPrimitive(node);
1189 fixupToNumber(node);
1194 case CallStringConstructor: {
1195 fixupToStringOrCallStringConstructor(node);
1199 case NewStringObject: {
1200 fixEdge<KnownStringUse>(node->child1());
1204 case NewArrayWithSpread: {
1205 watchHavingABadTime(node);
1207 BitVector* bitVector = node->bitVector();
1208 for (unsigned i = node->numChildren(); i--;) {
1209 if (bitVector->get(i))
1210 fixEdge<KnownCellUse>(m_graph.m_varArgChildren[node->firstChild() + i]);
1212 fixEdge<UntypedUse>(m_graph.m_varArgChildren[node->firstChild() + i]);
1219 // Note: We care about performing the protocol on our child's global object, not necessarily ours.
1221 watchHavingABadTime(node->child1().node());
1223 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->child1()->origin.semantic);
1224 // When we go down the fast path, we don't consult the prototype chain, so we must prove
1225 // that it doesn't contain any indexed properties, and that any holes will result in
1227 Structure* arrayPrototypeStructure = globalObject->arrayPrototype()->structure();
1228 Structure* objectPrototypeStructure = globalObject->objectPrototype()->structure();
1229 if (node->child1()->shouldSpeculateArray()
1230 && arrayPrototypeStructure->transitionWatchpointSetIsStillValid()
1231 && objectPrototypeStructure->transitionWatchpointSetIsStillValid()
1232 && globalObject->arrayPrototypeChainIsSane()
1233 && m_graph.isWatchingArrayIteratorProtocolWatchpoint(node->child1().node())
1234 && m_graph.isWatchingHavingABadTimeWatchpoint(node->child1().node())) {
1235 m_graph.registerAndWatchStructureTransition(objectPrototypeStructure);
1236 m_graph.registerAndWatchStructureTransition(arrayPrototypeStructure);
1237 fixEdge<ArrayUse>(node->child1());
1239 fixEdge<CellUse>(node->child1());
1244 watchHavingABadTime(node);
1246 for (unsigned i = m_graph.varArgNumChildren(node); i--;) {
1247 node->setIndexingType(
1248 leastUpperBoundOfIndexingTypeAndType(
1249 node->indexingType(), m_graph.varArgChild(node, i)->prediction()));
1251 switch (node->indexingType()) {
1252 case ALL_BLANK_INDEXING_TYPES:
1255 case ALL_UNDECIDED_INDEXING_TYPES:
1256 if (node->numChildren()) {
1257 // This will only happen if the children have no type predictions. We
1258 // would have already exited by now, but insert a forced exit just to
1260 m_insertionSet.insertNode(
1261 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
1264 case ALL_INT32_INDEXING_TYPES:
1265 for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
1266 fixEdge<Int32Use>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
1268 case ALL_DOUBLE_INDEXING_TYPES:
1269 for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
1270 fixEdge<DoubleRepRealUse>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
1272 case ALL_CONTIGUOUS_INDEXING_TYPES:
1273 case ALL_ARRAY_STORAGE_INDEXING_TYPES:
1282 case NewTypedArray: {
1283 watchHavingABadTime(node);
1285 if (node->child1()->shouldSpeculateInt32()) {
1286 fixEdge<Int32Use>(node->child1());
1287 node->clearFlags(NodeMustGenerate);
1293 case NewArrayWithSize: {
1294 watchHavingABadTime(node);
1295 fixEdge<Int32Use>(node->child1());
1299 case NewArrayBuffer: {
1300 watchHavingABadTime(node);
1305 fixupToObject(node);
1309 case CallObjectConstructor: {
1310 fixupCallObjectConstructor(node);
1319 case PutStructure: {
1320 fixEdge<KnownCellUse>(node->child1());
1325 case GetFromArguments: {
1326 fixEdge<KnownCellUse>(node->child1());
1331 case PutToArguments: {
1332 fixEdge<KnownCellUse>(node->child1());
1333 speculateForBarrier(node->child2());
1341 case GetGlobalObject: {
1342 fixEdge<KnownCellUse>(node->child1());
1346 case AllocatePropertyStorage:
1347 case ReallocatePropertyStorage: {
1348 fixEdge<KnownCellUse>(node->child1());
1352 case NukeStructureAndSetButterfly: {
1353 fixEdge<KnownCellUse>(node->child1());
1358 if (node->child1()->shouldSpeculateCell())
1359 fixEdge<CellUse>(node->child1());
1364 case GetByIdFlush: {
1365 // FIXME: This should be done in the ByteCodeParser based on reading the
1366 // PolymorphicAccess, which will surely tell us that this is a AccessCase::ArrayLength.
1367 // https://bugs.webkit.org/show_bug.cgi?id=154990
1368 auto uid = m_graph.identifiers()[node->identifierNumber()];
1369 if (node->child1()->shouldSpeculateCellOrOther()
1370 && !m_graph.hasExitSite(node->origin.semantic, BadType)
1371 && !m_graph.hasExitSite(node->origin.semantic, BadCache)
1372 && !m_graph.hasExitSite(node->origin.semantic, BadIndexingType)
1373 && !m_graph.hasExitSite(node->origin.semantic, ExoticObjectMode)) {
1375 if (uid == vm().propertyNames->length.impl()) {
1376 attemptToMakeGetArrayLength(node);
1380 if (uid == vm().propertyNames->lastIndex.impl()
1381 && node->child1()->shouldSpeculateRegExpObject()) {
1382 node->setOp(GetRegExpObjectLastIndex);
1383 node->clearFlags(NodeMustGenerate);
1384 fixEdge<RegExpObjectUse>(node->child1());
1389 if (node->child1()->shouldSpeculateNumber()) {
1390 if (uid == vm().propertyNames->toString.impl()) {
1391 if (m_graph.isWatchingNumberToStringWatchpoint(node)) {
1392 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
1393 if (node->child1()->shouldSpeculateInt32()) {
1394 insertCheck<Int32Use>(node->child1().node());
1395 m_graph.convertToConstant(node, m_graph.freeze(globalObject->numberProtoToStringFunction()));
1399 if (enableInt52() && node->child1()->shouldSpeculateAnyInt()) {
1400 insertCheck<Int52RepUse>(node->child1().node());
1401 m_graph.convertToConstant(node, m_graph.freeze(globalObject->numberProtoToStringFunction()));
1405 ASSERT(node->child1()->shouldSpeculateNumber());
1406 insertCheck<DoubleRepUse>(node->child1().node());
1407 m_graph.convertToConstant(node, m_graph.freeze(globalObject->numberProtoToStringFunction()));
1413 if (node->child1()->shouldSpeculateCell())
1414 fixEdge<CellUse>(node->child1());
1418 case GetByIdWithThis: {
1419 if (node->child1()->shouldSpeculateCell() && node->child2()->shouldSpeculateCell()) {
1420 fixEdge<CellUse>(node->child1());
1421 fixEdge<CellUse>(node->child2());
1428 case PutByIdDirect: {
1429 if (node->child1()->shouldSpeculateCellOrOther()
1430 && !m_graph.hasExitSite(node->origin.semantic, BadType)
1431 && !m_graph.hasExitSite(node->origin.semantic, BadCache)
1432 && !m_graph.hasExitSite(node->origin.semantic, BadIndexingType)
1433 && !m_graph.hasExitSite(node->origin.semantic, ExoticObjectMode)) {
1435 auto uid = m_graph.identifiers()[node->identifierNumber()];
1437 if (uid == vm().propertyNames->lastIndex.impl()
1438 && node->child1()->shouldSpeculateRegExpObject()) {
1439 node->setOp(SetRegExpObjectLastIndex);
1440 fixEdge<RegExpObjectUse>(node->child1());
1441 speculateForBarrier(node->child2());
1446 fixEdge<CellUse>(node->child1());
1451 case PutSetterById: {
1452 fixEdge<KnownCellUse>(node->child1());
1453 fixEdge<KnownCellUse>(node->child2());
1457 case PutGetterSetterById: {
1458 fixEdge<KnownCellUse>(node->child1());
1462 case PutGetterByVal:
1463 case PutSetterByVal: {
1464 fixEdge<KnownCellUse>(node->child1());
1465 fixEdge<KnownCellUse>(node->child3());
1469 case GetExecutable: {
1470 fixEdge<FunctionUse>(node->child1());
1474 case OverridesHasInstance:
1475 case CheckStructure:
1479 case GetButterflyWithoutCaging: {
1480 fixEdge<CellUse>(node->child1());
1484 case CheckStringIdent: {
1485 fixEdge<StringIdentUse>(node->child1());
1490 case ArrayifyToStructure: {
1491 fixEdge<CellUse>(node->child1());
1493 fixEdge<Int32Use>(node->child2());
1498 case GetGetterSetterByOffset: {
1499 if (!node->child1()->hasStorageResult())
1500 fixEdge<KnownCellUse>(node->child1());
1501 fixEdge<KnownCellUse>(node->child2());
1505 case MultiGetByOffset: {
1506 fixEdge<CellUse>(node->child1());
1511 if (!node->child1()->hasStorageResult())
1512 fixEdge<KnownCellUse>(node->child1());
1513 fixEdge<KnownCellUse>(node->child2());
1514 unsigned index = indexForChecks();
1515 insertInferredTypeCheck(
1516 m_insertionSet, index, originForCheck(index), node->child3().node(),
1517 node->storageAccessData().inferredType);
1518 speculateForBarrier(node->child3());
1522 case MultiPutByOffset: {
1523 fixEdge<CellUse>(node->child1());
1528 if (!(node->child1()->prediction() & ~SpecCell))
1529 fixEdge<CellUse>(node->child1());
1530 fixEdge<CellUse>(node->child2());
1534 case InstanceOfCustom:
1535 fixEdge<CellUse>(node->child2());
1539 if (node->child2()->shouldSpeculateInt32()) {
1540 convertToHasIndexedProperty(node);
1544 fixEdge<CellUse>(node->child1());
1548 case HasOwnProperty: {
1549 fixEdge<ObjectUse>(node->child1());
1550 #if (CPU(X86) || CPU(MIPS)) && USE(JSVALUE32_64)
1551 // We don't have enough registers to do anything interesting on x86 and mips.
1552 fixEdge<UntypedUse>(node->child2());
1554 if (node->child2()->shouldSpeculateString())
1555 fixEdge<StringUse>(node->child2());
1556 else if (node->child2()->shouldSpeculateSymbol())
1557 fixEdge<SymbolUse>(node->child2());
1559 fixEdge<UntypedUse>(node->child2());
1565 m_graph.doToChildren(
1568 switch (edge.useKind()) {
1570 if (edge->shouldSpeculateInt32ForArithmetic())
1571 edge.setUseKind(Int32Use);
1576 observeUseKindOnEdge(edge);
1582 // Phantoms are meaningless past Fixup. We recreate them on-demand in the backend.
1587 RELEASE_ASSERT(enableInt52());
1588 node->convertToIdentity();
1589 fixEdge<Int52RepUse>(node->child1());
1590 node->setResult(NodeResultInt52);
1594 case GetArrayLength: {
1595 fixEdge<KnownCellUse>(node->child1());
1599 case GetTypedArrayByteOffset: {
1600 fixEdge<KnownCellUse>(node->child1());
1605 case CompareBelowEq: {
1606 fixEdge<Int32Use>(node->child1());
1607 fixEdge<Int32Use>(node->child2());
1611 case GetPrototypeOf: {
1612 fixupGetPrototypeOf(node);
1619 case GetIndexedPropertyStorage:
1621 case CheckTierUpInLoop:
1622 case CheckTierUpAtReturn:
1623 case CheckTierUpAndOSREnter:
1624 case InvalidationPoint:
1627 case ConstantStoragePointer:
1634 case Identity: // This should have been cleaned up.
1635 case BooleanToNumber:
1636 case PhantomNewObject:
1637 case PhantomNewFunction:
1638 case PhantomNewGeneratorFunction:
1639 case PhantomNewAsyncGeneratorFunction:
1640 case PhantomNewAsyncFunction:
1641 case PhantomCreateActivation:
1642 case PhantomDirectArguments:
1643 case PhantomCreateRest:
1645 case PhantomNewArrayWithSpread:
1646 case PhantomClonedArguments:
1647 case GetMyArgumentByVal:
1648 case GetMyArgumentByValOutOfBounds:
1649 case GetVectorLength:
1651 case CheckStructureImmediate:
1652 case CheckStructureOrEmpty:
1653 case MaterializeNewObject:
1654 case MaterializeCreateActivation:
1659 case FencedStoreBarrier:
1660 case GetRegExpObjectLastIndex:
1661 case SetRegExpObjectLastIndex:
1662 case RecordRegExpCachedResult:
1663 // These are just nodes that we don't currently expect to see during fixup.
1664 // If we ever wanted to insert them prior to fixup, then we just have to create
1665 // fixup rules for them.
1666 DFG_CRASH(m_graph, node, "Unexpected node during fixup");
1669 case PutGlobalVariable: {
1670 fixEdge<CellUse>(node->child1());
1671 speculateForBarrier(node->child2());
1676 if (node->child1()->shouldSpeculateObject()) {
1677 m_insertionSet.insertNode(
1678 m_indexInBlock, SpecNone, Check, node->origin,
1679 Edge(node->child1().node(), ObjectUse));
1680 m_graph.convertToConstant(node, jsBoolean(true));
1681 observeUseKindOnNode<ObjectUse>(node);
1685 case IsCellWithType: {
1686 fixupIsCellWithType(node);
1690 case GetEnumerableLength: {
1691 fixEdge<CellUse>(node->child1());
1694 case HasGenericProperty: {
1695 fixEdge<CellUse>(node->child2());
1698 case HasStructureProperty: {
1699 fixEdge<StringUse>(node->child2());
1700 fixEdge<KnownCellUse>(node->child3());
1703 case HasIndexedProperty: {
1705 node->arrayMode().refine(
1707 node->child1()->prediction(),
1708 node->child2()->prediction(),
1711 blessArrayOperation(node->child1(), node->child2(), node->child3());
1712 fixEdge<CellUse>(node->child1());
1713 fixEdge<KnownInt32Use>(node->child2());
1716 case GetDirectPname: {
1717 Edge& base = m_graph.varArgChild(node, 0);
1718 Edge& property = m_graph.varArgChild(node, 1);
1719 Edge& index = m_graph.varArgChild(node, 2);
1720 Edge& enumerator = m_graph.varArgChild(node, 3);
1721 fixEdge<CellUse>(base);
1722 fixEdge<KnownCellUse>(property);
1723 fixEdge<KnownInt32Use>(index);
1724 fixEdge<KnownCellUse>(enumerator);
1727 case GetPropertyEnumerator: {
1728 fixEdge<CellUse>(node->child1());
1731 case GetEnumeratorStructurePname: {
1732 fixEdge<KnownCellUse>(node->child1());
1733 fixEdge<KnownInt32Use>(node->child2());
1736 case GetEnumeratorGenericPname: {
1737 fixEdge<KnownCellUse>(node->child1());
1738 fixEdge<KnownInt32Use>(node->child2());
1741 case ToIndexString: {
1742 fixEdge<KnownInt32Use>(node->child1());
1746 // We want to insert type checks based on the instructionTypeSet of the TypeLocation, not the globalTypeSet.
1747 // Because the instructionTypeSet is contained in globalTypeSet, if we produce a type check for
1748 // type T for the instructionTypeSet, the global type set must also have information for type T.
1749 // So if it the type check succeeds for type T in the instructionTypeSet, a type check for type T
1750 // in the globalTypeSet would've also succeeded.
1751 // (The other direction does not hold in general).
1753 RefPtr<TypeSet> typeSet = node->typeLocation()->m_instructionTypeSet;
1754 RuntimeTypeMask seenTypes = typeSet->seenTypes();
1755 if (typeSet->doesTypeConformTo(TypeAnyInt)) {
1756 if (node->child1()->shouldSpeculateInt32()) {
1757 fixEdge<Int32Use>(node->child1());
1762 if (enableInt52()) {
1763 fixEdge<AnyIntUse>(node->child1());
1768 // Must not perform fixEdge<NumberUse> here since the type set only includes TypeAnyInt. Double values should be logged.
1771 if (typeSet->doesTypeConformTo(TypeNumber | TypeAnyInt)) {
1772 fixEdge<NumberUse>(node->child1());
1774 } else if (typeSet->doesTypeConformTo(TypeString)) {
1775 fixEdge<StringUse>(node->child1());
1777 } else if (typeSet->doesTypeConformTo(TypeBoolean)) {
1778 fixEdge<BooleanUse>(node->child1());
1780 } else if (typeSet->doesTypeConformTo(TypeUndefined | TypeNull) && (seenTypes & TypeUndefined) && (seenTypes & TypeNull)) {
1781 fixEdge<OtherUse>(node->child1());
1783 } else if (typeSet->doesTypeConformTo(TypeObject)) {
1786 ConcurrentJSLocker locker(typeSet->m_lock);
1787 set = typeSet->structureSet(locker);
1789 if (!set.isEmpty()) {
1790 fixEdge<CellUse>(node->child1());
1791 node->convertToCheckStructure(m_graph.addStructureSet(set));
1798 case CreateClonedArguments: {
1799 watchHavingABadTime(node);
1803 case CreateScopedArguments:
1804 case CreateActivation:
1806 case NewGeneratorFunction:
1807 case NewAsyncGeneratorFunction:
1808 case NewAsyncFunction: {
1809 // Child 1 is always the current scope, which is guaranteed to be an object
1810 // FIXME: should be KnownObjectUse once that exists (https://bugs.webkit.org/show_bug.cgi?id=175689)
1811 fixEdge<KnownCellUse>(node->child1());
1815 case PushWithScope: {
1816 // Child 1 is always the current scope, which is guaranteed to be an object
1817 // FIXME: should be KnownObjectUse once that exists (https://bugs.webkit.org/show_bug.cgi?id=175689)
1818 fixEdge<KnownCellUse>(node->child1());
1819 if (node->child2()->shouldSpeculateObject())
1820 fixEdge<ObjectUse>(node->child2());
1824 case SetFunctionName: {
1825 // The first child is guaranteed to be a cell because op_set_function_name is only used
1826 // on a newly instantiated function object (the first child).
1827 fixEdge<KnownCellUse>(node->child1());
1828 fixEdge<UntypedUse>(node->child2());
1833 watchHavingABadTime(node);
1834 fixEdge<KnownInt32Use>(node->child1());
1838 case ResolveScopeForHoistingFuncDeclInEval: {
1839 fixEdge<KnownCellUse>(node->child1());
1844 case PutDynamicVar: {
1845 fixEdge<KnownCellUse>(node->child1());
1849 case LogShadowChickenPrologue: {
1850 fixEdge<KnownCellUse>(node->child1());
1853 case LogShadowChickenTail: {
1854 fixEdge<UntypedUse>(node->child1());
1855 fixEdge<KnownCellUse>(node->child2());
1860 if (node->child1().useKind() == MapObjectUse)
1861 fixEdge<MapObjectUse>(node->child1());
1862 else if (node->child1().useKind() == SetObjectUse)
1863 fixEdge<SetObjectUse>(node->child1());
1865 RELEASE_ASSERT_NOT_REACHED();
1868 if (node->child2()->shouldSpeculateBoolean())
1869 fixEdge<BooleanUse>(node->child2());
1870 else if (node->child2()->shouldSpeculateInt32())
1871 fixEdge<Int32Use>(node->child2());
1872 else if (node->child2()->shouldSpeculateSymbol())
1873 fixEdge<SymbolUse>(node->child2());
1874 else if (node->child2()->shouldSpeculateObject())
1875 fixEdge<ObjectUse>(node->child2());
1876 else if (node->child2()->shouldSpeculateString())
1877 fixEdge<StringUse>(node->child2());
1878 else if (node->child2()->shouldSpeculateCell())
1879 fixEdge<CellUse>(node->child2());
1881 fixEdge<UntypedUse>(node->child2());
1883 fixEdge<UntypedUse>(node->child2());
1884 #endif // USE(JSVALUE64)
1886 fixEdge<Int32Use>(node->child3());
1889 case GetMapBucketHead:
1890 if (node->child1().useKind() == MapObjectUse)
1891 fixEdge<MapObjectUse>(node->child1());
1892 else if (node->child1().useKind() == SetObjectUse)
1893 fixEdge<SetObjectUse>(node->child1());
1895 RELEASE_ASSERT_NOT_REACHED();
1898 case GetMapBucketNext:
1899 case LoadKeyFromMapBucket:
1900 case LoadValueFromMapBucket:
1901 fixEdge<CellUse>(node->child1());
1906 if (node->child1()->shouldSpeculateBoolean()) {
1907 fixEdge<BooleanUse>(node->child1());
1911 if (node->child1()->shouldSpeculateInt32()) {
1912 fixEdge<Int32Use>(node->child1());
1916 if (node->child1()->shouldSpeculateSymbol()) {
1917 fixEdge<SymbolUse>(node->child1());
1921 if (node->child1()->shouldSpeculateObject()) {
1922 fixEdge<ObjectUse>(node->child1());
1926 if (node->child1()->shouldSpeculateString()) {
1927 fixEdge<StringUse>(node->child1());
1931 if (node->child1()->shouldSpeculateCell()) {
1932 fixEdge<CellUse>(node->child1());
1936 fixEdge<UntypedUse>(node->child1());
1938 fixEdge<UntypedUse>(node->child1());
1939 #endif // USE(JSVALUE64)
1943 case NormalizeMapKey: {
1944 fixupNormalizeMapKey(node);
1949 fixEdge<WeakMapObjectUse>(node->child1());
1950 fixEdge<ObjectUse>(node->child2());
1951 fixEdge<Int32Use>(node->child3());
1956 fixEdge<SetObjectUse>(node->child1());
1957 fixEdge<Int32Use>(node->child3());
1962 fixEdge<MapObjectUse>(m_graph.varArgChild(node, 0));
1963 fixEdge<Int32Use>(m_graph.varArgChild(node, 3));
1967 case DefineDataProperty: {
1968 fixEdge<CellUse>(m_graph.varArgChild(node, 0));
1969 Edge& propertyEdge = m_graph.varArgChild(node, 1);
1970 if (propertyEdge->shouldSpeculateSymbol())
1971 fixEdge<SymbolUse>(propertyEdge);
1972 else if (propertyEdge->shouldSpeculateStringIdent())
1973 fixEdge<StringIdentUse>(propertyEdge);
1974 else if (propertyEdge->shouldSpeculateString())
1975 fixEdge<StringUse>(propertyEdge);
1977 fixEdge<UntypedUse>(propertyEdge);
1978 fixEdge<UntypedUse>(m_graph.varArgChild(node, 2));
1979 fixEdge<KnownInt32Use>(m_graph.varArgChild(node, 3));
1984 fixEdge<StringUse>(node->child1());
1985 fixEdge<Int32Use>(node->child2());
1987 fixEdge<Int32Use>(node->child3());
1992 // We currently only support StringUse since that will ensure that
1993 // ToLowerCase is a pure operation. If we decide to update this with
1994 // more types in the future, we need to ensure that the clobberize rules
1996 fixEdge<StringUse>(node->child1());
2000 case NumberToStringWithRadix: {
2001 if (node->child1()->shouldSpeculateInt32())
2002 fixEdge<Int32Use>(node->child1());
2003 else if (enableInt52() && node->child1()->shouldSpeculateAnyInt())
2004 fixEdge<Int52RepUse>(node->child1());
2006 fixEdge<DoubleRepUse>(node->child1());
2007 fixEdge<Int32Use>(node->child2());
2011 case DefineAccessorProperty: {
2012 fixEdge<CellUse>(m_graph.varArgChild(node, 0));
2013 Edge& propertyEdge = m_graph.varArgChild(node, 1);
2014 if (propertyEdge->shouldSpeculateSymbol())
2015 fixEdge<SymbolUse>(propertyEdge);
2016 else if (propertyEdge->shouldSpeculateStringIdent())
2017 fixEdge<StringIdentUse>(propertyEdge);
2018 else if (propertyEdge->shouldSpeculateString())
2019 fixEdge<StringUse>(propertyEdge);
2021 fixEdge<UntypedUse>(propertyEdge);
2022 fixEdge<CellUse>(m_graph.varArgChild(node, 2));
2023 fixEdge<CellUse>(m_graph.varArgChild(node, 3));
2024 fixEdge<KnownInt32Use>(m_graph.varArgChild(node, 4));
2028 case CheckSubClass: {
2029 fixupCheckSubClass(node);
2033 case CallDOMGetter: {
2034 DOMJIT::CallDOMGetterSnippet* snippet = node->callDOMGetterData()->snippet;
2035 fixEdge<CellUse>(node->child1()); // DOM.
2036 if (snippet && snippet->requireGlobalObject)
2037 fixEdge<KnownCellUse>(node->child2()); // GlobalObject.
2047 attemptToMakeCallDOM(node);
2052 if (node->child1()->shouldSpeculateInt32() && !node->child2()) {
2053 fixEdge<Int32Use>(node->child1());
2054 node->convertToIdentity();
2058 if (node->child1()->shouldSpeculateString()) {
2059 fixEdge<StringUse>(node->child1());
2060 node->clearFlags(NodeMustGenerate);
2064 fixEdge<Int32Use>(node->child2());
2069 case IdentityWithProfile: {
2070 node->clearFlags(NodeMustGenerate);
2074 case ThrowStaticError:
2075 fixEdge<StringUse>(node->child1());
2078 #if !ASSERT_DISABLED
2079 // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
2082 case LazyJSConstant:
2083 case DoubleConstant:
2086 case GetArgumentCountIncludingThis:
2092 case GetGlobalLexicalVariable:
2095 case CheckTypeInfoFlags:
2096 case TailCallInlinedCaller:
2097 case DirectTailCallInlinedCaller:
2099 case DirectConstruct:
2102 case TailCallVarargsInlinedCaller:
2103 case ConstructVarargs:
2104 case CallForwardVarargs:
2105 case ConstructForwardVarargs:
2106 case TailCallForwardVarargs:
2107 case TailCallForwardVarargsInlinedCaller:
2109 case ForwardVarargs:
2110 case ProfileControlFlow:
2115 case IsTypedArrayView:
2120 case IsObjectOrNull:
2122 case CreateDirectArguments:
2126 case DirectTailCall:
2127 case TailCallVarargs:
2129 case CountExecution:
2130 case SuperSamplerBegin:
2131 case SuperSamplerEnd:
2137 case ExtractOSREntryLocal:
2138 case ExtractCatchLocal:
2141 case InitializeEntrypointArguments:
2146 case PutByIdWithThis:
2147 case PutByValWithThis:
2148 case GetByValWithThis:
2150 case NumberToStringWithValidRadixConstant:
2161 void watchHavingABadTime(Node* node)
2163 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
2165 // If this global object is not having a bad time, watch it. We go down this path anytime the code
2166 // does an array allocation. The types of array allocations may change if we start to have a bad
2167 // time. It's easier to reason about this if we know that whenever the types change after we start
2168 // optimizing, the code just gets thrown out. Doing this at FixupPhase is just early enough, since
2169 // prior to this point nobody should have been doing optimizations based on the indexing type of
2171 if (!globalObject->isHavingABadTime()) {
2172 m_graph.watchpoints().addLazily(globalObject->havingABadTimeWatchpoint());
2173 m_graph.freeze(globalObject);
2177 template<UseKind useKind>
2178 void createToString(Node* node, Edge& edge)
2180 Node* toString = m_insertionSet.insertNode(
2181 m_indexInBlock, SpecString, ToString, node->origin,
2182 Edge(edge.node(), useKind));
2188 toString->clearFlags(NodeMustGenerate);
2193 edge.setNode(toString);
2196 template<UseKind useKind>
2197 void attemptToForceStringArrayModeByToStringConversion(ArrayMode& arrayMode, Node* node)
2199 ASSERT(arrayMode == ArrayMode(Array::Generic));
2201 if (!m_graph.canOptimizeStringObjectAccess(node->origin.semantic))
2204 createToString<useKind>(node, node->child1());
2205 arrayMode = ArrayMode(Array::String);
2208 template<UseKind useKind>
2209 bool isStringObjectUse()
2212 case StringObjectUse:
2213 case StringOrStringObjectUse:
2220 template<UseKind useKind>
2221 void convertStringAddUse(Node* node, Edge& edge)
2223 if (useKind == StringUse) {
2224 observeUseKindOnNode<StringUse>(edge.node());
2225 m_insertionSet.insertNode(
2226 m_indexInBlock, SpecNone, Check, node->origin,
2227 Edge(edge.node(), StringUse));
2228 edge.setUseKind(KnownStringUse);
2232 observeUseKindOnNode<useKind>(edge.node());
2233 createToString<useKind>(node, edge);
2236 void convertToMakeRope(Node* node)
2238 node->setOpAndDefaultFlags(MakeRope);
2239 fixupMakeRope(node);
2242 void fixupMakeRope(Node* node)
2244 for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
2245 Edge& edge = node->children.child(i);
2248 edge.setUseKind(KnownStringUse);
2249 JSString* string = edge->dynamicCastConstant<JSString*>(vm());
2252 if (string->length())
2255 // Don't allow the MakeRope to have zero children.
2256 if (!i && !node->child2())
2259 node->children.removeEdge(i--);
2262 if (!node->child2()) {
2263 ASSERT(!node->child3());
2264 node->convertToIdentity();
2268 void fixupIsCellWithType(Node* node)
2270 switch (node->speculatedTypeForQuery()) {
2272 if (node->child1()->shouldSpeculateString()) {
2273 m_insertionSet.insertNode(
2274 m_indexInBlock, SpecNone, Check, node->origin,
2275 Edge(node->child1().node(), StringUse));
2276 m_graph.convertToConstant(node, jsBoolean(true));
2277 observeUseKindOnNode<StringUse>(node);
2282 case SpecProxyObject:
2283 if (node->child1()->shouldSpeculateProxyObject()) {
2284 m_insertionSet.insertNode(
2285 m_indexInBlock, SpecNone, Check, node->origin,
2286 Edge(node->child1().node(), ProxyObjectUse));
2287 m_graph.convertToConstant(node, jsBoolean(true));
2288 observeUseKindOnNode<ProxyObjectUse>(node);
2293 case SpecRegExpObject:
2294 if (node->child1()->shouldSpeculateRegExpObject()) {
2295 m_insertionSet.insertNode(
2296 m_indexInBlock, SpecNone, Check, node->origin,
2297 Edge(node->child1().node(), RegExpObjectUse));
2298 m_graph.convertToConstant(node, jsBoolean(true));
2299 observeUseKindOnNode<RegExpObjectUse>(node);
2305 if (node->child1()->shouldSpeculateArray()) {
2306 m_insertionSet.insertNode(
2307 m_indexInBlock, SpecNone, Check, node->origin,
2308 Edge(node->child1().node(), ArrayUse));
2309 m_graph.convertToConstant(node, jsBoolean(true));
2310 observeUseKindOnNode<ArrayUse>(node);
2315 case SpecDerivedArray:
2316 if (node->child1()->shouldSpeculateDerivedArray()) {
2317 m_insertionSet.insertNode(
2318 m_indexInBlock, SpecNone, Check, node->origin,
2319 Edge(node->child1().node(), DerivedArrayUse));
2320 m_graph.convertToConstant(node, jsBoolean(true));
2321 observeUseKindOnNode<DerivedArrayUse>(node);
2327 if (node->child1()->shouldSpeculateCell()) {
2328 fixEdge<CellUse>(node->child1());
2332 if (node->child1()->shouldSpeculateNotCell()) {
2333 m_insertionSet.insertNode(
2334 m_indexInBlock, SpecNone, Check, node->origin,
2335 Edge(node->child1().node(), NotCellUse));
2336 m_graph.convertToConstant(node, jsBoolean(false));
2337 observeUseKindOnNode<NotCellUse>(node);
2342 void fixupGetPrototypeOf(Node* node)
2344 // Reflect.getPrototypeOf only accepts Objects. For Reflect.getPrototypeOf, ByteCodeParser attaches ObjectUse edge filter before fixup phase.
2345 if (node->child1().useKind() != ObjectUse) {
2346 if (node->child1()->shouldSpeculateString()) {
2347 insertCheck<StringUse>(node->child1().node());
2348 m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->stringPrototype()));
2351 if (node->child1()->shouldSpeculateInt32()) {
2352 insertCheck<Int32Use>(node->child1().node());
2353 m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->numberPrototype()));
2356 if (enableInt52() && node->child1()->shouldSpeculateAnyInt()) {
2357 insertCheck<Int52RepUse>(node->child1().node());
2358 m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->numberPrototype()));
2361 if (node->child1()->shouldSpeculateNumber()) {
2362 insertCheck<NumberUse>(node->child1().node());
2363 m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->numberPrototype()));
2366 if (node->child1()->shouldSpeculateSymbol()) {
2367 insertCheck<SymbolUse>(node->child1().node());
2368 m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->symbolPrototype()));
2371 if (node->child1()->shouldSpeculateBoolean()) {
2372 insertCheck<BooleanUse>(node->child1().node());
2373 m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->booleanPrototype()));
2378 if (node->child1()->shouldSpeculateFinalObject()) {
2379 fixEdge<FinalObjectUse>(node->child1());
2380 node->clearFlags(NodeMustGenerate);
2383 if (node->child1()->shouldSpeculateArray()) {
2384 fixEdge<ArrayUse>(node->child1());
2385 node->clearFlags(NodeMustGenerate);
2388 if (node->child1()->shouldSpeculateFunction()) {
2389 fixEdge<FunctionUse>(node->child1());
2390 node->clearFlags(NodeMustGenerate);
2395 void fixupToThis(Node* node)
2397 ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->isStrictMode() ? StrictMode : NotStrictMode;
2399 if (ecmaMode == StrictMode) {
2400 if (node->child1()->shouldSpeculateBoolean()) {
2401 fixEdge<BooleanUse>(node->child1());
2402 node->convertToIdentity();
2406 if (node->child1()->shouldSpeculateInt32()) {
2407 fixEdge<Int32Use>(node->child1());
2408 node->convertToIdentity();
2412 if (enableInt52() && node->child1()->shouldSpeculateAnyInt()) {
2413 fixEdge<Int52RepUse>(node->child1());
2414 node->convertToIdentity();
2415 node->setResult(NodeResultInt52);
2419 if (node->child1()->shouldSpeculateNumber()) {
2420 fixEdge<DoubleRepUse>(node->child1());
2421 node->convertToIdentity();
2422 node->setResult(NodeResultDouble);
2426 if (node->child1()->shouldSpeculateSymbol()) {
2427 fixEdge<SymbolUse>(node->child1());
2428 node->convertToIdentity();
2432 if (node->child1()->shouldSpeculateStringIdent()) {
2433 fixEdge<StringIdentUse>(node->child1());
2434 node->convertToIdentity();
2438 if (node->child1()->shouldSpeculateString()) {
2439 fixEdge<StringUse>(node->child1());
2440 node->convertToIdentity();
2445 if (node->child1()->shouldSpeculateOther()) {
2446 if (ecmaMode == StrictMode) {
2447 fixEdge<OtherUse>(node->child1());
2448 node->convertToIdentity();
2452 m_insertionSet.insertNode(
2453 m_indexInBlock, SpecNone, Check, node->origin,
2454 Edge(node->child1().node(), OtherUse));
2455 observeUseKindOnNode<OtherUse>(node->child1().node());
2456 m_graph.convertToConstant(
2457 node, m_graph.globalThisObjectFor(node->origin.semantic));
2461 // FIXME: This should cover other use cases but we don't have use kinds for them. It's not critical,
2462 // however, since we cover all the missing cases in constant folding.
2463 // https://bugs.webkit.org/show_bug.cgi?id=157213
2464 if (node->child1()->shouldSpeculateStringObject()) {
2465 fixEdge<StringObjectUse>(node->child1());
2466 node->convertToIdentity();
2470 if (isFinalObjectSpeculation(node->child1()->prediction())) {
2471 fixEdge<FinalObjectUse>(node->child1());
2472 node->convertToIdentity();
2477 void fixupToPrimitive(Node* node)
2479 if (node->child1()->shouldSpeculateInt32()) {
2480 fixEdge<Int32Use>(node->child1());
2481 node->convertToIdentity();
2485 if (node->child1()->shouldSpeculateString()) {
2486 fixEdge<StringUse>(node->child1());
2487 node->convertToIdentity();
2491 if (node->child1()->shouldSpeculateStringObject()
2492 && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
2493 fixEdge<StringObjectUse>(node->child1());
2494 node->convertToToString();
2498 if (node->child1()->shouldSpeculateStringOrStringObject()
2499 && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
2500 fixEdge<StringOrStringObjectUse>(node->child1());
2501 node->convertToToString();
2506 void fixupToNumber(Node* node)
2508 // If the prediction of the child is Number, we attempt to convert ToNumber to Identity.
2509 if (node->child1()->shouldSpeculateNumber()) {
2510 if (isInt32Speculation(node->getHeapPrediction())) {
2511 // If the both predictions of this node and the child is Int32, we just convert ToNumber to Identity, that's simple.
2512 if (node->child1()->shouldSpeculateInt32()) {
2513 fixEdge<Int32Use>(node->child1());
2514 node->convertToIdentity();
2518 // 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.
2519 // 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.
2520 fixEdge<DoubleRepUse>(node->child1());
2521 node->setOp(DoubleAsInt32);
2522 if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
2523 node->setArithMode(Arith::CheckOverflow);
2525 node->setArithMode(Arith::CheckOverflowAndNegativeZero);
2529 fixEdge<DoubleRepUse>(node->child1());
2530 node->convertToIdentity();
2531 node->setResult(NodeResultDouble);
2535 fixEdge<UntypedUse>(node->child1());
2536 node->setResult(NodeResultJS);
2539 void fixupToObject(Node* node)
2541 if (node->child1()->shouldSpeculateObject()) {
2542 fixEdge<ObjectUse>(node->child1());
2543 node->convertToIdentity();
2547 // ToObject(Null/Undefined) can throw an error. We can emit filters to convert ToObject to CallObjectConstructor.
2549 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
2551 if (node->child1()->shouldSpeculateString()) {
2552 insertCheck<StringUse>(node->child1().node());
2553 fixEdge<KnownStringUse>(node->child1());
2554 node->convertToNewStringObject(m_graph.registerStructure(globalObject->stringObjectStructure()));
2558 if (node->child1()->shouldSpeculateSymbol()) {
2559 insertCheck<SymbolUse>(node->child1().node());
2560 node->convertToCallObjectConstructor(m_graph.freeze(globalObject));
2564 if (node->child1()->shouldSpeculateNumber()) {
2565 insertCheck<NumberUse>(node->child1().node());
2566 node->convertToCallObjectConstructor(m_graph.freeze(globalObject));
2570 if (node->child1()->shouldSpeculateBoolean()) {
2571 insertCheck<BooleanUse>(node->child1().node());
2572 node->convertToCallObjectConstructor(m_graph.freeze(globalObject));
2576 fixEdge<UntypedUse>(node->child1());
2579 void fixupCallObjectConstructor(Node* node)
2581 if (node->child1()->shouldSpeculateObject()) {
2582 fixEdge<ObjectUse>(node->child1());
2583 node->convertToIdentity();
2587 if (node->child1()->shouldSpeculateString()) {
2588 auto* globalObject = jsCast<JSGlobalObject*>(node->cellOperand()->cell());
2589 insertCheck<StringUse>(node->child1().node());
2590 fixEdge<KnownStringUse>(node->child1());
2591 node->convertToNewStringObject(m_graph.registerStructure(globalObject->stringObjectStructure()));
2595 // While ToObject(Null/Undefined) throws an error, CallObjectConstructor(Null/Undefined) generates a new empty object.
2596 if (node->child1()->shouldSpeculateOther()) {
2597 insertCheck<OtherUse>(node->child1().node());
2598 node->convertToNewObject(m_graph.registerStructure(jsCast<JSGlobalObject*>(node->cellOperand()->cell())->objectStructureForObjectConstructor()));
2602 fixEdge<UntypedUse>(node->child1());
2605 void fixupToStringOrCallStringConstructor(Node* node)
2607 if (node->child1()->shouldSpeculateString()) {
2608 fixEdge<StringUse>(node->child1());
2609 node->convertToIdentity();
2613 if (node->child1()->shouldSpeculateStringObject()
2614 && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
2615 fixEdge<StringObjectUse>(node->child1());
2619 if (node->child1()->shouldSpeculateStringOrStringObject()
2620 && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
2621 fixEdge<StringOrStringObjectUse>(node->child1());
2625 if (node->child1()->shouldSpeculateCell()) {
2626 fixEdge<CellUse>(node->child1());
2630 if (node->child1()->shouldSpeculateInt32()) {
2631 fixEdge<Int32Use>(node->child1());
2632 node->clearFlags(NodeMustGenerate);
2636 if (enableInt52() && node->child1()->shouldSpeculateAnyInt()) {
2637 fixEdge<Int52RepUse>(node->child1());
2638 node->clearFlags(NodeMustGenerate);
2642 if (node->child1()->shouldSpeculateNumber()) {
2643 fixEdge<DoubleRepUse>(node->child1());
2644 node->clearFlags(NodeMustGenerate);
2648 // ToString(Symbol) throws an error. So if the child1 can include Symbols,
2649 // we need to care about it in the clobberize. In the following case,
2650 // since NotCellUse edge filter is used and this edge filters Symbols,
2651 // we can say that ToString never throws an error!
2652 if (node->child1()->shouldSpeculateNotCell()) {
2653 fixEdge<NotCellUse>(node->child1());
2654 node->clearFlags(NodeMustGenerate);
2659 bool attemptToMakeFastStringAdd(Node* node)
2661 bool goodToGo = true;
2662 m_graph.doToChildren(
2665 if (edge->shouldSpeculateString())
2667 if (m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
2668 if (edge->shouldSpeculateStringObject())
2670 if (edge->shouldSpeculateStringOrStringObject())
2678 m_graph.doToChildren(
2681 if (edge->shouldSpeculateString()) {
2682 convertStringAddUse<StringUse>(node, edge);
2685 ASSERT(m_graph.canOptimizeStringObjectAccess(node->origin.semantic));
2686 if (edge->shouldSpeculateStringObject()) {
2687 convertStringAddUse<StringObjectUse>(node, edge);
2690 if (edge->shouldSpeculateStringOrStringObject()) {
2691 convertStringAddUse<StringOrStringObjectUse>(node, edge);
2694 RELEASE_ASSERT_NOT_REACHED();
2697 convertToMakeRope(node);
2701 void fixupGetAndSetLocalsInBlock(BasicBlock* block)
2705 ASSERT(block->isReachable);
2707 for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
2708 Node* node = m_currentNode = block->at(m_indexInBlock);
2709 if (node->op() != SetLocal && node->op() != GetLocal)
2712 VariableAccessData* variable = node->variableAccessData();
2713 switch (node->op()) {
2715 switch (variable->flushFormat()) {
2717 node->setResult(NodeResultDouble);
2720 node->setResult(NodeResultInt52);
2728 // NOTE: Any type checks we put here may get hoisted by fixupChecksInBlock(). So, if we
2729 // add new type checking use kind for SetLocals, we need to modify that code as well.
2731 switch (variable->flushFormat()) {
2732 case FlushedJSValue:
2735 fixEdge<DoubleRepUse>(node->child1());
2738 fixEdge<Int32Use>(node->child1());
2741 fixEdge<Int52RepUse>(node->child1());
2744 fixEdge<CellUse>(node->child1());
2746 case FlushedBoolean:
2747 fixEdge<BooleanUse>(node->child1());
2750 RELEASE_ASSERT_NOT_REACHED();
2756 RELEASE_ASSERT_NOT_REACHED();
2760 m_insertionSet.execute(block);
2763 void addStringReplacePrimordialChecks(Node* searchRegExp)
2765 Node* node = m_currentNode;
2767 // Check that structure of searchRegExp is RegExp object
2768 m_insertionSet.insertNode(
2769 m_indexInBlock, SpecNone, Check, node->origin,
2770 Edge(searchRegExp, RegExpObjectUse));
2772 auto emitPrimordialCheckFor = [&] (JSValue primordialProperty, UniquedStringImpl* propertyUID) {
2773 unsigned index = m_graph.identifiers().ensure(propertyUID);
2775 Node* actualProperty = m_insertionSet.insertNode(
2776 m_indexInBlock, SpecNone, TryGetById, node->origin,
2777 OpInfo(index), OpInfo(SpecFunction), Edge(searchRegExp, CellUse));
2779 m_insertionSet.insertNode(
2780 m_indexInBlock, SpecNone, CheckCell, node->origin,
2781 OpInfo(m_graph.freeze(primordialProperty)), Edge(actualProperty, CellUse));
2784 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
2786 // Check that searchRegExp.exec is the primordial RegExp.prototype.exec
2787 emitPrimordialCheckFor(globalObject->regExpProtoExecFunction(), vm().propertyNames->exec.impl());
2788 // Check that searchRegExp.global is the primordial RegExp.prototype.global
2789 emitPrimordialCheckFor(globalObject->regExpProtoGlobalGetter(), vm().propertyNames->global.impl());
2790 // Check that searchRegExp.unicode is the primordial RegExp.prototype.unicode
2791 emitPrimordialCheckFor(globalObject->regExpProtoUnicodeGetter(), vm().propertyNames->unicode.impl());
2792 // Check that searchRegExp[Symbol.match] is the primordial RegExp.prototype[Symbol.replace]
2793 emitPrimordialCheckFor(globalObject->regExpProtoSymbolReplaceFunction(), vm().propertyNames->replaceSymbol.impl());
2796 Node* checkArray(ArrayMode arrayMode, const NodeOrigin& origin, Node* array, Node* index, bool (*storageCheck)(const ArrayMode&) = canCSEStorage)
2798 ASSERT(arrayMode.isSpecific());
2800 if (arrayMode.type() == Array::String) {
2801 m_insertionSet.insertNode(
2802 m_indexInBlock, SpecNone, Check, origin, Edge(array, StringUse));
2804 // Note that we only need to be using a structure check if we opt for SaneChain, since
2805 // that needs to protect against JSArray's __proto__ being changed.
2806 Structure* structure = arrayMode.originalArrayStructure(m_graph, origin.semantic);
2808 Edge indexEdge = index ? Edge(index, Int32Use) : Edge();
2810 if (arrayMode.doesConversion()) {
2812 m_insertionSet.insertNode(
2813 m_indexInBlock, SpecNone, ArrayifyToStructure, origin,
2814 OpInfo(m_graph.registerStructure(structure)), OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
2816 m_insertionSet.insertNode(
2817 m_indexInBlock, SpecNone, Arrayify, origin,
2818 OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
2822 m_insertionSet.insertNode(
2823 m_indexInBlock, SpecNone, CheckStructure, origin,
2824 OpInfo(m_graph.addStructureSet(structure)), Edge(array, CellUse));
2826 m_insertionSet.insertNode(
2827 m_indexInBlock, SpecNone, CheckArray, origin,
2828 OpInfo(arrayMode.asWord()), Edge(array, CellUse));
2833 if (!storageCheck(arrayMode))
2836 if (arrayMode.usesButterfly()) {
2837 return m_insertionSet.insertNode(
2838 m_indexInBlock, SpecNone, GetButterfly, origin, Edge(array, CellUse));
2841 return m_insertionSet.insertNode(
2842 m_indexInBlock, SpecNone, GetIndexedPropertyStorage, origin,
2843 OpInfo(arrayMode.asWord()), Edge(array, KnownCellUse));
2846 void blessArrayOperation(Edge base, Edge index, Edge& storageChild)
2848 Node* node = m_currentNode;
2850 switch (node->arrayMode().type()) {
2851 case Array::ForceExit: {
2852 m_insertionSet.insertNode(
2853 m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
2857 case Array::SelectUsingPredictions:
2858 case Array::Unprofiled:
2859 RELEASE_ASSERT_NOT_REACHED();
2862 case Array::Generic:
2866 Node* storage = checkArray(node->arrayMode(), node->origin, base.node(), index.node());
2870 storageChild = Edge(storage);
2875 bool alwaysUnboxSimplePrimitives()
2880 // Any boolean, int, or cell value is profitable to unbox on 32-bit because it
2886 template<UseKind useKind>
2887 void observeUseKindOnNode(Node* node)
2889 if (useKind == UntypedUse)
2891 observeUseKindOnNode(node, useKind);
2894 void observeUseKindOnEdge(Edge edge)
2896 observeUseKindOnNode(edge.node(), edge.useKind());
2899 void observeUseKindOnNode(Node* node, UseKind useKind)
2901 if (node->op() != GetLocal)
2904 // FIXME: The way this uses alwaysUnboxSimplePrimitives() is suspicious.
2905 // https://bugs.webkit.org/show_bug.cgi?id=121518
2907 VariableAccessData* variable = node->variableAccessData();
2911 if (alwaysUnboxSimplePrimitives()
2912 || isInt32Speculation(variable->prediction()))
2913 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
2918 case DoubleRepRealUse:
2919 if (variable->doubleFormatState() == UsingDoubleFormat)
2920 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
2923 case KnownBooleanUse:
2924 if (alwaysUnboxSimplePrimitives()
2925 || isBooleanSpeculation(variable->prediction()))
2926 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
2929 if (isAnyIntSpeculation(variable->prediction()))
2930 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
2937 case KnownStringUse:
2939 case StringObjectUse:
2940 case StringOrStringObjectUse:
2941 if (alwaysUnboxSimplePrimitives()
2942 || isCellSpeculation(variable->prediction()))
2943 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
2950 template<UseKind useKind>
2951 void fixEdge(Edge& edge)
2953 observeUseKindOnNode<useKind>(edge.node());
2954 edge.setUseKind(useKind);
2957 unsigned indexForChecks()
2959 unsigned index = m_indexInBlock;
2960 while (!m_block->at(index)->origin.exitOK)
2965 NodeOrigin originForCheck(unsigned index)
2967 return m_block->at(index)->origin.withSemantic(m_currentNode->origin.semantic);
2970 void speculateForBarrier(Edge value)
2972 // Currently, the DFG won't take advantage of this speculation. But, we want to do it in
2973 // the DFG anyway because if such a speculation would be wrong, we want to know before
2974 // we do an expensive compile.
2976 if (value->shouldSpeculateInt32()) {
2977 insertCheck<Int32Use>(value.node());
2981 if (value->shouldSpeculateBoolean()) {
2982 insertCheck<BooleanUse>(value.node());
2986 if (value->shouldSpeculateOther()) {
2987 insertCheck<OtherUse>(value.node());
2991 if (value->shouldSpeculateNumber()) {
2992 insertCheck<NumberUse>(value.node());
2996 if (value->shouldSpeculateNotCell()) {
2997 insertCheck<NotCellUse>(value.node());
3002 template<UseKind useKind>
3003 void insertCheck(Node* node)
3005 observeUseKindOnNode<useKind>(node);
3006 unsigned index = indexForChecks();
3007 m_insertionSet.insertNode(index, SpecNone, Check, originForCheck(index), Edge(node, useKind));
3010 void fixIntConvertingEdge(Edge& edge)
3012 Node* node = edge.node();
3013 if (node->shouldSpeculateInt32OrBoolean()) {
3014 fixIntOrBooleanEdge(edge);
3019 if (node->shouldSpeculateAnyInt())
3020 useKind = Int52RepUse;
3021 else if (node->shouldSpeculateNumber())
3022 useKind = DoubleRepUse;
3024 useKind = NotCellUse;
3025 Node* newNode = m_insertionSet.insertNode(
3026 m_indexInBlock, SpecInt32Only, ValueToInt32, m_currentNode->origin,
3027 Edge(node, useKind));
3028 observeUseKindOnNode(node, useKind);
3030 edge = Edge(newNode, KnownInt32Use);
3033 void fixIntOrBooleanEdge(Edge& edge)
3035 Node* node = edge.node();
3036 if (!node->sawBooleans()) {
3037 fixEdge<Int32Use>(edge);
3042 if (node->shouldSpeculateBoolean())
3043 useKind = BooleanUse;
3045 useKind = UntypedUse;
3046 Node* newNode = m_insertionSet.insertNode(
3047 m_indexInBlock, SpecInt32Only, BooleanToNumber, m_currentNode->origin,
3048 Edge(node, useKind));
3049 observeUseKindOnNode(node, useKind);
3051 edge = Edge(newNode, Int32Use);
3054 void fixDoubleOrBooleanEdge(Edge& edge)
3056 Node* node = edge.node();
3057 if (!node->sawBooleans()) {
3058 fixEdge<DoubleRepUse>(edge);
3063 if (node->shouldSpeculateBoolean())
3064 useKind = BooleanUse;
3066 useKind = UntypedUse;
3067 Node* newNode = m_insertionSet.insertNode(
3068 m_indexInBlock, SpecInt32Only, BooleanToNumber, m_currentNode->origin,
3069 Edge(node, useKind));
3070 observeUseKindOnNode(node, useKind);