Bug 959150 part 5 - Avoid reallocating the attribute holder when parsing with nsHtml5StringParser. r=smaug.

This commit is contained in:
Henri Sivonen 2014-03-05 21:38:50 +02:00
parent 813381050b
commit 31c6b31aee
8 changed files with 61 additions and 50 deletions

View File

@ -497,12 +497,12 @@ public class Tokenizer implements Locator {
private boolean html4ModeCompatibleWithXhtml1Schemata;
private final boolean newAttributesEachTime;
private int mappingLangToXmlLang;
// ]NOCPP]
private final boolean newAttributesEachTime;
private boolean shouldSuspend;
protected boolean confident;
@ -554,8 +554,12 @@ public class Tokenizer implements Locator {
this.doctypeName = null;
this.publicIdentifier = null;
this.systemIdentifier = null;
// [NOCPP[
this.attributes = null;
// CPPONLY: this.viewingXmlSource = viewingXmlSource;
// ]NOCPP]
// CPPONLY: this.attributes = tokenHandler.HasBuilder() ? new HtmlAttributes(mappingLangToXmlLang) : null;
// CPPONLY: this.newAttributesEachTime = !tokenHandler.HasBuilder();
// CPPONLY: this.viewingXmlSource = viewingXmlSource;
}
public void setInterner(Interner interner) {
@ -1096,21 +1100,6 @@ public class Tokenizer implements Locator {
errorHandler.warning(spe);
}
/**
*
*/
private void resetAttributes() {
// [NOCPP[
if (newAttributesEachTime) {
// ]NOCPP]
attributes = null;
// [NOCPP[
} else {
attributes.clear(mappingLangToXmlLang);
}
// ]NOCPP]
}
private void strBufToElementNameString() {
// if (strBufOffset != -1) {
// return ElementName.elementNameByBuffer(buf, strBufOffset, strBufLen);
@ -1136,17 +1125,26 @@ public class Tokenizer implements Locator {
// CPPONLY: if (!viewingXmlSource) {
tokenHandler.endTag(tagName);
// CPPONLY: }
Portability.delete(attributes);
// CPPONLY: if (newAttributesEachTime) {
// CPPONLY: Portability.delete(attributes);
// CPPONLY: attributes = null;
// CPPONLY: }
} else {
// CPPONLY: if (viewingXmlSource) {
// CPPONLY: Portability.delete(attributes);
// CPPONLY: assert newAttributesEachTime;
// CPPONLY: Portability.delete(attributes);
// CPPONLY: attributes = null;
// CPPONLY: } else {
tokenHandler.startTag(tagName, attrs, selfClosing);
// CPPONLY: }
}
tagName.release();
tagName = null;
resetAttributes();
if (newAttributesEachTime) {
attributes = null;
} else {
attributes.clear(mappingLangToXmlLang);
}
/*
* The token handler may have called setStateAndEndTagExpectation
* and changed stateSave since the start of this method.
@ -6597,11 +6595,11 @@ public class Tokenizer implements Locator {
attributeName = null;
}
tokenHandler.endTokenization();
// [NOCPP[
if (attributes != null) {
attributes.clear(mappingLangToXmlLang);
Portability.delete(attributes);
attributes = null;
}
// ]NOCPP]
}
public void requestSuspension() {
@ -6680,16 +6678,12 @@ public class Tokenizer implements Locator {
attributeName.release();
attributeName = null;
}
// [NOCPP[
if (newAttributesEachTime) {
// ]NOCPP]
if (attributes != null) {
Portability.delete(attributes);
attributes = null;
}
// [NOCPP[
}
// ]NOCPP]
}
public void loadState(Tokenizer other) throws SAXException {
@ -7005,6 +6999,8 @@ public class Tokenizer implements Locator {
void destructor() {
// The translator will write refcount tracing stuff here
Portability.delete(attributes);
attributes = null;
}
// [NOCPP[

View File

@ -3027,9 +3027,9 @@ public abstract class TreeBuilder<T> implements TokenHandler,
if (selfClosing) {
errSelfClosing();
}
if (attributes != HtmlAttributes.EMPTY_ATTRIBUTES) {
Portability.delete(attributes);
}
// CPPONLY: if (mBuilder == null && attributes != HtmlAttributes.EMPTY_ATTRIBUTES) {
// CPPONLY: Portability.delete(attributes);
// CPPONLY: }
}
private void startTagTitleInHead(ElementName elementName, HtmlAttributes attributes) throws SAXException {

View File

@ -98,7 +98,8 @@ nsHtml5Tokenizer::nsHtml5Tokenizer(nsHtml5TreeBuilder* tokenHandler, bool viewin
doctypeName(nullptr),
publicIdentifier(nullptr),
systemIdentifier(nullptr),
attributes(nullptr),
attributes(tokenHandler->HasBuilder() ? new nsHtml5HtmlAttributes(0) : nullptr),
newAttributesEachTime(!tokenHandler->HasBuilder()),
viewingXmlSource(viewingXmlSource)
{
MOZ_COUNT_CTOR(nsHtml5Tokenizer);
@ -283,12 +284,6 @@ nsHtml5Tokenizer::flushChars(char16_t* buf, int32_t pos)
cstart = INT32_MAX;
}
void
nsHtml5Tokenizer::resetAttributes()
{
attributes = nullptr;
}
void
nsHtml5Tokenizer::strBufToElementNameString()
{
@ -307,17 +302,26 @@ nsHtml5Tokenizer::emitCurrentTagToken(bool selfClosing, int32_t pos)
if (!viewingXmlSource) {
tokenHandler->endTag(tagName);
}
delete attributes;
if (newAttributesEachTime) {
delete attributes;
attributes = nullptr;
}
} else {
if (viewingXmlSource) {
MOZ_ASSERT(newAttributesEachTime);
delete attributes;
attributes = nullptr;
} else {
tokenHandler->startTag(tagName, attrs, selfClosing);
}
}
tagName->release();
tagName = nullptr;
resetAttributes();
if (newAttributesEachTime) {
attributes = nullptr;
} else {
attributes->clear(0);
}
return stateSave;
}
@ -3932,11 +3936,6 @@ nsHtml5Tokenizer::end()
attributeName = nullptr;
}
tokenHandler->endTokenization();
if (attributes) {
attributes->clear(0);
delete attributes;
attributes = nullptr;
}
}
void
@ -3981,9 +3980,11 @@ nsHtml5Tokenizer::resetToDataState()
attributeName->release();
attributeName = nullptr;
}
if (attributes) {
delete attributes;
attributes = nullptr;
if (newAttributesEachTime) {
if (attributes) {
delete attributes;
attributes = nullptr;
}
}
}
@ -4080,6 +4081,8 @@ nsHtml5Tokenizer::setEncodingDeclarationHandler(nsHtml5StreamParser* encodingDec
nsHtml5Tokenizer::~nsHtml5Tokenizer()
{
MOZ_COUNT_DTOR(nsHtml5Tokenizer);
delete attributes;
attributes = nullptr;
}
void

View File

@ -130,6 +130,7 @@ class nsHtml5Tokenizer
nsString* publicIdentifier;
nsString* systemIdentifier;
nsHtml5HtmlAttributes* attributes;
bool newAttributesEachTime;
bool shouldSuspend;
protected:
bool confident;
@ -206,7 +207,6 @@ class nsHtml5Tokenizer
protected:
void flushChars(char16_t* buf, int32_t pos);
private:
void resetAttributes();
void strBufToElementNameString();
int32_t emitCurrentTagToken(bool selfClosing, int32_t pos);
void attributeNameComplete();

View File

@ -2,6 +2,11 @@
* 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/. */
inline nsHtml5HtmlAttributes* GetAttributes()
{
return attributes;
}
nsAutoPtr<nsHtml5Highlighter> mViewSource;
/**

View File

@ -1890,7 +1890,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
if (selfClosing) {
errSelfClosing();
}
if (attributes != nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
if (!mBuilder && attributes != nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
delete attributes;
}
}

View File

@ -81,7 +81,8 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName, nsHtml5Htm
aAttributes,
mozilla::dom::FROM_PARSER_FRAGMENT,
mBuilder);
if (aAttributes != nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
if (MOZ_UNLIKELY(aAttributes != tokenizer->GetAttributes() &&
aAttributes != nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES)) {
delete aAttributes;
}
return elem;
@ -511,6 +512,8 @@ nsHtml5TreeBuilder::addAttributesToElement(nsIContentHandle* aElement, nsHtml5Ht
}
if (mBuilder) {
MOZ_ASSERT(aAttributes == tokenizer->GetAttributes(),
"Using attribute other than the tokenizer's to add to body or html.");
nsresult rv = nsHtml5TreeOperation::AddAttributes(
static_cast<nsIContent*>(aElement),
aAttributes,

View File

@ -119,6 +119,10 @@
mPreventScriptExecution = aPrevent;
}
bool HasBuilder() {
return mBuilder;
}
void EnableViewSource(nsHtml5Highlighter* aHighlighter);
void errStrayStartTag(nsIAtom* aName);