Skip to content

Commit f63c817

Browse files
committed
perf issues with rowspan="0" on huge complex tables
https://bugs.webkit.org/show_bug.cgi?id=291405 rdar://146056348 Reviewed by Alan Baradlay. The HTML specification states that rowspan="0" should span all remaining rows in the current table row group (tbody, thead, or tfoot). In a previous patch, we made WebKit returns maxRowspan (65,534) instead of calculating the actual number of remaining rows. This caused severe performance issues during table grid construction. When RenderTableSection::addCell() processes a cell with rowspan="0", it calls ensureRows(insertionRow + rowSpan) to allocate grid space. With rowSpan returning 65,534, this created massive grid structures even for simple tables with just 2-3 rows. Example: - A table with 3 rows and 1 cell with rowspan="0" - Expected: ensureRows(0 + 3) = 3 rows - Actual (before fix): ensureRows(0 + 65534) = 65,534 rows - Result: 65,534 iterations instead of 3 (~21,845x slower) In more dramatic scenarios, it would crash Safari with tables with ~1000+ cells with rowspan="0", it means millions of iterations. This patch implements a two-layer approach: 1. DOM Layer (HTMLTableCellElement::rowSpan()): Return 0 for rowspan="0" instead of maxRowspan (65,534) This kind of go back to what was done before. 2. Rendering Layer (RenderTableCell::rowSpan()): When rowSpan from DOM is 0, calculate actual remaining rows using the DOM structure via calculateRowSpanForRowspanZero() During grid construction (recalcCells()), the DOM structure is complete but the render tree is being built incrementally. We must count rows from the DOM, not the render tree. This fix makes WebKit spec-compliant and matches Chrome/Firefox behavior. * LayoutTests/platform/glib/tables/mozilla/bugs/bug30332-1-expected.txt: * LayoutTests/platform/glib/tables/mozilla/bugs/bug30332-2-expected.txt: * LayoutTests/platform/glib/tables/mozilla/bugs/bug9879-1-expected.txt: * LayoutTests/platform/glib/tables/mozilla_expected_failures/bugs/bug9879-1-expected.txt: * LayoutTests/platform/ios/tables/mozilla/bugs/bug30332-1-expected.txt: * LayoutTests/platform/ios/tables/mozilla/bugs/bug30332-2-expected.txt: * LayoutTests/platform/ios/tables/mozilla/bugs/bug9879-1-expected.txt: * LayoutTests/platform/ios/tables/mozilla_expected_failures/bugs/bug9879-1-expected.txt: * LayoutTests/platform/mac/tables/mozilla/bugs/bug30332-1-expected.txt: * LayoutTests/platform/mac/tables/mozilla/bugs/bug30332-2-expected.txt: * LayoutTests/platform/mac/tables/mozilla/bugs/bug9879-1-expected.txt: * LayoutTests/platform/mac/tables/mozilla_expected_failures/bugs/bug9879-1-expected.txt: * Source/WebCore/html/HTMLTableCellElement.cpp: (WebCore::HTMLTableCellElement::rowSpan const): Return 0 for rowspan="0" instead of maxRowspan (65,534). * Source/WebCore/rendering/RenderTableCell.cpp: (WebCore::RenderTableCell::calculateRowSpanForRowspanZero const): (WebCore::RenderTableCell::calculateRowSpanForRowspanZero const): Added. Navigate DOM structure to calculate actual remaining rows in the table section. Uses sectionElement->numRows() which is stable during grid construction, unlike render tree traversal. * Source/WebCore/rendering/RenderTableCell.h: (WebCore::RenderTableCell::rowSpan const): Add calculateRowSpanForRowspanZero() helper function declaration. Modify inline rowSpan() to call helper when DOM returns 0. Canonical link: https://commits.webkit.org/306891@main
1 parent 1fbb758 commit f63c817

File tree

15 files changed

+57
-27
lines changed

15 files changed

+57
-27
lines changed

