зеркало из https://github.com/mozilla/gecko-dev.git
Bug 406137. Fix crashes on redhat.com etc by avoiding RecoverFloats traversing stale float caches. r+sr=dbaron
This commit is contained in:
Родитель
cf314091fe
Коммит
0b47bce39d
|
@ -1845,7 +1845,14 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
||||||
|
|
||||||
// Now repair the line and update |aState.mY| by calling
|
// Now repair the line and update |aState.mY| by calling
|
||||||
// |ReflowLine| or |SlideLine|.
|
// |ReflowLine| or |SlideLine|.
|
||||||
if (line->IsDirty() && !willReflowAgain) {
|
// If we're going to reflow everything again, then no need to reflow
|
||||||
|
// the dirty line ... unless the line has floats, in which case we'd
|
||||||
|
// better reflow it now to refresh its float cache, which may contain
|
||||||
|
// dangling frame pointers! Ugh! This reflow of the line may be
|
||||||
|
// incorrect because we skipped reflowing previous lines (e.g., floats
|
||||||
|
// may be placed incorrectly), but that's OK because we'll mark the
|
||||||
|
// line dirty below under "if (aState.mReflowState.mDiscoveredClearance..."
|
||||||
|
if (line->IsDirty() && (line->HasFloats() || !willReflowAgain)) {
|
||||||
lastLineMovedUp = PR_TRUE;
|
lastLineMovedUp = PR_TRUE;
|
||||||
|
|
||||||
PRBool maybeReflowingForFirstTime =
|
PRBool maybeReflowingForFirstTime =
|
||||||
|
@ -1867,6 +1874,9 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
||||||
*aState.mReflowState.mDiscoveredClearance) {
|
*aState.mReflowState.mDiscoveredClearance) {
|
||||||
line->MarkDirty();
|
line->MarkDirty();
|
||||||
willReflowAgain = PR_TRUE;
|
willReflowAgain = PR_TRUE;
|
||||||
|
// Note that once we've entered this state, every line that gets here
|
||||||
|
// (e.g. because it has floats) gets marked dirty and reflowed again.
|
||||||
|
// in the next pass. This is important, see above.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line->HasFloats()) {
|
if (line->HasFloats()) {
|
||||||
|
@ -1937,8 +1947,20 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
||||||
else
|
else
|
||||||
repositionViews = PR_TRUE;
|
repositionViews = PR_TRUE;
|
||||||
|
|
||||||
// XXX EVIL O(N^2) EVIL
|
if (willReflowAgain) {
|
||||||
aState.RecoverStateFrom(line, deltaY);
|
NS_ASSERTION(!line->HasFloats(), "Possibly stale float cache here!");
|
||||||
|
// If we're going to reflow everything again, and this line has no
|
||||||
|
// cached floats, then there is no need to recover float state. The line
|
||||||
|
// may be a block that contains other lines with floats, but in that
|
||||||
|
// case RecoverStateFrom would only add floats to the space manager.
|
||||||
|
// We don't need to do that because everything's going to get reflowed
|
||||||
|
// again "for real". Calling RecoverStateFrom in this situation could
|
||||||
|
// be lethal because the block's descendant lines may have float
|
||||||
|
// caches containing dangling frame pointers. Ugh!
|
||||||
|
} else {
|
||||||
|
// XXX EVIL O(N^2) EVIL
|
||||||
|
aState.RecoverStateFrom(line, deltaY);
|
||||||
|
}
|
||||||
|
|
||||||
// Keep mY up to date in case we're propagating reflow damage
|
// Keep mY up to date in case we're propagating reflow damage
|
||||||
// and also because our final height may depend on it. If the
|
// and also because our final height may depend on it. If the
|
||||||
|
|
Загрузка…
Ссылка в новой задаче