Bug 1290218 Part 2: Uplift mInner pointer from CSSStyleSheetInner into StyleSheetInfo. draft
authorBrad Werth <bwerth@mozilla.com>
Mon, 06 Feb 2017 11:37:39 -0800
changeset 480741 7d7246aa3ee347209761ffd51eb279819c52754c
parent 480740 3fb60f69f3ceb4d47f81ab0b4f485b2d3bdfca0d
child 480742 b5e6576befc4aa94699fd3b6c84fb39b32311a59
push id44647
push userbwerth@mozilla.com
push dateWed, 08 Feb 2017 21:49:09 +0000
bugs1290218
milestone54.0a1
Bug 1290218 Part 2: Uplift mInner pointer from CSSStyleSheetInner into StyleSheetInfo. MozReview-Commit-ID: K6FbTN1r4Qg
layout/style/CSSStyleSheet.cpp
layout/style/CSSStyleSheet.h
layout/style/StyleSheet.cpp
layout/style/StyleSheet.h
layout/style/nsCSSRuleProcessor.cpp
--- a/layout/style/CSSStyleSheet.cpp
+++ b/layout/style/CSSStyleSheet.cpp
@@ -213,18 +213,19 @@ 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);
+    CSSStyleSheetInner* inner = static_cast<CSSStyleSheetInner*>(s->mInner);
+    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 +398,38 @@ 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 = aCopy.mInner;
 
-  mInner->AddSheet(this);
+  CSSStyleSheetInner* inner = static_cast<CSSStyleSheetInner*>(mInner);
+  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);
+  CSSStyleSheetInner* inner = static_cast<CSSStyleSheetInner*>(mInner);
+  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 +446,23 @@ 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) {
+  CSSStyleSheetInner* inner = static_cast<CSSStyleSheetInner*>(mInner);
+  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 +482,29 @@ 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) {
+  CSSStyleSheetInner* inner = static_cast<CSSStyleSheetInner*>(mInner);
+  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 +630,62 @@ CSSStyleSheet::FindOwningWindowInnerID()
 }
 
 void
 CSSStyleSheet::AppendStyleRule(css::Rule* aRule)
 {
   NS_PRECONDITION(nullptr != aRule, "null arg");
 
   WillDirty();
-  mInner->mOrderedRules.AppendObject(aRule);
+  CSSStyleSheetInner* inner = static_cast<CSSStyleSheetInner*>(mInner);
+  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();
+  CSSStyleSheetInner* inner = static_cast<CSSStyleSheetInner*>(mInner);
+  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);
+  CSSStyleSheetInner* inner = static_cast<CSSStyleSheetInner*>(mInner);
+  return inner->mOrderedRules.SafeObjectAt(aIndex);
 }
 
 void
 CSSStyleSheet::EnsureUniqueInner()
 {
   mDirty = true;
 
-  MOZ_ASSERT(mInner->mSheets.Length() != 0,
+  CSSStyleSheetInner* inner = static_cast<CSSStyleSheetInner*>(mInner);
+  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 +728,18 @@ 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);
+  CSSStyleSheetInner* inner = static_cast<CSSStyleSheetInner*>(mInner);
+  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 +785,23 @@ 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();
+  CSSStyleSheetInner* inner = static_cast<CSSStyleSheetInner*>(mInner);
+  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 +829,24 @@ 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())) {
+
+  CSSStyleSheetInner* inner = static_cast<CSSStyleSheetInner*>(mInner);
+  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 +862,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 +893,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 +912,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 +947,32 @@ 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())) {
+  CSSStyleSheetInner* inner = static_cast<CSSStyleSheetInner*>(mInner);
+  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);
     }
   }
 }
@@ -1106,22 +1119,24 @@ CSSStyleSheet::ReparseSheet(const nsAStr
   } else {
     loader = new css::Loader(StyleBackendType::Gecko);
   }
 
   mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, true);
 
   WillDirty();
 
+  CSSStyleSheetInner* inner = static_cast<CSSStyleSheetInner*>(mInner);
+
   // 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 +1155,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 +1173,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 static_cast<CSSStyleSheetInner*>(mInner)->mNameSpaceMap;
+  }
 
   already_AddRefed<CSSStyleSheet> Clone(CSSStyleSheet* aCloneParent,
                                         css::ImportRule* aCloneOwnerRule,
                                         nsIDocument* aCloneDocument,
                                         nsINode* aCloneOwningNode) const;
 
   bool IsModified() const final override { return mDirty; }
 
@@ -223,18 +225,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(nullptr)
 {
   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,18 @@ nsCSSRuleProcessor::CascadeSheet(CSSStyl
 
     StyleSheet* child = aSheet->GetFirstChild();
     while (child) {
       CascadeSheet(child->AsGecko(), aData);
 
       child = child->mNext;
     }
 
-    if (!aSheet->mInner->mOrderedRules.EnumerateForwards(CascadeRuleEnumFunc,
+    CSSStyleSheetInner* inner = static_cast<CSSStyleSheetInner*>(aSheet->mInner);
+    if (!inner->mOrderedRules.EnumerateForwards(CascadeRuleEnumFunc,
                                                          aData))
       return false;
   }
   return true;
 }
 
 static int CompareWeightData(const void* aArg1, const void* aArg2,
                              void* closure)