tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 998d878da24d0b2889cfff28337b20d9e8b74796
parent 476c551dc522acb523a09d2764bffb62098b96ed
Author: Emilio Cobos Álvarez <emilio@crisal.io>
Date:   Fri, 17 Oct 2025 06:33:35 +0000

Bug 1994893 - Remove VerifyIncrementalReflow and co. r=layout-reviewers,TYLin

I bet nobody has used this since forever. Just running my local central build
(without the previous patch) with GECKO_VERIFY_REFLOW_FLAGS=verify stack
overflows, and it probably has at least for years.

Keeping this code around seems unnecessary.

Differential Revision: https://phabricator.services.mozilla.com/D268977

Diffstat:
Mlayout/base/PresShell.cpp | 493-------------------------------------------------------------------------------
Mlayout/base/PresShell.h | 16----------------
2 files changed, 0 insertions(+), 509 deletions(-)

diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp @@ -266,49 +266,6 @@ struct RangePaintInfo { #undef NOISY -// ---------------------------------------------------------------------- - -#ifdef DEBUG -// Set the environment variable GECKO_VERIFY_REFLOW_FLAGS to one or -// more of the following flags (comma separated) for handy debug -// output. -static VerifyReflowFlags gVerifyReflowFlags; - -struct VerifyReflowFlagData { - const char* name; - VerifyReflowFlags bit; -}; - -static const VerifyReflowFlagData gFlags[] = { - // clang-format off - { "verify", VerifyReflowFlags::On }, - { "reflow", VerifyReflowFlags::Noisy }, - { "all", VerifyReflowFlags::All }, - { "list-commands", VerifyReflowFlags::DumpCommands }, - { "noisy-commands", VerifyReflowFlags::NoisyCommands }, - { "really-noisy-commands", VerifyReflowFlags::ReallyNoisyCommands }, - { "resize", VerifyReflowFlags::DuringResizeReflow }, - // clang-format on -}; - -# define NUM_VERIFY_REFLOW_FLAGS (sizeof(gFlags) / sizeof(gFlags[0])) - -static void ShowVerifyReflowFlags() { - printf("Here are the available GECKO_VERIFY_REFLOW_FLAGS:\n"); - const VerifyReflowFlagData* flag = gFlags; - const VerifyReflowFlagData* limit = gFlags + NUM_VERIFY_REFLOW_FLAGS; - while (flag < limit) { - printf(" %s\n", flag->name); - ++flag; - } - printf("Note: GECKO_VERIFY_REFLOW_FLAGS is a comma separated list of flag\n"); - printf("names (no whitespace)\n"); -} -#endif - -//======================================================================== -//======================================================================== -//======================================================================== #ifdef MOZ_REFLOW_PERF class ReflowCountMgr; @@ -630,74 +587,6 @@ bool PresShell::sProcessInteractable = false; Modifiers PresShell::sCurrentModifiers = MODIFIER_NONE; -static bool gVerifyReflowEnabled; - -bool PresShell::GetVerifyReflowEnable() { -#ifdef DEBUG - static bool firstTime = true; - if (firstTime) { - firstTime = false; - char* flags = PR_GetEnv("GECKO_VERIFY_REFLOW_FLAGS"); - if (flags) { - bool error = false; - - for (;;) { - char* comma = strchr(flags, ','); - if (comma) *comma = '\0'; - - bool found = false; - const VerifyReflowFlagData* flag = gFlags; - const VerifyReflowFlagData* limit = gFlags + NUM_VERIFY_REFLOW_FLAGS; - while (flag < limit) { - if (nsCRT::strcasecmp(flag->name, flags) == 0) { - gVerifyReflowFlags |= flag->bit; - found = true; - break; - } - ++flag; - } - - if (!found) error = true; - - if (!comma) break; - - *comma = ','; - flags = comma + 1; - } - - if (error) ShowVerifyReflowFlags(); - } - - if (VerifyReflowFlags::On & gVerifyReflowFlags) { - gVerifyReflowEnabled = true; - - printf("Note: verifyreflow is enabled"); - if (VerifyReflowFlags::Noisy & gVerifyReflowFlags) { - printf(" (noisy)"); - } - if (VerifyReflowFlags::All & gVerifyReflowFlags) { - printf(" (all)"); - } - if (VerifyReflowFlags::DumpCommands & gVerifyReflowFlags) { - printf(" (show reflow commands)"); - } - if (VerifyReflowFlags::NoisyCommands & gVerifyReflowFlags) { - printf(" (noisy reflow commands)"); - if (VerifyReflowFlags::ReallyNoisyCommands & gVerifyReflowFlags) { - printf(" (REALLY noisy reflow commands)"); - } - } - printf("\n"); - } - } -#endif - return gVerifyReflowEnabled; -} - -void PresShell::SetVerifyReflowEnable(bool aEnabled) { - gVerifyReflowEnabled = aEnabled; -} - void PresShell::AddAutoWeakFrame(AutoWeakFrame* aWeakFrame) { if (aWeakFrame->GetFrame()) { aWeakFrame->GetFrame()->AddStateBits(NS_FRAME_EXTERNAL_REFERENCE); @@ -1759,18 +1648,6 @@ nsresult PresShell::Initialize() { mDidInitialize = true; -#ifdef DEBUG - if (VerifyReflowFlags::NoisyCommands & gVerifyReflowFlags) { - if (mDocument) { - nsIURI* uri = mDocument->GetDocumentURI(); - if (uri) { - printf("*** PresShell::Initialize (this=%p, url='%s')\n", (void*)this, - uri->GetSpecOrDefault().get()); - } - } - } -#endif - // Get the root frame from the frame constructor. // XXXbz it would be nice to move this somewhere else... like frame manager // Init(), say. But we need to make sure our views are all set up by the @@ -2726,23 +2603,6 @@ void PresShell::FrameNeedsReflow(nsIFrame* aFrame, return; } -#ifdef DEBUG - // printf("gShellCounter: %d\n", gShellCounter++); - if (mInVerifyReflow) return; - - if (VerifyReflowFlags::NoisyCommands & gVerifyReflowFlags) { - printf("\nPresShell@%p: frame %p needs reflow\n", (void*)this, - (void*)aFrame); - if (VerifyReflowFlags::ReallyNoisyCommands & gVerifyReflowFlags) { - printf("Current content model:\n"); - Element* rootElement = mDocument->GetRootElement(); - if (rootElement) { - rootElement->List(stdout, 0); - } - } - } -#endif - AutoTArray<nsIFrame*, 4> subtrees; subtrees.AppendElement(aFrame); @@ -10949,29 +10809,6 @@ bool PresShell::DoReflow(nsIFrame* target, bool aInterruptible, return !interrupted; } -#ifdef DEBUG -void PresShell::DoVerifyReflow() { - if (GetVerifyReflowEnable()) { - // First synchronously render what we have so far so that we can - // see it. - nsView* rootView = mViewManager->GetRootView(); - mViewManager->InvalidateView(rootView); - - FlushPendingNotifications(FlushType::Layout); - mInVerifyReflow = true; - bool ok = VerifyIncrementalReflow(); - mInVerifyReflow = false; - if (VerifyReflowFlags::All & gVerifyReflowFlags) { - printf("ProcessReflowCommands: finished (%s)\n", ok ? "ok" : "failed"); - } - - if (!mDirtyRoots.IsEmpty()) { - printf("XXX yikes! reflow commands queued during verify-reflow\n"); - } - } -} -#endif - // used with Telemetry metrics #define NS_LONG_REFLOW_TIME_MS 5000 @@ -10990,12 +10827,6 @@ bool PresShell::ProcessReflowCommands(bool aInterruptible) { auto timerStart = mozilla::TimeStamp::Now(); bool interrupted = false; if (!mDirtyRoots.IsEmpty()) { -#ifdef DEBUG - if (VerifyReflowFlags::DumpCommands & gVerifyReflowFlags) { - printf("ProcessReflowCommands: begin incremental reflow\n"); - } -#endif - // If reflow is interruptible, then make a note of our deadline. const PRIntervalTime deadline = aInterruptible @@ -11046,14 +10877,6 @@ bool PresShell::ProcessReflowCommands(bool aInterruptible) { DidDoReflow(aInterruptible); } -#ifdef DEBUG - if (VerifyReflowFlags::DumpCommands & gVerifyReflowFlags) { - printf("\nPresShell::ProcessReflowCommands() finished: this=%p\n", - (void*)this); - } - DoVerifyReflow(); -#endif - { TimeDuration elapsed = TimeStamp::Now() - timerStart; int32_t intElapsed = int32_t(elapsed.ToMilliseconds()); @@ -11236,323 +11059,7 @@ bool PresShell::DelayedKeyEvent::IsKeyPressEvent() { return mEvent->mMessage == eKeyPress; } -// Start of DEBUG only code - -#ifdef DEBUG - -static void LogVerifyMessage(nsIFrame* k1, nsIFrame* k2, const char* aMsg) { - nsAutoString n1, n2; - if (k1) { - k1->GetFrameName(n1); - } else { - n1.AssignLiteral(u"(null)"); - } - - if (k2) { - k2->GetFrameName(n2); - } else { - n2.AssignLiteral(u"(null)"); - } - - printf("verifyreflow: %s %p != %s %p %s\n", - NS_LossyConvertUTF16toASCII(n1).get(), (void*)k1, - NS_LossyConvertUTF16toASCII(n2).get(), (void*)k2, aMsg); -} - -static void LogVerifyMessage(nsIFrame* k1, nsIFrame* k2, const char* aMsg, - const nsRect& r1, const nsRect& r2) { - printf("VerifyReflow Error:\n"); - nsAutoString name; - - if (k1) { - k1->GetFrameName(name); - printf(" %s %p ", NS_LossyConvertUTF16toASCII(name).get(), (void*)k1); - } - printf("{%d, %d, %d, %d} != \n", r1.x, r1.y, r1.width, r1.height); - - if (k2) { - k2->GetFrameName(name); - printf(" %s %p ", NS_LossyConvertUTF16toASCII(name).get(), (void*)k2); - } - printf("{%d, %d, %d, %d}\n %s\n", r2.x, r2.y, r2.width, r2.height, aMsg); -} - -static void LogVerifyMessage(nsIFrame* k1, nsIFrame* k2, const char* aMsg, - const nsIntRect& r1, const nsIntRect& r2) { - printf("VerifyReflow Error:\n"); - nsAutoString name; - - if (k1) { - k1->GetFrameName(name); - printf(" %s %p ", NS_LossyConvertUTF16toASCII(name).get(), (void*)k1); - } - printf("{%d, %d, %d, %d} != \n", r1.x, r1.y, r1.width, r1.height); - - if (k2) { - k2->GetFrameName(name); - printf(" %s %p ", NS_LossyConvertUTF16toASCII(name).get(), (void*)k2); - } - printf("{%d, %d, %d, %d}\n %s\n", r2.x, r2.y, r2.width, r2.height, aMsg); -} - -static bool CompareTrees(nsPresContext* aFirstPresContext, - nsIFrame* aFirstFrame, - nsPresContext* aSecondPresContext, - nsIFrame* aSecondFrame) { - if (!aFirstPresContext || !aFirstFrame || !aSecondPresContext || - !aSecondFrame) - return true; - // XXX Evil hack to reduce false positives; I can't seem to figure - // out how to flush scrollbar changes correctly - // if (aFirstFrame->IsScrollbarFrame()) - // return true; - bool ok = true; - const auto& childLists1 = aFirstFrame->ChildLists(); - const auto& childLists2 = aSecondFrame->ChildLists(); - auto iterLists1 = childLists1.begin(); - auto iterLists2 = childLists2.begin(); - do { - const nsFrameList& kids1 = iterLists1 != childLists1.end() - ? iterLists1->mList - : nsFrameList::EmptyList(); - const nsFrameList& kids2 = iterLists2 != childLists2.end() - ? iterLists2->mList - : nsFrameList::EmptyList(); - int32_t l1 = kids1.GetLength(); - int32_t l2 = kids2.GetLength(); - if (l1 != l2) { - ok = false; - LogVerifyMessage(kids1.FirstChild(), kids2.FirstChild(), - "child counts don't match: "); - printf("%d != %d\n", l1, l2); - if (!(VerifyReflowFlags::All & gVerifyReflowFlags)) { - break; - } - } - - LayoutDeviceIntRect r1, r2; - nsView* v1; - nsView* v2; - for (auto kids1Iter = kids1.begin(), kids2Iter = kids2.begin();; - ++kids1Iter, ++kids2Iter) { - nsIFrame* k1 = *kids1Iter; - nsIFrame* k2 = *kids2Iter; - if (((nullptr == k1) && (nullptr != k2)) || - ((nullptr != k1) && (nullptr == k2))) { - ok = false; - LogVerifyMessage(k1, k2, "child lists are different\n"); - break; - } else if (nullptr != k1) { - // Verify that the frames are the same size - if (!k1->GetRect().IsEqualInterior(k2->GetRect())) { - ok = false; - LogVerifyMessage(k1, k2, "(frame rects)", k1->GetRect(), - k2->GetRect()); - } - - // Make sure either both have views or neither have views; if they - // do have views, make sure the views are the same size. If the - // views have widgets, make sure they both do or neither does. If - // they do, make sure the widgets are the same size. - v1 = k1->GetView(); - v2 = k2->GetView(); - if (((nullptr == v1) && (nullptr != v2)) || - ((nullptr != v1) && (nullptr == v2))) { - ok = false; - LogVerifyMessage(k1, k2, "child views are not matched\n"); - } else if (nullptr != v1) { - if (!v1->GetBounds().IsEqualInterior(v2->GetBounds())) { - LogVerifyMessage(k1, k2, "(view rects)", v1->GetBounds(), - v2->GetBounds()); - } - - nsIWidget* w1 = v1->GetWidget(); - nsIWidget* w2 = v2->GetWidget(); - if (((nullptr == w1) && (nullptr != w2)) || - ((nullptr != w1) && (nullptr == w2))) { - ok = false; - LogVerifyMessage(k1, k2, "child widgets are not matched\n"); - } else if (nullptr != w1) { - r1 = w1->GetBounds(); - r2 = w2->GetBounds(); - if (!r1.IsEqualEdges(r2)) { - LogVerifyMessage(k1, k2, "(widget rects)", r1.ToUnknownRect(), - r2.ToUnknownRect()); - } - } - } - if (!ok && !(VerifyReflowFlags::All & gVerifyReflowFlags)) { - break; - } - - // XXX Should perhaps compare their float managers. - - // Compare the sub-trees too - if (!CompareTrees(aFirstPresContext, k1, aSecondPresContext, k2)) { - ok = false; - if (!(VerifyReflowFlags::All & gVerifyReflowFlags)) { - break; - } - } - } else { - break; - } - } - if (!ok && (!(VerifyReflowFlags::All & gVerifyReflowFlags))) { - break; - } - - ++iterLists1; - ++iterLists2; - const bool lists1Done = iterLists1 == childLists1.end(); - const bool lists2Done = iterLists2 == childLists2.end(); - if (lists1Done != lists2Done || - (!lists1Done && iterLists1->mID != iterLists2->mID)) { - if (!(VerifyReflowFlags::All & gVerifyReflowFlags)) { - ok = false; - } - LogVerifyMessage(kids1.FirstChild(), kids2.FirstChild(), - "child list names are not matched: "); - fprintf(stdout, "%s != %s\n", - !lists1Done ? ChildListName(iterLists1->mID) : "(null)", - !lists2Done ? ChildListName(iterLists2->mID) : "(null)"); - break; - } - } while (ok && iterLists1 != childLists1.end()); - - return ok; -} -#endif - -#if 0 -static nsIFrame* -FindTopFrame(nsIFrame* aRoot) -{ - if (aRoot) { - nsIContent* content = aRoot->GetContent(); - if (content) { - nsAtom* tag; - content->GetTag(tag); - if (nullptr != tag) { - NS_RELEASE(tag); - return aRoot; - } - } - - // Try one of the children - for (nsIFrame* kid : aRoot->PrincipalChildList()) { - nsIFrame* result = FindTopFrame(kid); - if (nullptr != result) { - return result; - } - } - } - return nullptr; -} -#endif - #ifdef DEBUG - -// After an incremental reflow, we verify the correctness by doing a -// full reflow into a fresh frame tree. -bool PresShell::VerifyIncrementalReflow() { - if (VerifyReflowFlags::Noisy & gVerifyReflowFlags) { - printf("Building Verification Tree...\n"); - } - - // Create a presentation context to view the new frame tree - auto cx = MakeRefPtr<nsRootPresContext>( - mDocument, mPresContext->IsPaginated() - ? nsPresContext::eContext_PrintPreview - : nsPresContext::eContext_Galley); - - nsDeviceContext* dc = mPresContext->DeviceContext(); - nsresult rv = cx->Init(dc); - NS_ENSURE_SUCCESS(rv, false); - - // Get our scrolling preference - nsView* rootView = mViewManager->GetRootView(); - NS_ENSURE_TRUE(rootView->HasWidget(), false); - - // Create a new view manager. - auto vm = MakeRefPtr<nsViewManager>(dc); - - // Create a child window of the parent that is our "root view/window" - // Create a view - nsRect tbounds = mPresContext->GetVisibleArea(); - nsView* view = vm->CreateView(tbounds, nullptr); - NS_ENSURE_TRUE(view, false); - - // Setup hierarchical relationship in view manager - vm->SetRootView(view); - - // Make the new presentation context the same size as our - // presentation context. - cx->SetVisibleArea(mPresContext->GetVisibleArea()); - - RefPtr<PresShell> presShell = mDocument->CreatePresShell(cx, vm); - NS_ENSURE_TRUE(presShell, false); - - // Note that after we create the shell, we must make sure to destroy it - presShell->SetVerifyReflowEnable( - false); // turn off verify reflow while we're - // reflowing the test frame tree - vm->SetPresShell(presShell); - { - nsAutoCauseReflowNotifier crNotifier(this); - presShell->Initialize(); - } - presShell->FlushPendingNotifications(FlushType::Layout); - presShell->SetVerifyReflowEnable( - true); // turn on verify reflow again now that - // we're done reflowing the test frame tree - // Force the non-primary presshell to unsuppress; it doesn't want to normally - // because it thinks it's hidden - presShell->mPaintingSuppressed = false; - if (VerifyReflowFlags::Noisy & gVerifyReflowFlags) { - printf("Verification Tree built, comparing...\n"); - } - - // Now that the document has been reflowed, use its frame tree to - // compare against our frame tree. - nsIFrame* root1 = mFrameConstructor->GetRootFrame(); - nsIFrame* root2 = presShell->GetRootFrame(); - bool ok = CompareTrees(mPresContext, root1, cx, root2); - if (!ok && (VerifyReflowFlags::Noisy & gVerifyReflowFlags)) { - printf("Verify reflow failed, primary tree:\n"); - root1->List(stdout); - printf("Verification tree:\n"); - root2->List(stdout); - } - -# if 0 - // Sample code for dumping page to png - // XXX Needs to be made more flexible - if (!ok) { - nsString stra; - static int num = 0; - stra.AppendLiteral("C:\\mozilla\\mozilla\\debug\\filea"); - stra.AppendInt(num); - stra.AppendLiteral(".png"); - gfxUtils::WriteAsPNG(presShell, stra); - nsString strb; - strb.AppendLiteral("C:\\mozilla\\mozilla\\debug\\fileb"); - strb.AppendInt(num); - strb.AppendLiteral(".png"); - gfxUtils::WriteAsPNG(presShell, strb); - ++num; - } -# endif - - presShell->EndObservingDocument(); - presShell->Destroy(); - if (VerifyReflowFlags::Noisy & gVerifyReflowFlags) { - printf("Finished Verifying Reflow...\n"); - } - - return ok; -} - // Layout debugging hooks void PresShell::ListComputedStyles(FILE* out, int32_t aIndent) { nsIFrame* rootFrame = GetRootFrame(); diff --git a/layout/base/PresShell.h b/layout/base/PresShell.h @@ -740,18 +740,6 @@ class PresShell final : public nsStubDocumentObserver, */ MOZ_CAN_RUN_SCRIPT void ReconstructFrames(); - /** - * See if reflow verification is enabled. To enable reflow verification add - * "verifyreflow:1" to your MOZ_LOG environment variable (any non-zero - * debug level will work). Or, call SetVerifyReflowEnable with true. - */ - static bool GetVerifyReflowEnable(); - - /** - * Set the verify-reflow enable flag. - */ - static void SetVerifyReflowEnable(bool aEnabled); - nsIFrame* GetAbsoluteContainingBlock(nsIFrame* aFrame); // https://drafts.csswg.org/css-anchor-position-1/#target @@ -3182,11 +3170,7 @@ class PresShell final : public nsStubDocumentObserver, VisibleFrames mApproximatelyVisibleFrames; #ifdef DEBUG - MOZ_CAN_RUN_SCRIPT_BOUNDARY bool VerifyIncrementalReflow(); - MOZ_CAN_RUN_SCRIPT_BOUNDARY void DoVerifyReflow(); void VerifyHasDirtyRootAncestor(nsIFrame* aFrame); - - bool mInVerifyReflow = false; // The reflow root under which we're currently reflowing. Null when // not in reflow. nsIFrame* mCurrentReflowRoot = nullptr;