Changeset 41469 in webkit


Ignore:
Timestamp:
Mar 5, 2009 6:40:36 PM (15 years ago)
Author:
eric@webkit.org
Message:

Reviewed by David Hyatt.

Changes to RenderLayer destruction to hopefully help catch an elusive crasher
https://bugs.webkit.org/show_bug.cgi?id=24409

Added a new RenderBoxModelObject::destroyLayer() call which is
now the only way which RenderLayers should ever be destroyed.
This ensures that the pointer to the layer is cleared in the
RenderObject after destruction, allowing us to ASSERT in the
RenderBoxModelObject destructor.

  • rendering/RenderBox.cpp: (WebCore::RenderBox::calcAbsoluteHorizontalReplaced):
  • rendering/RenderBoxModelObject.cpp: (WebCore::RenderBoxModelObject::~RenderBoxModelObject): (WebCore::RenderBoxModelObject::destroyLayer): (WebCore::RenderBoxModelObject::destroy): (WebCore::RenderBoxModelObject::styleDidChange):
  • rendering/RenderBoxModelObject.h:
  • rendering/RenderLayer.cpp: (WebCore::RenderLayer::stackingContext): (WebCore::RenderLayer::destroy): (WebCore::RenderLayer::removeOnlyThisLayer):
  • rendering/RenderLayer.h:
  • rendering/RenderObject.cpp: (WebCore::RenderObject::destroy):
  • rendering/RenderWidget.cpp: (WebCore::RenderWidget::destroy):
