Changeset 155796 in webkit


Ignore:
Timestamp:
Sep 15, 2013 12:27:52 AM (11 years ago)
Author:
akling@apple.com
Message:

Get rid of ref-counting on RenderWidget.
<https://webkit.org/b/121357>

Reviewed by Darin Adler.

Source/WebCore:

Instead of RenderView tracking RenderWidgets, have FrameView track Widgets
that are currently in the render tree.

To protect ourselves during NPAPI tomfoolery, we now let RenderWidget hand
out weak pointers through a createWeakPtr() method so call sites can monitor
the renderer for deletion without having to take shared ownership.

This works out quite nicely since instead of keeping a limping object alive
for a little longer just so we can call methods on it (to accomplish nothing),
we're forced to check right away if it's gone, and take immediate action.

De-virtualized RenderObject::destroy() since it's no longer needed for
RenderWidget to defer destruction.

  • page/FrameView.cpp:

(WebCore::FrameView::layout):
(WebCore::FrameView::repaintFixedElementsAfterScrolling):

Call updateWidgetPositions() on FrameView instead of RenderView.

(WebCore::FrameView::updateEmbeddedObject):

Turn null checking of embedded object's element backpointer into an
assertion. This will eventually go away completely once that renderer
can return a HTMLFrameOwnerElement&.

Use WeakPtr to check for renderer destruction following the call out
to updateWidget().

(WebCore::FrameView::updateEmbeddedObjects):

Slap a WidgetHierarchyUpdatesSuspensionScope guard on this function
to defer Widget updates until all the updateEmbeddedObject calls are
done. This avoids RenderWidget::setWidget() having to handle 'this'
disappearing from underneath.

Also use a ListHashSet with a null sentinel to avoid looping forever.

(WebCore::FrameView::performPostLayoutTasks):

Only call updateEmbeddedObjects() once since that function no longer
operates in chunks.

(WebCore::FrameView::notifyWidgetsInAllFrames):

Call notifyWidgets() on FrameView instead of RenderView.

(WebCore::FrameView::didAddWidgetToRenderTree):
(WebCore::FrameView::willRemoveWidgetFromRenderTree):

Added. These are called by RenderWidget when a Widget is being
added or removed from a RenderWidget.

(WebCore::collectWidgets):

Helper to collect raw Widget pointers into a Vector and ref them.

(WebCore::FrameView::updateWidgetPositions):

Moved here from RenderView. This function holds a ref on all the
attached Widgets and calls RenderWidget::updateWidgetPosition() on
their corresponding renderers.

(WebCore::FrameView::notifyWidgets):

Moved here from RenderView. Holds a ref on all the widgets while
calling Widget::notifyWidget() on each one.

  • rendering/RenderLayer.cpp:

(WebCore::RenderLayer::scrollTo):

Call updateWidgetPositions() on FrameView instead of RenderView.

  • rendering/RenderObject.h:

De-virtualized destroy().

  • rendering/RenderView.cpp:
  • rendering/RenderView.h:

Moved a bunch of things to FrameView. Made protected section private
since nothing inherits from RenderView.

  • rendering/RenderWidget.h:

(WebCore::RenderWidget::createWeakPtr):

Added a WeakPtr factory for clients that want to monitor this object
for destruction.

  • rendering/RenderWidget.cpp:

(WebCore::RenderWidget::RenderWidget):
(WebCore::RenderWidget::willBeDestroyed):
(WebCore::RenderWidget::~RenderWidget):

Removed ref counting.
Removed registration with RenderView in ctor/willBeDestroyed.

(WebCore::RenderWidget::setWidgetGeometry):

Monitor the RenderWidget itself through a WeakPtr and check on it
after each step that we're still alive. In that case just bail out.

(WebCore::RenderWidget::setWidget):

Register the incoming/outgoing Widget with the FrameView.
Use a WeakPtr to check on 'this' after updateWidgetGeometry().

(WebCore::RenderWidget::updateWidgetPosition):

