Bug 1843949 - Preallocate attribute array with the known size from parsing. r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D183809
This commit is contained in:
Markus Stange 2023-09-02 18:46:30 +00:00
Родитель d3e6d914c9
Коммит fe7358f6c8
5 изменённых файлов: 25 добавлений и 4 удалений

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

@ -302,7 +302,16 @@ bool AttrArray::GrowBy(uint32_t aGrowSize) {
capacity = 1u << shift;
}
CheckedUint32 sizeInBytes = capacity.value();
return GrowTo(capacity.value());
}
bool AttrArray::GrowTo(uint32_t aCapacity) {
uint32_t oldCapacity = mImpl ? mImpl->mCapacity : 0;
if (aCapacity <= oldCapacity) {
return true;
}
CheckedUint32 sizeInBytes = aCapacity;
sizeInBytes *= sizeof(InternalAttr);
if (!sizeInBytes.isValid()) {
return false;
@ -314,7 +323,7 @@ bool AttrArray::GrowBy(uint32_t aGrowSize) {
}
MOZ_ASSERT(sizeInBytes.value() ==
Impl::AllocationSizeForAttributes(capacity.value()));
Impl::AllocationSizeForAttributes(aCapacity));
const bool needToInitialize = !mImpl;
Impl* oldImpl = mImpl.release();
@ -332,7 +341,7 @@ bool AttrArray::GrowBy(uint32_t aGrowSize) {
mImpl->mAttrCount = 0;
}
mImpl->mCapacity = capacity.value();
mImpl->mCapacity = aCapacity;
return true;
}

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

@ -181,9 +181,10 @@ class AttrArray {
AttrArray(const AttrArray& aOther) = delete;
AttrArray& operator=(const AttrArray& aOther) = delete;
private:
bool GrowBy(uint32_t aGrowSize);
bool GrowTo(uint32_t aCapacity);
private:
// Tries to create an attribute, growing the buffer if needed, with the given
// name and value.
//

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

@ -2686,6 +2686,10 @@ nsresult Element::SetAttrAndNotify(
return NS_OK;
}
void Element::TryReserveAttributeCount(uint32_t aAttributeCount) {
(void)mAttrs.GrowTo(aAttributeCount);
}
bool Element::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
const nsAString& aValue,
nsIPrincipal* aMaybeScriptedPrincipal,

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

@ -1658,6 +1658,12 @@ class Element : public FragmentOrElement {
SetAttr(kNameSpaceID_None, aAttr, aValue, aTriggeringPrincipal, true);
}
/**
* Preallocate space in this element's attribute array for the given
* total number of attributes.
*/
void TryReserveAttributeCount(uint32_t aAttributeCount);
/**
* Set a content attribute via a reflecting nullable string IDL
* attribute (e.g. a CORS attribute). If DOMStringIsNull(aValue),

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

@ -406,6 +406,7 @@ nsresult nsHtml5TreeOperation::AddAttributes(nsIContent* aNode,
void nsHtml5TreeOperation::SetHTMLElementAttributes(
Element* aElement, nsAtom* aName, nsHtml5HtmlAttributes* aAttributes) {
int32_t len = aAttributes->getLength();
aElement->TryReserveAttributeCount((uint32_t)len);
for (int32_t i = 0; i < len; i++) {
nsHtml5String val = aAttributes->getValueNoBoundsCheck(i);
nsAtom* klass = val.MaybeAsAtom();