зеркало из https://github.com/mozilla/gecko-dev.git
Bug 934995, Speed up querySelectorAll by doing less allocations, r=bz
--HG-- extra : rebase_source : 757985381b6413257ef2bf82e7602fc6b0298545
This commit is contained in:
Родитель
4a207df851
Коммит
a322b7c183
|
@ -95,6 +95,10 @@ public:
|
|||
virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> scope)
|
||||
MOZ_OVERRIDE = 0;
|
||||
|
||||
void SetCapacity(uint32_t aCapacity)
|
||||
{
|
||||
mElements.SetCapacity(aCapacity);
|
||||
}
|
||||
protected:
|
||||
/**
|
||||
* To be called from non-destructor locations (e.g. unlink) that want to
|
||||
|
|
|
@ -2337,8 +2337,8 @@ AddScopeElements(TreeMatchContext& aMatchContext,
|
|||
// Actually find elements matching aSelectorList (which must not be
|
||||
// null) and which are descendants of aRoot and put them in aList. If
|
||||
// onlyFirstMatch, then stop once the first one is found.
|
||||
template<bool onlyFirstMatch, class T>
|
||||
inline static nsresult
|
||||
template<bool onlyFirstMatch, class Collector, class T>
|
||||
MOZ_ALWAYS_INLINE static nsresult
|
||||
FindMatchingElements(nsINode* aRoot, const nsAString& aSelector, T &aList)
|
||||
{
|
||||
|
||||
|
@ -2424,6 +2424,7 @@ FindMatchingElements(nsINode* aRoot, const nsAString& aSelector, T &aList)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
Collector results;
|
||||
for (nsIContent* cur = aRoot->GetFirstChild();
|
||||
cur;
|
||||
cur = cur->GetNextNode(aRoot)) {
|
||||
|
@ -2431,10 +2432,19 @@ FindMatchingElements(nsINode* aRoot, const nsAString& aSelector, T &aList)
|
|||
nsCSSRuleProcessor::SelectorListMatches(cur->AsElement(),
|
||||
matchingContext,
|
||||
selectorList)) {
|
||||
aList.AppendElement(cur->AsElement());
|
||||
if (onlyFirstMatch) {
|
||||
aList.AppendElement(cur->AsElement());
|
||||
return NS_OK;
|
||||
}
|
||||
results.AppendElement(cur->AsElement());
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t len = results.Length();
|
||||
if (len) {
|
||||
aList.SetCapacity(len);
|
||||
for (uint32_t i = 0; i < len; ++i) {
|
||||
aList.AppendElement(results.ElementAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2447,6 +2457,10 @@ struct ElementHolder {
|
|||
NS_ABORT_IF_FALSE(!mElement, "Should only get one element");
|
||||
mElement = aElement;
|
||||
}
|
||||
void SetCapacity(uint32_t aCapacity) { MOZ_CRASH("Don't call me!"); }
|
||||
uint32_t Length() { return 0; }
|
||||
Element* ElementAt(uint32_t aIndex) { return nullptr; }
|
||||
|
||||
Element* mElement;
|
||||
};
|
||||
|
||||
|
@ -2454,7 +2468,7 @@ Element*
|
|||
nsINode::QuerySelector(const nsAString& aSelector, ErrorResult& aResult)
|
||||
{
|
||||
ElementHolder holder;
|
||||
aResult = FindMatchingElements<true>(this, aSelector, holder);
|
||||
aResult = FindMatchingElements<true, ElementHolder>(this, aSelector, holder);
|
||||
|
||||
return holder.mElement;
|
||||
}
|
||||
|
@ -2464,7 +2478,10 @@ nsINode::QuerySelectorAll(const nsAString& aSelector, ErrorResult& aResult)
|
|||
{
|
||||
nsRefPtr<nsSimpleContentList> contentList = new nsSimpleContentList(this);
|
||||
|
||||
aResult = FindMatchingElements<false>(this, aSelector, *contentList);
|
||||
aResult =
|
||||
FindMatchingElements<false, nsAutoTArray<Element*, 128>>(this,
|
||||
aSelector,
|
||||
*contentList);
|
||||
|
||||
return contentList.forget();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче