From 9279153af8634f69e8e29385617ef9e7dca70793 Mon Sep 17 00:00:00 2001 From: FranklinDM Date: Tue, 26 Mar 2024 01:48:18 +0800 Subject: [PATCH] Issue #2112 - Part 14: Remove style context source and use rule node directly Based on reverting bug 1260310. --- layout/style/StyleContextSource.h | 99 ------------------------------- layout/style/moz.build | 1 - layout/style/nsStyleContext.cpp | 85 +++++++++++--------------- layout/style/nsStyleContext.h | 54 +++++++---------- 4 files changed, 54 insertions(+), 185 deletions(-) delete mode 100644 layout/style/StyleContextSource.h diff --git a/layout/style/StyleContextSource.h b/layout/style/StyleContextSource.h deleted file mode 100644 index 9af2ebe074..0000000000 --- a/layout/style/StyleContextSource.h +++ /dev/null @@ -1,99 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_StyleContextSource_h -#define mozilla_StyleContextSource_h - -#include "nsRuleNode.h" - -namespace mozilla { - -// Temporary holder of Gecko Rule Nodes. -// TODO: This struct is marked for removal. -// -// The rule node is the node in the lexicographic tree of rule nodes -// (the "rule tree") that indicates which style rules are used to -// compute the style data, and in what cascading order. The least -// specific rule matched is the one whose rule node is a child of the -// root of the rule tree, and the most specific rule matched is the -// |mRule| member of the rule node. - -// Underlying pointer without any strong ownership semantics. -struct NonOwningStyleContextSource -{ - MOZ_IMPLICIT NonOwningStyleContextSource(nsRuleNode* aRuleNode) - : mBits(reinterpret_cast(aRuleNode)) {} - - bool operator==(const NonOwningStyleContextSource& aOther) const { - return mBits == aOther.mBits; - } - bool operator!=(const NonOwningStyleContextSource& aOther) const { - return !(*this == aOther); - } - - bool IsNull() const { return !mBits; } - - nsRuleNode* AsGeckoRuleNode() const { - return reinterpret_cast(mBits); - } - - bool MatchesNoRules() const { - return AsGeckoRuleNode()->IsRoot(); - } - -private: - uintptr_t mBits; -}; - -// Higher-level struct that owns a strong reference to the source. The source -// is never null. -struct OwningStyleContextSource -{ - explicit OwningStyleContextSource(already_AddRefed aRuleNode) - : mRaw(aRuleNode.take()) - { - MOZ_COUNT_CTOR(OwningStyleContextSource); - MOZ_ASSERT(!mRaw.IsNull()); - }; - - OwningStyleContextSource(OwningStyleContextSource&& aOther) - : mRaw(aOther.mRaw) - { - MOZ_COUNT_CTOR(OwningStyleContextSource); - aOther.mRaw = nullptr; - } - - OwningStyleContextSource& operator=(OwningStyleContextSource&) = delete; - OwningStyleContextSource(OwningStyleContextSource&) = delete; - - ~OwningStyleContextSource() { - MOZ_COUNT_DTOR(OwningStyleContextSource); - if (mRaw.IsNull()) { - // We must have invoked the move constructor. - } else { - RefPtr releaseme = dont_AddRef(AsGeckoRuleNode()); - } - } - - bool operator==(const OwningStyleContextSource& aOther) const { - return mRaw == aOther.mRaw; - } - bool operator!=(const OwningStyleContextSource& aOther) const { - return !(*this == aOther); - } - bool IsNull() const { return mRaw.IsNull(); } - - NonOwningStyleContextSource AsRaw() const { return mRaw; } - nsRuleNode* AsGeckoRuleNode() const { return mRaw.AsGeckoRuleNode(); } - - bool MatchesNoRules() const { return mRaw.MatchesNoRules(); } - -private: - NonOwningStyleContextSource mRaw; -}; - -} // namespace mozilla - -#endif // mozilla_StyleContextSource_h diff --git a/layout/style/moz.build b/layout/style/moz.build index ce97516d29..7595212966 100644 --- a/layout/style/moz.build +++ b/layout/style/moz.build @@ -90,7 +90,6 @@ EXPORTS.mozilla += [ 'SheetType.h', 'StyleAnimationValue.h', 'StyleComplexColor.h', - 'StyleContextSource.h', 'StyleSetHandle.h', 'StyleSetHandleInlines.h', 'StyleSheet.h', diff --git a/layout/style/nsStyleContext.cpp b/layout/style/nsStyleContext.cpp index 2ea1d5a875..6fd271667b 100644 --- a/layout/style/nsStyleContext.cpp +++ b/layout/style/nsStyleContext.cpp @@ -76,14 +76,15 @@ static bool sExpensiveStyleStructAssertionsEnabled; #endif nsStyleContext::nsStyleContext(nsStyleContext* aParent, - OwningStyleContextSource&& aSource, nsIAtom* aPseudoTag, - CSSPseudoElementType aPseudoType) + CSSPseudoElementType aPseudoType, + nsRuleNode* aRuleNode, + bool aSkipParentDisplayBasedStyleFixup) : mParent(aParent) , mChild(nullptr) , mEmptyChild(nullptr) , mPseudoTag(aPseudoTag) - , mSource(Move(aSource)) + , mRuleNode(aRuleNode) , mCachedResetData(nullptr) , mBits(((uint64_t)aPseudoType) << NS_STYLE_CONTEXT_TYPE_SHIFT) , mRefCnt(0) @@ -93,43 +94,14 @@ nsStyleContext::nsStyleContext(nsStyleContext* aParent, #endif { MOZ_COUNT_CTOR(nsStyleContext); -} -nsStyleContext::nsStyleContext(nsStyleContext* aParent, - nsIAtom* aPseudoTag, - CSSPseudoElementType aPseudoType, - already_AddRefed aRuleNode, - bool aSkipParentDisplayBasedStyleFixup) - : nsStyleContext(aParent, OwningStyleContextSource(Move(aRuleNode)), - aPseudoTag, aPseudoType) -{ - if (aParent) { -#ifdef DEBUG - nsRuleNode *r1 = mParent->RuleNode(), *r2 = mSource.AsGeckoRuleNode(); - while (r1->GetParent()) - r1 = r1->GetParent(); - while (r2->GetParent()) - r2 = r2->GetParent(); - NS_ASSERTION(r1 == r2, "must be in the same rule tree as parent"); -#endif - } else { - PresContext()->PresShell()->StyleSet()->RootStyleContextAdded(); - } - - mSource.AsGeckoRuleNode()->SetUsedDirectly(); // before ApplyStyleFixups()! - FinishConstruction(aSkipParentDisplayBasedStyleFixup); -} - -void -nsStyleContext::FinishConstruction(bool aSkipParentDisplayBasedStyleFixup) -{ // This check has to be done "backward", because if it were written the // more natural way it wouldn't fail even when it needed to. static_assert((UINT64_MAX >> NS_STYLE_CONTEXT_TYPE_SHIFT) >= static_cast( CSSPseudoElementType::MAX), "pseudo element bits no longer fit in a uint64_t"); - MOZ_ASSERT(!mSource.IsNull()); + MOZ_ASSERT(aRuleNode); #ifdef DEBUG static_assert(MOZ_ARRAY_LENGTH(nsStyleContext::sDependencyTable) @@ -141,8 +113,20 @@ nsStyleContext::FinishConstruction(bool aSkipParentDisplayBasedStyleFixup) mPrevSibling = this; if (mParent) { mParent->AddChild(this); +#ifdef DEBUG + nsRuleNode *r1 = mParent->RuleNode(), *r2 = aRuleNode; + while (r1->GetParent()) + r1 = r1->GetParent(); + while (r2->GetParent()) + r2 = r2->GetParent(); + NS_ASSERTION(r1 == r2, "must be in the same rule tree as parent"); +#endif + } else { + PresContext()->PresShell()->StyleSet()->RootStyleContextAdded(); } + mRuleNode->SetUsedDirectly(); // before ApplyStyleFixups()! + SetStyleBits(); ApplyStyleFixups(aSkipParentDisplayBasedStyleFixup); @@ -291,7 +275,7 @@ void nsStyleContext::AddChild(nsStyleContext* aChild) aChild->mNextSibling == aChild, "child already in a child list"); - nsStyleContext **listPtr = aChild->mSource.MatchesNoRules() ? &mEmptyChild : &mChild; + nsStyleContext **listPtr = aChild->mRuleNode->IsRoot() ? &mEmptyChild : &mChild; // Explicitly dereference listPtr so that compiler doesn't have to know that mNextSibling // etc. don't alias with what ever listPtr points at. nsStyleContext *list = *listPtr; @@ -311,7 +295,7 @@ void nsStyleContext::RemoveChild(nsStyleContext* aChild) { NS_PRECONDITION(nullptr != aChild && this == aChild->mParent, "bad argument"); - nsStyleContext **list = aChild->mSource.MatchesNoRules() ? &mEmptyChild : &mChild; + nsStyleContext **list = aChild->mRuleNode->IsRoot() ? &mEmptyChild : &mChild; if (aChild->mPrevSibling != aChild) { // has siblings if ((*list) == aChild) { @@ -377,27 +361,27 @@ nsStyleContext::MoveTo(nsStyleContext* aNewParent) already_AddRefed nsStyleContext::FindChildWithRules(const nsIAtom* aPseudoTag, - NonOwningStyleContextSource aSource, - NonOwningStyleContextSource aSourceIfVisited, + nsRuleNode* aRuleNode, + nsRuleNode* aRulesIfVisited, bool aRelevantLinkVisited) { uint32_t threshold = 10; // The # of siblings we're willing to examine // before just giving this whole thing up. RefPtr result; - nsStyleContext *list = aSource.MatchesNoRules() ? mEmptyChild : mChild; + nsStyleContext *list = aRuleNode->IsRoot() ? mEmptyChild : mChild; if (list) { nsStyleContext *child = list; do { - if (child->mSource.AsRaw() == aSource && + if (child->mRuleNode == aRuleNode && child->mPseudoTag == aPseudoTag && !child->IsStyleIfVisited() && child->RelevantLinkVisited() == aRelevantLinkVisited) { bool match = false; - if (!aSourceIfVisited.IsNull()) { + if (aRulesIfVisited) { match = child->GetStyleIfVisited() && - child->GetStyleIfVisited()->mSource.AsRaw() == aSourceIfVisited; + child->GetStyleIfVisited()->mRuleNode == aRulesIfVisited; } else { match = !child->GetStyleIfVisited(); } @@ -430,9 +414,8 @@ const void* nsStyleContext::StyleData(nsStyleStructID aSID) const void* cachedData = GetCachedStyleData(aSID); if (cachedData) return cachedData; // We have computed data stored on this node in the context tree. - // Our style source will take care of it for us. - const void* newData; - newData = mSource.AsGeckoRuleNode()->GetStyleData(aSID, this, true); + // Our rule node will take care of it for us. + const void* newData = mRuleNode->GetStyleData(aSID, this, true); if (!nsCachedStyleData::IsReset(aSID)) { // always cache inherited data on the style context; the rule // node set the bit in mBits for us if needed. @@ -918,12 +901,12 @@ nsStyleContext::CalcStyleDifferenceInternal(StyleContextLike* aNewContext, // we could later get a small change in one of those structs that we // don't want to miss. - // If our sources are the same, then any differences in style data + // If our rule nodes are the same, then any differences in style data // are already accounted for by differences on ancestors. We know // this because CalcStyleDifference is always called on two style // contexts that point to the same element, so we know that our // position in the style context tree is the same and our position in - // the rule node tree (if applicable) is also the same. + // the rule node tree is also the same. // However, if there were noninherited style change hints on the // parent, we might produce these same noninherited hints on this // style context's frame due to 'inherit' values, so we do need to @@ -931,13 +914,13 @@ nsStyleContext::CalcStyleDifferenceInternal(StyleContextLike* aNewContext, // (Things like 'em' units are handled by the change hint produced // by font-size changing, so we don't need to worry about them like // we worry about 'inherit' values.) - bool compare = StyleSource() != aNewContext->StyleSource(); + bool compare = mRuleNode != aNewContext->mRuleNode; DebugOnly structsFound = 0; // If we had any change in variable values, then we'll need to examine // all of the other style structs too, even if the new style context has - // the same source as the old one. + // the same rule node as the old one. const nsStyleVariables* thisVariables = PeekStyleVariables(); if (thisVariables) { structsFound |= NS_STYLE_INHERIT_BIT(Variables); @@ -1249,10 +1232,10 @@ void nsStyleContext::List(FILE* out, int32_t aIndent, bool aListDescendants) str.Append(' '); } - if (mSource.AsGeckoRuleNode()) { + if (mRuleNode) { fprintf_stderr(out, "%s{\n", str.get()); str.Truncate(); - nsRuleNode* ruleNode = mSource.AsGeckoRuleNode(); + nsRuleNode* ruleNode = mRuleNode; while (ruleNode) { nsIStyleRule *styleRule = ruleNode->GetRule(); if (styleRule) { @@ -1325,7 +1308,7 @@ NS_NewStyleContext(nsStyleContext* aParentContext, RefPtr node = aRuleNode; RefPtr context = new (aRuleNode->PresContext()) - nsStyleContext(aParentContext, aPseudoTag, aPseudoType, node.forget(), + nsStyleContext(aParentContext, aPseudoTag, aPseudoType, aRuleNode, aSkipParentDisplayBasedStyleFixup); return context.forget(); } diff --git a/layout/style/nsStyleContext.h b/layout/style/nsStyleContext.h index 995f4ee5a0..18fcd3f47a 100644 --- a/layout/style/nsStyleContext.h +++ b/layout/style/nsStyleContext.h @@ -10,9 +10,9 @@ #include "mozilla/Assertions.h" #include "mozilla/RestyleLogging.h" -#include "mozilla/StyleContextSource.h" #include "nsCSSAnonBoxes.h" #include "nsStyleSet.h" +#include "nsRuleNode.h" class nsIAtom; class nsPresContext; @@ -70,7 +70,7 @@ public: */ nsStyleContext(nsStyleContext* aParent, nsIAtom* aPseudoTag, mozilla::CSSPseudoElementType aPseudoType, - already_AddRefed aRuleNode, + nsRuleNode* aRuleNode, bool aSkipParentDisplayBasedStyleFixup); void* operator new(size_t sz, nsPresContext* aPresContext); @@ -135,9 +135,7 @@ public: return mRefCnt == 1; } - nsPresContext* PresContext() const { - return mSource.AsGeckoRuleNode()->PresContext(); - } + nsPresContext* PresContext() const { return mRuleNode->PresContext(); } nsStyleContext* GetParent() const { return mParent; } @@ -156,14 +154,14 @@ public: // Find, if it already exists *and is easily findable* (i.e., near the // start of the child list), a style context whose: // * GetPseudo() matches aPseudoTag - // * mSource matches aSource - // * !!GetStyleIfVisited() == !!aSourceIfVisited, and, if they're - // non-null, GetStyleIfVisited()->mSource == aSourceIfVisited + // * RuleNode() matches aRules + // * !GetStyleIfVisited() == !aRulesIfVisited, and, if they're + // non-null, GetStyleIfVisited()->RuleNode() == aRulesIfVisited // * RelevantLinkVisited() == aRelevantLinkVisited already_AddRefed FindChildWithRules(const nsIAtom* aPseudoTag, - mozilla::NonOwningStyleContextSource aSource, - mozilla::NonOwningStyleContextSource aSourceIfVisited, + nsRuleNode* aRules, + nsRuleNode* aRulesIfVisited, bool aRelevantLinkVisited); // Does this style context or any of its ancestors have text @@ -289,9 +287,7 @@ public: return mBits & nsCachedStyleData::GetBitForSID(aSID); } - nsRuleNode* RuleNode() { - return mSource.AsGeckoRuleNode(); - } + nsRuleNode* RuleNode() { return mRuleNode; } void AddStyleBit(const uint64_t& aBit) { mBits |= aBit; } @@ -478,21 +474,10 @@ public: return cachedData; } - mozilla::NonOwningStyleContextSource StyleSource() const { return mSource.AsRaw(); } - private: // Private destructor, to discourage deletion outside of Release(): ~nsStyleContext(); - // Delegated Helper constructor. - nsStyleContext(nsStyleContext* aParent, - mozilla::OwningStyleContextSource&& aSource, - nsIAtom* aPseudoTag, - mozilla::CSSPseudoElementType aPseudoType); - - // Helper post-contruct hook. - void FinishConstruction(bool aSkipParentDisplayBasedStyleFixup); - void AddChild(nsStyleContext* aChild); void RemoveChild(nsStyleContext* aChild); @@ -547,9 +532,8 @@ private: } \ /* Have the rulenode deal */ \ AUTO_CHECK_DEPENDENCY(eStyleStruct_##name_); \ - const nsStyle##name_ * newData; \ - newData = mSource.AsGeckoRuleNode()-> \ - GetStyle##name_(this, mBits); \ + const nsStyle##name_ * newData = \ + mRuleNode->GetStyle##name_(this, mBits); \ /* always cache inherited data on the style context; the rule */ \ /* node set the bit in mBits for us if needed. */ \ mCachedInheritedData.mStyleStructs[eStyleStruct_##name_] = \ @@ -568,9 +552,8 @@ private: } \ /* Have the rulenode deal */ \ AUTO_CHECK_DEPENDENCY(eStyleStruct_##name_); \ - const nsStyle##name_ * newData; \ - newData = mSource.AsGeckoRuleNode()-> \ - GetStyle##name_(this); \ + const nsStyle##name_ * newData = \ + mRuleNode->GetStyle##name_(this); \ return newData; \ } #include "nsStyleStructList.h" @@ -616,10 +599,13 @@ private: // the relevant atom. nsCOMPtr mPseudoTag; - // The source for our style data, a nsRuleNode struct. - // This never changes after construction, except - // when it's released and nulled out during teardown. - const mozilla::OwningStyleContextSource mSource; + // The rule node is the node in the lexicographic tree of rule nodes + // (the "rule tree") that indicates which style rules are used to + // compute the style data, and in what cascading order. The least + // specific rule matched is the one whose rule node is a child of the + // root of the rule tree, and the most specific rule matched is the + // |mRule| member of |mRuleNode|. + const RefPtr mRuleNode; // mCachedInheritedData and mCachedResetData point to both structs that // are owned by this style context and structs that are owned by one of