LayoutTests/platform/glib/tables/mozilla/bugs/bug30332-1-expected.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ layer at (0,0) size 800x600
1212
RenderTable {TABLE} at (0,0) size 784x38 [border: (5px outset #000000)]
1313
RenderTableSection {TBODY} at (5,5) size 774x28
1414
RenderTableRow {TR} at (0,2) size 774x0
15-
RenderTableCell {TD} at (2,3) size 373x22 [border: (1px inset #000000)] [r=0 c=0 rs=65534 cs=1]
15+
RenderTableCell {TD} at (2,3) size 373x22 [border: (1px inset #000000)] [r=0 c=0 rs=2 cs=1]
1616
RenderText {#text} at (2,3) size 27x18
1717
text run at (2,2) width 27: "One"
1818
RenderTableRow {TR} at (0,4) size 774x22

LayoutTests/platform/glib/tables/mozilla/bugs/bug30332-2-expected.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ layer at (0,0) size 800x222
1212
RenderTable {TABLE} at (0,0) size 784x38 [border: (5px outset #000000)]
1313
RenderTableSection {TBODY} at (5,5) size 774x28
1414
RenderTableRow {TR} at (0,2) size 774x0
15-
RenderTableCell {TD} at (2,3) size 373x22 [border: (1px inset #000000)] [r=0 c=0 rs=65534 cs=1]
15+
RenderTableCell {TD} at (2,3) size 373x22 [border: (1px inset #000000)] [r=0 c=0 rs=2 cs=1]
1616
RenderText {#text} at (2,3) size 27x18
1717
text run at (2,2) width 27: "One"
1818
RenderTableRow {TR} at (0,4) size 774x22

LayoutTests/platform/glib/tables/mozilla/bugs/bug9879-1-expected.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ layer at (0,0) size 800x348
66
RenderTable {TABLE} at (0,0) size 156x52 [border: (1px outset #000000)]
77
RenderTableSection {TBODY} at (1,1) size 154x50
88
RenderTableRow {TR} at (0,2) size 154x22
9-
RenderTableCell {TD} at (2,14) size 70x22 [border: (1px inset #000000)] [r=0 c=0 rs=65534 cs=1]
9+
RenderTableCell {TD} at (2,14) size 70x22 [border: (1px inset #000000)] [r=0 c=0 rs=2 cs=1]
1010
RenderText {#text} at (2,14) size 66x18
1111
text run at (2,2) width 66: "rowspan 0"
1212
RenderTableCell {TD} at (74,2) size 64x22 [border: (1px inset #000000)] [r=0 c=1 rs=1 cs=1]
@@ -81,7 +81,7 @@ layer at (0,0) size 800x348
8181
RenderTableCell {TD} at (2,2) size 31x22 [border: (1px inset #000000)] [r=0 c=0 rs=1 cs=1]
8282
RenderText {#text} at (2,2) size 27x18
8383
text run at (2,2) width 27: "auto"
84-
RenderTableCell {TD} at (35,14) size 70x22 [border: (1px inset #000000)] [r=0 c=1 rs=65534 cs=1]
84+
RenderTableCell {TD} at (35,14) size 70x22 [border: (1px inset #000000)] [r=0 c=1 rs=2 cs=1]
8585
RenderText {#text} at (2,14) size 66x18
8686
text run at (2,2) width 66: "rowspan 0"
8787
RenderTableCell {TD} at (107,2) size 31x22 [border: (1px inset #000000)] [r=0 c=2 rs=1 cs=1]

LayoutTests/platform/glib/tables/mozilla_expected_failures/bugs/bug9879-1-expected.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ layer at (0,0) size 800x348
66
RenderTable {TABLE} at (0,0) size 156x52 [border: (1px outset #000000)]
77
RenderTableSection {TBODY} at (1,1) size 154x50
88
RenderTableRow {TR} at (0,2) size 154x22
9-
RenderTableCell {TD} at (2,14) size 70x22 [border: (1px inset #000000)] [r=0 c=0 rs=65534 cs=1]
9+
RenderTableCell {TD} at (2,14) size 70x22 [border: (1px inset #000000)] [r=0 c=0 rs=2 cs=1]
1010
RenderText {#text} at (2,14) size 66x18
1111
text run at (2,2) width 66: "rowspan 0"
1212
RenderTableCell {TD} at (74,2) size 64x22 [border: (1px inset #000000)] [r=0 c=1 rs=1 cs=1]
@@ -81,7 +81,7 @@ layer at (0,0) size 800x348
8181
RenderTableCell {TD} at (2,2) size 31x22 [border: (1px inset #000000)] [r=0 c=0 rs=1 cs=1]
8282
RenderText {#text} at (2,2) size 27x18
8383
text run at (2,2) width 27: "auto"
84-
RenderTableCell {TD} at (35,14) size 70x22 [border: (1px inset #000000)] [r=0 c=1 rs=65534 cs=1]
84+
RenderTableCell {TD} at (35,14) size 70x22 [border: (1px inset #000000)] [r=0 c=1 rs=2 cs=1]
8585
RenderText {#text} at (2,14) size 66x18
8686
text run at (2,2) width 66: "rowspan 0"
8787
RenderTableCell {TD} at (107,2) size 31x22 [border: (1px inset #000000)] [r=0 c=2 rs=1 cs=1]

LayoutTests/platform/ios/tables/mozilla/bugs/bug30332-1-expected.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ layer at (0,0) size 800x600
1212
RenderTable {TABLE} at (0,0) size 784x40 [border: (5px outset #000000)]
1313
RenderTableSection {TBODY} at (5,5) size 774x30
1414
RenderTableRow {TR} at (0,2) size 774x0
15-
RenderTableCell {TD} at (2,3) size 375x24 [border: (1px inset #000000)] [r=0 c=0 rs=65534 cs=1]
15+
RenderTableCell {TD} at (2,3) size 375x24 [border: (1px inset #000000)] [r=0 c=0 rs=2 cs=1]
1616
RenderText {#text} at (2,3) size 27x20
1717
text run at (2,2) width 27: "One"
1818
RenderTableRow {TR} at (0,4) size 774x24

LayoutTests/platform/ios/tables/mozilla/bugs/bug30332-2-expected.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ layer at (0,0) size 800x240
1212
RenderTable {TABLE} at (0,0) size 784x40 [border: (5px outset #000000)]
1313
RenderTableSection {TBODY} at (5,5) size 774x30
1414
RenderTableRow {TR} at (0,2) size 774x0
15-
RenderTableCell {TD} at (2,3) size 375x24 [border: (1px inset #000000)] [r=0 c=0 rs=65534 cs=1]
15+
RenderTableCell {TD} at (2,3) size 375x24 [border: (1px inset #000000)] [r=0 c=0 rs=2 cs=1]
1616
RenderText {#text} at (2,3) size 27x20
1717
text run at (2,2) width 27: "One"
1818
RenderTableRow {TR} at (0,4) size 774x24

LayoutTests/platform/ios/tables/mozilla/bugs/bug9879-1-expected.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ layer at (0,0) size 800x376
66
RenderTable {TABLE} at (0,0) size 158x56 [border: (1px outset #000000)]
77
RenderTableSection {TBODY} at (1,1) size 156x54
88
RenderTableRow {TR} at (0,2) size 156x24
9-
RenderTableCell {TD} at (2,15) size 71x24 [border: (1px inset #000000)] [r=0 c=0 rs=65534 cs=1]
9+
RenderTableCell {TD} at (2,15) size 71x24 [border: (1px inset #000000)] [r=0 c=0 rs=2 cs=1]
1010
RenderText {#text} at (2,15) size 67x20
1111
text run at (2,2) width 67: "rowspan 0"
1212
RenderTableCell {TD} at (74,2) size 66x24 [border: (1px inset #000000)] [r=0 c=1 rs=1 cs=1]
@@ -81,7 +81,7 @@ layer at (0,0) size 800x376
8181
RenderTableCell {TD} at (2,2) size 32x24 [border: (1px inset #000000)] [r=0 c=0 rs=1 cs=1]
8282
RenderText {#text} at (2,2) size 28x20
8383
text run at (2,2) width 28: "auto"
84-
RenderTableCell {TD} at (35,15) size 71x24 [border: (1px inset #000000)] [r=0 c=1 rs=65534 cs=1]
84+
RenderTableCell {TD} at (35,15) size 71x24 [border: (1px inset #000000)] [r=0 c=1 rs=2 cs=1]
8585
RenderText {#text} at (2,15) size 67x20
8686
text run at (2,2) width 67: "rowspan 0"
8787
RenderTableCell {TD} at (107,2) size 33x24 [border: (1px inset #000000)] [r=0 c=2 rs=1 cs=1]

LayoutTests/platform/ios/tables/mozilla_expected_failures/bugs/bug9879-1-expected.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ layer at (0,0) size 800x376
66
RenderTable {TABLE} at (0,0) size 158x56 [border: (1px outset #000000)]
77
RenderTableSection {TBODY} at (1,1) size 156x54
88
RenderTableRow {TR} at (0,2) size 156x24
9-
RenderTableCell {TD} at (2,15) size 71x24 [border: (1px inset #000000)] [r=0 c=0 rs=65534 cs=1]
9+
RenderTableCell {TD} at (2,15) size 71x24 [border: (1px inset #000000)] [r=0 c=0 rs=2 cs=1]
1010
RenderText {#text} at (2,15) size 67x20
1111
text run at (2,2) width 67: "rowspan 0"
1212
RenderTableCell {TD} at (74,2) size 66x24 [border: (1px inset #000000)] [r=0 c=1 rs=1 cs=1]
@@ -81,7 +81,7 @@ layer at (0,0) size 800x376
8181
RenderTableCell {TD} at (2,2) size 32x24 [border: (1px inset #000000)] [r=0 c=0 rs=1 cs=1]
8282
RenderText {#text} at (2,2) size 28x20
8383
text run at (2,2) width 28: "auto"
84-
RenderTableCell {TD} at (35,15) size 71x24 [border: (1px inset #000000)] [r=0 c=1 rs=65534 cs=1]
84+
RenderTableCell {TD} at (35,15) size 71x24 [border: (1px inset #000000)] [r=0 c=1 rs=2 cs=1]
8585
RenderText {#text} at (2,15) size 67x20
8686
text run at (2,2) width 67: "rowspan 0"
8787
RenderTableCell {TD} at (107,2) size 33x24 [border: (1px inset #000000)] [r=0 c=2 rs=1 cs=1]

LayoutTests/platform/mac/tables/mozilla/bugs/bug30332-1-expected.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ layer at (0,0) size 800x600
1212
RenderTable {TABLE} at (0,0) size 784x38 [border: (5px outset #000000)]
1313
RenderTableSection {TBODY} at (5,5) size 774x28
1414
RenderTableRow {TR} at (0,2) size 774x0
15-
RenderTableCell {TD} at (2,3) size 375x22 [border: (1px inset #000000)] [r=0 c=0 rs=65534 cs=1]
15+
RenderTableCell {TD} at (2,3) size 375x22 [border: (1px inset #000000)] [r=0 c=0 rs=2 cs=1]
1616
RenderText {#text} at (2,3) size 27x18
1717
text run at (2,2) width 27: "One"
1818
RenderTableRow {TR} at (0,4) size 774x22

LayoutTests/platform/mac/tables/mozilla/bugs/bug30332-2-expected.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ layer at (0,0) size 800x222
1212
RenderTable {TABLE} at (0,0) size 784x38 [border: (5px outset #000000)]
1313
RenderTableSection {TBODY} at (5,5) size 774x28
1414
RenderTableRow {TR} at (0,2) size 774x0
15-
RenderTableCell {TD} at (2,3) size 375x22 [border: (1px inset #000000)] [r=0 c=0 rs=65534 cs=1]
15+
RenderTableCell {TD} at (2,3) size 375x22 [border: (1px inset #000000)] [r=0 c=0 rs=2 cs=1]
1616
RenderText {#text} at (2,3) size 27x18
1717
text run at (2,2) width 27: "One"
1818
RenderTableRow {TR} at (0,4) size 774x22

0 commit comments

Comments
 (0)