Ignore:
Timestamp:
Feb 2, 2015, 10:15:44 AM (10 years ago)
Author:
[email protected]
Message:

Converting Flushes and PhantomLocals to Phantoms requires an OSR availability analysis rather than just using the SetLocal's child
https://bugs.webkit.org/show_bug.cgi?id=141107

Reviewed by Michael Saboff.

See the bugzilla for a discussion of the problem. This addresses the problem by ensuring
that Flushes are always strength-reduced to PhantomLocals, and CPS rethreading does a mini
OSR availability analysis to determine the right MovHint value to use for the Phantom.

  • dfg/DFGCPSRethreadingPhase.cpp:

(JSC::DFG::CPSRethreadingPhase::CPSRethreadingPhase):
(JSC::DFG::CPSRethreadingPhase::freeUnnecessaryNodes):
(JSC::DFG::CPSRethreadingPhase::clearVariables):
(JSC::DFG::CPSRethreadingPhase::canonicalizeFlushOrPhantomLocalFor):
(JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlock):
(JSC::DFG::CPSRethreadingPhase::clearVariablesAtHeadAndTail): Deleted.

  • dfg/DFGNode.h:

(JSC::DFG::Node::convertPhantomToPhantomLocal):
(JSC::DFG::Node::convertFlushToPhantomLocal):
(JSC::DFG::Node::convertToPhantomLocal): Deleted.

  • dfg/DFGStrengthReductionPhase.cpp:

(JSC::DFG::StrengthReductionPhase::handleNode):

  • tests/stress/inline-call-that-doesnt-use-all-args.js: Added.

(foo):
(bar):
(baz):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp

    r173069 r179477  
    11/*
    2  * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4040    CPSRethreadingPhase(Graph& graph)
    4141        : Phase(graph, "CPS rethreading")
     42        , m_availableForOSR(OperandsLike, graph.block(0)->variablesAtHead)
    4243    {
    4344    }
     
    99100                    case SetArgument:
    100101                    case SetLocal:
    101                         node->convertToPhantomLocal();
     102                        node->convertPhantomToPhantomLocal();
    102103                        break;
    103104                    default:
     
    120121   
    121122    template<OperandKind operandKind>
    122     void clearVariablesAtHeadAndTail()
     123    void clearVariables()
    123124    {
    124125        ASSERT(
    125126            m_block->variablesAtHead.sizeFor<operandKind>()
    126127            == m_block->variablesAtTail.sizeFor<operandKind>());
     128        ASSERT(
     129            m_block->variablesAtHead.sizeFor<operandKind>()
     130            == m_availableForOSR.sizeFor<operandKind>());
    127131       
    128132        for (unsigned i = m_block->variablesAtHead.sizeFor<operandKind>(); i--;) {
    129             m_block->variablesAtHead.atFor<operandKind>(i) = 0;
    130             m_block->variablesAtTail.atFor<operandKind>(i) = 0;
     133            m_block->variablesAtHead.atFor<operandKind>(i) = nullptr;
     134            m_block->variablesAtTail.atFor<operandKind>(i) = nullptr;
     135            m_availableForOSR.atFor<operandKind>(i) = Edge();
    131136        }
    132137    }
     
    260265                // know that I would have read the value written by that SetLocal. This is
    261266                // redundant and inefficient, since really it just means that we want to
    262                 // be keeping the operand to the SetLocal alive. The SetLocal may die, and
    263                 // we'll be fine because OSR tracks dead SetLocals.
    264                
    265                 // So we turn this into a Phantom on the child of the SetLocal.
    266                
     267                // keep the last MovHinted value of that local alive.
     268               
     269                node->children.setChild1(m_availableForOSR.atFor<operandKind>(idx));
    267270                node->convertToPhantom();
    268                 node->children.setChild1(otherNode->child1());
    269271                return;
    270272            }
     
    312314        ASSERT(m_block->isReachable);
    313315       
    314         clearVariablesAtHeadAndTail<ArgumentOperand>();
    315         clearVariablesAtHeadAndTail<LocalOperand>();
     316        clearVariables<ArgumentOperand>();
     317        clearVariables<LocalOperand>();
    316318       
    317319        // Assumes that all phi references have been removed. Assumes that things that
     
    383385                break;
    384386               
     387            case MovHint:
     388                m_availableForOSR.operand(node->unlinkedLocal()) = node->child1();
     389                break;
     390               
    385391            default:
    386392                break;
     
    523529    Vector<PhiStackEntry, 128> m_localPhiStack;
    524530    Vector<Node*, 128> m_flushedLocalOpWorklist;
     531    Operands<Edge> m_availableForOSR;
    525532};
    526533
Note: See TracChangeset for help on using the changeset viewer.