From 650f6b5eb31dfe6c60da16d1498f8cc3efac4dfa Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sat, 18 Jan 2020 14:04:17 -0500 Subject: Bug 1355479 - Flatten attribute storage in the HTML parser to AutoTArray to avoid malloc. - Removes nsHtml5ReleasableAttributeName - Adds nsHtml5AttributeEntry.h - Makes nsHtml5HtmlAttributes no longer gentered. Tag UXP Issue #1344 --- parser/html/moz.build | 3 +- parser/html/nsHtml5AttributeEntry.h | 91 ++++++++++++ parser/html/nsHtml5HtmlAttributes.cpp | 188 ++++++++++++------------- parser/html/nsHtml5HtmlAttributes.h | 54 +++---- parser/html/nsHtml5ReleasableAttributeName.cpp | 34 ----- parser/html/nsHtml5ReleasableAttributeName.h | 21 --- 6 files changed, 212 insertions(+), 179 deletions(-) create mode 100644 parser/html/nsHtml5AttributeEntry.h delete mode 100644 parser/html/nsHtml5ReleasableAttributeName.cpp delete mode 100644 parser/html/nsHtml5ReleasableAttributeName.h (limited to 'parser') diff --git a/parser/html/moz.build b/parser/html/moz.build index a3f88f46c..e9bfdbbb9 100644 --- a/parser/html/moz.build +++ b/parser/html/moz.build @@ -19,6 +19,8 @@ EXPORTS += [ 'nsHtml5AtomList.h', 'nsHtml5Atoms.h', 'nsHtml5AtomTable.h', + 'nsHtml5AttributeEntry.h', + 'nsHtml5AttributeName.h', 'nsHtml5ByteReadable.h', 'nsHtml5DependentUTF16Buffer.h', 'nsHtml5DocumentBuilder.h', @@ -71,7 +73,6 @@ UNIFIED_SOURCES += [ 'nsHtml5Parser.cpp', 'nsHtml5PlainTextUtils.cpp', 'nsHtml5Portability.cpp', - 'nsHtml5ReleasableAttributeName.cpp', 'nsHtml5Speculation.cpp', 'nsHtml5SpeculativeLoad.cpp', 'nsHtml5StackNode.cpp', diff --git a/parser/html/nsHtml5AttributeEntry.h b/parser/html/nsHtml5AttributeEntry.h new file mode 100644 index 000000000..75dd10842 --- /dev/null +++ b/parser/html/nsHtml5AttributeEntry.h @@ -0,0 +1,91 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsHtml5AttributeEntry_h +#define nsHtml5AttributeEntry_h + +#include "nsHtml5AttributeName.h" + +class nsHtml5AttributeEntry final +{ +public: + nsHtml5AttributeEntry(nsHtml5AttributeName* aName, + nsHtml5String aValue, + int32_t aLine) + : mLine(aLine) + , mValue(aValue) + { + // Let's hope the compiler coalesces the following as appropriate. + mLocals[0] = aName->getLocal(0); + mLocals[1] = aName->getLocal(1); + mLocals[2] = aName->getLocal(2); + mPrefixes[0] = aName->getPrefix(0); + mPrefixes[1] = aName->getPrefix(1); + mPrefixes[2] = aName->getPrefix(2); + mUris[0] = aName->getUri(0); + mUris[1] = aName->getUri(1); + mUris[2] = aName->getUri(2); + } + + // Isindex-only so doesn't need to deal with SVG and MathML + nsHtml5AttributeEntry(nsIAtom* aName, nsHtml5String aValue, int32_t aLine) + : mLine(aLine) + , mValue(aValue) + { + // Let's hope the compiler coalesces the following as appropriate. + mLocals[0] = aName; + mLocals[1] = aName; + mLocals[2] = aName; + mPrefixes[0] = nullptr; + mPrefixes[1] = nullptr; + mPrefixes[2] = nullptr; + mUris[0] = kNameSpaceID_None; + mUris[1] = kNameSpaceID_None; + mUris[2] = kNameSpaceID_None; + } + + inline nsIAtom* GetLocal(int32_t aMode) { return mLocals[aMode]; } + + inline nsIAtom* GetPrefix(int32_t aMode) { return mPrefixes[aMode]; } + + inline int32_t GetUri(int32_t aMode) { return mUris[aMode]; } + + inline nsHtml5String GetValue() { return mValue; } + + inline int32_t GetLine() { return mLine; } + + inline void ReleaseValue() { mValue.Release(); } + + inline nsHtml5AttributeEntry Clone(nsHtml5AtomTable* aInterner) + { + // Copy the memory + nsHtml5AttributeEntry clone(*this); + // Increment refcount for value + clone.mValue = this->mValue.Clone(); + if (aInterner) { + // Now if we have an interner, we'll need to rewrite non-static atoms. + // Only the local names may be non-static, in which case all three + // are the same. + nsIAtom* local = GetLocal(0); + if (!local->IsStaticAtom()) { + nsAutoString str; + local->ToString(str); + local = aInterner->GetAtom(str); + clone.mLocals[0] = local; + clone.mLocals[1] = local; + clone.mLocals[2] = local; + } + } + return clone; + } + +private: + nsIAtom* mLocals[3]; + nsIAtom* mPrefixes[3]; + int32_t mUris[3]; + int32_t mLine; + nsHtml5String mValue; +}; + +#endif // nsHtml5AttributeEntry_h diff --git a/parser/html/nsHtml5HtmlAttributes.cpp b/parser/html/nsHtml5HtmlAttributes.cpp index 1460b5ca0..bdccd8145 100644 --- a/parser/html/nsHtml5HtmlAttributes.cpp +++ b/parser/html/nsHtml5HtmlAttributes.cpp @@ -23,11 +23,6 @@ * DEALINGS IN THE SOFTWARE. */ -/* - * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT. - * Please edit HtmlAttributes.java instead and regenerate. - */ - #define nsHtml5HtmlAttributes_cpp__ #include "nsIAtom.h" @@ -59,12 +54,8 @@ nsHtml5HtmlAttributes* nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES = nullptr; -nsHtml5HtmlAttributes::nsHtml5HtmlAttributes(int32_t mode) - : mode(mode), - length(0), - names(jArray::newJArray(8)), - values(jArray::newJArray(8)), - lines(jArray::newJArray(8)) +nsHtml5HtmlAttributes::nsHtml5HtmlAttributes(int32_t aMode) + : mMode(aMode) { MOZ_COUNT_CTOR(nsHtml5HtmlAttributes); } @@ -76,11 +67,13 @@ nsHtml5HtmlAttributes::~nsHtml5HtmlAttributes() clear(0); } -int32_t -nsHtml5HtmlAttributes::getIndex(nsHtml5AttributeName* name) +int32_t +nsHtml5HtmlAttributes::getIndex(nsHtml5AttributeName* aName) { - for (int32_t i = 0; i < length; i++) { - if (names[i] == name) { + for (size_t i = 0; i < mStorage.Length(); i++) { + if (mStorage[i].GetLocal(NS_HTML5ATTRIBUTE_NAME_HTML) == + aName->getLocal(NS_HTML5ATTRIBUTE_NAME_HTML)) { + // It's release asserted elsewhere that i can't be too large. return i; } } @@ -88,9 +81,9 @@ nsHtml5HtmlAttributes::getIndex(nsHtml5AttributeName* name) } nsHtml5String -nsHtml5HtmlAttributes::getValue(nsHtml5AttributeName* name) +nsHtml5HtmlAttributes::getValue(nsHtml5AttributeName* aName) { - int32_t index = getIndex(name); + int32_t index = getIndex(aName); if (index == -1) { return nullptr; } else { @@ -101,106 +94,98 @@ nsHtml5HtmlAttributes::getValue(nsHtml5AttributeName* name) int32_t nsHtml5HtmlAttributes::getLength() { - return length; + return mStorage.Length(); } -nsIAtom* -nsHtml5HtmlAttributes::getLocalNameNoBoundsCheck(int32_t index) +nsIAtom* +nsHtml5HtmlAttributes::getLocalNameNoBoundsCheck(int32_t aIndex) { - MOZ_ASSERT(index < length && index >= 0, "Index out of bounds"); - return names[index]->getLocal(mode); + MOZ_ASSERT(aIndex < int32_t(mStorage.Length()) && aIndex >= 0, + "Index out of bounds"); + return mStorage[aIndex].GetLocal(mMode); } -int32_t -nsHtml5HtmlAttributes::getURINoBoundsCheck(int32_t index) +int32_t +nsHtml5HtmlAttributes::getURINoBoundsCheck(int32_t aIndex) { - MOZ_ASSERT(index < length && index >= 0, "Index out of bounds"); - return names[index]->getUri(mode); + MOZ_ASSERT(aIndex < int32_t(mStorage.Length()) && aIndex >= 0, + "Index out of bounds"); + return mStorage[aIndex].GetUri(mMode); } -nsIAtom* -nsHtml5HtmlAttributes::getPrefixNoBoundsCheck(int32_t index) +nsIAtom* +nsHtml5HtmlAttributes::getPrefixNoBoundsCheck(int32_t aIndex) { - MOZ_ASSERT(index < length && index >= 0, "Index out of bounds"); - return names[index]->getPrefix(mode); + MOZ_ASSERT(aIndex < int32_t(mStorage.Length()) && aIndex >= 0, + "Index out of bounds"); + return mStorage[aIndex].GetPrefix(mMode); } nsHtml5String -nsHtml5HtmlAttributes::getValueNoBoundsCheck(int32_t index) +nsHtml5HtmlAttributes::getValueNoBoundsCheck(int32_t aIndex) { - MOZ_ASSERT(index < length && index >= 0, "Index out of bounds"); - return values[index]; + MOZ_ASSERT(aIndex < int32_t(mStorage.Length()) && aIndex >= 0, + "Index out of bounds"); + return mStorage[aIndex].GetValue(); } -nsHtml5AttributeName* -nsHtml5HtmlAttributes::getAttributeNameNoBoundsCheck(int32_t index) +int32_t +nsHtml5HtmlAttributes::getLineNoBoundsCheck(int32_t aIndex) { - MOZ_ASSERT(index < length && index >= 0, "Index out of bounds"); - return names[index]; + MOZ_ASSERT(aIndex < int32_t(mStorage.Length()) && aIndex >= 0, + "Index out of bounds"); + return mStorage[aIndex].GetLine(); } -int32_t -nsHtml5HtmlAttributes::getLineNoBoundsCheck(int32_t index) +void +nsHtml5HtmlAttributes::addAttribute(nsHtml5AttributeName* aName, + nsHtml5String aValue, + int32_t aLine) { - MOZ_ASSERT(index < length && index >= 0, "Index out of bounds"); - return lines[index]; + mStorage.AppendElement(nsHtml5AttributeEntry(aName, aValue, aLine)); + MOZ_RELEASE_ASSERT(mStorage.Length() <= INT32_MAX, + "Can't handle this many attributes."); } -void -nsHtml5HtmlAttributes::addAttribute(nsHtml5AttributeName* name, nsHtml5String value, int32_t line) +// Isindex-only, so doesn't need to deal with SVG and MathML +void +nsHtml5HtmlAttributes::AddAttributeWithLocal(nsIAtom* aName, + nsHtml5String aValue, + int32_t aLine) { - if (names.length == length) { - int32_t newLen = length << 1; - jArray newNames = jArray::newJArray(newLen); - nsHtml5ArrayCopy::arraycopy(names, newNames, names.length); - names = newNames; - jArray newValues = jArray::newJArray(newLen); - nsHtml5ArrayCopy::arraycopy(values, newValues, values.length); - values = newValues; - jArray newLines = jArray::newJArray(newLen); - nsHtml5ArrayCopy::arraycopy(lines, newLines, lines.length); - lines = newLines; - } - names[length] = name; - values[length] = value; - lines[length] = line; - length++; + mStorage.AppendElement(nsHtml5AttributeEntry(aName, aValue, aLine)); + MOZ_RELEASE_ASSERT(mStorage.Length() <= INT32_MAX, + "Can't handle this many attributes."); } -void -nsHtml5HtmlAttributes::clear(int32_t m) +void +nsHtml5HtmlAttributes::clear(int32_t aMode) { - for (int32_t i = 0; i < length; i++) { - names[i]->release(); - names[i] = nullptr; - values[i].Release(); - values[i] = nullptr; + for (nsHtml5AttributeEntry& entry : mStorage) { + entry.ReleaseValue(); } - length = 0; - mode = m; + mStorage.TruncateLength(0); + mMode = aMode; } -void -nsHtml5HtmlAttributes::releaseValue(int32_t i) +void +nsHtml5HtmlAttributes::releaseValue(int32_t aIndex) { - values[i].Release(); + mStorage[aIndex].ReleaseValue(); } void nsHtml5HtmlAttributes::clearWithoutReleasingContents() { - for (int32_t i = 0; i < length; i++) { - names[i] = nullptr; - values[i] = nullptr; - } - length = 0; + mStorage.TruncateLength(0); } -bool -nsHtml5HtmlAttributes::contains(nsHtml5AttributeName* name) +bool +nsHtml5HtmlAttributes::contains(nsHtml5AttributeName* aName) { - for (int32_t i = 0; i < length; i++) { - if (name->equalsAnother(names[i])) { + for (size_t i = 0; i < mStorage.Length(); i++) { + if (mStorage[i].GetLocal(NS_HTML5ATTRIBUTE_NAME_HTML) == + aName->getLocal(NS_HTML5ATTRIBUTE_NAME_HTML)) { return true; } } @@ -210,43 +195,44 @@ nsHtml5HtmlAttributes::contains(nsHtml5AttributeName* name) void nsHtml5HtmlAttributes::adjustForMath() { - mode = NS_HTML5ATTRIBUTE_NAME_MATHML; + mMode = NS_HTML5ATTRIBUTE_NAME_MATHML; } void nsHtml5HtmlAttributes::adjustForSvg() { - mode = NS_HTML5ATTRIBUTE_NAME_SVG; + mMode = NS_HTML5ATTRIBUTE_NAME_SVG; } -nsHtml5HtmlAttributes* -nsHtml5HtmlAttributes::cloneAttributes(nsHtml5AtomTable* interner) +nsHtml5HtmlAttributes* +nsHtml5HtmlAttributes::cloneAttributes(nsHtml5AtomTable* aInterner) { - MOZ_ASSERT((!length) || !mode || mode == 3); - nsHtml5HtmlAttributes* clone = new nsHtml5HtmlAttributes(0); - for (int32_t i = 0; i < length; i++) { - clone->addAttribute(names[i]->cloneAttributeName(interner), nsHtml5Portability::newStringFromString(values[i]), lines[i]); + MOZ_ASSERT(mStorage.IsEmpty() || !mMode); + nsHtml5HtmlAttributes* clone = + new nsHtml5HtmlAttributes(NS_HTML5ATTRIBUTE_NAME_HTML); + for (nsHtml5AttributeEntry& entry : mStorage) { + clone->AddEntry(entry.Clone(aInterner)); } return clone; } -bool -nsHtml5HtmlAttributes::equalsAnother(nsHtml5HtmlAttributes* other) +bool +nsHtml5HtmlAttributes::equalsAnother(nsHtml5HtmlAttributes* aOther) { - MOZ_ASSERT(!mode || mode == 3, "Trying to compare attributes in foreign content."); - int32_t otherLength = other->getLength(); - if (length != otherLength) { + MOZ_ASSERT(!mMode, "Trying to compare attributes in foreign content."); + if (mStorage.Length() != aOther->mStorage.Length()) { return false; } - for (int32_t i = 0; i < length; i++) { + for (nsHtml5AttributeEntry& entry : mStorage) { bool found = false; - nsIAtom* ownLocal = names[i]->getLocal(NS_HTML5ATTRIBUTE_NAME_HTML); - for (int32_t j = 0; j < otherLength; j++) { - if (ownLocal == other->names[j]->getLocal(NS_HTML5ATTRIBUTE_NAME_HTML)) { + nsIAtom* ownLocal = entry.GetLocal(NS_HTML5ATTRIBUTE_NAME_HTML); + for (nsHtml5AttributeEntry& otherEntry : aOther->mStorage) { + if (ownLocal == otherEntry.GetLocal(NS_HTML5ATTRIBUTE_NAME_HTML)) { found = true; - if (!nsHtml5Portability::stringEqualsString(values[i], other->values[j])) { + if (!entry.GetValue().Equals(otherEntry.GetValue())) { return false; } + break; } } if (!found) { @@ -256,6 +242,12 @@ nsHtml5HtmlAttributes::equalsAnother(nsHtml5HtmlAttributes* other) return true; } +void +nsHtml5HtmlAttributes::AddEntry(nsHtml5AttributeEntry&& aEntry) +{ + mStorage.AppendElement(aEntry); +} + void nsHtml5HtmlAttributes::initializeStatics() { diff --git a/parser/html/nsHtml5HtmlAttributes.h b/parser/html/nsHtml5HtmlAttributes.h index f97e80c8a..8dde05771 100644 --- a/parser/html/nsHtml5HtmlAttributes.h +++ b/parser/html/nsHtml5HtmlAttributes.h @@ -23,11 +23,6 @@ * DEALINGS IN THE SOFTWARE. */ -/* - * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT. - * Please edit HtmlAttributes.java instead and regenerate. - */ - #ifndef nsHtml5HtmlAttributes_h #define nsHtml5HtmlAttributes_h @@ -45,6 +40,8 @@ #include "nsIUnicodeDecoder.h" #include "nsHtml5Macros.h" #include "nsIContentHandle.h" +#include "nsTArray.h" +#include "nsHtml5AttributeEntry.h" class nsHtml5StreamParser; @@ -63,32 +60,39 @@ class nsHtml5HtmlAttributes public: static nsHtml5HtmlAttributes* EMPTY_ATTRIBUTES; private: - int32_t mode; - int32_t length; - autoJArray names; - autoJArray values; - autoJArray lines; + AutoTArray mStorage; + int32_t mMode; + void AddEntry(nsHtml5AttributeEntry&& aEntry); + public: - explicit nsHtml5HtmlAttributes(int32_t mode); + explicit nsHtml5HtmlAttributes(int32_t aMode); ~nsHtml5HtmlAttributes(); - int32_t getIndex(nsHtml5AttributeName* name); - nsHtml5String getValue(nsHtml5AttributeName* name); + + // Remove getIndex when removing isindex support + int32_t getIndex(nsHtml5AttributeName* aName); + + nsHtml5String getValue(nsHtml5AttributeName* aName); int32_t getLength(); - nsIAtom* getLocalNameNoBoundsCheck(int32_t index); - int32_t getURINoBoundsCheck(int32_t index); - nsIAtom* getPrefixNoBoundsCheck(int32_t index); - nsHtml5String getValueNoBoundsCheck(int32_t index); - nsHtml5AttributeName* getAttributeNameNoBoundsCheck(int32_t index); - int32_t getLineNoBoundsCheck(int32_t index); - void addAttribute(nsHtml5AttributeName* name, nsHtml5String value, int32_t line); - void clear(int32_t m); - void releaseValue(int32_t i); + nsIAtom* getLocalNameNoBoundsCheck(int32_t aIndex); + int32_t getURINoBoundsCheck(int32_t aIndex); + nsIAtom* getPrefixNoBoundsCheck(int32_t aIndex); + nsHtml5String getValueNoBoundsCheck(int32_t aIndex); + nsHtml5AttributeName* getAttributeNameNoBoundsCheck(int32_t aIndex); + int32_t getLineNoBoundsCheck(int32_t aIndex); + void addAttribute(nsHtml5AttributeName* aName, + nsHtml5String aValue, + int32_t aLine); + void AddAttributeWithLocal(nsIAtom* aName, + nsHtml5String aValue, + int32_t aLine); + void clear(int32_t aMode); + void releaseValue(int32_t aIndex); void clearWithoutReleasingContents(); - bool contains(nsHtml5AttributeName* name); + bool contains(nsHtml5AttributeName* aName); void adjustForMath(); void adjustForSvg(); - nsHtml5HtmlAttributes* cloneAttributes(nsHtml5AtomTable* interner); - bool equalsAnother(nsHtml5HtmlAttributes* other); + nsHtml5HtmlAttributes* cloneAttributes(nsHtml5AtomTable* aInterner); + bool equalsAnother(nsHtml5HtmlAttributes* aOther); static void initializeStatics(); static void releaseStatics(); }; diff --git a/parser/html/nsHtml5ReleasableAttributeName.cpp b/parser/html/nsHtml5ReleasableAttributeName.cpp deleted file mode 100644 index 4cef131e7..000000000 --- a/parser/html/nsHtml5ReleasableAttributeName.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsHtml5ReleasableAttributeName.h" -#include "nsHtml5Portability.h" -#include "nsHtml5AtomTable.h" - -nsHtml5ReleasableAttributeName::nsHtml5ReleasableAttributeName(int32_t* uri, nsIAtom** local, nsIAtom** prefix) - : nsHtml5AttributeName(uri, local, prefix) -{ -} - -nsHtml5AttributeName* -nsHtml5ReleasableAttributeName::cloneAttributeName(nsHtml5AtomTable* aInterner) -{ - nsIAtom* l = getLocal(0); - if (aInterner) { - if (!l->IsStaticAtom()) { - nsAutoString str; - l->ToString(str); - l = aInterner->GetAtom(str); - } - } - return new nsHtml5ReleasableAttributeName(nsHtml5AttributeName::ALL_NO_NS, - nsHtml5AttributeName::SAME_LOCAL(l), - nsHtml5AttributeName::ALL_NO_PREFIX); -} - -void -nsHtml5ReleasableAttributeName::release() -{ - delete this; -} diff --git a/parser/html/nsHtml5ReleasableAttributeName.h b/parser/html/nsHtml5ReleasableAttributeName.h deleted file mode 100644 index e9766173b..000000000 --- a/parser/html/nsHtml5ReleasableAttributeName.h +++ /dev/null @@ -1,21 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nsHtml5ReleasableAttributeName_h -#define nsHtml5ReleasableAttributeName_h - -#include "nsHtml5AttributeName.h" -#include "mozilla/Attributes.h" - -class nsHtml5AtomTable; - -class nsHtml5ReleasableAttributeName final : public nsHtml5AttributeName -{ - public: - nsHtml5ReleasableAttributeName(int32_t* uri, nsIAtom** local, nsIAtom** prefix); - virtual nsHtml5AttributeName* cloneAttributeName(nsHtml5AtomTable* aInterner); - virtual void release(); -}; - -#endif // nsHtml5ReleasableAttributeName_h -- cgit v1.2.3