Diff
Copied: branches/chromium/1084/LayoutTests/fast/block/line-layout/line-break-obj-removal-crash-expected.txt (from rev 115343, trunk/LayoutTests/fast/block/line-layout/line-break-obj-removal-crash-expected.txt) (0 => 116147)
--- branches/chromium/1084/LayoutTests/fast/block/line-layout/line-break-obj-removal-crash-expected.txt (rev 0)
+++ branches/chromium/1084/LayoutTests/fast/block/line-layout/line-break-obj-removal-crash-expected.txt 2012-05-04 19:46:31 UTC (rev 116147)
@@ -0,0 +1,2 @@
+
+PASS, if no crash or assert in debug
Copied: branches/chromium/1084/LayoutTests/fast/block/line-layout/line-break-obj-removal-crash.html (from rev 115343, trunk/LayoutTests/fast/block/line-layout/line-break-obj-removal-crash.html) (0 => 116147)
--- branches/chromium/1084/LayoutTests/fast/block/line-layout/line-break-obj-removal-crash.html (rev 0)
+++ branches/chromium/1084/LayoutTests/fast/block/line-layout/line-break-obj-removal-crash.html 2012-05-04 19:46:31 UTC (rev 116147)
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<style>
+.style1:nth-last-child(odd) { padding-right: 100px; }
+.styleCounterBefore:before { position: absolute; content: counter(section); }
+</style>
+<script>
+window._onload_ = function() {
+ divElem = document.createElement('div');
+ divElem.setAttribute('class', 'styleCounterBefore');
+ document.documentElement.appendChild(divElem);
+ brElem = document.createElement('br');
+ document.documentElement.appendChild(brElem);
+ sampElem = document.createElement('samp');
+ sampElem.setAttribute('class', 'style1');
+ document.documentElement.appendChild(sampElem);
+ spanElem = document.createElement('span');
+ spanElem.setAttribute('class', 'styleCounterBefore');
+ trElem = document.createElement('tr');
+ document.documentElement.appendChild(trElem);
+ sampElem.appendChild(spanElem);
+ document.documentElement.offsetHeight;
+ document.documentElement.removeChild(trElem);
+
+ document.documentElement.appendChild(document.createTextNode('PASS, if no crash or assert in debug'));
+
+ if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+}
+</script>
+</html>
Modified: branches/chromium/1084/Source/WebCore/rendering/RenderLineBoxList.cpp (116146 => 116147)
--- branches/chromium/1084/Source/WebCore/rendering/RenderLineBoxList.cpp 2012-05-04 19:45:03 UTC (rev 116146)
+++ branches/chromium/1084/Source/WebCore/rendering/RenderLineBoxList.cpp 2012-05-04 19:46:31 UTC (rev 116147)
@@ -321,9 +321,9 @@
if (!firstBox) {
// For an empty inline, go ahead and propagate the check up to our parent, unless the parent
// is already dirty.
- if (container->isInline() && !container->parent()->selfNeedsLayout()) {
+ if (container->isInline() && !container->parent()->ancestorLineBoxDirty()) {
container->parent()->dirtyLinesFromChangedChild(container);
- container->setNeedsLayout(true); // Mark the container as needing layout to avoid dirtying the same lines again across multiple destroy() calls of the same subtree.
+ container->setAncestorLineBoxDirty(); // Mark the container to avoid dirtying the same lines again across multiple destroy() calls of the same subtree.
}
return;
}
@@ -361,9 +361,9 @@
// we won't find a previous sibling, but firstBox can be pointing to a following sibling.
// This isn't good enough, since we won't locate the root line box that encloses the removed
// <br>. We have to just over-invalidate a bit and go up to our parent.
- if (!inlineContainer->parent()->selfNeedsLayout()) {
+ if (!inlineContainer->parent()->ancestorLineBoxDirty()) {
inlineContainer->parent()->dirtyLinesFromChangedChild(inlineContainer);
- inlineContainer->setNeedsLayout(true); // Mark the container as needing layout to avoid dirtying the same lines again across multiple destroy() calls of the same subtree.
+ inlineContainer->setAncestorLineBoxDirty(); // Mark the container to avoid dirtying the same lines again across multiple destroy() calls of the same subtree.
}
return;
}
Modified: branches/chromium/1084/Source/WebCore/rendering/RenderObject.cpp (116146 => 116147)
--- branches/chromium/1084/Source/WebCore/rendering/RenderObject.cpp 2012-05-04 19:45:03 UTC (rev 116146)
+++ branches/chromium/1084/Source/WebCore/rendering/RenderObject.cpp 2012-05-04 19:46:31 UTC (rev 116147)
@@ -101,6 +101,8 @@
bool RenderObject::s_affectsParentBlock = false;
+RenderObjectAncestorLineboxDirtySet* RenderObject::s_ancestorLineboxDirtySet = 0;
+
void* RenderObject::operator new(size_t sz, RenderArena* renderArena)
{
return renderArena->allocate(sz);
@@ -2280,6 +2282,8 @@
toRenderBoxModelObject(this)->destroyLayer();
}
+ setAncestorLineBoxDirty(false);
+
clearLayoutRootIfNeeded();
}
Modified: branches/chromium/1084/Source/WebCore/rendering/RenderObject.h (116146 => 116147)
--- branches/chromium/1084/Source/WebCore/rendering/RenderObject.h 2012-05-04 19:45:03 UTC (rev 116146)
+++ branches/chromium/1084/Source/WebCore/rendering/RenderObject.h 2012-05-04 19:46:31 UTC (rev 116147)
@@ -37,6 +37,7 @@
#include "RenderStyle.h"
#include "TextAffinity.h"
#include "TransformationMatrix.h"
+#include <wtf/HashSet.h>
#include <wtf/UnusedParam.h>
#if USE(CG) || USE(CAIRO) || USE(SKIA) || PLATFORM(QT)
@@ -117,6 +118,8 @@
};
#endif
+typedef WTF::HashSet<const RenderObject*> RenderObjectAncestorLineboxDirtySet;
+
#ifndef NDEBUG
const int showTreeCharacterOffset = 39;
#endif
@@ -369,6 +372,22 @@
bool hasColumns() const { return m_bitfields.hasColumns(); }
void setHasColumns(bool b = true) { m_bitfields.setHasColumns(b); }
+ bool ancestorLineBoxDirty() const { return s_ancestorLineboxDirtySet && s_ancestorLineboxDirtySet->contains(this); }
+ void setAncestorLineBoxDirty(bool b = true)
+ {
+ if (b) {
+ if (!s_ancestorLineboxDirtySet)
+ s_ancestorLineboxDirtySet = new RenderObjectAncestorLineboxDirtySet;
+ s_ancestorLineboxDirtySet->add(this);
+ } else if (s_ancestorLineboxDirtySet) {
+ s_ancestorLineboxDirtySet->remove(this);
+ if (s_ancestorLineboxDirtySet->isEmpty()) {
+ delete s_ancestorLineboxDirtySet;
+ s_ancestorLineboxDirtySet = 0;
+ }
+ }
+ }
+
bool inRenderFlowThread() const { return m_bitfields.inRenderFlowThread(); }
void setInRenderFlowThread(bool b = true) { m_bitfields.setInRenderFlowThread(b); }
@@ -890,6 +909,8 @@
RenderObject* m_previous;
RenderObject* m_next;
+ static RenderObjectAncestorLineboxDirtySet* s_ancestorLineboxDirtySet;
+
#ifndef NDEBUG
bool m_hasAXObject : 1;
bool m_setNeedsLayoutForbidden : 1;
@@ -1050,6 +1071,7 @@
setNeedsSimplifiedNormalFlowLayout(false);
setNormalChildNeedsLayout(false);
setNeedsPositionedMovementLayout(false);
+ setAncestorLineBoxDirty(false);
}
}