DFGFixupPhase.cpp 55.2 KB
Newer Older
1
/*
2
 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include "config.h"
#include "DFGFixupPhase.h"

#if ENABLE(DFG_JIT)

#include "DFGGraph.h"
32
#include "DFGInsertionSet.h"
33
#include "DFGPhase.h"
34
#include "DFGPredictionPropagationPhase.h"
35
#include "DFGVariableAccessDataDump.h"
36
#include "Operations.h"
37 38 39 40 41 42 43

namespace JSC { namespace DFG {

class FixupPhase : public Phase {
public:
    FixupPhase(Graph& graph)
        : Phase(graph, "fixup")
44
        , m_insertionSet(graph)
45 46 47
    {
    }
    
48
    bool run()
49
    {
50 51 52
        ASSERT(m_graph.m_fixpointState == BeforeFixpoint);
        ASSERT(m_graph.m_form == ThreadedCPS);
        
53
        m_profitabilityChanged = false;
54 55
        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex)
            fixupBlock(m_graph.m_blocks[blockIndex].get());
56 57 58 59 60 61 62 63 64 65 66
        
        while (m_profitabilityChanged) {
            m_profitabilityChanged = false;
            
            for (unsigned i = m_graph.m_argumentPositions.size(); i--;)
                m_graph.m_argumentPositions[i].mergeArgumentUnboxingAwareness();
            
            for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex)
                fixupSetLocalsInBlock(m_graph.m_blocks[blockIndex].get());
        }
        
67
        return true;
68 69 70
    }

private:
71 72
    void fixupBlock(BasicBlock* block)
    {
73 74 75
        if (!block)
            return;
        ASSERT(block->isReachable);
76
        m_block = block;
77
        for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
78 79
            m_currentNode = block->at(m_indexInBlock);
            fixupNode(m_currentNode);
80
        }
81
        m_insertionSet.execute(block);
82 83
    }
    
84
    void fixupNode(Node* node)
85
    {
86
        NodeType op = node->op();
87 88

#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
89
        dataLogF("   %s @%u: ", Graph::opName(op), node->index());
90 91 92
#endif
        
        switch (op) {
93
        case SetLocal: {
94
            // This gets handled by fixupSetLocalsInBlock().
95 96 97 98 99 100 101 102
            break;
        }
            
        case BitAnd:
        case BitOr:
        case BitXor:
        case BitRShift:
        case BitLShift:
oliver@apple.com's avatar
oliver@apple.com committed
103 104
        case BitURShift:
        case ArithIMul: {
105 106 107 108 109 110
            fixIntEdge(node->child1());
            fixIntEdge(node->child2());
            break;
        }
            
        case UInt32ToNumber: {
111
            setUseKindAndUnboxIfProfitable<KnownInt32Use>(node->child1());
112 113 114 115 116 117 118 119 120 121
            break;
        }
            
        case DoubleAsInt32: {
            RELEASE_ASSERT_NOT_REACHED();
            break;
        }
            
        case ValueToInt32: {
            if (node->child1()->shouldSpeculateInteger()) {
122
                setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
123
                break;
124 125 126
            }
            
            if (node->child1()->shouldSpeculateNumber()) {
127
                setUseKindAndUnboxIfProfitable<NumberUse>(node->child1());
128 129 130 131
                break;
            }
            
            if (node->child1()->shouldSpeculateBoolean()) {
132
                setUseKindAndUnboxIfProfitable<BooleanUse>(node->child1());
133 134 135
                break;
            }
            
136
            setUseKindAndUnboxIfProfitable<NotCellUse>(node->child1());
137 138 139 140 141 142 143 144 145 146 147 148
            break;
        }
            
        case Int32ToDouble: {
            RELEASE_ASSERT_NOT_REACHED();
            break;
        }
            
        case ValueAdd: {
            if (attemptToMakeIntegerAdd(node))
                break;
            if (Node::shouldSpeculateNumberExpectingDefined(node->child1().node(), node->child2().node())) {
149 150
                fixDoubleEdge<NumberUse>(node->child1());
                fixDoubleEdge<NumberUse>(node->child2());
151 152
                break;
            }
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
            
            // FIXME: Optimize for the case where one of the operands is the
            // empty string. Also consider optimizing for the case where we don't
            // believe either side is the emtpy string. Both of these things should
            // be easy.
            
            if (node->child1()->shouldSpeculateString()
                && attemptToMakeFastStringAdd<StringUse>(node, node->child1(), node->child2()))
                break;
            if (node->child2()->shouldSpeculateString()
                && attemptToMakeFastStringAdd<StringUse>(node, node->child2(), node->child1()))
                break;
            if (node->child1()->shouldSpeculateStringObject()
                && attemptToMakeFastStringAdd<StringObjectUse>(node, node->child1(), node->child2()))
                break;
            if (node->child2()->shouldSpeculateStringObject()
                && attemptToMakeFastStringAdd<StringObjectUse>(node, node->child2(), node->child1()))
                break;
            if (node->child1()->shouldSpeculateStringOrStringObject()
                && attemptToMakeFastStringAdd<StringOrStringObjectUse>(node, node->child1(), node->child2()))
                break;
            if (node->child2()->shouldSpeculateStringOrStringObject()
                && attemptToMakeFastStringAdd<StringOrStringObjectUse>(node, node->child2(), node->child1()))
                break;
177 178 179
            break;
        }
            
180 181 182 183 184
        case MakeRope: {
            fixupMakeRope(node);
            break;
        }
            
185 186 187 188
        case ArithAdd:
        case ArithSub: {
            if (attemptToMakeIntegerAdd(node))
                break;
189 190
            fixDoubleEdge<NumberUse>(node->child1());
            fixDoubleEdge<NumberUse>(node->child2());
191 192 193 194 195
            break;
        }
            
        case ArithNegate: {
            if (m_graph.negateShouldSpeculateInteger(node)) {
196
                setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
197 198
                break;
            }
199
            fixDoubleEdge<NumberUse>(node->child1());
200 201 202 203 204
            break;
        }
            
        case ArithMul: {
            if (m_graph.mulShouldSpeculateInteger(node)) {
205 206
                setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
                setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
207 208
                break;
            }
209 210
            fixDoubleEdge<NumberUse>(node->child1());
            fixDoubleEdge<NumberUse>(node->child2());
211 212 213
            break;
        }

214 215
        case ArithDiv:
        case ArithMod: {
216 217
            if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
                && node->canSpeculateInteger()) {
218
                if (isX86() || isARMv7s()) {
219 220
                    setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
                    setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
221
                    break;
222
                }
223 224 225 226 227 228
                injectInt32ToDoubleNode(node->child1());
                injectInt32ToDoubleNode(node->child2());

                // We don't need to do ref'ing on the children because we're stealing them from
                // the original division.
                Node* newDivision = m_insertionSet.insertNode(
229
                    m_indexInBlock, SpecDouble, *node);
230 231 232
                
                node->setOp(DoubleAsInt32);
                node->children.initialize(Edge(newDivision, KnownNumberUse), Edge(), Edge());
233
                break;
234
            }
235 236
            fixDoubleEdge<NumberUse>(node->child1());
            fixDoubleEdge<NumberUse>(node->child2());
237 238
            break;
        }
239
            
240
        case ArithMin:
241
        case ArithMax: {
242 243
            if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
                && node->canSpeculateInteger()) {
244 245
                setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
                setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
246
                break;
247
            }
248 249
            fixDoubleEdge<NumberUse>(node->child1());
            fixDoubleEdge<NumberUse>(node->child2());
250 251 252 253 254 255
            break;
        }
            
        case ArithAbs: {
            if (node->child1()->shouldSpeculateIntegerForArithmetic()
                && node->canSpeculateInteger()) {
256
                setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
257 258
                break;
            }
259
            fixDoubleEdge<NumberUse>(node->child1());
260 261
            break;
        }
262
            
263
        case ArithSqrt: {
264
            fixDoubleEdge<NumberUse>(node->child1());
265 266
            break;
        }
267 268 269
            
        case LogicalNot: {
            if (node->child1()->shouldSpeculateBoolean())
270
                setUseKindAndUnboxIfProfitable<BooleanUse>(node->child1());
271
            else if (node->child1()->shouldSpeculateObjectOrOther())
272
                setUseKindAndUnboxIfProfitable<ObjectOrOtherUse>(node->child1());
273
            else if (node->child1()->shouldSpeculateInteger())
274
                setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
275
            else if (node->child1()->shouldSpeculateNumber())
276
                fixDoubleEdge<NumberUse>(node->child1());
277 278 279 280 281
            break;
        }
            
        case TypeOf: {
            if (node->child1()->shouldSpeculateString())
282
                setUseKindAndUnboxIfProfitable<StringUse>(node->child1());
283
            else if (node->child1()->shouldSpeculateCell())
284
                setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
285 286 287
            break;
        }
            
288 289 290 291
        case CompareEqConstant: {
            break;
        }

292 293 294 295 296 297
        case CompareEq:
        case CompareLess:
        case CompareLessEq:
        case CompareGreater:
        case CompareGreaterEq: {
            if (Node::shouldSpeculateInteger(node->child1().node(), node->child2().node())) {
298 299
                setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
                setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
300 301 302
                break;
            }
            if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
303 304
                fixDoubleEdge<NumberUse>(node->child1());
                fixDoubleEdge<NumberUse>(node->child2());
305 306 307 308
                break;
            }
            if (node->op() != CompareEq)
                break;
309 310 311 312 313
            if (Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
                setUseKindAndUnboxIfProfitable<BooleanUse>(node->child1());
                setUseKindAndUnboxIfProfitable<BooleanUse>(node->child2());
                break;
            }
314 315 316
            if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && GPRInfo::numberOfRegisters >= 7) {
                setUseKindAndUnboxIfProfitable<StringUse>(node->child1());
                setUseKindAndUnboxIfProfitable<StringUse>(node->child2());
317
                break;
318
            }
319
            if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
320 321
                setUseKindAndUnboxIfProfitable<ObjectUse>(node->child1());
                setUseKindAndUnboxIfProfitable<ObjectUse>(node->child2());
322 323 324
                break;
            }
            if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObjectOrOther()) {
325 326
                setUseKindAndUnboxIfProfitable<ObjectUse>(node->child1());
                setUseKindAndUnboxIfProfitable<ObjectOrOtherUse>(node->child2());
327 328 329
                break;
            }
            if (node->child1()->shouldSpeculateObjectOrOther() && node->child2()->shouldSpeculateObject()) {
330 331
                setUseKindAndUnboxIfProfitable<ObjectOrOtherUse>(node->child1());
                setUseKindAndUnboxIfProfitable<ObjectUse>(node->child2());
332 333
                break;
            }
334 335
            break;
        }
336 337
            
        case CompareStrictEqConstant: {
338 339 340 341
            break;
        }
            
        case CompareStrictEq: {
342 343 344 345 346
            if (Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
                setUseKindAndUnboxIfProfitable<BooleanUse>(node->child1());
                setUseKindAndUnboxIfProfitable<BooleanUse>(node->child2());
                break;
            }
347
            if (Node::shouldSpeculateInteger(node->child1().node(), node->child2().node())) {
348 349
                setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
                setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
350 351 352
                break;
            }
            if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
353 354
                fixDoubleEdge<NumberUse>(node->child1());
                fixDoubleEdge<NumberUse>(node->child2());
355 356
                break;
            }
357 358 359
            if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && GPRInfo::numberOfRegisters >= 7) {
                setUseKindAndUnboxIfProfitable<StringUse>(node->child1());
                setUseKindAndUnboxIfProfitable<StringUse>(node->child2());
360
                break;
361
            }
362
            if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
363 364
                setUseKindAndUnboxIfProfitable<ObjectUse>(node->child1());
                setUseKindAndUnboxIfProfitable<ObjectUse>(node->child2());
365 366 367 368 369
                break;
            }
            break;
        }

370 371 372 373
        case StringFromCharCode:
            setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
            break;

374 375 376 377 378
        case StringCharAt:
        case StringCharCodeAt: {
            // Currently we have no good way of refining these.
            ASSERT(node->arrayMode() == ArrayMode(Array::String));
            blessArrayOperation(node->child1(), node->child2(), node->child3());
379 380
            setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
            setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
381 382 383
            break;
        }

384
        case GetByVal: {
385 386 387 388 389
            node->setArrayMode(
                node->arrayMode().refine(
                    node->child1()->prediction(),
                    node->child2()->prediction(),
                    SpecNone, node->flags()));
390
            
391
            blessArrayOperation(node->child1(), node->child2(), node->child3());
392
            
393
            ArrayMode arrayMode = node->arrayMode();
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412
            switch (arrayMode.type()) {
            case Array::Double:
                if (arrayMode.arrayClass() == Array::OriginalArray
                    && arrayMode.speculation() == Array::InBounds
                    && arrayMode.conversion() == Array::AsIs
                    && m_graph.globalObjectFor(node->codeOrigin)->arrayPrototypeChainIsSane()
                    && !(node->flags() & NodeUsedAsOther))
                    node->setArrayMode(arrayMode.withSpeculation(Array::SaneChain));
                break;
                
            case Array::String:
                if ((node->prediction() & ~SpecString)
                    || m_graph.hasExitSite(node->codeOrigin, OutOfBounds))
                    node->setArrayMode(arrayMode.withSpeculation(Array::OutOfBounds));
                break;
                
            default:
                break;
            }
413
            
414 415 416 417 418 419 420 421
            switch (node->arrayMode().type()) {
            case Array::SelectUsingPredictions:
            case Array::Unprofiled:
            case Array::Undecided:
                RELEASE_ASSERT_NOT_REACHED();
                break;
            case Array::Generic:
#if USE(JSVALUE32_64)
422
                setUseKindAndUnboxIfProfitable<CellUse>(node->child1()); // Speculating cell due to register pressure on 32-bit.
423 424 425 426 427
#endif
                break;
            case Array::ForceExit:
                break;
            default:
428 429
                setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
                setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
430 431 432
                break;
            }
            
433 434
            break;
        }
435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461
            
        case PutByVal:
        case PutByValAlias: {
            Edge& child1 = m_graph.varArgChild(node, 0);
            Edge& child2 = m_graph.varArgChild(node, 1);
            Edge& child3 = m_graph.varArgChild(node, 2);

            node->setArrayMode(
                node->arrayMode().refine(
                    child1->prediction(),
                    child2->prediction(),
                    child3->prediction()));
            
            blessArrayOperation(child1, child2, m_graph.varArgChild(node, 3));
            
            switch (node->arrayMode().modeForPut().type()) {
            case Array::SelectUsingPredictions:
            case Array::Unprofiled:
            case Array::Undecided:
                RELEASE_ASSERT_NOT_REACHED();
                break;
            case Array::ForceExit:
            case Array::Generic:
#if USE(JSVALUE32_64)
                // Due to register pressure on 32-bit, we speculate cell and
                // ignore the base-is-not-cell case entirely by letting the
                // baseline JIT handle it.
462
                setUseKindAndUnboxIfProfitable<CellUse>(child1);
463 464 465
#endif
                break;
            case Array::Int32:
466 467 468
                setUseKindAndUnboxIfProfitable<KnownCellUse>(child1);
                setUseKindAndUnboxIfProfitable<Int32Use>(child2);
                setUseKindAndUnboxIfProfitable<Int32Use>(child3);
469 470
                break;
            case Array::Double:
471 472 473
                setUseKindAndUnboxIfProfitable<KnownCellUse>(child1);
                setUseKindAndUnboxIfProfitable<Int32Use>(child2);
                fixDoubleEdge<RealNumberUse>(child3);
474 475 476 477 478 479 480 481
                break;
            case Array::Int8Array:
            case Array::Int16Array:
            case Array::Int32Array:
            case Array::Uint8Array:
            case Array::Uint8ClampedArray:
            case Array::Uint16Array:
            case Array::Uint32Array:
482 483
                setUseKindAndUnboxIfProfitable<KnownCellUse>(child1);
                setUseKindAndUnboxIfProfitable<Int32Use>(child2);
484
                if (child3->shouldSpeculateInteger())
485
                    setUseKindAndUnboxIfProfitable<Int32Use>(child3);
486
                else
487
                    fixDoubleEdge<NumberUse>(child3);
488 489 490
                break;
            case Array::Float32Array:
            case Array::Float64Array:
491 492 493
                setUseKindAndUnboxIfProfitable<KnownCellUse>(child1);
                setUseKindAndUnboxIfProfitable<Int32Use>(child2);
                fixDoubleEdge<NumberUse>(child3);
494 495
                break;
            default:
496 497
                setUseKindAndUnboxIfProfitable<KnownCellUse>(child1);
                setUseKindAndUnboxIfProfitable<Int32Use>(child2);
498 499
                break;
            }
500 501
            break;
        }
502 503
            
        case ArrayPush: {
504 505 506 507 508 509 510 511 512
            // May need to refine the array mode in case the value prediction contravenes
            // the array prediction. For example, we may have evidence showing that the
            // array is in Int32 mode, but the value we're storing is likely to be a double.
            // Then we should turn this into a conversion to Double array followed by the
            // push. On the other hand, we absolutely don't want to refine based on the
            // base prediction. If it has non-cell garbage in it, then we want that to be
            // ignored. That's because ArrayPush can't handle any array modes that aren't
            // array-related - so if refine() turned this into a "Generic" ArrayPush then
            // that would break things.
513 514 515
            node->setArrayMode(
                node->arrayMode().refine(
                    node->child1()->prediction() & SpecCell,
516
                    SpecInt32,
517
                    node->child2()->prediction()));
518
            blessArrayOperation(node->child1(), Edge(), node->child3());
519
            setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
520
            
521
            switch (node->arrayMode().type()) {
522
            case Array::Int32:
523
                setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
524
                break;
525
            case Array::Double:
526
                fixDoubleEdge<RealNumberUse>(node->child2());
527 528 529 530
                break;
            default:
                break;
            }
531 532 533
            break;
        }
            
534
        case ArrayPop: {
535
            blessArrayOperation(node->child1(), Edge(), node->child2());
536
            setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
537
            break;
538 539
        }
            
540 541
        case RegExpExec:
        case RegExpTest: {
542 543
            setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
            setUseKindAndUnboxIfProfitable<CellUse>(node->child2());
544 545 546 547
            break;
        }
            
        case Branch: {
548
            if (node->child1()->shouldSpeculateBoolean())
549
                setUseKindAndUnboxIfProfitable<BooleanUse>(node->child1());
550
            else if (node->child1()->shouldSpeculateObjectOrOther())
551
                setUseKindAndUnboxIfProfitable<ObjectOrOtherUse>(node->child1());
552
            else if (node->child1()->shouldSpeculateInteger())
553
                setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
554
            else if (node->child1()->shouldSpeculateNumber())
555
                fixDoubleEdge<NumberUse>(node->child1());
556

557
            Node* logicalNot = node->child1().node();
558
            if (logicalNot->op() == LogicalNot) {
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587
                
                // Make sure that OSR exit can't observe the LogicalNot. If it can,
                // then we must compute it and cannot peephole around it.
                bool found = false;
                bool ok = true;
                for (unsigned i = m_indexInBlock; i--;) {
                    Node* candidate = m_block->at(i);
                    if (candidate == logicalNot) {
                        found = true;
                        break;
                    }
                    if (candidate->canExit()) {
                        ok = false;
                        found = true;
                        break;
                    }
                }
                ASSERT_UNUSED(found, found);
                
                if (ok) {
                    Edge newChildEdge = logicalNot->child1();
                    if (newChildEdge->hasBooleanResult()) {
                        node->children.setChild1(newChildEdge);
                        
                        BlockIndex toBeTaken = node->notTakenBlockIndex();
                        BlockIndex toBeNotTaken = node->takenBlockIndex();
                        node->setTakenBlockIndex(toBeTaken);
                        node->setNotTakenBlockIndex(toBeNotTaken);
                    }
588
                }
589
            }
590 591 592
            break;
        }
            
593 594 595 596 597 598 599
        case Switch: {
            SwitchData* data = node->switchData();
            switch (data->kind) {
            case SwitchImm:
                if (node->child1()->shouldSpeculateInteger())
                    setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
                break;
600 601 602 603
            case SwitchChar:
                if (node->child1()->shouldSpeculateString())
                    setUseKindAndUnboxIfProfitable<StringUse>(node->child1());
                break;
604 605 606 607
            }
            break;
        }
            
608
        case ToPrimitive: {
609
            fixupToPrimitive(node);
610 611 612
            break;
        }
            
613
        case ToString: {
614
            fixupToString(node);
615 616 617 618 619 620 621 622
            break;
        }
            
        case NewStringObject: {
            setUseKindAndUnboxIfProfitable<KnownStringUse>(node->child1());
            break;
        }
            
623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638
        case NewArray: {
            for (unsigned i = m_graph.varArgNumChildren(node); i--;) {
                node->setIndexingType(
                    leastUpperBoundOfIndexingTypeAndType(
                        node->indexingType(), m_graph.varArgChild(node, i)->prediction()));
            }
            switch (node->indexingType()) {
            case ALL_BLANK_INDEXING_TYPES:
                CRASH();
                break;
            case ALL_UNDECIDED_INDEXING_TYPES:
                if (node->numChildren()) {
                    // This will only happen if the children have no type predictions. We
                    // would have already exited by now, but insert a forced exit just to
                    // be safe.
                    m_insertionSet.insertNode(
639
                        m_indexInBlock, SpecNone, ForceOSRExit, node->codeOrigin);
640 641 642 643
                }
                break;
            case ALL_INT32_INDEXING_TYPES:
                for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
644
                    setUseKindAndUnboxIfProfitable<Int32Use>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
645
                break;
646 647
            case ALL_DOUBLE_INDEXING_TYPES:
                for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
648
                    setUseKindAndUnboxIfProfitable<RealNumberUse>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
649
                break;
650 651 652 653 654 655 656
            case ALL_CONTIGUOUS_INDEXING_TYPES:
            case ALL_ARRAY_STORAGE_INDEXING_TYPES:
                break;
            default:
                CRASH();
                break;
            }
657 658 659
            break;
        }
            
660
        case NewArrayWithSize: {
661
            setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
662 663 664
            break;
        }
            
665 666 667
        case ToThis: {
            ECMAMode ecmaMode = m_graph.executableFor(node->codeOrigin)->isStrictMode() ? StrictMode : NotStrictMode;

668
            if (isOtherSpeculation(node->child1()->prediction())) {
669 670 671 672 673 674
                if (ecmaMode == StrictMode) {
                    setUseKindAndUnboxIfProfitable<OtherUse>(node->child1());
                    node->convertToIdentity();
                    break;
                }

675 676 677 678 679 680 681 682
                m_insertionSet.insertNode(
                    m_indexInBlock, SpecNone, Phantom, node->codeOrigin,
                    Edge(node->child1().node(), OtherUse));
                observeUseKindOnNode<OtherUse>(node->child1().node());
                node->convertToWeakConstant(m_graph.globalThisObjectFor(node->codeOrigin));
                break;
            }
            
683
            if (isFinalObjectSpeculation(node->child1()->prediction())) {
684
                setUseKindAndUnboxIfProfitable<ObjectUse>(node->child1());
685 686 687 688
                node->convertToIdentity();
                break;
            }
            
689 690 691
            break;
        }
            
692
        case CreateThis: {
693
            setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
694 695 696
            break;
        }
            
697 698
        case GetMyArgumentByVal:
        case GetMyArgumentByValSafe: {
699
            setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
700 701
            break;
        }
702
            
703 704
        case GetClosureRegisters:
        case PutClosureVar:
705 706 707 708 709 710 711 712 713
        case SkipTopScope:
        case SkipScope:
        case SetCallee:
        case SetMyScope:
        case PutStructure:
        case AllocatePropertyStorage:
        case ReallocatePropertyStorage:
        case GetScope:
        case GetButterfly: {
714
            setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
715 716 717
            break;
        }
            
718 719 720
        case GetById: {
            if (!node->child1()->shouldSpeculateCell())
                break;
721
            setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
722 723
            if (!isInt32Speculation(node->prediction()))
                break;
724
            if (m_graph.identifiers()[node->identifierNumber()] != vm().propertyNames->length.impl())
725
                break;
726
            CodeBlock* profiledBlock = m_graph.baselineCodeBlockFor(node->codeOrigin);
727
            ArrayProfile* arrayProfile = 
728
                profiledBlock->getArrayProfile(node->codeOrigin.bytecodeIndex);
729 730
            ArrayMode arrayMode = ArrayMode(Array::SelectUsingPredictions);
            if (arrayProfile) {
731
                ConcurrentJITLocker locker(profiledBlock->m_lock);
732 733 734 735
                arrayProfile->computeUpdatedPrediction(locker, profiledBlock);
                arrayMode = ArrayMode::fromObserved(locker, arrayProfile, Array::Read, false);
                arrayMode = arrayMode.refine(node->child1()->prediction(), node->prediction());
                if (arrayMode.supportsLength() && arrayProfile->hasDefiniteStructure(locker)) {
736
                    m_insertionSet.insertNode(
737
                        m_indexInBlock, SpecNone, CheckStructure, node->codeOrigin,
738
                        OpInfo(m_graph.addStructureSet(arrayProfile->expectedStructure(locker))),
739 740 741 742
                        node->child1());
                }
            } else
                arrayMode = arrayMode.refine(node->child1()->prediction(), node->prediction());
743 744 745 746 747 748 749 750 751 752 753
            
            if (arrayMode.type() == Array::Generic) {
                // Check if the input is something that we can't get array length for, but for which we
                // could insert some conversions in order to transform it into something that we can do it
                // for.
                if (node->child1()->shouldSpeculateStringObject())
                    attemptToForceStringArrayModeByToStringConversion<StringObjectUse>(arrayMode, node);
                else if (node->child1()->shouldSpeculateStringOrStringObject())
                    attemptToForceStringArrayModeByToStringConversion<StringOrStringObjectUse>(arrayMode, node);
            }
            
754
            if (!arrayMode.supportsLength())
755
                break;
756 757 758
            node->setOp(GetArrayLength);
            ASSERT(node->flags() & NodeMustGenerate);
            node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
759
            setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
760 761
            node->setArrayMode(arrayMode);
            
762
            Node* storage = checkArray(arrayMode, node->codeOrigin, node->child1().node(), 0, lengthNeedsStorage);
763 764 765 766
            if (!storage)
                break;
            
            node->child2() = Edge(storage);
767 768 769
            break;
        }
            
770 771
        case GetByIdFlush: {
            if (node->child1()->shouldSpeculateCell())
772
                setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
773 774 775
            break;
        }
            
776 777 778 779 780 781 782 783 784
        case CheckExecutable:
        case CheckStructure:
        case ForwardCheckStructure:
        case StructureTransitionWatchpoint:
        case ForwardStructureTransitionWatchpoint:
        case CheckFunction:
        case PutById:
        case PutByIdDirect:
        case CheckHasInstance: {
785
            setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
786 787
            break;
        }
788
            
789 790
        case CheckArray:
        case ForwardCheckArray: {
791 792
            switch (node->arrayMode().type()) {
            case Array::String:
793
                setUseKindAndUnboxIfProfitable<StringUse>(node->child1());
794
                break;
795
            default:
796
                setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
797 798 799 800 801
                break;
            }
            break;
        }
            
802 803
        case Arrayify:
        case ArrayifyToStructure: {
804
            setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
805
            if (node->child2())
806
                setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
807 808 809 810 811
            break;
        }
            
        case GetByOffset: {
            if (!node->child1()->hasStorageResult())
812
                setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
813 814 815 816 817
            break;
        }
            
        case PutByOffset: {
            if (!node->child1()->hasStorageResult())
818 819
                setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
            setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child2());
820 821 822 823 824 825 826
            break;
        }
            
        case InstanceOf: {
            // FIXME: This appears broken: CheckHasInstance already does an unconditional cell
            // check. https://bugs.webkit.org/show_bug.cgi?id=107479
            if (!(node->child1()->prediction() & ~SpecCell))
827 828
                setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
            setUseKindAndUnboxIfProfitable<CellUse>(node->child2());
829 830
            break;
        }
831 832 833 834 835 836 837 838
            
        case In: {
            // FIXME: We should at some point have array profiling on op_in, in which
            // case we would be able to turn this into a kind of GetByVal.
            
            setUseKindAndUnboxIfProfitable<CellUse>(node->child2());
            break;
        }
839 840 841 842 843 844 845 846 847 848 849 850 851 852 853

        case Phantom:
        case Identity: {
            switch (node->child1().useKind()) {
            case NumberUse:
                if (node->child1()->shouldSpeculateIntegerForArithmetic())
                    node->child1().setUseKind(Int32Use);
                break;
            default:
                break;
            }
            observeUseKindOnEdge(node->child1());
            break;
        }

854 855 856 857 858 859 860
        case GetArrayLength:
        case Nop:
        case Phi:
        case ForwardInt32ToDouble:
        case PhantomPutStructure:
        case GetIndexedPropertyStorage:
        case LastNodeType:
861 862 863
        case MovHint:
        case MovHintAndCheck:
        case ZombieHint:
864 865 866 867 868 869 870 871 872 873 874 875 876 877 878
            RELEASE_ASSERT_NOT_REACHED();
            break;
        
#if !ASSERT_DISABLED    
        // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
        case SetArgument:
        case JSConstant:
        case WeakJSConstant:
        case GetLocal:
        case GetCallee:
        case Flush:
        case PhantomLocal:
        case GetLocalUnlinked:
        case InlineStart:
        case GetMyScope:
879
        case GetClosureVar:
880 881 882
        case GetGlobalVar:
        case PutGlobalVar:
        case GlobalVarWatchpoint:
883
        case VarInjectionWatchpoint:
884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913
        case AllocationProfileWatchpoint:
        case Call:
        case Construct:
        case NewObject:
        case NewArrayBuffer:
        case NewRegexp:
        case Breakpoint:
        case IsUndefined:
        case IsBoolean:
        case IsNumber:
        case IsString:
        case IsObject:
        case IsFunction:
        case CreateActivation:
        case TearOffActivation:
        case CreateArguments:
        case PhantomArguments:
        case TearOffArguments:
        case GetMyArgumentsLength:
        case GetMyArgumentsLengthSafe:
        case CheckArgumentsNotCreated:
        case NewFunction:
        case NewFunctionNoCheck:
        case NewFunctionExpression:
        case Jump:
        case Return:
        case Throw:
        case ThrowReferenceError:
        case CountExecution:
        case ForceOSRExit:
914
        case ForwardForceOSRExit:
915
        case CheckWatchdogTimer:
916 917
            break;
#else
918 919
        default:
            break;
920
#endif
921 922 923
        }

#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
924
        if (!(node->flags() & NodeHasVarArgs)) {
925
            dataLogF("new children: ");
926
            node->dumpChildren(WTF::dataFile());
927
        }
928
        dataLogF("\n");
929 930 931
#endif
    }
    
932
    template<UseKind useKind>
933
    void createToString(Node* node, Edge& edge)
934
    {
935
        edge.setNode(m_insertionSet.insertNode(
936
            m_indexInBlock, SpecString, ToString, node->codeOrigin,
937
            Edge(edge.node(), useKind)));
938 939 940 941 942 943 944 945 946 947
    }
    
    template<UseKind useKind>
    void attemptToForceStringArrayModeByToStringConversion(ArrayMode& arrayMode, Node* node)
    {
        ASSERT(arrayMode == ArrayMode(Array::Generic));
        
        if (!canOptimizeStringObjectAccess(node->codeOrigin))
            return;
        
948
        createToString<useKind>(node, node->child1());
949 950 951
        arrayMode = ArrayMode(Array::String);
    }
    
952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981
    template<UseKind useKind>
    bool isStringObjectUse()
    {
        switch (useKind) {
        case StringObjectUse:
        case StringOrStringObjectUse:
            return true;
        default:
            return false;
        }
    }
    
    template<UseKind useKind>
    void convertStringAddUse(Node* node, Edge& edge)
    {
        if (useKind == StringUse) {
            // This preserves the binaryUseKind() invariant ot ValueAdd: ValueAdd's
            // two edges will always have identical use kinds, which makes the
            // decision process much easier.
            observeUseKindOnNode<StringUse>(edge.node());
            m_insertionSet.insertNode(
                m_indexInBlock, SpecNone, Phantom, node->codeOrigin,
                Edge(edge.node(), StringUse));
            edge.setUseKind(KnownStringUse);
            return;
        }
        
        // FIXME: We ought to be able to have a ToPrimitiveToString node.
        
        observeUseKindOnNode<useKind>(edge.node());
982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002
        createToString<useKind>(node, edge);
    }
    
    void convertToMakeRope(Node* node)
    {
        node->setOpAndDefaultFlags(MakeRope);
        fixupMakeRope(node);
    }
    
    void fixupMakeRope(Node* node)
    {
        for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
            Edge& edge = node->children.child(i);
            if (!edge)
                break;
            edge.setUseKind(KnownStringUse);
            if (!m_graph.isConstant(edge.node()))
                continue;
            JSString* string = jsCast<JSString*>(m_graph.valueOfJSConstant(edge.node()).asCell());
            if (string->length())
                continue;
1003 1004 1005 1006 1007
            
            // Don't allow the MakeRope to have zero children.
            if (!i && !node->child2())
                break;
            
1008 1009 1010 1011 1012 1013 1014
            node->children.removeEdge(i--);
        }
        
        if (!node->child2()) {
            ASSERT(!node->child3());
            node->convertToIdentity();
        }
1015 1016
    }
    
1017 1018 1019