Closed
Bug 1278461
Opened 8 years ago
Closed 8 years ago
[css-grid] Assertion failure: "NS_STATE_GRID_DID_PUSH_ITEMS lied" with -moz-column, grid, display:contents
Categories
(Core :: Layout, defect)
Core
Layout
Tracking
()
RESOLVED
FIXED
mozilla52
People
(Reporter: jruderman, Assigned: bradwerth)
References
Details
(Keywords: assertion, testcase)
Attachments
(3 files, 2 obsolete files)
375 bytes,
text/html
|
Details | |
16.55 KB,
text/plain
|
Details | |
3.83 KB,
patch
|
Details | Diff | Splinter Review |
Assertion failure: foundOwnPushedChild || !items.IsEmpty() || mDidPushItemsBitMayLie (NS_STATE_GRID_DID_PUSH_ITEMS lied), at layout/generic/nsGridContainerFrame.cpp:5435
Reporter | ||
Comment 1•8 years ago
|
||
Updated•8 years ago
|
Assignee: nobody → mats
Summary: Assertion failure: "NS_STATE_GRID_DID_PUSH_ITEMS lied" with -moz-column, grid, display:contents → [css-grid] Assertion failure: "NS_STATE_GRID_DID_PUSH_ITEMS lied" with -moz-column, grid, display:contents
Assignee | ||
Comment 3•8 years ago
|
||
Mats, this is the smallest intervention I could find to deal with this testcase. I couldn't find a way to prevent setting the NS_STATE_GRID_DID_PUSH_ITEMS bit or to unset it only in the right conditions, so I instead use the existing mDidPushItemsBitMayLie variable. https://treeherder.mozilla.org/#/jobs?repo=try&revision=25223d6962cc
Attachment #8793067 -
Flags: feedback?(mats)
Comment 4•8 years ago
|
||
It's not clear to me why we fix the prev-in-flow's state here. Do we actually assert, during reflow of 'this', something about the the prev-in-flow's state? Or is this just setting the mDidPushItemsBitMayLie bit for a potential future reflow of prev-in-flow? Can you elaborate on the series of steps of pushing/pulling items, reflowing nsGridContainerFrames etc, that leads up to this state where we will assert? What does the frame trees look like, and what are the DID_PUSH_ITEMS bits set to in each step?
Flags: needinfo?(bwerth)
Assignee | ||
Comment 5•8 years ago
|
||
(In reply to Mats Palmgren (:mats) from comment #4) > Or is this just setting the mDidPushItemsBitMayLie bit for a potential > future reflow of > prev-in-flow? It is this. In the testcase, a fragmented grid is reflowed, and the first fragment nsGridContainerFrame sets the bit. Without this patch, then the second fragment nsGridContainerFrame takes all of the overflow children BUT leaves the bit set. The testcase then makes a dynamic style change to "display:contents", and the first fragment is reflowed without touching the bit, triggering the assert. It would be a better solution to ensure that the NS_STATE_GRID_DID_PUSH_ITEMS bit is cleared on appropriate nsGridContainerFrames when the style is changed, before triggering reflow. I tried to isolate an appopriate point to do this, but I couldn't find an existing nsGridContainerFrame virtual function that would work for both this testcase and the existing tests. The closest candidate I found was nsGridContainerFrame::DrainSelfOverflowList, which is definitely called during the dynamic style change and solved the problem for this testcase, but clearing the bit there triggered a different assert when running layout/reftests/css-grid/grid-fragmentation-dyn1-016.html. There's probably a way to thread the needle, but I wasn't able to find it. If the approach in the proposed patch is unacceptable, I'll go back to this investigation and keep trying. My goal then would be to try to avoid creating another virtual function in nsGridContainerFrame. I'll briefly make an argument for the proposed patch: If we're going to have a flag called mDidPushItemsBitMayLie, and we currently set it when we remove some but not all of the possible pushed items (in nsGridContainerFrame::RemoveFrame), then the usage in this proposed patch is consistent with that.
Flags: needinfo?(bwerth) → needinfo?(mats)
Comment 6•8 years ago
|
||
> then the second fragment nsGridContainerFrame takes all of the overflow children BUT leaves the bit set This is a correct behavior, the bit reflects that we "pushed an item", so the child frame may be on the Overflow list of the container that pushed, or on the Principal or Overflow lists of any of the pushing container's continuations. > The testcase then makes a dynamic style change to "display:contents", and the first fragment is reflowed without touching the bit, triggering the assert. OK, so we got a call to RemoveFrame from that, right? Why didn't the mDidPushItemsBitMayLie assignment there help? Can we just set mDidPushItemsBitMayLie on 'this' and all its prev-in-flows there? > It would be a better solution to ensure that the NS_STATE_GRID_DID_PUSH_ITEMS This means we need to walk the child lists of continuations to figure out if the bit should be set or not, which is expensive. It's better to do it at the start of Reflow, so that it coalesces multiple child removals etc. Also it's more robust if DID_PUSH_ITEMS only means "we did push some item in the past, but it may have been removed since then" rather than relying on it to be exact at all times. I'm aiming for it to be correct in the case of pulling/pushing items due to reflows though, but care less about dynamic changes like restyle.
Flags: needinfo?(mats)
Comment 7•8 years ago
|
||
Just to make sure I understand what happens in the test... We fragment the grid container in two columns, the "x" item ends up in the 2nd column and since we pushed it the first container fragment has the DID_PUSH_ITEMS set. Then we set display:contents on "x" and its frame is destroyed, we get a call to RemoveFrame (with the 2nd container fragment as 'this') and set mDidPushItemsBitMayLie on 'this' there? Then we reflow the 1st container fragment but it can't find any pushed items on its next-in-flows so it asserts?
Assignee | ||
Comment 8•8 years ago
|
||
(In reply to Mats Palmgren (:mats) from comment #6) > > The testcase then makes a dynamic style change to "display:contents", and the first fragment is reflowed without touching the bit, triggering the assert. > > OK, so we got a call to RemoveFrame from that, right? > Why didn't the mDidPushItemsBitMayLie assignment there help? > Can we just set mDidPushItemsBitMayLie on 'this' and all its prev-in-flows > there? Indeed, RemoveFrame is called on the second fragment nsGridContainerFrame, but not on the first. I will extend the setting to all prev-in-flows and that should also solve the problem. > Just to make sure I understand what happens in the test... > We fragment the grid container in two columns, the "x" item > ends up in the 2nd column and since we pushed it the first > container fragment has the DID_PUSH_ITEMS set. Then we set > display:contents on "x" and its frame is destroyed, we get > a call to RemoveFrame (with the 2nd container fragment as > 'this') and set mDidPushItemsBitMayLie on 'this' there? > Then we reflow the 1st container fragment but it can't find > any pushed items on its next-in-flows so it asserts? Yes that seems to be what is happening. I'll follow your proposed approach (RemoveFrame set of the mDidPushItemsBitMayLie flag goes back through prev-in-flow containers) to solve it.
Assignee | ||
Comment 9•8 years ago
|
||
RemoveFrame propegates the mDidPushItemsBitMayLie bit up the prev-in-flow chain. https://treeherder.mozilla.org/#/jobs?repo=try&revision=9bd82226b234
Attachment #8793067 -
Attachment is obsolete: true
Attachment #8793067 -
Flags: feedback?(mats)
Attachment #8793515 -
Flags: review?(mats)
Comment 10•8 years ago
|
||
Comment on attachment 8793515 [details] [diff] [review] fixGridAssert2.patch Thanks! Does this also fix the other bug filed yesterday?
Attachment #8793515 -
Flags: review?(mats) → review+
Assignee | ||
Comment 11•8 years ago
|
||
To be determined. I can't replicate bug 1304184 with current mozilla-central (prior to this patch), so I'm building the specific revision mentioned in the other bug and testing again.
Assignee | ||
Comment 12•8 years ago
|
||
Since this is r+ and probably-related bug 1304184 needs more time to replicate and remediate, I'm putting this in for checkin now.
Keywords: checkin-needed
Comment 13•8 years ago
|
||
Can you please include the testcase as a crashtest?
Assignee | ||
Comment 14•8 years ago
|
||
Confirmed that this fix also fixes bug 1304184 which has a similar pathology. I will add both testcases as crashtests in next patch.
Flags: needinfo?(bwerth)
Assignee | ||
Comment 15•8 years ago
|
||
Adds the testcase requested in comment 13, and also a testcase for bug 1304184, which this patch also fixes.
Attachment #8793515 -
Attachment is obsolete: true
Assignee | ||
Comment 16•8 years ago
|
||
(In reply to Brad Werth [:bradwerth] from comment #15) > Adds the testcase requested in comment 13, and also a testcase for bug > 1304184, which this patch also fixes. s/testcase/crashtest
Assignee | ||
Updated•8 years ago
|
Keywords: checkin-needed
Comment 17•8 years ago
|
||
Pushed by ryanvm@gmail.com: https://hg.mozilla.org/integration/mozilla-inbound/rev/d343d42820d9 Prevent an assert from tripping when removing an overflowed frame during a partial reflow. r=mats
Keywords: checkin-needed
Comment 18•8 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/d343d42820d9
Status: NEW → RESOLVED
Closed: 8 years ago
status-firefox52:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla52
Comment 19•8 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/d343d42820d9
Updated•8 years ago
|
Flags: in-testsuite? → in-testsuite+
You need to log in
before you can comment on or make changes to this bug.
Description
•