Location:
trunk/WebCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r41468 r41469  
     12009-03-05  Eric Seidel  <eric@webkit.org>
     2
     3        Reviewed by David Hyatt.
     4
     5        Changes to RenderLayer destruction to hopefully help catch an elusive crasher
     6        https://bugs.webkit.org/show_bug.cgi?id=24409
     7       
     8        Added a new RenderBoxModelObject::destroyLayer() call which is
     9        now the only way which RenderLayers should ever be destroyed.
     10        This ensures that the pointer to the layer is cleared in the
     11        RenderObject after destruction, allowing us to ASSERT in the
     12        RenderBoxModelObject destructor.
     13
     14        * rendering/RenderBox.cpp:
     15        (WebCore::RenderBox::calcAbsoluteHorizontalReplaced):
     16        * rendering/RenderBoxModelObject.cpp:
     17        (WebCore::RenderBoxModelObject::~RenderBoxModelObject):
     18        (WebCore::RenderBoxModelObject::destroyLayer):
     19        (WebCore::RenderBoxModelObject::destroy):
     20        (WebCore::RenderBoxModelObject::styleDidChange):
     21        * rendering/RenderBoxModelObject.h:
     22        * rendering/RenderLayer.cpp:
     23        (WebCore::RenderLayer::stackingContext):
     24        (WebCore::RenderLayer::destroy):
     25        (WebCore::RenderLayer::removeOnlyThisLayer):
     26        * rendering/RenderLayer.h:
     27        * rendering/RenderObject.cpp:
     28        (WebCore::RenderObject::destroy):
     29        * rendering/RenderWidget.cpp:
     30        (WebCore::RenderWidget::destroy):
     31
    1322009-03-05  Eric Seidel  <eric@webkit.org>
    233
  • trunk/WebCore/rendering/RenderBox.cpp

    r41387 r41469  
    23552355            RenderObject* po = parent();
    23562356            // 'staticX' should already have been set through layout of the parent.
    2357             int staticPosition = layer()->staticX() + containerWidth + toRenderBoxModelObject(containerBlock)->borderRight();
     2357            int staticPosition = layer()->staticX() + containerWidth + containerBlock->borderRight();
    23582358            for ( ; po && po != containerBlock; po = po->parent()) {
    23592359                if (po->isBox())
  • trunk/WebCore/rendering/RenderBoxModelObject.cpp

    r41317 r41469  
    5151RenderBoxModelObject::~RenderBoxModelObject()
    5252{
     53    // Our layer should have been destroyed and cleared by now
     54    ASSERT(!hasLayer());
     55    ASSERT(!m_layer);
     56}
     57
     58void RenderBoxModelObject::destroyLayer()
     59{
     60    ASSERT(hasLayer());
     61    ASSERT(m_layer);
     62    m_layer->destroy(renderArena());
     63    m_layer = 0;
     64    setHasLayer(false);
    5365}
    5466
     
    5870    if (m_layer)
    5971        m_layer->clearClipRects();
     72
     73    // RenderObject::destroy calls back to destroyLayer() for layer destruction
    6074    RenderObject::destroy();
    6175}
     
    101115        }
    102116    } else if (layer() && layer()->parent()) {
    103        
    104         RenderLayer* layer = m_layer;
    105         m_layer = 0;
    106         setHasLayer(false);
    107117        setHasTransform(false); // Either a transform wasn't specified or the object doesn't support transforms, so just null out the bit.
    108118        setHasReflection(false);
    109         layer->removeOnlyThisLayer();
     119        m_layer->removeOnlyThisLayer(); // calls destroyLayer() which clears m_layer
    110120        if (s_wasFloating && isFloating())
    111121            setChildNeedsLayout(true);
  • trunk/WebCore/rendering/RenderBoxModelObject.h

    r41203 r41469  
    9797    int verticalPosition(bool firstLine) const;
    9898
     99    // Called by RenderObject::destroy() (and RenderWidget::destroy()) and is the only way layers should ever be destroyed
     100    void destroyLayer();
     101
    99102protected:
    100103    void calculateBackgroundImageGeometry(const FillLayer*, int tx, int ty, int w, int h, IntRect& destRect, IntPoint& phase, IntSize& tileSize);
     
    124127
    125128// This will catch anyone doing an unnecessary cast.
    126 void toRenderBoxModelObject(const RenderBox*);
     129void toRenderBoxModelObject(const RenderBoxModelObject*);
    127130
    128131} // namespace WebCore
  • trunk/WebCore/rendering/RenderLayer.cpp

    r41458 r41469  
    611611}
    612612
    613 RenderLayer *RenderLayer::stackingContext() const
    614 {
    615     RenderLayer* curr = parent();
    616     for ( ; curr && !curr->renderer()->isRenderView() && !curr->renderer()->isRoot() &&
    617           curr->renderer()->style()->hasAutoZIndex();
    618           curr = curr->parent()) { }
    619     return curr;
     613RenderLayer* RenderLayer::stackingContext() const
     614{
     615    RenderLayer* layer = parent();
     616    while (layer && !layer->renderer()->isRenderView() && !layer->renderer()->isRoot() && layer->renderer()->style()->hasAutoZIndex())
     617        layer = layer->parent();
     618    return layer;
    620619}
    621620
     
    771770
    772771void RenderLayer::destroy(RenderArena* renderArena)
    773 {   
     772{
    774773    delete this;
    775774
     
    881880        current = next;
    882881    }
    883    
    884     destroy(renderer()->renderArena());
     882
     883    m_renderer->destroyLayer();
    885884}
    886885
  • trunk/WebCore/rendering/RenderLayer.h

    r41455 r41469  
    415415    bool has3DTransform() const { return m_transform && !m_transform->isAffine(); }
    416416
    417     void destroy(RenderArena*);
    418 
    419417     // Overloaded new operator.  Derived classes must override operator new
    420418    // in order to allocate out of the RenderArena.
     
    520518    friend class RenderLayerBacking;
    521519    friend class RenderLayerCompositor;
     520    friend class RenderBoxModelObject;
     521
     522    // Only safe to call from RenderBoxModelObject::destroyLayer(RenderArena*)
     523    void destroy(RenderArena*);
    522524
    523525protected:
  • trunk/WebCore/rendering/RenderObject.cpp

    r41455 r41469  
    18401840    // FIXME: Would like to do this in RenderBoxModelObject, but the timing is so complicated that this can't easily
    18411841    // be moved into RenderBoxModelObject::destroy.
    1842     RenderArena* arena = renderArena();
    18431842    if (hasLayer())
    1844         toRenderBoxModelObject(this)->layer()->destroy(arena);
    1845     arenaDelete(arena, this);
     1843        toRenderBoxModelObject(this)->destroyLayer();
     1844    arenaDelete(renderArena(), this);
    18461845}
    18471846
  • trunk/WebCore/rendering/RenderWidget.cpp

    r40987 r41469  
    9292        setOverrideSize(-1);
    9393
    94     RenderArena* arena = renderArena();
    95 
    96     if (hasLayer())
    97         layer()->clearClipRects();
    98 
    9994    if (style() && (style()->height().isPercent() || style()->minHeight().isPercent() || style()->maxHeight().isPercent()))
    10095        RenderBlock::removePercentHeightDescendant(this);
    10196
     97    if (hasLayer()) {
     98        layer()->clearClipRects();
     99        destroyLayer();
     100    }
     101
     102    // Grab the arena from node()->document()->renderArena() before clearing the node pointer.
     103    // Clear the node before deref-ing, as this may be deleted when deref is called.
     104    RenderArena* arena = renderArena();
    102105    setNode(0);
    103 
    104     if (hasLayer())
    105         layer()->destroy(arena);
    106 
    107106    deref(arena);
    108107}
Note: See TracChangeset for help on using the changeset viewer.