Title: [199552] trunk/Source/WebCore
- Revision
- 199552
- Author
- [email protected]
- Date
- 2016-04-14 14:09:19 -0700 (Thu, 14 Apr 2016)
Log Message
Collapsed border cache invalidation can lead to O(n^2) during style resolve
https://bugs.webkit.org/show_bug.cgi?id=156570
Reviewed by Darin Adler.
RenderTable::invalidateCollapsedBorders traverses all cells. It is called when table cell border changes.
This can result in O(n^2) during style resolve.
* rendering/RenderTable.cpp:
(WebCore::RenderTable::layout):
(WebCore::RenderTable::invalidateCollapsedBorders):
For cell border style change invalidate the hasEmptyCollapsedBorder bits only for the neighbouring cells.
They are the only ones that can be affected.
* rendering/RenderTable.h:
(WebCore::RenderTable::collapsedBordersAreValid):
(WebCore::RenderTable::collapsedEmptyBorderIsPresent):
(WebCore::RenderTable::currentBorderValue):
* rendering/RenderTableCell.cpp:
(WebCore::RenderTableCell::styleDidChange):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (199551 => 199552)
--- trunk/Source/WebCore/ChangeLog 2016-04-14 20:49:12 UTC (rev 199551)
+++ trunk/Source/WebCore/ChangeLog 2016-04-14 21:09:19 UTC (rev 199552)
@@ -1,3 +1,27 @@
+2016-04-14 Antti Koivisto <[email protected]>
+
+ Collapsed border cache invalidation can lead to O(n^2) during style resolve
+ https://bugs.webkit.org/show_bug.cgi?id=156570
+
+ Reviewed by Darin Adler.
+
+ RenderTable::invalidateCollapsedBorders traverses all cells. It is called when table cell border changes.
+ This can result in O(n^2) during style resolve.
+
+ * rendering/RenderTable.cpp:
+ (WebCore::RenderTable::layout):
+ (WebCore::RenderTable::invalidateCollapsedBorders):
+
+ For cell border style change invalidate the hasEmptyCollapsedBorder bits only for the neighbouring cells.
+ They are the only ones that can be affected.
+
+ * rendering/RenderTable.h:
+ (WebCore::RenderTable::collapsedBordersAreValid):
+ (WebCore::RenderTable::collapsedEmptyBorderIsPresent):
+ (WebCore::RenderTable::currentBorderValue):
+ * rendering/RenderTableCell.cpp:
+ (WebCore::RenderTableCell::styleDidChange):
+
2016-04-14 Manuel Rego Casasnovas <[email protected]>
[css-grid] Implement CSSGridTemplateAreasValue::equals
Modified: trunk/Source/WebCore/rendering/RenderTable.cpp (199551 => 199552)
--- trunk/Source/WebCore/rendering/RenderTable.cpp 2016-04-14 20:49:12 UTC (rev 199551)
+++ trunk/Source/WebCore/rendering/RenderTable.cpp 2016-04-14 21:09:19 UTC (rev 199552)
@@ -586,14 +586,32 @@
clearNeedsLayout();
}
-void RenderTable::invalidateCollapsedBorders()
+void RenderTable::invalidateCollapsedBorders(RenderTableCell* cellWithStyleChange)
{
m_collapsedBordersValid = false;
m_collapsedBorders.clear();
+
+ for (auto& section : childrenOfType<RenderTableSection>(*this))
+ section.clearCachedCollapsedBorders();
+
+ if (!m_collapsedEmptyBorderIsPresent)
+ return;
+
+ if (cellWithStyleChange) {
+ // It is enough to invalidate just the surrounding cells when cell border style changes.
+ cellWithStyleChange->invalidateHasEmptyCollapsedBorders();
+ if (auto* below = cellBelow(cellWithStyleChange))
+ below->invalidateHasEmptyCollapsedBorders();
+ if (auto* above = cellAbove(cellWithStyleChange))
+ above->invalidateHasEmptyCollapsedBorders();
+ if (auto* before = cellBefore(cellWithStyleChange))
+ before->invalidateHasEmptyCollapsedBorders();
+ if (auto* after = cellAfter(cellWithStyleChange))
+ after->invalidateHasEmptyCollapsedBorders();
+ return;
+ }
+
for (auto& section : childrenOfType<RenderTableSection>(*this)) {
- section.clearCachedCollapsedBorders();
- if (!m_collapsedEmptyBorderIsPresent)
- continue;
for (auto* row = section.firstRow(); row; row = row->nextRow()) {
for (auto* cell = row->firstCell(); cell; cell = cell->nextCell()) {
ASSERT(cell->table() == this);
Modified: trunk/Source/WebCore/rendering/RenderTable.h (199551 => 199552)
--- trunk/Source/WebCore/rendering/RenderTable.h 2016-04-14 20:49:12 UTC (rev 199551)
+++ trunk/Source/WebCore/rendering/RenderTable.h 2016-04-14 21:09:19 UTC (rev 199552)
@@ -239,7 +239,7 @@
typedef Vector<CollapsedBorderValue> CollapsedBorderValues;
bool collapsedBordersAreValid() const { return m_collapsedBordersValid; }
- void invalidateCollapsedBorders();
+ void invalidateCollapsedBorders(RenderTableCell* cellWithStyleChange = nullptr);
void collapsedEmptyBorderIsPresent() { m_collapsedEmptyBorderIsPresent = true; }
const CollapsedBorderValue* currentBorderValue() const { return m_currentBorder; }
Modified: trunk/Source/WebCore/rendering/RenderTableCell.cpp (199551 => 199552)
--- trunk/Source/WebCore/rendering/RenderTableCell.cpp 2016-04-14 20:49:12 UTC (rev 199551)
+++ trunk/Source/WebCore/rendering/RenderTableCell.cpp 2016-04-14 21:09:19 UTC (rev 199552)
@@ -423,7 +423,7 @@
// If border was changed, notify table.
RenderTable* table = this->table();
if (table && oldStyle && oldStyle->border() != style().border())
- table->invalidateCollapsedBorders();
+ table->invalidateCollapsedBorders(this);
}
// The following rules apply for resolving conflicts and figuring out which border
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes