Changeset 130548 in webkit


Ignore:
Timestamp:
Oct 5, 2012 1:47:16 PM (12 years ago)
Author:
eric@webkit.org
Message:

Make tables which don't use col/row span much faster to layout
https://bugs.webkit.org/show_bug.cgi?id=98221

Reviewed by Julien Chaffraix.

My sense is that most tables on webpages do not use colspan/rowspan
so I stole another bit from RenderTableCell::m_column to avoid
having to re-parse the colSpan/rowSpan attributes for every cell
when doing table layout.
This made these symbols disappear from biggrid.html/redraw.html (dglazkov's spreadsheets benchmarks)
as well as moved our robohornet/resizecol.html number from an average of 3221ms to 2608ms (~20%!).

I removed m_hasHTMLTableCellElement (from http://trac.webkit.org/changeset/97691)
since it was attempting to do the same sort of optimization.

  • rendering/RenderTableCell.cpp:

(WebCore::RenderTableCell::RenderTableCell):
(WebCore::RenderTableCell::parseColSpanFromDOM):
(WebCore::RenderTableCell::parseRowSpanFromDOM):
(WebCore::RenderTableCell::layout):

  • rendering/RenderTableCell.h:

(WebCore::RenderTableCell::colSpan):
(WebCore::RenderTableCell::rowSpan):
(RenderTableCell):

Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r130547 r130548  
     12012-10-05  Eric Seidel  <eric@webkit.org>
     2
     3        Make tables which don't use col/row span much faster to layout
     4        https://bugs.webkit.org/show_bug.cgi?id=98221
     5
     6        Reviewed by Julien Chaffraix.
     7
     8        My sense is that most tables on webpages do not use colspan/rowspan
     9        so I stole another bit from RenderTableCell::m_column to avoid
     10        having to re-parse the colSpan/rowSpan attributes for every cell
     11        when doing table layout.
     12        This made these symbols disappear from biggrid.html/redraw.html (dglazkov's spreadsheets benchmarks)
     13        as well as moved our robohornet/resizecol.html number from an average of 3221ms to 2608ms (~20%!).
     14
     15        I removed m_hasHTMLTableCellElement (from http://trac.webkit.org/changeset/97691)
     16        since it was attempting to do the same sort of optimization.
     17
     18        * rendering/RenderTableCell.cpp:
     19        (WebCore::RenderTableCell::RenderTableCell):
     20        (WebCore::RenderTableCell::parseColSpanFromDOM):
     21        (WebCore::RenderTableCell::parseRowSpanFromDOM):
     22        (WebCore::RenderTableCell::layout):
     23        * rendering/RenderTableCell.h:
     24        (WebCore::RenderTableCell::colSpan):
     25        (WebCore::RenderTableCell::rowSpan):
     26        (RenderTableCell):
     27
    1282012-10-05  Oli Lan  <olilan@chromium.org>
    229
  • trunk/Source/WebCore/rendering/RenderTableCell.cpp

    r130454 r130548  
    4848using namespace HTMLNames;
    4949
     50struct SameSizeAsRenderTableCell : public RenderBlock {
     51    unsigned bitfields;
     52    int paddings[2];
     53};
     54
     55COMPILE_ASSERT(sizeof(RenderTableCell) == sizeof(SameSizeAsRenderTableCell), RenderTableCell_should_stay_small);
     56
     57
    5058RenderTableCell::RenderTableCell(Node* node)
    5159    : RenderBlock(node)
    5260    , m_column(unsetColumnIndex)
    5361    , m_cellWidthChanged(false)
    54     , m_hasHTMLTableCellElement(node && (node->hasTagName(tdTag) || node->hasTagName(thTag)))
    5562    , m_intrinsicPaddingBefore(0)
    5663    , m_intrinsicPaddingAfter(0)
    5764{
     65    // We only update the flags when notified of DOM changes in colSpanOrRowSpanChanged()
     66    // so we need to set their initial values here in case something asks for colSpan()/rowSpan() before then.
     67    updateColAndRowSpanFlags();
    5868}
    5969
     
    6676}
    6777
     78unsigned RenderTableCell::parseColSpanFromDOM() const
     79{
     80    ASSERT(node());
     81    if (node()->hasTagName(tdTag) || node()->hasTagName(thTag))
     82        return toHTMLTableCellElement(node())->colSpan();
    6883#if ENABLE(MATHML)
    69 inline bool isMathMLElement(Node* node)
    70 {
    71     return node && node->isElementNode() && toElement(node)->isMathMLElement();
    72 }
     84    if (node()->hasTagName(MathMLNames::mtdTag))
     85        return toMathMLElement(node())->colSpan();
    7386#endif
    74 
    75 unsigned RenderTableCell::colSpan() const
    76 {
    77     if (UNLIKELY(!m_hasHTMLTableCellElement)) {
     87    return 1;
     88}
     89
     90unsigned RenderTableCell::parseRowSpanFromDOM() const
     91{
     92    ASSERT(node());
     93    if (node()->hasTagName(tdTag) || node()->hasTagName(thTag))
     94        return toHTMLTableCellElement(node())->rowSpan();
    7895#if ENABLE(MATHML)
    79         if (isMathMLElement(node()))
    80             return toMathMLElement(node())->colSpan();
     96    if (node()->hasTagName(MathMLNames::mtdTag))
     97        return toMathMLElement(node())->rowSpan();
    8198#endif
    82         return 1;
    83     }
    84 
    85     return toHTMLTableCellElement(node())->colSpan();
    86 }
    87 
    88 unsigned RenderTableCell::rowSpan() const
    89 {
    90     if (UNLIKELY(!m_hasHTMLTableCellElement)) {
    91 #if ENABLE(MATHML)
    92         if (isMathMLElement(node()))
    93             return toMathMLElement(node())->rowSpan();
    94 #endif
    95         return 1;
    96     }
    97 
    98     return toHTMLTableCellElement(node())->rowSpan();
     99    return 1;
     100}
     101
     102void RenderTableCell::updateColAndRowSpanFlags()
     103{
     104    // The vast majority of table cells do not have a colspan or rowspan,
     105    // so we keep a bool to know if we need to bother reading from the DOM.
     106    m_hasColSpan = node() && parseColSpanFromDOM() != 1;
     107    m_hasRowSpan = node() && parseRowSpanFromDOM() != 1;
    99108}
    100109
    101110void RenderTableCell::colSpanOrRowSpanChanged()
    102111{
    103 #if ENABLE(MATHML)
    104     ASSERT(m_hasHTMLTableCellElement || isMathMLElement(node()));
    105 #else
    106     ASSERT(m_hasHTMLTableCellElement);
    107 #endif
    108112    ASSERT(node());
    109113#if ENABLE(MATHML)
     
    112116    ASSERT(node()->hasTagName(tdTag) || node()->hasTagName(thTag));
    113117#endif
     118
     119    updateColAndRowSpanFlags();
     120
     121    // FIXME: I suspect that we could return early here if !m_hasColSpan && !m_hasRowSpan.
    114122
    115123    setNeedsLayoutAndPrefWidthsRecalc();
  • trunk/Source/WebCore/rendering/RenderTableCell.h

    r130454 r130548  
    3131namespace WebCore {
    3232
    33 static const unsigned unsetColumnIndex = 0x3FFFFFFF;
    34 static const unsigned maxColumnIndex = 0x3FFFFFFE; // 1,073,741,823
     33static const unsigned unsetColumnIndex = 0x1FFFFFFF;
     34static const unsigned maxColumnIndex = 0x1FFFFFFE; // 536,870,910
    3535
    3636enum IncludeBorderColorOrNot { DoNotIncludeBorderColor, IncludeBorderColor };
     
    4040    explicit RenderTableCell(Node*);
    4141   
    42     unsigned colSpan() const;
    43     unsigned rowSpan() const;
     42    unsigned colSpan() const
     43    {
     44        if (!m_hasColSpan)
     45            return 1;
     46        return parseColSpanFromDOM();
     47    }
     48    unsigned rowSpan() const
     49    {
     50        if (!m_hasRowSpan)
     51            return 1;
     52        return parseRowSpanFromDOM();
     53    }
    4454
    4555    // Called from HTMLTableCellElement.
     
    228238    CollapsedBorderValue computeCollapsedAfterBorder(IncludeBorderColorOrNot = IncludeBorderColor) const;
    229239
    230     unsigned m_column : 30;
    231     bool m_cellWidthChanged : 1;
    232     bool m_hasHTMLTableCellElement : 1;
     240    void updateColAndRowSpanFlags();
     241
     242    unsigned parseRowSpanFromDOM() const;
     243    unsigned parseColSpanFromDOM() const;
     244
     245    // Note MSVC will only pack members if they have identical types, hence we use unsigned instead of bool here.
     246    unsigned m_column : 29;
     247    unsigned m_cellWidthChanged : 1;
     248    unsigned m_hasColSpan: 1;
     249    unsigned m_hasRowSpan: 1;
    233250    int m_intrinsicPaddingBefore;
    234251    int m_intrinsicPaddingAfter;
Note: See TracChangeset for help on using the changeset viewer.