Changeset 25797 in webkit


Ignore:
Timestamp:
Sep 28, 2007, 2:49:55 PM (18 years ago)
Author:
harrison
Message:

Reviewed by Darin Adler.

<rdar://problem/5511128> Crash closing or reloading this SVG

  • dom/ContainerNode.cpp: (WebCore::dispatchChildInsertionEvents): (WebCore::dispatchChildRemovalEvents): Use DocPtr instead of RefPtr, since these events are dispatched when the Document is being being torn down by removedLastRef().
  • dom/DocPtr.h: (WebCore::DocPtr::DocPtr): Fix longstanding typo in template so that the DocPtr(DocPtr) constructor can be used.
  • dom/Document.cpp: (WebCore::Document::Document): (WebCore::Document::removedLastRef):
  • dom/Document.h: (WebCore::Document::selfOnlyRef): (WebCore::Document::selfOnlyDeref):
  • platform/Shared.h: (WebCore::Shared::Shared): (WebCore::Shared::ref): (WebCore::Shared::deref): (WebCore::Shared::hasOneRef): (WebCore::TreeShared::TreeShared): (WebCore::TreeShared::ref): (WebCore::TreeShared::deref): (WebCore::TreeShared::hasOneRef): (WebCore::TreeShared::refCount): Add debug-only checks for a document being ref-counted while being deleted.