Use a WeakPtr to check on 'this' after updateWidgetGeometry().

  • GNUmakefile.list.am:
  • rendering/RenderWidgetProtector.h:

Removed.

Source/WTF:

  • wtf/WeakPtr.h:

(WTF::WeakPtr::operator!):

Add operator! to WeakPtr.

Location:
trunk/Source
Files:
1 deleted
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r155775 r155796  
     12013-09-14  Andreas Kling  <akling@apple.com>
     2
     3        Get rid of ref-counting on RenderWidget.
     4        <https://webkit.org/b/121357>
     5
     6        Reviewed by Darin Adler.
     7
     8        * wtf/WeakPtr.h:
     9        (WTF::WeakPtr::operator!):
     10
     11            Add operator! to WeakPtr.
     12
    1132013-09-14  Darin Adler  <darin@apple.com>
    214
  • trunk/Source/WTF/wtf/WeakPtr.h

    r154294 r155796  
    101101
    102102    T* get() const { return m_ref->get(); }
     103    bool operator!() const { return !m_ref; }
    103104
    104105private:
  • trunk/Source/WebCore/ChangeLog

    r155795 r155796  
     12013-09-15  Andreas Kling  <akling@apple.com>
     2
     3        Get rid of ref-counting on RenderWidget.
     4        <https://webkit.org/b/121357>
     5
     6        Reviewed by Darin Adler.
     7
     8        Instead of RenderView tracking RenderWidgets, have FrameView track Widgets
     9        that are currently in the render tree.
     10
     11        To protect ourselves during NPAPI tomfoolery, we now let RenderWidget hand
     12        out weak pointers through a createWeakPtr() method so call sites can monitor
     13        the renderer for deletion without having to take shared ownership.
     14
     15        This works out quite nicely since instead of keeping a limping object alive
     16        for a little longer just so we can call methods on it (to accomplish nothing),
     17        we're forced to check right away if it's gone, and take immediate action.
     18
     19        De-virtualized RenderObject::destroy() since it's no longer needed for
     20        RenderWidget to defer destruction.
     21
     22        * page/FrameView.cpp:
     23        (WebCore::FrameView::layout):
     24        (WebCore::FrameView::repaintFixedElementsAfterScrolling):
     25
     26            Call updateWidgetPositions() on FrameView instead of RenderView.
     27
     28        (WebCore::FrameView::updateEmbeddedObject):
     29
     30            Turn null checking of embedded object's element backpointer into an
     31            assertion. This will eventually go away completely once that renderer
     32            can return a HTMLFrameOwnerElement&.
     33
     34            Use WeakPtr to check for renderer destruction following the call out
     35            to updateWidget().
     36
     37        (WebCore::FrameView::updateEmbeddedObjects):
     38
     39            Slap a WidgetHierarchyUpdatesSuspensionScope guard on this function
     40            to defer Widget updates until all the updateEmbeddedObject calls are
     41            done. This avoids RenderWidget::setWidget() having to handle 'this'
     42            disappearing from underneath.
     43
     44            Also use a ListHashSet with a null sentinel to avoid looping forever.
     45
     46        (WebCore::FrameView::performPostLayoutTasks):
     47
     48            Only call updateEmbeddedObjects() once since that function no longer
     49            operates in chunks.
     50
     51        (WebCore::FrameView::notifyWidgetsInAllFrames):
     52
     53            Call notifyWidgets() on FrameView instead of RenderView.
     54
     55        (WebCore::FrameView::didAddWidgetToRenderTree):
     56        (WebCore::FrameView::willRemoveWidgetFromRenderTree):
     57
     58            Added. These are called by RenderWidget when a Widget is being
     59            added or removed from a RenderWidget.
     60
     61        (WebCore::collectWidgets):
     62
     63            Helper to collect raw Widget pointers into a Vector and ref them.
     64
     65        (WebCore::FrameView::updateWidgetPositions):
     66
     67            Moved here from RenderView. This function holds a ref on all the
     68            attached Widgets and calls RenderWidget::updateWidgetPosition() on
     69            their corresponding renderers.
     70
     71        (WebCore::FrameView::notifyWidgets):
     72
     73            Moved here from RenderView. Holds a ref on all the widgets while
     74            calling Widget::notifyWidget() on each one.
     75
     76        * rendering/RenderLayer.cpp:
     77        (WebCore::RenderLayer::scrollTo):
     78
     79            Call updateWidgetPositions() on FrameView instead of RenderView.
     80
     81        * rendering/RenderObject.h:
     82
     83            De-virtualized destroy().
     84
     85        * rendering/RenderView.cpp:
     86        * rendering/RenderView.h:
     87
     88            Moved a bunch of things to FrameView. Made protected section private
     89            since nothing inherits from RenderView.
     90
     91        * rendering/RenderWidget.h:
     92        (WebCore::RenderWidget::createWeakPtr):
     93
     94            Added a WeakPtr factory for clients that want to monitor this object
     95            for destruction.
     96           
     97        * rendering/RenderWidget.cpp:
     98        (WebCore::RenderWidget::RenderWidget):
     99        (WebCore::RenderWidget::willBeDestroyed):
     100        (WebCore::RenderWidget::~RenderWidget):
     101
     102            Removed ref counting.
     103            Removed registration with RenderView in ctor/willBeDestroyed.
     104
     105        (WebCore::RenderWidget::setWidgetGeometry):
     106
     107            Monitor the RenderWidget itself through a WeakPtr and check on it
     108            after each step that we're still alive. In that case just bail out.
     109
     110        (WebCore::RenderWidget::setWidget):
     111
     112            Register the incoming/outgoing Widget with the FrameView.
     113            Use a WeakPtr to check on 'this' after updateWidgetGeometry().
     114
     115        (WebCore::RenderWidget::updateWidgetPosition):
     116
     117            Use a WeakPtr to check on 'this' after updateWidgetGeometry().
     118
     119        * GNUmakefile.list.am:
     120        * rendering/RenderWidgetProtector.h:
     121
     122            Removed.
     123
     124
    11252013-09-14  Sam Weinig  <sam@webkit.org>
    2126
  • trunk/Source/WebCore/GNUmakefile.list.am

    r155779 r155796  
    45414541        Source/WebCore/rendering/RenderWidget.cpp \
    45424542        Source/WebCore/rendering/RenderWidget.h \
    4543         Source/WebCore/rendering/RenderWidgetProtector.h \
    45444543        Source/WebCore/rendering/RenderWordBreak.cpp \
    45454544        Source/WebCore/rendering/RenderWordBreak.h \
  • trunk/Source/WebCore/page/FrameView.cpp

    r155660 r155796  
    128128#endif
    129129
    130 // The maximum number of updateEmbeddedObjects iterations that should be done before returning.
    131 static const unsigned maxUpdateEmbeddedObjectsIterations = 2;
    132 
    133130static RenderLayer::UpdateLayerPositionsFlags updateLayerPositionFlags(RenderLayer* layer, bool isRelayoutingSubtree, bool didFullRepaint)
    134131{
     
    13461343    else {
    13471344        if (!m_inSynchronousPostLayout) {
    1348             if (inChildFrameLayoutWithFrameFlattening) {
    1349                 if (RenderView* renderView = this->renderView())
    1350                     renderView->updateWidgetPositions();
    1351             } else {
     1345            if (inChildFrameLayoutWithFrameFlattening)
     1346                updateWidgetPositions();
     1347            else {
    13521348                m_inSynchronousPostLayout = true;
    13531349                performPostLayoutTasks(); // Calls resumeScheduledEvents().
     
    14021398{
    14031399    if (!m_embeddedObjectsToUpdate)
    1404         m_embeddedObjectsToUpdate = adoptPtr(new HashSet<RenderEmbeddedObject*>);
     1400        m_embeddedObjectsToUpdate = adoptPtr(new ListHashSet<RenderEmbeddedObject*>);
    14051401
    14061402    ASSERT(embeddedObject.frameOwnerElement());
     
    19951991    if (m_nestedLayoutCount <= 1 && hasViewportConstrainedObjects()) {
    19961992        if (RenderView* renderView = this->renderView()) {
    1997             renderView->updateWidgetPositions();
     1993            updateWidgetPositions();
    19981994            renderView->layer()->updateLayerPositionsAfterDocumentScroll();
    19991995        }
     
    26512647void FrameView::updateEmbeddedObject(RenderEmbeddedObject& embeddedObject)
    26522648{
    2653     ASSERT(m_embeddedObjectsToUpdate->contains(&embeddedObject));
    2654 
    2655     // The object may have already been destroyed (thus element cleared),
    2656     // but FrameView holds a manual ref, so it won't have been deleted.
    2657     if (!embeddedObject.frameOwnerElement())
    2658         return;
    2659 
    26602649    // No need to update if it's already crashed or known to be missing.
    26612650    if (embeddedObject.isPluginUnavailable())
    26622651        return;
     2652
     2653    // FIXME: RenderEmbeddedObject::frameOwnerElement() should return a reference.
     2654    ASSERT(embeddedObject.frameOwnerElement());
    26632655
    26642656    HTMLFrameOwnerElement& element = *embeddedObject.frameOwnerElement();
     
    26712663        return;
    26722664    }
     2665
     2666    auto weakRenderer = embeddedObject.createWeakPtr();
    26732667
    26742668    // FIXME: This could turn into a real virtual dispatch if we defined
     
    26922686        ASSERT_NOT_REACHED();
    26932687
    2694     // Caution: it's possible the object was destroyed again, since loading a
    2695     // plugin may run any arbitrary JavaScript.
     2688    // It's possible the renderer was destroyed below updateWidget() since loading a plugin may execute arbitrary JavaScript.
     2689    if (!weakRenderer)
     2690        return;
     2691
    26962692    embeddedObject.updateWidgetPosition();
    26972693}
    26982694
    2699 bool FrameView::updateEmbeddedObjects()
     2695void FrameView::updateEmbeddedObjects()
    27002696{
    27012697    if (m_nestedLayoutCount > 1 || !m_embeddedObjectsToUpdate || m_embeddedObjectsToUpdate->isEmpty())
    2702         return true;
    2703 
    2704     // Protect RendereArena from getting wiped out, when Document is detached during updateWidget().
    2705     RefPtr<RenderArena> protectedArena = frame().document()->renderArena();
    2706 
    2707     Vector<RenderEmbeddedObject*> embeddedObjects;
    2708     embeddedObjects.reserveInitialCapacity(m_embeddedObjectsToUpdate->size());
    2709     for (auto it = m_embeddedObjectsToUpdate->begin(), end = m_embeddedObjectsToUpdate->end(); it != end; ++it) {
    2710         RenderEmbeddedObject& object = **it;
    2711         embeddedObjects.uncheckedAppend(&object);
    2712         object.ref();
    2713     }
    2714 
    2715     for (unsigned i = 0; i < embeddedObjects.size(); ++i) {
    2716         RenderEmbeddedObject& object = *embeddedObjects[i];
    2717         updateEmbeddedObject(object);
    2718         m_embeddedObjectsToUpdate->remove(&object);
    2719     }
    2720 
    2721     for (unsigned i = 0; i < embeddedObjects.size(); ++i)
    2722         embeddedObjects[i]->deref(protectedArena.get());
    2723    
    2724     return m_embeddedObjectsToUpdate->isEmpty();
     2698        return;
     2699
     2700    WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
     2701
     2702    // Insert a marker for where we should stop.
     2703    ASSERT(!m_embeddedObjectsToUpdate->contains(nullptr));
     2704    m_embeddedObjectsToUpdate->add(nullptr);
     2705
     2706    while (!m_embeddedObjectsToUpdate->isEmpty()) {
     2707        RenderEmbeddedObject* embeddedObject = m_embeddedObjectsToUpdate->takeFirst();
     2708        if (!embeddedObject)
     2709            break;
     2710        updateEmbeddedObject(*embeddedObject);
     2711    }
    27252712}
    27262713
     
    27772764    frame().loader().client().dispatchDidLayout();
    27782765
    2779     if (RenderView* renderView = this->renderView())
    2780         renderView->updateWidgetPositions();
    2781    
    2782     // layout() protects FrameView, but it still can get destroyed when updateWidgets()
     2766    updateWidgetPositions();
     2767   
     2768    // layout() protects FrameView, but it still can get destroyed when updateEmbeddedObjects()
    27832769    // is called through the post layout timer.
    27842770    Ref<FrameView> protect(*this);
    2785     for (unsigned i = 0; i < maxUpdateEmbeddedObjectsIterations; i++) {
    2786         if (updateEmbeddedObjects())
    2787             break;
    2788     }
     2771
     2772    updateEmbeddedObjects();
    27892773
    27902774    if (page) {
     
    41554139{
    41564140    for (Frame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext(m_frame.get())) {
    4157         if (RenderView* root = frame->contentRenderer())
    4158             root->notifyWidgets(notification);
     4141        if (FrameView* view = frame->view())
     4142            view->notifyWidgets(notification);
    41594143    }
    41604144}
     
    42584242}
    42594243
     4244void FrameView::didAddWidgetToRenderTree(Widget& widget)
     4245{
     4246    ASSERT(!m_widgetsInRenderTree.contains(&widget));
     4247    m_widgetsInRenderTree.add(&widget);
     4248}
     4249
     4250void FrameView::willRemoveWidgetFromRenderTree(Widget& widget)
     4251{
     4252    ASSERT(m_widgetsInRenderTree.contains(&widget));
     4253    m_widgetsInRenderTree.remove(&widget);
     4254}
     4255
     4256static Vector<RefPtr<Widget>> collectAndProtectWidgets(const HashSet<Widget*>& set)
     4257{
     4258    Vector<RefPtr<Widget>> widgets;
     4259    copyToVector(set, widgets);
     4260    return widgets;
     4261}
     4262
     4263void FrameView::updateWidgetPositions()
     4264{
     4265    // updateWidgetPosition() can possibly cause layout to be re-entered (via plug-ins running
     4266    // scripts in response to NPP_SetWindow, for example), so we need to keep the Widgets
     4267    // alive during enumeration.
     4268    auto protectedWidgets = collectAndProtectWidgets(m_widgetsInRenderTree);
     4269
     4270    for (unsigned i = 0, size = protectedWidgets.size(); i < size; ++i) {
     4271        if (RenderWidget* renderWidget = RenderWidget::find(protectedWidgets[i].get()))
     4272            renderWidget->updateWidgetPosition();
     4273    }
     4274}
     4275
     4276void FrameView::notifyWidgets(WidgetNotification notification)
     4277{
     4278    auto protectedWidgets = collectAndProtectWidgets(m_widgetsInRenderTree);
     4279
     4280    for (unsigned i = 0, size = protectedWidgets.size(); i < size; ++i)
     4281        protectedWidgets[i]->notifyWidget(notification);
     4282}
     4283
    42604284} // namespace WebCore
  • trunk/Source/WebCore/page/FrameView.h

    r155524 r155796  
    3434#include "ScrollView.h"
    3535#include <wtf/Forward.h>
     36#include <wtf/ListHashSet.h>
    3637#include <wtf/OwnPtr.h>
    3738#include <wtf/text/WTFString.h>
     
    438439    void setScrollPinningBehavior(ScrollPinningBehavior);
    439440
     441    void updateWidgetPositions();
     442    void didAddWidgetToRenderTree(Widget&);
     443    void willRemoveWidgetFromRenderTree(Widget&);
     444
    440445protected:
    441446    virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) OVERRIDE;
     
    524529    double adjustedDeferredRepaintDelay() const;
    525530
    526     bool updateEmbeddedObjects();
     531    void updateEmbeddedObjects();
    527532    void updateEmbeddedObject(RenderEmbeddedObject&);
    528533    void scrollToAnchor();
     
    544549    void notifyWidgetsInAllFrames(WidgetNotification);
    545550    void removeFromAXObjectCache();
    546    
     551    void notifyWidgets(WidgetNotification);
     552
     553    HashSet<Widget*> m_widgetsInRenderTree;
     554
    547555    static double sCurrentPaintTimeStamp; // used for detecting decoded resource thrash in the cache
    548556
     
    550558    LayoutSize m_margins;
    551559
    552     OwnPtr<HashSet<RenderEmbeddedObject*>> m_embeddedObjectsToUpdate;
     560    OwnPtr<ListHashSet<RenderEmbeddedObject*>> m_embeddedObjectsToUpdate;
    553561    const RefPtr<Frame> m_frame;
    554562
  • trunk/Source/WebCore/rendering/RenderEmbeddedObject.cpp

    r155631 r155796  
    5454#include "RenderTheme.h"
    5555#include "RenderView.h"
    56 #include "RenderWidgetProtector.h"
    5756#include "Settings.h"
    5857#include "Text.h"
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r155607 r155796  
    22472247        view.frameView().updateAnnotatedRegions();
    22482248#endif
    2249         view.updateWidgetPositions();
     2249        view.frameView().updateWidgetPositions();
    22502250
    22512251        if (!m_updatingMarqueePosition) {
  • trunk/Source/WebCore/rendering/RenderObject.h

    r155591 r155796  
    943943
    944944    void destroyAndCleanupAnonymousWrappers();
    945     virtual void destroy();
     945    void destroy();
    946946
    947947    // Virtual function helpers for the deprecated Flexible Box Layout (display: -webkit-box).
  • trunk/Source/WebCore/rendering/RenderView.cpp

    r155530 r155796  
    4343#include "RenderSelectionInfo.h"
    4444#include "RenderWidget.h"
    45 #include "RenderWidgetProtector.h"
    4645#include "StyleInheritedData.h"
    4746#include "TransformState.h"
     
    955954}
    956955
    957 size_t RenderView::getRetainedWidgets(Vector<RenderWidget*>& renderWidgets)
    958 {
    959     size_t size = m_widgets.size();
    960 
    961     renderWidgets.reserveCapacity(size);
    962 
    963     RenderWidgetSet::const_iterator end = m_widgets.end();
    964     for (RenderWidgetSet::const_iterator it = m_widgets.begin(); it != end; ++it) {
    965         renderWidgets.uncheckedAppend(*it);
    966         (*it)->ref();
    967     }
    968    
    969     return size;
    970 }
    971 
    972 void RenderView::releaseWidgets(Vector<RenderWidget*>& renderWidgets)
    973 {
    974     size_t size = renderWidgets.size();
    975 
    976     for (size_t i = 0; i < size; ++i)
    977         renderWidgets[i]->deref(renderArena());
    978 }
    979 
    980 void RenderView::updateWidgetPositions()
    981 {
    982     // updateWidgetPosition() can possibly cause layout to be re-entered (via plug-ins running
    983     // scripts in response to NPP_SetWindow, for example), so we need to keep the Widgets
    984     // alive during enumeration.   
    985 
    986     Vector<RenderWidget*> renderWidgets;
    987     size_t size = getRetainedWidgets(renderWidgets);
    988    
    989     for (size_t i = 0; i < size; ++i)
    990         renderWidgets[i]->updateWidgetPosition();
    991 
    992     releaseWidgets(renderWidgets);
    993 }
    994 
    995 void RenderView::addWidget(RenderWidget* o)
    996 {
    997     m_widgets.add(o);
    998 }
    999 
    1000 void RenderView::removeWidget(RenderWidget* o)
    1001 {
    1002     m_widgets.remove(o);
    1003 }
    1004 
    1005 void RenderView::notifyWidgets(WidgetNotification notification)
    1006 {
    1007     Vector<RenderWidget*> renderWidgets;
    1008     size_t size = getRetainedWidgets(renderWidgets);
    1009 
    1010     for (size_t i = 0; i < size; ++i)
    1011         renderWidgets[i]->notifyWidget(notification);
    1012 
    1013     releaseWidgets(renderWidgets);
    1014 }
    1015 
    1016956LayoutRect RenderView::viewRect() const
    1017957{
     
    1020960    return frameView().visibleContentRect();
    1021961}
    1022 
    1023962
    1024963IntRect RenderView::unscaledDocumentRect() const
  • trunk/Source/WebCore/rendering/RenderView.h

    r155370 r155796  
    3434class ImageQualityController;
    3535class RenderQuote;
    36 class RenderWidget;
    3736
    3837#if USE(ACCELERATED_COMPOSITING)
     
    109108
    110109    virtual LayoutRect viewRect() const OVERRIDE;
    111 
    112     void updateWidgetPositions();
    113     void addWidget(RenderWidget*);
    114     void removeWidget(RenderWidget*);
    115    
    116     void notifyWidgets(WidgetNotification);
    117110
    118111    // layoutDelta is used transiently during layout to store how far an object has moved from its
     
    293286#endif
    294287
    295     size_t getRetainedWidgets(Vector<RenderWidget*>&);
    296     void releaseWidgets(Vector<RenderWidget*>&);
    297 
    298288    void pushLayoutStateForCurrentFlowThread(const RenderObject*);
    299289    void popLayoutStateForCurrentFlowThread();
     
    302292    friend class LayoutStateDisabler;
    303293
    304 protected:
     294private:
    305295    FrameView& m_frameView;
    306296
     
    330320    int m_maximalOutlineSize; // Used to apply a fudge factor to dirty-rect checks on blocks/tables.
    331321
    332     typedef HashSet<RenderWidget*> RenderWidgetSet;
    333     RenderWidgetSet m_widgets;
    334 
    335 private:
    336322    bool shouldUsePrintingLayout() const;
    337323
  • trunk/Source/WebCore/rendering/RenderWidget.cpp

    r155598 r155796  
    3434#include "RenderLayer.h"
    3535#include "RenderView.h"
    36 #include "RenderWidgetProtector.h"
    3736#include <wtf/StackStats.h>
    3837#include <wtf/Ref.h>
     
    9291RenderWidget::RenderWidget(HTMLFrameOwnerElement* element)
    9392    : RenderReplaced(element)
     93    , m_weakPtrFactory(this)
    9494    , m_widget(0)
    9595    , m_frameView(element->document().view())
    96     // Reference counting is used to prevent the widget from being
    97     // destroyed while inside the Widget code, which might not be
    98     // able to handle that.
    99     , m_refCount(1)
    10096{
    10197    setInline(false);
    102     view().addWidget(this);
    10398}
    10499
    105100void RenderWidget::willBeDestroyed()
    106101{
    107     view().removeWidget(this);
    108    
    109102    if (AXObjectCache* cache = document().existingAXObjectCache()) {
    110103        cache->childrenChanged(this->parent());
     
    117110}
    118111
    119 void RenderWidget::destroy()
    120 {
    121     willBeDestroyed();
    122 
    123     // Grab the arena from node()->document().renderArena() before clearing the node pointer.
    124     // Clear the node before deref-ing, as this may be deleted when deref is called.
    125     RenderArena* arena = renderArena();
    126     clearNode();
    127     deref(arena);
    128 }
    129 
    130112RenderWidget::~RenderWidget()
    131113{
    132     ASSERT(m_refCount <= 0);
    133     clearWidget();
    134114}
    135115
     
    157137    m_clipRect = clipRect;
    158138
    159     RenderWidgetProtector protector(this);
    160     Ref<HTMLFrameOwnerElement> protectElement(*frameOwnerElement());
     139    WeakPtr<RenderWidget> weakThis = createWeakPtr();
     140
     141    // This call *may* cause this renderer to disappear from underneath...
    161142    m_widget->setFrameRect(newFrame);
    162143
    163     if (clipChanged && !boundsChanged)
     144    // ...so we follow up with a sanity check.
     145    if (!weakThis)
     146        return true;
     147
     148    if (clipChanged && !boundsChanged) {
     149        // This call *may* cause this renderer to disappear from underneath...
    164150        m_widget->clipRectChanged();
    165    
     151
     152        // ...so here's another sanity check.
     153        if (!weakThis)
     154            return true;
     155    }
     156
    166157#if USE(ACCELERATED_COMPOSITING)
    167158    if (hasLayer() && layer()->isComposited())
     
    194185    if (m_widget) {
    195186        moveWidgetToParentSoon(m_widget.get(), 0);
     187        view().frameView().willRemoveWidgetFromRenderTree(*m_widget);
    196188        widgetRendererMap().remove(m_widget.get());
    197         clearWidget();
     189        m_widget = nullptr;
    198190    }
    199191    m_widget = widget;
    200192    if (m_widget) {
    201193        widgetRendererMap().add(m_widget.get(), this);
     194        view().frameView().didAddWidgetToRenderTree(*m_widget);
    202195        // If we've already received a layout, apply the calculated space to the
    203196        // widget immediately, but we have to have really been fully constructed (with a non-null
    204197        // style pointer).
    205198        if (style()) {
    206             if (!needsLayout())
     199            if (!needsLayout()) {
     200                WeakPtr<RenderWidget> weakThis = createWeakPtr();
    207201                updateWidgetGeometry();
     202                if (!weakThis)
     203                    return;
     204            }
    208205
    209206            if (style()->visibility() != VISIBLE)
     
    341338}
    342339
    343 void RenderWidget::deref(RenderArena *arena)
    344 {
    345     if (--m_refCount <= 0)
    346         arenaDelete(arena, this);
    347 }
    348 
    349340void RenderWidget::updateWidgetPosition()
    350341{
     
    352343        return;
    353344
     345    WeakPtr<RenderWidget> weakThis = createWeakPtr();
     346
    354347    bool boundsChanged = updateWidgetGeometry();
    355    
     348
     349    if (!weakThis)
     350        return;
     351
    356352    // if the frame bounds got changed, or if view needs layout (possibly indicating
    357353    // content size is wrong) we have to do a layout to set the right widget size
     
    381377}
    382378
    383 void RenderWidget::clearWidget()
    384 {
    385     m_widget = 0;
    386 }
    387 
    388379RenderWidget* RenderWidget::find(const Widget* widget)
    389380{
  • trunk/Source/WebCore/rendering/RenderWidget.h

    r155598 r155796  
    2727#include "RenderReplaced.h"
    2828#include "Widget.h"
     29#include <wtf/WeakPtr.h>
    2930
    3031namespace WebCore {
     
    7273    void notifyWidget(WidgetNotification);
    7374
    74     RenderArena* ref() { ++m_refCount; return renderArena(); }
    75     void deref(RenderArena*);
    76 
    7775#if USE(ACCELERATED_COMPOSITING)
    7876    bool requiresAcceleratedCompositing() const;
    7977#endif
     78
     79    WeakPtr<RenderWidget> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
    8080
    8181    virtual void viewCleared() { }
     
    8585
    8686    FrameView* frameView() const { return m_frameView; }
    87 
    88     void clearWidget();
    8987
    9088    virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE FINAL;
     
    107105
    108106    virtual void willBeDestroyed() OVERRIDE FINAL;
    109     virtual void destroy() OVERRIDE FINAL;
    110107    virtual void setSelectionState(SelectionState) OVERRIDE FINAL;
    111108    virtual void setOverlapTestResult(bool) OVERRIDE FINAL;
     
    114111    bool updateWidgetGeometry();
    115112
     113    WeakPtrFactory<RenderWidget> m_weakPtrFactory;
    116114    RefPtr<Widget> m_widget;
    117115    FrameView* m_frameView;
    118116    IntRect m_clipRect; // The rectangle needs to remain correct after scrolling, so it is stored in content view coordinates, and not clipped to window.
    119     int m_refCount;
    120117};
    121118
Note: See TracChangeset for help on using the changeset viewer.