Bug 1290218 Part 2: Uplift mInner pointer from CSSStyleSheetInner into StyleSheetInfo.
MozReview-Commit-ID: K6FbTN1r4Qg
--- a/layout/style/CSSStyleSheet.cpp
+++ b/layout/style/CSSStyleSheet.cpp
@@ -213,18 +213,18 @@ CSSStyleSheet::SizeOfIncludingThis(Mallo
while (s) {
// Each inner can be shared by multiple sheets. So we only count the inner
// if this sheet is the last one in the list of those sharing it. As a
// result, the last such sheet takes all the blame for the memory
// consumption of the inner, which isn't ideal but it's better than
// double-counting the inner. We use last instead of first since the first
// sheet may be held in the nsXULPrototypeCache and not used in a window at
// all.
- if (s->mInner->mSheets.LastElement() == s) {
- n += s->mInner->SizeOfIncludingThis(aMallocSizeOf);
+ if (Inner()->mSheets.LastElement() == s) {
+ n += Inner()->SizeOfIncludingThis(aMallocSizeOf);
}
// Measurement of the following members may be added later if DMD finds it
// is worthwhile:
// - s->mRuleCollection
// - s->mRuleProcessors
//
// The following members are not measured:
@@ -397,36 +397,35 @@ CSSStyleSheet::CSSStyleSheet(const CSSSt
css::ImportRule* aOwnerRuleToUse,
nsIDocument* aDocumentToUse,
nsINode* aOwningNodeToUse)
: StyleSheet(aCopy, aDocumentToUse, aOwningNodeToUse),
mOwnerRule(aOwnerRuleToUse),
mDirty(aCopy.mDirty),
mInRuleProcessorCache(false),
mScopeElement(nullptr),
- mInner(aCopy.mInner),
mRuleProcessors(nullptr)
{
mParent = aParentToUse;
- mInner->AddSheet(this);
+ Inner()->AddSheet(this);
if (mDirty) { // CSSOM's been there, force full copy now
NS_ASSERTION(mInner->mComplete, "Why have rules been accessed on an incomplete sheet?");
// FIXME: handle failure?
EnsureUniqueInner();
}
}
CSSStyleSheet::~CSSStyleSheet()
{
UnparentChildren();
DropRuleCollection();
- mInner->RemoveSheet(this);
+ Inner()->RemoveSheet(this);
// XXX The document reference is not reference counted and should
// not be released. The document will let us know when it is going
// away.
if (mRuleProcessors) {
NS_ASSERTION(mRuleProcessors->Length() == 0, "destructing sheet with rule processor reference");
delete mRuleProcessors; // weak refs, should be empty here anyway
}
if (mInRuleProcessorCache) {
@@ -443,22 +442,22 @@ CSSStyleSheet::DropRuleCollection()
}
}
void
CSSStyleSheet::UnlinkInner()
{
// We can only have a cycle through our inner if we have a unique inner,
// because otherwise there are no JS wrappers for anything in the inner.
- if (mInner->mSheets.Length() != 1) {
+ if (Inner()->mSheets.Length() != 1) {
return;
}
- mInner->mOrderedRules.EnumerateForwards(SetStyleSheetReference, nullptr);
- mInner->mOrderedRules.Clear();
+ Inner()->mOrderedRules.EnumerateForwards(SetStyleSheetReference, nullptr);
+ Inner()->mOrderedRules.Clear();
// Have to be a bit careful with child sheets, because we want to
// drop their mNext pointers and null out their mParent and
// mDocument, but don't want to work with deleted objects. And we
// don't want to do any addrefing in the process, just to make sure
// we don't confuse the cycle collector (though on the face of it,
// addref/release pairs during unlink should probably be ok).
RefPtr<StyleSheet> child;
@@ -478,28 +477,28 @@ CSSStyleSheet::UnlinkInner()
}
}
void
CSSStyleSheet::TraverseInner(nsCycleCollectionTraversalCallback &cb)
{
// We can only have a cycle through our inner if we have a unique inner,
// because otherwise there are no JS wrappers for anything in the inner.
- if (mInner->mSheets.Length() != 1) {
+ if (Inner()->mSheets.Length() != 1) {
return;
}
StyleSheet* childSheet = GetFirstChild();
while (childSheet) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "child sheet");
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMCSSStyleSheet*, childSheet));
childSheet = childSheet->mNext;
}
- const nsCOMArray<css::Rule>& rules = mInner->mOrderedRules;
+ const nsCOMArray<css::Rule>& rules = Inner()->mOrderedRules;
for (int32_t i = 0, count = rules.Count(); i < count; ++i) {
if (!rules[i]->IsCCLeaf()) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mOrderedRules[i]");
cb.NoteXPCOMChild(rules[i]);
}
}
}
@@ -625,58 +624,58 @@ CSSStyleSheet::FindOwningWindowInnerID()
}
void
CSSStyleSheet::AppendStyleRule(css::Rule* aRule)
{
NS_PRECONDITION(nullptr != aRule, "null arg");
WillDirty();
- mInner->mOrderedRules.AppendObject(aRule);
+ Inner()->mOrderedRules.AppendObject(aRule);
aRule->SetStyleSheet(this);
DidDirty();
if (css::Rule::NAMESPACE_RULE == aRule->GetType()) {
#ifdef DEBUG
nsresult rv =
#endif
RegisterNamespaceRule(aRule);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"RegisterNamespaceRule returned error");
}
}
int32_t
CSSStyleSheet::StyleRuleCount() const
{
- return mInner->mOrderedRules.Count();
+ return Inner()->mOrderedRules.Count();
}
css::Rule*
CSSStyleSheet::GetStyleRuleAt(int32_t aIndex) const
{
// Important: If this function is ever made scriptable, we must add
// a security check here. See GetCssRules below for an example.
- return mInner->mOrderedRules.SafeObjectAt(aIndex);
+ return Inner()->mOrderedRules.SafeObjectAt(aIndex);
}
void
CSSStyleSheet::EnsureUniqueInner()
{
mDirty = true;
- MOZ_ASSERT(mInner->mSheets.Length() != 0,
+ MOZ_ASSERT(Inner()->mSheets.Length() != 0,
"unexpected number of outers");
- if (mInner->mSheets.Length() == 1) {
+ if (Inner()->mSheets.Length() == 1) {
// already unique
return;
}
- CSSStyleSheetInner* clone = mInner->CloneFor(this);
+ CSSStyleSheetInner* clone = Inner()->CloneFor(this);
MOZ_ASSERT(clone);
- mInner->RemoveSheet(this);
+ Inner()->RemoveSheet(this);
mInner = clone;
// otherwise the rule processor has pointers to the old rules
ClearRuleCascades();
// let our containing style sets know that if we call
// nsPresContext::EnsureSafeToHandOutCSSRules we will need to restyle the
// document
@@ -719,17 +718,17 @@ ListRules(const nsCOMArray<css::Rule>& a
}
void
CSSStyleSheet::List(FILE* out, int32_t aIndent) const
{
StyleSheet::List(out, aIndent);
fprintf_stderr(out, "%s", "Rules in source order:\n");
- ListRules(mInner->mOrderedRules, out, aIndent);
+ ListRules(Inner()->mOrderedRules, out, aIndent);
}
#endif
void
CSSStyleSheet::ClearRuleCascades()
{
// We might be in ClearRuleCascades because we had a modification
// to the sheet that resulted in an nsCSSSelector being destroyed.
@@ -775,22 +774,22 @@ CSSStyleSheet::DidDirty()
MOZ_ASSERT(!mInner->mComplete || mDirty,
"caller must have called WillDirty()");
ClearRuleCascades();
}
nsresult
CSSStyleSheet::RegisterNamespaceRule(css::Rule* aRule)
{
- if (!mInner->mNameSpaceMap) {
- nsresult rv = mInner->CreateNamespaceMap();
+ if (!Inner()->mNameSpaceMap) {
+ nsresult rv = Inner()->CreateNamespaceMap();
NS_ENSURE_SUCCESS(rv, rv);
}
- AddNamespaceRuleToMap(aRule, mInner->mNameSpaceMap);
+ AddNamespaceRuleToMap(aRule, Inner()->mNameSpaceMap);
return NS_OK;
}
css::Rule*
CSSStyleSheet::GetDOMOwnerRule() const
{
return mOwnerRule;
}
@@ -818,23 +817,23 @@ RuleHasPendingChildSheet(css::Rule *cssR
uint32_t
CSSStyleSheet::InsertRuleInternal(const nsAString& aRule,
uint32_t aIndex,
ErrorResult& aRv)
{
MOZ_ASSERT(mInner->mComplete);
WillDirty();
-
- if (aIndex > uint32_t(mInner->mOrderedRules.Count())) {
+
+ if (aIndex > uint32_t(Inner()->mOrderedRules.Count())) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return 0;
}
-
- NS_ASSERTION(uint32_t(mInner->mOrderedRules.Count()) <= INT32_MAX,
+
+ NS_ASSERTION(uint32_t(Inner()->mOrderedRules.Count()) <= INT32_MAX,
"Too many style rules!");
// Hold strong ref to the CSSLoader in case the document update
// kills the document
RefPtr<css::Loader> loader;
if (mDocument) {
loader = mDocument->CSSLoader();
NS_ASSERTION(loader, "Document with no CSS loader!");
@@ -850,17 +849,17 @@ CSSStyleSheet::InsertRuleInternal(const
if (NS_WARN_IF(aRv.Failed())) {
return 0;
}
// Hierarchy checking.
int32_t newType = rule->GetType();
// check that we're not inserting before a charset rule
- css::Rule* nextRule = mInner->mOrderedRules.SafeObjectAt(aIndex);
+ css::Rule* nextRule = Inner()->mOrderedRules.SafeObjectAt(aIndex);
if (nextRule) {
int32_t nextType = nextRule->GetType();
if (nextType == css::Rule::CHARSET_RULE) {
aRv.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
return 0;
}
if (nextType == css::Rule::IMPORT_RULE &&
@@ -881,17 +880,17 @@ CSSStyleSheet::InsertRuleInternal(const
if (aIndex != 0) {
// no inserting charset at nonzero position
if (newType == css::Rule::CHARSET_RULE) {
aRv.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
return 0;
}
- css::Rule* prevRule = mInner->mOrderedRules.SafeObjectAt(aIndex - 1);
+ css::Rule* prevRule = Inner()->mOrderedRules.SafeObjectAt(aIndex - 1);
int32_t prevType = prevRule->GetType();
if (newType == css::Rule::IMPORT_RULE &&
prevType != css::Rule::CHARSET_RULE &&
prevType != css::Rule::IMPORT_RULE) {
aRv.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
return 0;
}
@@ -900,17 +899,17 @@ CSSStyleSheet::InsertRuleInternal(const
prevType != css::Rule::CHARSET_RULE &&
prevType != css::Rule::IMPORT_RULE &&
prevType != css::Rule::NAMESPACE_RULE) {
aRv.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
return 0;
}
}
- if (!mInner->mOrderedRules.InsertObjectAt(rule, aIndex)) {
+ if (!Inner()->mOrderedRules.InsertObjectAt(rule, aIndex)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return 0;
}
DidDirty();
rule->SetStyleSheet(this);
@@ -935,31 +934,31 @@ CSSStyleSheet::InsertRuleInternal(const
return aIndex;
}
void
CSSStyleSheet::DeleteRuleInternal(uint32_t aIndex, ErrorResult& aRv)
{
// XXX TBI: handle @rule types
mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, true);
-
+
WillDirty();
- if (aIndex >= uint32_t(mInner->mOrderedRules.Count())) {
+ if (aIndex >= uint32_t(Inner()->mOrderedRules.Count())) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return;
}
- NS_ASSERTION(uint32_t(mInner->mOrderedRules.Count()) <= INT32_MAX,
+ NS_ASSERTION(uint32_t(Inner()->mOrderedRules.Count()) <= INT32_MAX,
"Too many style rules!");
// Hold a strong ref to the rule so it doesn't die when we RemoveObjectAt
- RefPtr<css::Rule> rule = mInner->mOrderedRules.ObjectAt(aIndex);
+ RefPtr<css::Rule> rule = Inner()->mOrderedRules.ObjectAt(aIndex);
if (rule) {
- mInner->mOrderedRules.RemoveObjectAt(aIndex);
+ Inner()->mOrderedRules.RemoveObjectAt(aIndex);
rule->SetStyleSheet(nullptr);
DidDirty();
if (mDocument) {
mDocument->StyleRuleRemoved(this, rule);
}
}
}
@@ -1109,19 +1108,19 @@ CSSStyleSheet::ReparseSheet(const nsAStr
mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, true);
WillDirty();
// detach existing rules (including child sheets via import rules)
css::LoaderReusableStyleSheets reusableSheets;
int ruleCount;
- while ((ruleCount = mInner->mOrderedRules.Count()) != 0) {
- RefPtr<css::Rule> rule = mInner->mOrderedRules.ObjectAt(ruleCount - 1);
- mInner->mOrderedRules.RemoveObjectAt(ruleCount - 1);
+ while ((ruleCount = Inner()->mOrderedRules.Count()) != 0) {
+ RefPtr<css::Rule> rule = Inner()->mOrderedRules.ObjectAt(ruleCount - 1);
+ Inner()->mOrderedRules.RemoveObjectAt(ruleCount - 1);
rule->SetStyleSheet(nullptr);
if (rule->GetType() == css::Rule::IMPORT_RULE) {
nsCOMPtr<nsIDOMCSSImportRule> importRule(do_QueryInterface(rule));
NS_ASSERTION(importRule, "GetType lied");
nsCOMPtr<nsIDOMCSSStyleSheet> childSheet;
importRule->GetStyleSheet(getter_AddRefs(childSheet));
@@ -1140,17 +1139,17 @@ CSSStyleSheet::ReparseSheet(const nsAStr
NS_ASSERTION(child->mParent == this, "Child sheet is not parented to this!");
StyleSheet* next = child->mNext;
child->mParent = nullptr;
child->mDocument = nullptr;
child->mNext = nullptr;
child = next;
}
SheetInfo().mFirstChild = nullptr;
- mInner->mNameSpaceMap = nullptr;
+ Inner()->mNameSpaceMap = nullptr;
uint32_t lineNumber = 1;
if (mOwningNode) {
nsCOMPtr<nsIStyleSheetLinkingElement> link = do_QueryInterface(mOwningNode);
if (link) {
lineNumber = link->GetLineNumber();
}
}
@@ -1158,18 +1157,18 @@ CSSStyleSheet::ReparseSheet(const nsAStr
nsCSSParser parser(loader, this);
nsresult rv = parser.ParseSheet(aInput, mInner->mSheetURI, mInner->mBaseURI,
mInner->mPrincipal, lineNumber, &reusableSheets);
DidDirty(); // we are always 'dirty' here since we always remove rules first
NS_ENSURE_SUCCESS(rv, rv);
// notify document of all new rules
if (mDocument) {
- for (int32_t index = 0; index < mInner->mOrderedRules.Count(); ++index) {
- RefPtr<css::Rule> rule = mInner->mOrderedRules.ObjectAt(index);
+ for (int32_t index = 0; index < Inner()->mOrderedRules.Count(); ++index) {
+ RefPtr<css::Rule> rule = Inner()->mOrderedRules.ObjectAt(index);
if (rule->GetType() == css::Rule::IMPORT_RULE &&
RuleHasPendingChildSheet(rule)) {
continue; // notify when loaded (see StyleSheetLoaded)
}
mDocument->StyleRuleAdded(this, rule);
}
}
return NS_OK;
--- a/layout/style/CSSStyleSheet.h
+++ b/layout/style/CSSStyleSheet.h
@@ -123,17 +123,19 @@ public:
nsresult DeleteRuleFromGroup(css::GroupRule* aGroup, uint32_t aIndex);
nsresult InsertRuleIntoGroup(const nsAString& aRule, css::GroupRule* aGroup, uint32_t aIndex, uint32_t* _retval);
void SetOwnerRule(css::ImportRule* aOwnerRule) { mOwnerRule = aOwnerRule; /* Not ref counted */ }
css::ImportRule* GetOwnerRule() const { return mOwnerRule; }
// Workaround overloaded-virtual warning in GCC.
using StyleSheet::GetOwnerRule;
- nsXMLNameSpaceMap* GetNameSpaceMap() const { return mInner->mNameSpaceMap; }
+ nsXMLNameSpaceMap* GetNameSpaceMap() const {
+ return Inner()->mNameSpaceMap;
+ }
already_AddRefed<CSSStyleSheet> Clone(CSSStyleSheet* aCloneParent,
css::ImportRule* aCloneOwnerRule,
nsIDocument* aCloneDocument,
nsINode* aCloneOwningNode) const;
bool IsModified() const final { return mDirty; }
@@ -202,16 +204,21 @@ protected:
void ClearRuleCascades();
// Add the namespace mapping from this @namespace rule to our namespace map
nsresult RegisterNamespaceRule(css::Rule* aRule);
// Drop our reference to mRuleCollection
void DropRuleCollection();
+ CSSStyleSheetInner* Inner() const
+ {
+ return static_cast<CSSStyleSheetInner*>(mInner);
+ }
+
// Unlink our inner, if needed, for cycle collection
void UnlinkInner();
// Traverse our inner, if needed, for cycle collection
void TraverseInner(nsCycleCollectionTraversalCallback &);
protected:
// Internal methods which do not have security check and completeness check.
dom::CSSRuleList* GetCssRulesInternal(ErrorResult& aRv);
@@ -223,18 +230,16 @@ protected:
css::ImportRule* mOwnerRule; // weak ref
RefPtr<CSSRuleListImpl> mRuleCollection;
bool mDirty; // has been modified
bool mInRuleProcessorCache;
RefPtr<dom::Element> mScopeElement;
- CSSStyleSheetInner* mInner;
-
AutoTArray<nsCSSRuleProcessor*, 8>* mRuleProcessors;
nsTArray<nsStyleSet*> mStyleSets;
friend class mozilla::StyleSheet;
friend class ::nsCSSRuleProcessor;
};
NS_DEFINE_STATIC_IID_ACCESSOR(CSSStyleSheet, NS_CSS_STYLE_SHEET_IMPL_CID)
--- a/layout/style/StyleSheet.cpp
+++ b/layout/style/StyleSheet.cpp
@@ -21,32 +21,34 @@ namespace mozilla {
StyleSheet::StyleSheet(StyleBackendType aType, css::SheetParsingMode aParsingMode)
: mParent(nullptr)
, mDocument(nullptr)
, mOwningNode(nullptr)
, mParsingMode(aParsingMode)
, mType(aType)
, mDisabled(false)
, mDocumentAssociationMode(NotOwnedByDocument)
+ , mInner(nullptr)
{
}
StyleSheet::StyleSheet(const StyleSheet& aCopy,
nsIDocument* aDocumentToUse,
nsINode* aOwningNodeToUse)
: mParent(nullptr)
, mTitle(aCopy.mTitle)
, mDocument(aDocumentToUse)
, mOwningNode(aOwningNodeToUse)
, mParsingMode(aCopy.mParsingMode)
, mType(aCopy.mType)
, mDisabled(aCopy.mDisabled)
// We only use this constructor during cloning. It's the cloner's
// responsibility to notify us if we end up being owned by a document.
, mDocumentAssociationMode(NotOwnedByDocument)
+ , mInner(aCopy.mInner) // Shallow copy, but concrete subclasses will fix up.
{
if (aCopy.mMedia) {
// XXX This is wrong; we should be keeping @import rules and
// sheets in sync!
mMedia = aCopy.mMedia->Clone();
}
}
--- a/layout/style/StyleSheet.h
+++ b/layout/style/StyleSheet.h
@@ -253,16 +253,20 @@ protected:
const StyleBackendType mType;
bool mDisabled;
// mDocumentAssociationMode determines whether mDocument directly owns us (in
// the sense that if it's known-live then we're known-live). Always
// NotOwnedByDocument when mDocument is null.
DocumentAssociationMode mDocumentAssociationMode;
+ // Core information we get from parsed sheets, which are shared amongst
+ // StyleSheet clones.
+ StyleSheetInfo* mInner;
+
friend class ::nsCSSRuleProcessor;
friend struct mozilla::ChildSheetListBuilder;
// Make CSSStyleSheet and ServoStyleSheet friends so they can access
// protected members of other StyleSheet objects (useful for iterating
// through children).
friend class mozilla::CSSStyleSheet;
friend class mozilla::ServoStyleSheet;
--- a/layout/style/nsCSSRuleProcessor.cpp
+++ b/layout/style/nsCSSRuleProcessor.cpp
@@ -3668,17 +3668,17 @@ nsCSSRuleProcessor::CascadeSheet(CSSStyl
StyleSheet* child = aSheet->GetFirstChild();
while (child) {
CascadeSheet(child->AsGecko(), aData);
child = child->mNext;
}
- if (!aSheet->mInner->mOrderedRules.EnumerateForwards(CascadeRuleEnumFunc,
+ if (!aSheet->Inner()->mOrderedRules.EnumerateForwards(CascadeRuleEnumFunc,
aData))
return false;
}
return true;
}
static int CompareWeightData(const void* aArg1, const void* aArg2,
void* closure)