Changeset 143940 in webkit


Ignore:
Timestamp:
Feb 25, 2013 10:02:42 AM (11 years ago)
Author:
Dimitri Glazkov
Message:

Revert r143840 because it caused flaky crashes.
https://bugs.webkit.org/show_bug.cgi?id=110766

Location:
trunk/Source/WebCore
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r143939 r143940  
     12013-02-25  Dimitri Glazkov  <dglazkov@chromium.org>
     2
     3        Revert r143840 because it caused flaky crashes.
     4        https://bugs.webkit.org/show_bug.cgi?id=110766
     5
    162013-02-25  Alexey Proskuryakov  <ap@apple.com>
    27
  • trunk/Source/WebCore/WebCore.exp.in

    r143840 r143940  
    14141414__ZNK7WebCore4Node13ownerDocumentEv
    14151415__ZNK7WebCore4Node14isDescendantOfEPKS0_
     1416__ZNK7WebCore4Node11isTreeScopeEv
    14161417__ZNK7WebCore4Node18getSubresourceURLsERN3WTF11ListHashSetINS_4KURLELm256ENS_8KURLHashEEE
    14171418__ZNK7WebCore4Node31numberOfScopedHTMLStyleChildrenEv
  • trunk/Source/WebCore/dom/Document.cpp

    r143926 r143940  
    418418    : ContainerNode(0, CreateDocument)
    419419    , TreeScope(this)
     420    , m_guardRefCount(0)
    420421    , m_styleResolverThrowawayTimer(this, &Document::styleResolverThrowawayTimerFired)
    421422    , m_lastStyleResolverAccessTime(0)
     
    489490#endif
    490491{
     492    setTreeScope(this);
     493
    491494    m_printing = false;
    492495    m_paginatedForScreen = false;
     
    588591    ASSERT(!m_styleRecalcTimer.isActive());
    589592    ASSERT(!m_parentTreeScope);
    590     ASSERT(!hasGuardRefCount());
     593    ASSERT(!m_guardRefCount);
    591594
    592595#if ENABLE(TEMPLATE_ELEMENT)
     
    655658}
    656659
    657 void Document::dispose()
    658 {
    659     // We must make sure not to be retaining any of our children through
    660     // these extra pointers or we will create a reference cycle.
    661     m_docType = 0;
    662     m_focusedNode = 0;
    663     m_hoverNode = 0;
    664     m_activeElement = 0;
    665     m_titleElement = 0;
    666     m_documentElement = 0;
    667     m_contextFeatures = ContextFeatures::defaultSwitch();
    668     m_userActionElements.documentDidRemoveLastRef();
     660void Document::removedLastRef()
     661{
     662    ASSERT(!m_deletionHasBegun);
     663    if (m_guardRefCount) {
     664        // If removing a child removes the last self-only ref, we don't
     665        // want the scope to be destructed until after
     666        // removeDetachedChildren returns, so we guard ourselves with an
     667        // extra self-only ref.
     668        guardRef();
     669
     670        // We must make sure not to be retaining any of our children through
     671        // these extra pointers or we will create a reference cycle.
     672        m_docType = 0;
     673        m_focusedNode = 0;
     674        m_hoverNode = 0;
     675        m_activeElement = 0;
     676        m_titleElement = 0;
     677        m_documentElement = 0;
     678        m_contextFeatures = ContextFeatures::defaultSwitch();
     679        m_userActionElements.documentDidRemoveLastRef();
    669680#if ENABLE(FULLSCREEN_API)
    670     m_fullScreenElement = 0;
    671     m_fullScreenElementStack.clear();
    672 #endif
    673 
    674     detachParser();
     681        m_fullScreenElement = 0;
     682        m_fullScreenElementStack.clear();
     683#endif
     684
     685        detachParser();
    675686
    676687#if ENABLE(CUSTOM_ELEMENTS)
     
    678689#endif
    679690
    680     // removeDetachedChildren() doesn't always unregister IDs,
    681     // so tear down scope information upfront to avoid having stale references in the map.
    682     destroyTreeScopeData();
    683     removeDetachedChildren();
    684 
    685     m_markers->detach();
    686 
    687     m_cssCanvasElements.clear();
     691        // removeDetachedChildren() doesn't always unregister IDs,
     692        // so tear down scope information upfront to avoid having stale references in the map.
     693        destroyTreeScopeData();
     694        removeDetachedChildren();
     695
     696        m_markers->detach();
     697
     698        m_cssCanvasElements.clear();
    688699
    689700#if ENABLE(REQUEST_ANIMATION_FRAME)
    690     // FIXME: consider using ActiveDOMObject.
    691     if (m_scriptedAnimationController)
    692         m_scriptedAnimationController->clearDocumentPointer();
    693     m_scriptedAnimationController.clear();
    694 #endif
     701        // FIXME: consider using ActiveDOMObject.
     702        if (m_scriptedAnimationController)
     703            m_scriptedAnimationController->clearDocumentPointer();
     704        m_scriptedAnimationController.clear();
     705#endif
     706
     707#ifndef NDEBUG
     708        m_inRemovedLastRefFunction = false;
     709#endif
     710
     711        guardDeref();
     712    } else {
     713#ifndef NDEBUG
     714        m_deletionHasBegun = true;
     715#endif
     716        delete this;
     717    }
    695718}
    696719
  • trunk/Source/WebCore/dom/Document.h

    r143865 r143940  
    232232    using ContainerNode::deref;
    233233
     234    // Nodes belonging to this document hold guard references -
     235    // these are enough to keep the document from being destroyed, but
     236    // not enough to keep it from removing its children. This allows a
     237    // node that outlives its document to still have a valid document
     238    // pointer without introducing reference cycles.
     239    void guardRef()
     240    {
     241        ASSERT(!m_deletionHasBegun);
     242        ++m_guardRefCount;
     243    }
     244
     245    void guardDeref()
     246    {
     247        ASSERT(!m_deletionHasBegun);
     248        --m_guardRefCount;
     249        if (!m_guardRefCount && !refCount()) {
     250#ifndef NDEBUG
     251            m_deletionHasBegun = true;
     252#endif
     253            delete this;
     254        }
     255    }
     256
    234257    Element* getElementById(const AtomicString& id) const;
    235258
     
    12031226    friend class IgnoreDestructiveWriteCountIncrementer;
    12041227
    1205     virtual void dispose() OVERRIDE;
    1206 
     1228    void removedLastRef();
     1229   
    12071230    void detachParser();
    12081231
     
    12711294    void addListenerType(ListenerType listenerType) { m_listenerTypes |= listenerType; }
    12721295    void addMutationEventListenerTypeIfEnabled(ListenerType);
     1296
     1297    int m_guardRefCount;
    12731298
    12741299    void styleResolverThrowawayTimerFired(Timer<Document>*);
     
    15911616    , m_next(0)
    15921617{
    1593     if (!m_treeScope)
     1618    if (document)
     1619        document->guardRef();
     1620    else
    15941621        m_treeScope = TreeScope::noDocumentInstance();
    1595     m_treeScope->guardRef();
    15961622
    15971623#if !defined(NDEBUG) || (defined(DUMP_NODE_STATISTICS) && DUMP_NODE_STATISTICS)
  • trunk/Source/WebCore/dom/DocumentFragment.cpp

    r143840 r143940  
    3535    : ContainerNode(document, constructionType)
    3636{
     37    ASSERT(document);
    3738}
    3839
    3940PassRefPtr<DocumentFragment> DocumentFragment::create(Document* document)
    4041{
    41     ASSERT(document);
    4242    return adoptRef(new DocumentFragment(document, Node::CreateDocumentFragment));
    4343}
  • trunk/Source/WebCore/dom/Node.cpp

    r143840 r143940  
    443443        m_next->setPreviousSibling(0);
    444444
    445     m_treeScope->guardDeref();
     445    if (doc)
     446        doc->guardDeref();
    446447
    447448    InspectorCounters::decrementCounter(InspectorCounters::NodeCounter);
     
    890891
    891892    return true;
     893}
     894
     895bool Node::isTreeScope() const
     896{
     897    return treeScope()->rootNode() == this;
    892898}
    893899
     
    25562562#endif
    25572563
    2558 // This is here for inlining
    2559 inline void TreeScope::removedLastRefToScope()
    2560 {
    2561     ASSERT(!deletionHasBegun());
    2562     if (m_guardRefCount) {
    2563         // If removing a child removes the last self-only ref, we don't
    2564         // want the scope to be destructed until after
    2565         // removeDetachedChildren returns, so we guard ourselves with an
    2566         // extra self-only ref.
    2567         guardRef();
    2568         dispose();
    2569 #ifndef NDEBUG
    2570         // We need to do this right now since guardDeref() can delete this.
    2571         rootNode()->m_inRemovedLastRefFunction = false;
    2572 #endif
    2573         guardDeref();
    2574     } else {
    2575 #ifndef NDEBUG
    2576         rootNode()->m_inRemovedLastRefFunction = false;
    2577         beginDeletion();
    2578 #endif
    2579         delete this;
    2580     }
    2581 }
    2582 
    25832564// It's important not to inline removedLastRef, because we don't want to inline the code to
    25842565// delete a Node at each deref call site.
     
    25882569    // faster for non-Document nodes, and because the call to removedLastRef that is inlined
    25892570    // at all deref call sites is smaller if it's a non-virtual function.
    2590     if (isTreeScope()) {
    2591         treeScope()->removedLastRefToScope();
     2571    if (isDocumentNode()) {
     2572        static_cast<Document*>(this)->removedLastRef();
    25922573        return;
    25932574    }
    2594 
    25952575#ifndef NDEBUG
    25962576    m_deletionHasBegun = true;
  • trunk/Source/WebCore/dom/Node.h

    r143840 r143940  
    249249
    250250    bool isDocumentNode() const;
    251     bool isTreeScope() const { return treeScope()->rootNode() == this; }
     251    bool isTreeScope() const;
    252252    bool isDocumentFragment() const { return getFlag(IsDocumentFragmentFlag); }
    253253    bool isShadowRoot() const { return isDocumentFragment() && isTreeScope(); }
  • trunk/Source/WebCore/dom/ShadowRoot.cpp

    r143840 r143940  
    5353
    5454ShadowRoot::ShadowRoot(Document* document, ShadowRootType type)
    55     : DocumentFragment(0, CreateShadowRoot)
     55    : DocumentFragment(document, CreateShadowRoot)
    5656    , TreeScope(this, document)
    5757    , m_prev(0)
     
    6464{
    6565    ASSERT(document);
     66    setTreeScope(this);
    6667
    6768#if PLATFORM(CHROMIUM)
     
    8788    if (hasRareData())
    8889        clearRareData();
    89 }
    90 
    91 void ShadowRoot::dispose()
    92 {
    93     removeDetachedChildren();
    9490}
    9591
  • trunk/Source/WebCore/dom/ShadowRoot.h

    r143840 r143940  
    101101    virtual ~ShadowRoot();
    102102
    103     virtual void dispose() OVERRIDE;
    104103    virtual bool childTypeAllowed(NodeType) const OVERRIDE;
    105104    virtual void childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) OVERRIDE;
  • trunk/Source/WebCore/dom/TreeScope.cpp

    r143840 r143940  
    6060    virtual ~SameSizeAsTreeScope();
    6161    void* pointers[8];
    62     int ints[1];
    6362};
    6463
     
    7170    , m_documentScope(document)
    7271    , m_parentTreeScope(document)
    73     , m_guardRefCount(0)
    7472    , m_idTargetObserverRegistry(IdTargetObserverRegistry::create())
    7573{
     
    7775    ASSERT(document);
    7876    ASSERT(rootNode != document);
    79     m_parentTreeScope->guardRef();
    80     m_rootNode->setTreeScope(this);
    8177}
    8278
     
    8581    , m_documentScope(document)
    8682    , m_parentTreeScope(0)
    87     , m_guardRefCount(0)
    8883    , m_idTargetObserverRegistry(IdTargetObserverRegistry::create())
    8984{
    9085    ASSERT(document);
    91     m_rootNode->setTreeScope(this);
    9286}
    9387
     
    9690    , m_documentScope(0)
    9791    , m_parentTreeScope(0)
    98     , m_guardRefCount(0)
    9992{
    10093}
     
    10295TreeScope::~TreeScope()
    10396{
    104     ASSERT(!m_guardRefCount);
    105     m_rootNode->setTreeScope(noDocumentInstance());
    106 
    10797    if (m_selection) {
    10898        m_selection->clearTreeScope();
    10999        m_selection = 0;
    110100    }
    111 
    112     if (m_parentTreeScope)
    113         m_parentTreeScope->guardDeref();
    114101}
    115102
     
    134121    ASSERT(newParentScope);
    135122
    136     newParentScope->guardRef();
    137     if (m_parentTreeScope)
    138         m_parentTreeScope->guardDeref();
    139123    m_parentTreeScope = newParentScope;
    140124    setDocumentScope(newParentScope->documentScope());
     
    432416}
    433417
    434 #ifndef NDEBUG
    435 bool TreeScope::deletionHasBegun()
    436 {
    437     return rootNode() && rootNode()->m_deletionHasBegun;
    438 }
    439 
    440 void TreeScope::beginDeletion()
    441 {
    442     ASSERT(this != noDocumentInstance());
    443     rootNode()->m_deletionHasBegun = true;
    444 }
    445 #endif
    446 
    447 int TreeScope::refCount() const
    448 {
    449     if (Node* root = rootNode())
    450         return root->refCount();
    451     return 0;
    452 }
    453 
    454418} // namespace WebCore
  • trunk/Source/WebCore/dom/TreeScope.h

    r143840 r143940  
    9393    void adoptIfNeeded(Node*);
    9494
    95     Node* rootNode() const { return m_rootNode; }
     95    ContainerNode* rootNode() const { return m_rootNode; }
    9696
    9797    IdTargetObserverRegistry& idTargetObserverRegistry() const { return *m_idTargetObserverRegistry.get(); }
     
    104104        return &instance;
    105105    }
    106 
    107     // Nodes belonging to this scope hold guard references -
    108     // these are enough to keep the scope from being destroyed, but
    109     // not enough to keep it from removing its children. This allows a
    110     // node that outlives its scope to still have a valid document
    111     // pointer without introducing reference cycles.
    112     void guardRef()
    113     {
    114         ASSERT(!deletionHasBegun());
    115         ++m_guardRefCount;
    116     }
    117 
    118     void guardDeref()
    119     {
    120         ASSERT(!deletionHasBegun());
    121         --m_guardRefCount;
    122         if (!m_guardRefCount && !refCount() && this != noDocumentInstance()) {
    123             beginDeletion();
    124             delete this;
    125         }
    126     }
    127 
    128     void removedLastRefToScope();
    129106
    130107protected:
     
    142119    }
    143120
    144     bool hasGuardRefCount() const { return m_guardRefCount; }
    145 
    146121private:
    147122    TreeScope();
    148123
    149     virtual void dispose() { }
    150 
    151     int refCount() const;
    152 #ifndef NDEBUG
    153     bool deletionHasBegun();
    154     void beginDeletion();
    155 #else
    156     bool deletionHasBegun() { return false; }
    157     void beginDeletion() { }
    158 #endif
    159 
    160     Node* m_rootNode;
     124    ContainerNode* m_rootNode;
    161125    Document* m_documentScope;
    162126    TreeScope* m_parentTreeScope;
    163     int m_guardRefCount;
    164127
    165128    OwnPtr<DocumentOrderedMap> m_elementsById;
  • trunk/Source/WebCore/dom/TreeScopeAdopter.cpp

    r143840 r143940  
    4141    ASSERT(needsScopeChange());
    4242
    43     m_oldScope->guardRef();
    44 
    4543    // If an element is moved from a document and then eventually back again the collection cache for
    4644    // that element may contain stale data as changes made to it will have updated the DOMTreeVersion
     
    5452
    5553    for (Node* node = root; node; node = NodeTraversal::next(node, root)) {
    56         updateTreeScope(node);
     54        node->setTreeScope(m_newScope);
    5755
    5856        if (willMoveToNewDocument)
     
    7977        }
    8078    }
    81 
    82     m_oldScope->guardDeref();
    8379}
    8480
     
    104100#endif
    105101
    106 inline void TreeScopeAdopter::updateTreeScope(Node* node) const
    107 {
    108     ASSERT(!node->isTreeScope());
    109     ASSERT(node->treeScope() == m_oldScope);
    110     m_newScope->guardRef();
    111     m_oldScope->guardDeref();
    112     node->setTreeScope(m_newScope);
    113 }
    114 
    115102inline void TreeScopeAdopter::moveNodeToNewDocument(Node* node, Document* oldDocument, Document* newDocument) const
    116103{
     
    123110    }
    124111
     112    newDocument->guardRef();
    125113    if (oldDocument)
    126114        oldDocument->moveNodeIteratorsToNewDocument(node, newDocument);
     
    136124    node->didMoveToNewDocument(oldDocument);
    137125    ASSERT(didMoveToNewDocumentWasCalled);
     126   
     127    if (oldDocument)
     128        oldDocument->guardDeref();
    138129}
    139130
  • trunk/Source/WebCore/dom/TreeScopeAdopter.h

    r143840 r143940  
    4646
    4747private:
    48     void updateTreeScope(Node*) const;
    4948    void moveTreeToNewScope(Node*) const;
    5049    void moveTreeToNewDocument(Node*, Document* oldDocument, Document* newDocument) const;
Note: See TracChangeset for help on using the changeset viewer.