Bug 934995, Speed up querySelectorAll by doing less allocations, r=bz

--HG--
extra : rebase_source : 757985381b6413257ef2bf82e7602fc6b0298545
This commit is contained in:
Olli Pettay 2013-11-07 21:59:48 +02:00
Родитель 4a207df851
Коммит a322b7c183
2 изменённых файлов: 26 добавлений и 5 удалений

Просмотреть файл

@ -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();
}