Changeset 63892 in webkit


Ignore:
Timestamp:
Jul 22, 2010 7:43:09 AM (14 years ago)
Author:
commit-queue@webkit.org
Message:

2010-07-22 Hayato Ito <hayato@chromium.org>

Reviewed by Darin Adler.

Refactor CSSSelector's destructor and make it inline.

https://bugs.webkit.org/show_bug.cgi?id=42726

Refactor with no behavior change, thus no new tests.

  • css/CSSSelector.cpp: (WebCore::CSSSelectorBag::~CSSSelectorBag): Make sure the bag is empty. (WebCore::CSSSelectorBag::add): Renamed from append(). (WebCore::CSSSelector::releaseOwnedSelectorsToBag): (WebCore::CSSSelector::deleteReachableSelectors):
  • css/CSSSelector.h: (WebCore::CSSSelector::~CSSSelector):
Location:
trunk/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r63891 r63892  
     12010-07-22  Hayato Ito  <hayato@chromium.org>
     2
     3        Reviewed by Darin Adler.
     4
     5        Refactor CSSSelector's destructor and make it inline.
     6
     7        https://bugs.webkit.org/show_bug.cgi?id=42726
     8
     9        Refactor with no behavior change, thus no new tests.
     10
     11        * css/CSSSelector.cpp:
     12        (WebCore::CSSSelectorBag::~CSSSelectorBag): Make sure the bag is empty.
     13        (WebCore::CSSSelectorBag::add): Renamed from append().
     14        (WebCore::CSSSelector::releaseOwnedSelectorsToBag):
     15        (WebCore::CSSSelector::deleteReachableSelectors):
     16        * css/CSSSelector.h:
     17        (WebCore::CSSSelector::~CSSSelector):
     18
    1192010-07-22  Yury Semikhatsky  <yurys@chromium.org>
    220
  • trunk/WebCore/css/CSSSelector.cpp

    r63747 r63892  
    3838using namespace HTMLNames;
    3939
    40 // A helper class to hold CSSSelectors.
    4140class CSSSelectorBag : public Noncopyable {
    4241public:
    4342    ~CSSSelectorBag()
    4443    {
    45         deleteAllValues(m_stack);
     44        ASSERT(isEmpty());
    4645    }
    4746
     
    5150    }
    5251
    53     void append(PassOwnPtr<CSSSelector> selector)
     52    void add(PassOwnPtr<CSSSelector> selector)
    5453    {
    5554        if (selector)
     
    6867    Vector<CSSSelector*, 16> m_stack;
    6968};
    70 
    71 CSSSelector::~CSSSelector()
    72 {
    73     // We should avoid a recursive destructor call, which causes stack overflow
    74     // if CSS Selectors are deeply nested.
    75 
    76     // Early exit if we have already processed the children of this selector.
    77     if (m_hasRareData) {
    78         if (!m_data.m_rareData)
    79             return;
    80     } else if (!m_data.m_tagHistory)
    81         return;
    82 
    83     CSSSelectorBag selectorsToBeDeleted;
    84     if (m_hasRareData) {
    85         selectorsToBeDeleted.append(m_data.m_rareData->m_tagHistory.release());
    86         selectorsToBeDeleted.append(m_data.m_rareData->m_simpleSelector.release());
    87         delete m_data.m_rareData;
    88     } else
    89         selectorsToBeDeleted.append(adoptPtr(m_data.m_tagHistory));
    90 
    91     // Traverse the tree of CSSSelector and delete each CSSSelector iteratively.
    92     while (!selectorsToBeDeleted.isEmpty()) {
    93         OwnPtr<CSSSelector> selector(selectorsToBeDeleted.takeAny());
    94         ASSERT(selector);
    95         if (selector->m_hasRareData) {
    96             ASSERT(selector->m_data.m_rareData);
    97             selectorsToBeDeleted.append(selector->m_data.m_rareData->m_tagHistory.release());
    98             selectorsToBeDeleted.append(selector->m_data.m_rareData->m_simpleSelector.release());
    99             delete selector->m_data.m_rareData;
    100             // Clear the pointer so that a destructor of the selector, which is
    101             // about to be called, can know the children are already processed.
    102             selector->m_data.m_rareData = 0;
    103         } else {
    104             selectorsToBeDeleted.append(adoptPtr(selector->m_data.m_tagHistory));
    105             // Clear the pointer for the same reason.
    106             selector->m_data.m_tagHistory = 0;
    107         }
    108     }
    109 }
    11069
    11170unsigned int CSSSelector::specificity()
     
    981940}
    982941
     942inline void CSSSelector::releaseOwnedSelectorsToBag(CSSSelectorBag& bag)
     943{
     944    if (m_hasRareData) {
     945        ASSERT(m_data.m_rareData);
     946        bag.add(m_data.m_rareData->m_tagHistory.release());
     947        bag.add(m_data.m_rareData->m_simpleSelector.release());
     948        delete m_data.m_rareData;
     949        // Clear the pointer so that a destructor of this selector will not
     950        // traverse this chain.
     951        m_data.m_rareData = 0;
     952    } else {
     953        bag.add(adoptPtr(m_data.m_tagHistory));
     954        // Clear the pointer for the same reason.
     955        m_data.m_tagHistory = 0;
     956    }
     957}
     958
     959void CSSSelector::deleteReachableSelectors()
     960{
     961    // Traverse the chain of selectors and delete each iteratively.
     962    CSSSelectorBag selectorsToBeDeleted;
     963    releaseOwnedSelectorsToBag(selectorsToBeDeleted);
     964    while (!selectorsToBeDeleted.isEmpty()) {
     965        OwnPtr<CSSSelector> selector(selectorsToBeDeleted.takeAny());
     966        ASSERT(selector);
     967        selector->releaseOwnedSelectorsToBag(selectorsToBeDeleted);
     968    }
     969}
     970
    983971} // namespace WebCore
  • trunk/WebCore/css/CSSSelector.h

    r63747 r63892  
    3131namespace WebCore {
    3232
     33    class CSSSelectorBag;
     34
    3335    // this class represents a selector for a StyleRule
    3436    class CSSSelector : public Noncopyable {
     
    5860        }
    5961
    60         ~CSSSelector();
     62        ~CSSSelector()
     63        {
     64            // Exit if this selector does not own any objects to be deleted.
     65            if (m_hasRareData) {
     66                if (!m_data.m_rareData)
     67                    return;
     68            } else if (!m_data.m_tagHistory)
     69                return;
     70
     71            // We can not delete the owned object(s) by simply calling delete
     72            // directly on them. That would lead to recursive destructor calls
     73            // which might cause stack overflow. We have to delete them
     74            // iteratively.
     75            deleteReachableSelectors();
     76        }
    6177
    6278        /**
     
    276292        bool m_isForPage              : 1;
    277293
     294        void releaseOwnedSelectorsToBag(CSSSelectorBag&);
     295        void deleteReachableSelectors();
     296
    278297        unsigned specificityForPage();
    279298        void extractPseudoType() const;
Note: See TracChangeset for help on using the changeset viewer.