Location:
trunk/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r25796 r25797  
     12007-09-28  David Harrison  <harrison@apple.com>
     2
     3        Reviewed by Darin Adler.
     4
     5        <rdar://problem/5511128> Crash closing or reloading this SVG
     6
     7        * dom/ContainerNode.cpp:
     8        (WebCore::dispatchChildInsertionEvents):
     9        (WebCore::dispatchChildRemovalEvents):
     10        Use DocPtr instead of RefPtr, since these events are dispatched
     11        when the Document is being being torn down by removedLastRef().
     12
     13        * dom/DocPtr.h:
     14        (WebCore::DocPtr::DocPtr):
     15        Fix longstanding typo in template so that the DocPtr(DocPtr) constructor can be used.
     16
     17        * dom/Document.cpp:
     18        (WebCore::Document::Document):
     19        (WebCore::Document::removedLastRef):
     20        * dom/Document.h:
     21        (WebCore::Document::selfOnlyRef):
     22        (WebCore::Document::selfOnlyDeref):
     23        * platform/Shared.h:
     24        (WebCore::Shared::Shared):
     25        (WebCore::Shared::ref):
     26        (WebCore::Shared::deref):
     27        (WebCore::Shared::hasOneRef):
     28        (WebCore::TreeShared::TreeShared):
     29        (WebCore::TreeShared::ref):
     30        (WebCore::TreeShared::deref):
     31        (WebCore::TreeShared::hasOneRef):
     32        (WebCore::TreeShared::refCount):
     33        Add debug-only checks for a document being ref-counted while being deleted.
     34
    1352007-09-27  Kevin McCullough  <kmccullough@apple.com>
    236
  • trunk/WebCore/dom/ContainerNode.cpp

    r25754 r25797  
    886886
    887887    RefPtr<Node> c = child;
    888     RefPtr<Document> doc = child->document();
     888    DocPtr<Document> doc = child->document();
    889889
    890890    if (c->parentNode() && c->parentNode()->inDocument())
     
    920920{
    921921    RefPtr<Node> c = child;
    922     RefPtr<Document> doc = child->document();
     922    DocPtr<Document> doc = child->document();
    923923
    924924    // update auxiliary doc info (e.g. iterators) to note that node is being removed
  • trunk/WebCore/dom/DocPtr.h

    r25754 r25797  
    3030    DocPtr() : m_ptr(0) {}
    3131    DocPtr(T *ptr) : m_ptr(ptr) { if (ptr) ptr->selfOnlyRef(); }
    32     DocPtr(const DocPtr &o) : m_ptr(o.m_ptr) { if (T *ptr = m_ptr) ptr->selfOnlyRefRef(); }
     32    DocPtr(const DocPtr &o) : m_ptr(o.m_ptr) { if (T *ptr = m_ptr) ptr->selfOnlyRef(); }
    3333    ~DocPtr() { if (T *ptr = m_ptr) ptr->selfOnlyDeref(); }
    3434   
  • trunk/WebCore/dom/Document.cpp

    r25754 r25797  
    268268    , m_designMode(inherit)
    269269    , m_selfOnlyRefCount(0)
     270#ifndef NDEBUG
     271    , m_hasDeleted(false)
     272#endif
    270273#if ENABLE(SVG)
    271274    , m_svgExtensions(0)
     
    342345void Document::removedLastRef()
    343346{
     347    ASSERT(!m_hasDeleted);
    344348    if (m_selfOnlyRefCount) {
    345349        // if removing a child removes the last self-only ref, we don't
     
    366370        delete m_tokenizer;
    367371        m_tokenizer = 0;
    368     } else
     372    } else {
     373#ifndef NDEBUG
     374        m_hasDeleted = true;
     375#endif
    369376        delete this;
     377    }
    370378}
    371379
  • trunk/WebCore/dom/Document.h

    r25754 r25797  
    138138public:
    139139    Document(DOMImplementation*, Frame*, bool isXHTML = false);
    140     ~Document();
     140    virtual ~Document();
    141141
    142142    virtual void removedLastRef();
     
    148148    // pointer without introducing reference cycles
    149149
    150     void selfOnlyRef() { ++m_selfOnlyRefCount; }
    151     void selfOnlyDeref() {
     150    void selfOnlyRef()
     151    {
     152        ASSERT(!m_hasDeleted);
     153        ++m_selfOnlyRefCount;
     154    }
     155    void selfOnlyDeref()
     156    {
     157        ASSERT(!m_hasDeleted);
    152158        --m_selfOnlyRefCount;
    153         if (!m_selfOnlyRefCount && !refCount())
     159        if (!m_selfOnlyRefCount && !refCount()) {
     160#ifndef NDEBUG
     161            m_hasDeleted = true;
     162#endif
    154163            delete this;
     164        }
    155165    }
    156166
     
    873883   
    874884    int m_selfOnlyRefCount;
     885#ifndef NDEBUG
     886    bool m_hasDeleted;
     887#endif
    875888
    876889    HTMLFormElement::CheckedRadioButtons m_checkedRadioButtons;
  • trunk/WebCore/platform/Shared.h

    r25754 r25797  
    3232        : m_refCount(0)
    3333#ifndef NDEBUG
    34         , m_inDestructor(0)
     34        , m_hasDeleted(false)
    3535#endif
    3636    {
     
    3939    void ref()
    4040    {
    41         ASSERT(!m_inDestructor);
     41        ASSERT(!m_hasDeleted);
    4242        ++m_refCount;
    4343    }
     
    4545    void deref()
    4646    {
    47         ASSERT(!m_inDestructor);
     47        ASSERT(!m_hasDeleted);
    4848        if (--m_refCount <= 0) {
    4949#ifndef NDEBUG
    50             m_inDestructor = true;
     50            m_hasDeleted = true;
    5151#endif
    5252            delete static_cast<T*>(this);
     
    5656    bool hasOneRef()
    5757    {
    58         ASSERT(!m_inDestructor);
     58        ASSERT(!m_hasDeleted);
    5959        return m_refCount == 1;
    6060    }
     
    6868    int m_refCount;
    6969#ifndef NDEBUG
    70     bool m_inDestructor;
     70    bool m_hasDeleted;
    7171#endif
    7272};
    7373
    74 template<class T> class TreeShared {
     74template<class T> class TreeShared : Noncopyable {
    7575public:
    76     TreeShared() : m_refCount(0), m_parent(0) { }
    77     TreeShared(T* parent) : m_refCount(0), m_parent(parent) { }
     76    TreeShared()
     77        : m_refCount(0)
     78        , m_parent(0)
     79#ifndef NDEBUG
     80        , m_hasRemovedLastRef(false)
     81#endif
     82    {
     83    }
     84    TreeShared(T* parent)
     85        : m_refCount(0)
     86        , m_parent(parent)
     87#ifndef NDEBUG
     88        , m_hasRemovedLastRef(false)
     89#endif
     90    {
     91    }
    7892    virtual ~TreeShared() { }
    7993
    8094    virtual void removedLastRef() { delete static_cast<T*>(this); }
    8195
    82     void ref() { ++m_refCount;  }
    83     void deref() { if (--m_refCount <= 0 && !m_parent) removedLastRef(); }
    84     bool hasOneRef() { return m_refCount == 1; }
    85     int refCount() const { return m_refCount; }
     96    void ref()
     97    {
     98        ASSERT(!m_hasRemovedLastRef);
     99        ++m_refCount;
     100    }
     101
     102    void deref()
     103    {
     104        ASSERT(!m_hasRemovedLastRef);
     105        if (--m_refCount <= 0 && !m_parent) {
     106#ifndef NDEBUG
     107            m_hasRemovedLastRef = true;
     108#endif
     109            removedLastRef();
     110        }
     111    }
     112
     113    bool hasOneRef() const
     114    {
     115        ASSERT(!m_hasRemovedLastRef);
     116        return m_refCount == 1;
     117    }
     118
     119    int refCount() const
     120    {
     121        return m_refCount;
     122    }
    86123
    87124    void setParent(T* parent) { m_parent = parent; }
     
    91128    int m_refCount;
    92129    T* m_parent;
    93 
    94     TreeShared(const TreeShared&);
    95     TreeShared& operator=(const TreeShared&);
     130#ifndef NDEBUG
     131    bool m_hasRemovedLastRef;
     132#endif
    96133};
    97134
Note: See TracChangeset for help on using the changeset viewer.