Bug 1176070 - Optimize nsTableFrame's FirstInFlow() lookups from calls to GetColumnISize(). r=dholbert
authorJonathan Kew <jkew@mozilla.com>
Tue, 23 Jun 2015 11:44:36 -0700
changeset 280819 e66ff38867c534f785a4e87cc0a4818b64ff60e7
parent 280818 ae459c286310272d23e45bdf3d9f982831d230d8
child 280820 fc4d79e8bad85bbf42a5c41c32603095da7cdbd3
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1176070
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1176070 - Optimize nsTableFrame's FirstInFlow() lookups from calls to GetColumnISize(). r=dholbert
layout/tables/nsTableFrame.cpp
layout/tables/nsTableFrame.h
layout/tables/nsTableRowFrame.cpp
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -1420,37 +1420,38 @@ nsTableFrame::GetLogicalSkipSides(const 
 
 void
 nsTableFrame::SetColumnDimensions(nscoord aBSize, WritingMode aWM,
                                   const LogicalMargin& aBorderPadding,
                                   nscoord aContainerWidth)
 {
   const nscoord colBSize = aBSize - (aBorderPadding.BStartEnd(aWM) +
                            GetRowSpacing(-1) + GetRowSpacing(GetRowCount()));
-
   int32_t colIdx = 0;
   LogicalPoint colGroupOrigin(aWM,
                               aBorderPadding.IStart(aWM) + GetColSpacing(-1),
                               aBorderPadding.BStart(aWM) + GetRowSpacing(-1));
   nsTableIterator iter(mColGroups);
+  nsTableFrame* fif = static_cast<nsTableFrame*>(FirstInFlow());
   for (nsIFrame* colGroupFrame = iter.First(); colGroupFrame;
        colGroupFrame = iter.Next()) {
     MOZ_ASSERT(colGroupFrame->GetType() == nsGkAtoms::tableColGroupFrame);
     // first we need to figure out the size of the colgroup
     int32_t groupFirstCol = colIdx;
     nscoord colGroupISize = 0;
     nscoord cellSpacingI = 0;
     nsTableIterator iterCol(*colGroupFrame);
     for (nsIFrame* colFrame = iterCol.First(); colFrame;
          colFrame = iterCol.Next()) {
       if (NS_STYLE_DISPLAY_TABLE_COLUMN ==
           colFrame->StyleDisplay()->mDisplay) {
         NS_ASSERTION(colIdx < GetColCount(), "invalid number of columns");
         cellSpacingI = GetColSpacing(colIdx);
-        colGroupISize += GetColumnISize(colIdx) + cellSpacingI;
+        colGroupISize += fif->GetColumnISizeFromFirstInFlow(colIdx) +
+                         cellSpacingI;
         ++colIdx;
       }
     }
     if (colGroupISize) {
       colGroupISize -= cellSpacingI;
     }
 
     LogicalRect colGroupRect(aWM, colGroupOrigin.I(aWM), colGroupOrigin.B(aWM),
@@ -1460,17 +1461,17 @@ nsTableFrame::SetColumnDimensions(nscoor
 
     // then we can place the columns correctly within the group
     colIdx = groupFirstCol;
     LogicalPoint colOrigin(aWM);
     for (nsIFrame* colFrame = iterCol.First(); colFrame;
          colFrame = iterCol.Next()) {
       if (NS_STYLE_DISPLAY_TABLE_COLUMN ==
           colFrame->StyleDisplay()->mDisplay) {
-        nscoord colISize = GetColumnISize(colIdx);
+        nscoord colISize = fif->GetColumnISizeFromFirstInFlow(colIdx);
         LogicalRect colRect(aWM, colOrigin.I(aWM), colOrigin.B(aWM),
                             colISize, colBSize);
         colFrame->SetRect(aWM, colRect, colGroupWidth);
         cellSpacingI = GetColSpacing(colIdx);
         colOrigin.I(aWM) += colISize + cellSpacingI;
         ++colIdx;
       }
     }
@@ -2191,28 +2192,29 @@ nsTableFrame::AdjustForCollapsingRowsCol
 
 nscoord
 nsTableFrame::GetCollapsedISize(const WritingMode aWM,
                                 const LogicalMargin& aBorderPadding)
 {
   NS_ASSERTION(!GetPrevInFlow(), "GetCollapsedISize called on next in flow");
   nscoord iSize = GetColSpacing(GetColCount());
   iSize += aBorderPadding.IStartEnd(aWM);
+  nsTableFrame* fif = static_cast<nsTableFrame*>(FirstInFlow());
   for (nsIFrame* groupFrame : mColGroups) {
     const nsStyleVisibility* groupVis = groupFrame->StyleVisibility();
     bool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE == groupVis->mVisible);
     nsTableColGroupFrame* cgFrame = (nsTableColGroupFrame*)groupFrame;
     for (nsTableColFrame* colFrame = cgFrame->GetFirstColumn(); colFrame;
          colFrame = colFrame->GetNextCol()) {
       const nsStyleDisplay* colDisplay = colFrame->StyleDisplay();
       int32_t colX = colFrame->GetColIndex();
       if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay) {
         const nsStyleVisibility* colVis = colFrame->StyleVisibility();
         bool collapseCol = (NS_STYLE_VISIBILITY_COLLAPSE == colVis->mVisible);
-        int32_t colISize = GetColumnISize(colX);
+        nscoord colISize = fif->GetColumnISizeFromFirstInFlow(colX);
         if (!collapseGroup && !collapseCol) {
           iSize += colISize;
           if (ColumnHasCellSpacingBefore(colX))
             iSize += GetColSpacing(colX-1);
         }
         else {
           SetNeedToCollapse(true);
         }
@@ -3630,25 +3632,22 @@ nsTableFrame::DistributeBSizeToRows(cons
       rgFrame->InvalidateFrameSubtree();
     }
     bOriginRG = bEndRG;
   }
 
   ResizeCells(*this);
 }
 
-int32_t
-nsTableFrame::GetColumnISize(int32_t aColIndex)
-{
-  nsTableFrame* firstInFlow = static_cast<nsTableFrame*>(FirstInFlow());
-  if (this == firstInFlow) {
-    nsTableColFrame* colFrame = GetColFrame(aColIndex);
-    return colFrame ? colFrame->GetFinalISize() : 0;
-  }
-  return firstInFlow->GetColumnISize(aColIndex);
+nscoord
+nsTableFrame::GetColumnISizeFromFirstInFlow(int32_t aColIndex)
+{
+  MOZ_ASSERT(this == FirstInFlow());
+  nsTableColFrame* colFrame = GetColFrame(aColIndex);
+  return colFrame ? colFrame->GetFinalISize() : 0;
 }
 
 nscoord
 nsTableFrame::GetColSpacing()
 {
   if (IsBorderCollapse())
     return 0;
 
@@ -3909,18 +3908,19 @@ nsTableFrame::Dump(bool            aDump
                    bool            aDumpCols,
                    bool            aDumpCellMap)
 {
   printf("***START TABLE DUMP*** \n");
   // dump the columns widths array
   printf("mColWidths=");
   int32_t numCols = GetColCount();
   int32_t colX;
+  nsTableFrame* fif = static_cast<nsTableFrame*>(FirstInFlow());
   for (colX = 0; colX < numCols; colX++) {
-    printf("%d ", GetColumnISize(colX));
+    printf("%d ", fif->GetColumnISizeFromFirstInFlow(colX));
   }
   printf("\n");
 
   if (aDumpRows) {
     nsIFrame* kidFrame = mFrames.FirstChild();
     while (kidFrame) {
       DumpRowGroup(kidFrame);
       kidFrame = kidFrame->GetNextSibling();
--- a/layout/tables/nsTableFrame.h
+++ b/layout/tables/nsTableFrame.h
@@ -394,18 +394,20 @@ public:
     return nsContainerFrame::IsFrameOfType(aFlags);
   }
 
 #ifdef DEBUG_FRAME_DUMP
   /** @see nsIFrame::GetFrameName */
   virtual nsresult GetFrameName(nsAString& aResult) const override;
 #endif
 
-  /** return the isize of the column at aColIndex    */
-  int32_t GetColumnISize(int32_t aColIndex);
+  /** Return the isize of the column at aColIndex.
+   *  This may only be called on the table's first-in-flow.
+   */
+  nscoord GetColumnISizeFromFirstInFlow(int32_t aColIndex);
 
   /** Helper to get the column spacing style value.
    *  The argument refers to the space between column aColIndex and column
    *  aColIndex + 1.  An index of -1 indicates the padding between the table
    *  and the left border, an index equal to the number of columns indicates
    *  the padding between the table and the right border.
    *
    *  Although in this class cell spacing does not depend on the index, it
--- a/layout/tables/nsTableRowFrame.cpp
+++ b/layout/tables/nsTableRowFrame.cpp
@@ -696,19 +696,22 @@ static nscoord
 CalcAvailISize(nsTableFrame&     aTableFrame,
                nsTableCellFrame& aCellFrame)
 {
   nscoord cellAvailISize = 0;
   int32_t colIndex;
   aCellFrame.GetColIndex(colIndex);
   int32_t colspan = aTableFrame.GetEffectiveColSpan(aCellFrame);
   NS_ASSERTION(colspan > 0, "effective colspan should be positive");
+  nsTableFrame* fifTable =
+    static_cast<nsTableFrame*>(aTableFrame.FirstInFlow());
 
   for (int32_t spanX = 0; spanX < colspan; spanX++) {
-    cellAvailISize += aTableFrame.GetColumnISize(colIndex + spanX);
+    cellAvailISize +=
+      fifTable->GetColumnISizeFromFirstInFlow(colIndex + spanX);
     if (spanX > 0 &&
         aTableFrame.ColumnHasCellSpacingBefore(colIndex + spanX)) {
       cellAvailISize += aTableFrame.GetColSpacing(colIndex + spanX - 1);
     }
   }
   return cellAvailISize;
 }
 
@@ -716,32 +719,34 @@ nscoord
 GetSpaceBetween(int32_t       aPrevColIndex,
                 int32_t       aColIndex,
                 int32_t       aColSpan,
                 nsTableFrame& aTableFrame,
                 bool          aCheckVisibility)
 {
   nscoord space = 0;
   int32_t colX;
+  nsTableFrame* fifTable =
+    static_cast<nsTableFrame*>(aTableFrame.FirstInFlow());
   for (colX = aPrevColIndex + 1; aColIndex > colX; colX++) {
     bool isCollapsed = false;
     if (!aCheckVisibility) {
-      space += aTableFrame.GetColumnISize(colX);
+      space += fifTable->GetColumnISizeFromFirstInFlow(colX);
     }
     else {
       nsTableColFrame* colFrame = aTableFrame.GetColFrame(colX);
       const nsStyleVisibility* colVis = colFrame->StyleVisibility();
       bool collapseCol = (NS_STYLE_VISIBILITY_COLLAPSE == colVis->mVisible);
       nsIFrame* cgFrame = colFrame->GetParent();
       const nsStyleVisibility* groupVis = cgFrame->StyleVisibility();
       bool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE ==
                               groupVis->mVisible);
       isCollapsed = collapseCol || collapseGroup;
       if (!isCollapsed)
-        space += aTableFrame.GetColumnISize(colX);
+        space += fifTable->GetColumnISizeFromFirstInFlow(colX);
     }
     if (!isCollapsed && aTableFrame.ColumnHasCellSpacingBefore(colX)) {
       space += aTableFrame.GetColSpacing(colX - 1);
     }
   }
   return space;
 }
 
@@ -1239,16 +1244,18 @@ nsTableRowFrame::CollapseRowIfNecessary(
   }
   else { // row is not collapsed
     nsTableIterator iter(*this);
     // remember the col index of the previous cell to handle rowspans into this
     // row
     int32_t firstPrevColIndex = -1;
     int32_t prevColIndex  = firstPrevColIndex;
     nscoord iPos = 0; // running total of children inline-axis offset
+    nsTableFrame* fifTable =
+      static_cast<nsTableFrame*>(tableFrame->FirstInFlow());
 
     int32_t colIncrement = 1;
 
     nsIFrame* kidFrame = iter.First();
     while (kidFrame) {
       nsTableCellFrame *cellFrame = do_QueryFrame(kidFrame);
       if (cellFrame) {
         int32_t cellColIndex;
@@ -1276,17 +1283,17 @@ nsTableRowFrame::CollapseRowIfNecessary(
           bool collapseCol = (NS_STYLE_VISIBILITY_COLLAPSE ==
                                 colVis->mVisible);
           nsIFrame* cgFrame = colFrame->GetParent();
           const nsStyleVisibility* groupVis = cgFrame->StyleVisibility();
           bool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE ==
                                   groupVis->mVisible);
           bool isCollapsed = collapseCol || collapseGroup;
           if (!isCollapsed) {
-            cRect.ISize(wm) += tableFrame->GetColumnISize(colX);
+            cRect.ISize(wm) += fifTable->GetColumnISizeFromFirstInFlow(colX);
             isVisible = true;
             if ((actualColSpan > 1)) {
               nsTableColFrame* nextColFrame =
                 tableFrame->GetColFrame(colX + colIncrement);
               const nsStyleVisibility* nextColVis =
               nextColFrame->StyleVisibility();
               if ( (NS_STYLE_VISIBILITY_COLLAPSE != nextColVis->mVisible) &&
                   tableFrame->ColumnHasCellSpacingBefore(colX + colIncrement)) {