commit eade387da45eb7b220989935c9b587b2cf4d2141
parent bd367a8e2912a1d7e436676a545241551390c494
Author: Timothy Nikkel <tnikkel@gmail.com>
Date: Fri, 14 Nov 2025 14:19:16 +0000
Bug 1999697. If we are "creating" an ASR for the second time during a paint, assert that we aren't changing any fields. r=layout-reviewers,emilio
When the anchor pos code gets the ASR for the anchor it will cause a second call to these functions. We want to make sure that we aren't changing ASR the second time as that would indicate a problem.
Differential Revision: https://phabricator.services.mozilla.com/D272250
Diffstat:
2 files changed, 61 insertions(+), 7 deletions(-)
diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp
@@ -168,10 +168,27 @@ void InitializeHitTestInfo(nsDisplayListBuilder* aBuilder,
/* static */
already_AddRefed<ActiveScrolledRoot> ActiveScrolledRoot::CreateASRForFrame(
const ActiveScrolledRoot* aParent,
- ScrollContainerFrame* aScrollContainerFrame) {
+ ScrollContainerFrame* aScrollContainerFrame
+#ifdef DEBUG
+ ,
+ const nsTArray<RefPtr<ActiveScrolledRoot>>& aActiveScrolledRoots
+#endif
+) {
RefPtr<ActiveScrolledRoot> asr =
aScrollContainerFrame->GetProperty(ActiveScrolledRootCache());
+#ifdef DEBUG
+ if (asr && aActiveScrolledRoots.Contains(asr)) {
+ // This is the second time we are "creating" this ASR in this paint. Assert
+ // that we aren't changing any of the values. (The values can change
+ // *between* paints, but not during one paint.)
+ MOZ_ASSERT(asr->mParent == aParent);
+ MOZ_ASSERT(asr->mFrame == aScrollContainerFrame);
+ MOZ_ASSERT(asr->mKind == ASRKind::Scroll);
+ MOZ_ASSERT(asr->mDepth == (aParent ? aParent->mDepth + 1 : 1));
+ }
+#endif
+
if (!asr) {
asr = new ActiveScrolledRoot();
@@ -189,13 +206,30 @@ already_AddRefed<ActiveScrolledRoot> ActiveScrolledRoot::CreateASRForFrame(
/* static */
already_AddRefed<ActiveScrolledRoot>
-ActiveScrolledRoot::CreateASRForStickyFrame(const ActiveScrolledRoot* aParent,
- nsIFrame* aStickyFrame) {
+ActiveScrolledRoot::CreateASRForStickyFrame(
+ const ActiveScrolledRoot* aParent, nsIFrame* aStickyFrame
+#ifdef DEBUG
+ ,
+ const nsTArray<RefPtr<ActiveScrolledRoot>>& aActiveScrolledRoots
+#endif
+) {
aStickyFrame = aStickyFrame->FirstContinuation();
RefPtr<ActiveScrolledRoot> asr =
aStickyFrame->GetProperty(StickyActiveScrolledRootCache());
+#ifdef DEBUG
+ if (asr && aActiveScrolledRoots.Contains(asr)) {
+ // This is the second time we are "creating" this ASR in this paint. Assert
+ // that we aren't changing any of the values. (The values can change
+ // *between* paints, but not during one paint.)
+ MOZ_ASSERT(asr->mParent == aParent);
+ MOZ_ASSERT(asr->mFrame == aStickyFrame);
+ MOZ_ASSERT(asr->mKind == ASRKind::Sticky);
+ MOZ_ASSERT(asr->mDepth == (aParent ? aParent->mDepth + 1 : 1));
+ }
+#endif
+
if (!asr) {
asr = new ActiveScrolledRoot();
@@ -1507,7 +1541,12 @@ ActiveScrolledRoot* nsDisplayListBuilder::AllocateActiveScrolledRoot(
const ActiveScrolledRoot* aParent,
ScrollContainerFrame* aScrollContainerFrame) {
RefPtr<ActiveScrolledRoot> asr =
- ActiveScrolledRoot::CreateASRForFrame(aParent, aScrollContainerFrame);
+ ActiveScrolledRoot::CreateASRForFrame(aParent, aScrollContainerFrame
+#ifdef DEBUG
+ ,
+ mActiveScrolledRoots
+#endif
+ );
mActiveScrolledRoots.AppendElement(asr);
return asr;
}
@@ -1515,7 +1554,12 @@ ActiveScrolledRoot* nsDisplayListBuilder::AllocateActiveScrolledRoot(
ActiveScrolledRoot* nsDisplayListBuilder::AllocateActiveScrolledRootForSticky(
const ActiveScrolledRoot* aParent, nsIFrame* aStickyFrame) {
RefPtr<ActiveScrolledRoot> asr =
- ActiveScrolledRoot::CreateASRForStickyFrame(aParent, aStickyFrame);
+ ActiveScrolledRoot::CreateASRForStickyFrame(aParent, aStickyFrame
+#ifdef DEBUG
+ ,
+ mActiveScrolledRoots
+#endif
+ );
mActiveScrolledRoots.AppendElement(asr);
return asr;
}
diff --git a/layout/painting/nsDisplayList.h b/layout/painting/nsDisplayList.h
@@ -187,9 +187,19 @@ struct ActiveScrolledRoot {
// TODO: Just have one function with an extra ASRKind parameter
static already_AddRefed<ActiveScrolledRoot> CreateASRForFrame(
const ActiveScrolledRoot* aParent,
- ScrollContainerFrame* aScrollContainerFrame);
+ ScrollContainerFrame* aScrollContainerFrame
+#ifdef DEBUG
+ ,
+ const nsTArray<RefPtr<ActiveScrolledRoot>>& aActiveScrolledRoots
+#endif
+ );
static already_AddRefed<ActiveScrolledRoot> CreateASRForStickyFrame(
- const ActiveScrolledRoot* aParent, nsIFrame* aStickyFrame);
+ const ActiveScrolledRoot* aParent, nsIFrame* aStickyFrame
+#ifdef DEBUG
+ ,
+ const nsTArray<RefPtr<ActiveScrolledRoot>>& aActiveScrolledRoots
+#endif
+ );
static const ActiveScrolledRoot* PickAncestor(
const ActiveScrolledRoot* aOne, const ActiveScrolledRoot* aTwo) {